1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * This file uses the low level AES and engine functions (which are deprecated 12e1051a39Sopenharmony_ci * for non-internal use) in order to implement the padlock engine AES ciphers. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <stdio.h> 17e1051a39Sopenharmony_ci#include <string.h> 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci#include <openssl/opensslconf.h> 20e1051a39Sopenharmony_ci#include <openssl/crypto.h> 21e1051a39Sopenharmony_ci#include <openssl/engine.h> 22e1051a39Sopenharmony_ci#include <openssl/evp.h> 23e1051a39Sopenharmony_ci#include <openssl/aes.h> 24e1051a39Sopenharmony_ci#include <openssl/rand.h> 25e1051a39Sopenharmony_ci#include <openssl/err.h> 26e1051a39Sopenharmony_ci#include <openssl/modes.h> 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_PADLOCKENG 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci/* 31e1051a39Sopenharmony_ci * VIA PadLock AES is available *ONLY* on some x86 CPUs. Not only that it 32e1051a39Sopenharmony_ci * doesn't exist elsewhere, but it even can't be compiled on other platforms! 33e1051a39Sopenharmony_ci */ 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_ci# undef COMPILE_PADLOCKENG 36e1051a39Sopenharmony_ci# if defined(PADLOCK_ASM) 37e1051a39Sopenharmony_ci# define COMPILE_PADLOCKENG 38e1051a39Sopenharmony_ci# ifdef OPENSSL_NO_DYNAMIC_ENGINE 39e1051a39Sopenharmony_cistatic ENGINE *ENGINE_padlock(void); 40e1051a39Sopenharmony_ci# endif 41e1051a39Sopenharmony_ci# endif 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ci# ifdef OPENSSL_NO_DYNAMIC_ENGINE 44e1051a39Sopenharmony_civoid engine_load_padlock_int(void); 45e1051a39Sopenharmony_civoid engine_load_padlock_int(void) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci/* On non-x86 CPUs it just returns. */ 48e1051a39Sopenharmony_ci# ifdef COMPILE_PADLOCKENG 49e1051a39Sopenharmony_ci ENGINE *toadd = ENGINE_padlock(); 50e1051a39Sopenharmony_ci if (!toadd) 51e1051a39Sopenharmony_ci return; 52e1051a39Sopenharmony_ci ERR_set_mark(); 53e1051a39Sopenharmony_ci ENGINE_add(toadd); 54e1051a39Sopenharmony_ci /* 55e1051a39Sopenharmony_ci * If the "add" worked, it gets a structural reference. So either way, we 56e1051a39Sopenharmony_ci * release our just-created reference. 57e1051a39Sopenharmony_ci */ 58e1051a39Sopenharmony_ci ENGINE_free(toadd); 59e1051a39Sopenharmony_ci /* 60e1051a39Sopenharmony_ci * If the "add" didn't work, it was probably a conflict because it was 61e1051a39Sopenharmony_ci * already added (eg. someone calling ENGINE_load_blah then calling 62e1051a39Sopenharmony_ci * ENGINE_load_builtin_engines() perhaps). 63e1051a39Sopenharmony_ci */ 64e1051a39Sopenharmony_ci ERR_pop_to_mark(); 65e1051a39Sopenharmony_ci# endif 66e1051a39Sopenharmony_ci} 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci# endif 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci# ifdef COMPILE_PADLOCKENG 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci/* Function for ENGINE detection and control */ 73e1051a39Sopenharmony_cistatic int padlock_available(void); 74e1051a39Sopenharmony_cistatic int padlock_init(ENGINE *e); 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci/* RNG Stuff */ 77e1051a39Sopenharmony_cistatic RAND_METHOD padlock_rand; 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci/* Cipher Stuff */ 80e1051a39Sopenharmony_cistatic int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 81e1051a39Sopenharmony_ci const int **nids, int nid); 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci/* Engine names */ 84e1051a39Sopenharmony_cistatic const char *padlock_id = "padlock"; 85e1051a39Sopenharmony_cistatic char padlock_name[100]; 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_ci/* Available features */ 88e1051a39Sopenharmony_cistatic int padlock_use_ace = 0; /* Advanced Cryptography Engine */ 89e1051a39Sopenharmony_cistatic int padlock_use_rng = 0; /* Random Number Generator */ 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci/* ===== Engine "management" functions ===== */ 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ci/* Prepare the ENGINE structure for registration */ 94e1051a39Sopenharmony_cistatic int padlock_bind_helper(ENGINE *e) 95e1051a39Sopenharmony_ci{ 96e1051a39Sopenharmony_ci /* Check available features */ 97e1051a39Sopenharmony_ci padlock_available(); 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ci /* 100e1051a39Sopenharmony_ci * RNG is currently disabled for reasons discussed in commentary just 101e1051a39Sopenharmony_ci * before padlock_rand_bytes function. 102e1051a39Sopenharmony_ci */ 103e1051a39Sopenharmony_ci padlock_use_rng = 0; 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci /* Generate a nice engine name with available features */ 106e1051a39Sopenharmony_ci BIO_snprintf(padlock_name, sizeof(padlock_name), 107e1051a39Sopenharmony_ci "VIA PadLock (%s, %s)", 108e1051a39Sopenharmony_ci padlock_use_rng ? "RNG" : "no-RNG", 109e1051a39Sopenharmony_ci padlock_use_ace ? "ACE" : "no-ACE"); 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci /* Register everything or return with an error */ 112e1051a39Sopenharmony_ci if (!ENGINE_set_id(e, padlock_id) || 113e1051a39Sopenharmony_ci !ENGINE_set_name(e, padlock_name) || 114e1051a39Sopenharmony_ci !ENGINE_set_init_function(e, padlock_init) || 115e1051a39Sopenharmony_ci (padlock_use_ace && !ENGINE_set_ciphers(e, padlock_ciphers)) || 116e1051a39Sopenharmony_ci (padlock_use_rng && !ENGINE_set_RAND(e, &padlock_rand))) { 117e1051a39Sopenharmony_ci return 0; 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci /* Everything looks good */ 121e1051a39Sopenharmony_ci return 1; 122e1051a39Sopenharmony_ci} 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ci# ifdef OPENSSL_NO_DYNAMIC_ENGINE 125e1051a39Sopenharmony_ci/* Constructor */ 126e1051a39Sopenharmony_cistatic ENGINE *ENGINE_padlock(void) 127e1051a39Sopenharmony_ci{ 128e1051a39Sopenharmony_ci ENGINE *eng = ENGINE_new(); 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ci if (eng == NULL) { 131e1051a39Sopenharmony_ci return NULL; 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci if (!padlock_bind_helper(eng)) { 135e1051a39Sopenharmony_ci ENGINE_free(eng); 136e1051a39Sopenharmony_ci return NULL; 137e1051a39Sopenharmony_ci } 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci return eng; 140e1051a39Sopenharmony_ci} 141e1051a39Sopenharmony_ci# endif 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_ci/* Check availability of the engine */ 144e1051a39Sopenharmony_cistatic int padlock_init(ENGINE *e) 145e1051a39Sopenharmony_ci{ 146e1051a39Sopenharmony_ci return (padlock_use_rng || padlock_use_ace); 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci# ifndef AES_ASM 150e1051a39Sopenharmony_cistatic int padlock_aes_set_encrypt_key(const unsigned char *userKey, 151e1051a39Sopenharmony_ci const int bits, 152e1051a39Sopenharmony_ci AES_KEY *key); 153e1051a39Sopenharmony_cistatic int padlock_aes_set_decrypt_key(const unsigned char *userKey, 154e1051a39Sopenharmony_ci const int bits, 155e1051a39Sopenharmony_ci AES_KEY *key); 156e1051a39Sopenharmony_ci# define AES_ASM 157e1051a39Sopenharmony_ci# define AES_set_encrypt_key padlock_aes_set_encrypt_key 158e1051a39Sopenharmony_ci# define AES_set_decrypt_key padlock_aes_set_decrypt_key 159e1051a39Sopenharmony_ci# include "../crypto/aes/aes_core.c" 160e1051a39Sopenharmony_ci# endif 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ci/* 163e1051a39Sopenharmony_ci * This stuff is needed if this ENGINE is being compiled into a 164e1051a39Sopenharmony_ci * self-contained shared-library. 165e1051a39Sopenharmony_ci */ 166e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_DYNAMIC_ENGINE 167e1051a39Sopenharmony_cistatic int padlock_bind_fn(ENGINE *e, const char *id) 168e1051a39Sopenharmony_ci{ 169e1051a39Sopenharmony_ci if (id && (strcmp(id, padlock_id) != 0)) { 170e1051a39Sopenharmony_ci return 0; 171e1051a39Sopenharmony_ci } 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ci if (!padlock_bind_helper(e)) { 174e1051a39Sopenharmony_ci return 0; 175e1051a39Sopenharmony_ci } 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ci return 1; 178e1051a39Sopenharmony_ci} 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ciIMPLEMENT_DYNAMIC_CHECK_FN() 181e1051a39Sopenharmony_ciIMPLEMENT_DYNAMIC_BIND_FN(padlock_bind_fn) 182e1051a39Sopenharmony_ci# endif /* !OPENSSL_NO_DYNAMIC_ENGINE */ 183e1051a39Sopenharmony_ci/* ===== Here comes the "real" engine ===== */ 184e1051a39Sopenharmony_ci 185e1051a39Sopenharmony_ci/* Some AES-related constants */ 186e1051a39Sopenharmony_ci# define AES_BLOCK_SIZE 16 187e1051a39Sopenharmony_ci# define AES_KEY_SIZE_128 16 188e1051a39Sopenharmony_ci# define AES_KEY_SIZE_192 24 189e1051a39Sopenharmony_ci# define AES_KEY_SIZE_256 32 190e1051a39Sopenharmony_ci /* 191e1051a39Sopenharmony_ci * Here we store the status information relevant to the current context. 192e1051a39Sopenharmony_ci */ 193e1051a39Sopenharmony_ci /* 194e1051a39Sopenharmony_ci * BIG FAT WARNING: Inline assembler in PADLOCK_XCRYPT_ASM() depends on 195e1051a39Sopenharmony_ci * the order of items in this structure. Don't blindly modify, reorder, 196e1051a39Sopenharmony_ci * etc! 197e1051a39Sopenharmony_ci */ 198e1051a39Sopenharmony_cistruct padlock_cipher_data { 199e1051a39Sopenharmony_ci unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */ 200e1051a39Sopenharmony_ci union { 201e1051a39Sopenharmony_ci unsigned int pad[4]; 202e1051a39Sopenharmony_ci struct { 203e1051a39Sopenharmony_ci int rounds:4; 204e1051a39Sopenharmony_ci int dgst:1; /* n/a in C3 */ 205e1051a39Sopenharmony_ci int align:1; /* n/a in C3 */ 206e1051a39Sopenharmony_ci int ciphr:1; /* n/a in C3 */ 207e1051a39Sopenharmony_ci unsigned int keygen:1; 208e1051a39Sopenharmony_ci int interm:1; 209e1051a39Sopenharmony_ci unsigned int encdec:1; 210e1051a39Sopenharmony_ci int ksize:2; 211e1051a39Sopenharmony_ci } b; 212e1051a39Sopenharmony_ci } cword; /* Control word */ 213e1051a39Sopenharmony_ci AES_KEY ks; /* Encryption key */ 214e1051a39Sopenharmony_ci}; 215e1051a39Sopenharmony_ci 216e1051a39Sopenharmony_ci/* Interface to assembler module */ 217e1051a39Sopenharmony_ciunsigned int padlock_capability(void); 218e1051a39Sopenharmony_civoid padlock_key_bswap(AES_KEY *key); 219e1051a39Sopenharmony_civoid padlock_verify_context(struct padlock_cipher_data *ctx); 220e1051a39Sopenharmony_civoid padlock_reload_key(void); 221e1051a39Sopenharmony_civoid padlock_aes_block(void *out, const void *inp, 222e1051a39Sopenharmony_ci struct padlock_cipher_data *ctx); 223e1051a39Sopenharmony_ciint padlock_ecb_encrypt(void *out, const void *inp, 224e1051a39Sopenharmony_ci struct padlock_cipher_data *ctx, size_t len); 225e1051a39Sopenharmony_ciint padlock_cbc_encrypt(void *out, const void *inp, 226e1051a39Sopenharmony_ci struct padlock_cipher_data *ctx, size_t len); 227e1051a39Sopenharmony_ciint padlock_cfb_encrypt(void *out, const void *inp, 228e1051a39Sopenharmony_ci struct padlock_cipher_data *ctx, size_t len); 229e1051a39Sopenharmony_ciint padlock_ofb_encrypt(void *out, const void *inp, 230e1051a39Sopenharmony_ci struct padlock_cipher_data *ctx, size_t len); 231e1051a39Sopenharmony_ciint padlock_ctr32_encrypt(void *out, const void *inp, 232e1051a39Sopenharmony_ci struct padlock_cipher_data *ctx, size_t len); 233e1051a39Sopenharmony_ciint padlock_xstore(void *out, int edx); 234e1051a39Sopenharmony_civoid padlock_sha1_oneshot(void *ctx, const void *inp, size_t len); 235e1051a39Sopenharmony_civoid padlock_sha1(void *ctx, const void *inp, size_t len); 236e1051a39Sopenharmony_civoid padlock_sha256_oneshot(void *ctx, const void *inp, size_t len); 237e1051a39Sopenharmony_civoid padlock_sha256(void *ctx, const void *inp, size_t len); 238e1051a39Sopenharmony_ci 239e1051a39Sopenharmony_ci/* 240e1051a39Sopenharmony_ci * Load supported features of the CPU to see if the PadLock is available. 241e1051a39Sopenharmony_ci */ 242e1051a39Sopenharmony_cistatic int padlock_available(void) 243e1051a39Sopenharmony_ci{ 244e1051a39Sopenharmony_ci unsigned int edx = padlock_capability(); 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci /* Fill up some flags */ 247e1051a39Sopenharmony_ci padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6)); 248e1051a39Sopenharmony_ci padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2)); 249e1051a39Sopenharmony_ci 250e1051a39Sopenharmony_ci return padlock_use_ace + padlock_use_rng; 251e1051a39Sopenharmony_ci} 252e1051a39Sopenharmony_ci 253e1051a39Sopenharmony_ci/* ===== AES encryption/decryption ===== */ 254e1051a39Sopenharmony_ci 255e1051a39Sopenharmony_ci# if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb) 256e1051a39Sopenharmony_ci# define NID_aes_128_cfb NID_aes_128_cfb128 257e1051a39Sopenharmony_ci# endif 258e1051a39Sopenharmony_ci 259e1051a39Sopenharmony_ci# if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb) 260e1051a39Sopenharmony_ci# define NID_aes_128_ofb NID_aes_128_ofb128 261e1051a39Sopenharmony_ci# endif 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ci# if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb) 264e1051a39Sopenharmony_ci# define NID_aes_192_cfb NID_aes_192_cfb128 265e1051a39Sopenharmony_ci# endif 266e1051a39Sopenharmony_ci 267e1051a39Sopenharmony_ci# if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb) 268e1051a39Sopenharmony_ci# define NID_aes_192_ofb NID_aes_192_ofb128 269e1051a39Sopenharmony_ci# endif 270e1051a39Sopenharmony_ci 271e1051a39Sopenharmony_ci# if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb) 272e1051a39Sopenharmony_ci# define NID_aes_256_cfb NID_aes_256_cfb128 273e1051a39Sopenharmony_ci# endif 274e1051a39Sopenharmony_ci 275e1051a39Sopenharmony_ci# if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb) 276e1051a39Sopenharmony_ci# define NID_aes_256_ofb NID_aes_256_ofb128 277e1051a39Sopenharmony_ci# endif 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci/* List of supported ciphers. */ 280e1051a39Sopenharmony_cistatic const int padlock_cipher_nids[] = { 281e1051a39Sopenharmony_ci NID_aes_128_ecb, 282e1051a39Sopenharmony_ci NID_aes_128_cbc, 283e1051a39Sopenharmony_ci NID_aes_128_cfb, 284e1051a39Sopenharmony_ci NID_aes_128_ofb, 285e1051a39Sopenharmony_ci NID_aes_128_ctr, 286e1051a39Sopenharmony_ci 287e1051a39Sopenharmony_ci NID_aes_192_ecb, 288e1051a39Sopenharmony_ci NID_aes_192_cbc, 289e1051a39Sopenharmony_ci NID_aes_192_cfb, 290e1051a39Sopenharmony_ci NID_aes_192_ofb, 291e1051a39Sopenharmony_ci NID_aes_192_ctr, 292e1051a39Sopenharmony_ci 293e1051a39Sopenharmony_ci NID_aes_256_ecb, 294e1051a39Sopenharmony_ci NID_aes_256_cbc, 295e1051a39Sopenharmony_ci NID_aes_256_cfb, 296e1051a39Sopenharmony_ci NID_aes_256_ofb, 297e1051a39Sopenharmony_ci NID_aes_256_ctr 298e1051a39Sopenharmony_ci}; 299e1051a39Sopenharmony_ci 300e1051a39Sopenharmony_cistatic int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids) / 301e1051a39Sopenharmony_ci sizeof(padlock_cipher_nids[0])); 302e1051a39Sopenharmony_ci 303e1051a39Sopenharmony_ci/* Function prototypes ... */ 304e1051a39Sopenharmony_cistatic int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 305e1051a39Sopenharmony_ci const unsigned char *iv, int enc); 306e1051a39Sopenharmony_ci 307e1051a39Sopenharmony_ci# define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \ 308e1051a39Sopenharmony_ci ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) ) 309e1051a39Sopenharmony_ci# define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\ 310e1051a39Sopenharmony_ci NEAREST_ALIGNED(EVP_CIPHER_CTX_get_cipher_data(ctx))) 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_cistatic int 313e1051a39Sopenharmony_cipadlock_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, 314e1051a39Sopenharmony_ci const unsigned char *in_arg, size_t nbytes) 315e1051a39Sopenharmony_ci{ 316e1051a39Sopenharmony_ci return padlock_ecb_encrypt(out_arg, in_arg, 317e1051a39Sopenharmony_ci ALIGNED_CIPHER_DATA(ctx), nbytes); 318e1051a39Sopenharmony_ci} 319e1051a39Sopenharmony_ci 320e1051a39Sopenharmony_cistatic int 321e1051a39Sopenharmony_cipadlock_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, 322e1051a39Sopenharmony_ci const unsigned char *in_arg, size_t nbytes) 323e1051a39Sopenharmony_ci{ 324e1051a39Sopenharmony_ci struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); 325e1051a39Sopenharmony_ci int ret; 326e1051a39Sopenharmony_ci 327e1051a39Sopenharmony_ci memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE); 328e1051a39Sopenharmony_ci if ((ret = padlock_cbc_encrypt(out_arg, in_arg, cdata, nbytes))) 329e1051a39Sopenharmony_ci memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE); 330e1051a39Sopenharmony_ci return ret; 331e1051a39Sopenharmony_ci} 332e1051a39Sopenharmony_ci 333e1051a39Sopenharmony_cistatic int 334e1051a39Sopenharmony_cipadlock_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, 335e1051a39Sopenharmony_ci const unsigned char *in_arg, size_t nbytes) 336e1051a39Sopenharmony_ci{ 337e1051a39Sopenharmony_ci struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); 338e1051a39Sopenharmony_ci size_t chunk; 339e1051a39Sopenharmony_ci 340e1051a39Sopenharmony_ci if ((chunk = EVP_CIPHER_CTX_get_num(ctx))) { /* borrow chunk variable */ 341e1051a39Sopenharmony_ci unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx); 342e1051a39Sopenharmony_ci 343e1051a39Sopenharmony_ci if (chunk >= AES_BLOCK_SIZE) 344e1051a39Sopenharmony_ci return 0; /* bogus value */ 345e1051a39Sopenharmony_ci 346e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_is_encrypting(ctx)) 347e1051a39Sopenharmony_ci while (chunk < AES_BLOCK_SIZE && nbytes != 0) { 348e1051a39Sopenharmony_ci ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk]; 349e1051a39Sopenharmony_ci chunk++, nbytes--; 350e1051a39Sopenharmony_ci } else 351e1051a39Sopenharmony_ci while (chunk < AES_BLOCK_SIZE && nbytes != 0) { 352e1051a39Sopenharmony_ci unsigned char c = *(in_arg++); 353e1051a39Sopenharmony_ci *(out_arg++) = c ^ ivp[chunk]; 354e1051a39Sopenharmony_ci ivp[chunk++] = c, nbytes--; 355e1051a39Sopenharmony_ci } 356e1051a39Sopenharmony_ci 357e1051a39Sopenharmony_ci EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE); 358e1051a39Sopenharmony_ci } 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci if (nbytes == 0) 361e1051a39Sopenharmony_ci return 1; 362e1051a39Sopenharmony_ci 363e1051a39Sopenharmony_ci memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE); 364e1051a39Sopenharmony_ci 365e1051a39Sopenharmony_ci if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) { 366e1051a39Sopenharmony_ci if (!padlock_cfb_encrypt(out_arg, in_arg, cdata, chunk)) 367e1051a39Sopenharmony_ci return 0; 368e1051a39Sopenharmony_ci nbytes -= chunk; 369e1051a39Sopenharmony_ci } 370e1051a39Sopenharmony_ci 371e1051a39Sopenharmony_ci if (nbytes) { 372e1051a39Sopenharmony_ci unsigned char *ivp = cdata->iv; 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci out_arg += chunk; 375e1051a39Sopenharmony_ci in_arg += chunk; 376e1051a39Sopenharmony_ci EVP_CIPHER_CTX_set_num(ctx, nbytes); 377e1051a39Sopenharmony_ci if (cdata->cword.b.encdec) { 378e1051a39Sopenharmony_ci cdata->cword.b.encdec = 0; 379e1051a39Sopenharmony_ci padlock_reload_key(); 380e1051a39Sopenharmony_ci padlock_aes_block(ivp, ivp, cdata); 381e1051a39Sopenharmony_ci cdata->cword.b.encdec = 1; 382e1051a39Sopenharmony_ci padlock_reload_key(); 383e1051a39Sopenharmony_ci while (nbytes) { 384e1051a39Sopenharmony_ci unsigned char c = *(in_arg++); 385e1051a39Sopenharmony_ci *(out_arg++) = c ^ *ivp; 386e1051a39Sopenharmony_ci *(ivp++) = c, nbytes--; 387e1051a39Sopenharmony_ci } 388e1051a39Sopenharmony_ci } else { 389e1051a39Sopenharmony_ci padlock_reload_key(); 390e1051a39Sopenharmony_ci padlock_aes_block(ivp, ivp, cdata); 391e1051a39Sopenharmony_ci padlock_reload_key(); 392e1051a39Sopenharmony_ci while (nbytes) { 393e1051a39Sopenharmony_ci *ivp = *(out_arg++) = *(in_arg++) ^ *ivp; 394e1051a39Sopenharmony_ci ivp++, nbytes--; 395e1051a39Sopenharmony_ci } 396e1051a39Sopenharmony_ci } 397e1051a39Sopenharmony_ci } 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE); 400e1051a39Sopenharmony_ci 401e1051a39Sopenharmony_ci return 1; 402e1051a39Sopenharmony_ci} 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_cistatic int 405e1051a39Sopenharmony_cipadlock_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, 406e1051a39Sopenharmony_ci const unsigned char *in_arg, size_t nbytes) 407e1051a39Sopenharmony_ci{ 408e1051a39Sopenharmony_ci struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); 409e1051a39Sopenharmony_ci size_t chunk; 410e1051a39Sopenharmony_ci 411e1051a39Sopenharmony_ci /* 412e1051a39Sopenharmony_ci * ctx->num is maintained in byte-oriented modes, such as CFB and OFB... 413e1051a39Sopenharmony_ci */ 414e1051a39Sopenharmony_ci if ((chunk = EVP_CIPHER_CTX_get_num(ctx))) { /* borrow chunk variable */ 415e1051a39Sopenharmony_ci unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx); 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci if (chunk >= AES_BLOCK_SIZE) 418e1051a39Sopenharmony_ci return 0; /* bogus value */ 419e1051a39Sopenharmony_ci 420e1051a39Sopenharmony_ci while (chunk < AES_BLOCK_SIZE && nbytes != 0) { 421e1051a39Sopenharmony_ci *(out_arg++) = *(in_arg++) ^ ivp[chunk]; 422e1051a39Sopenharmony_ci chunk++, nbytes--; 423e1051a39Sopenharmony_ci } 424e1051a39Sopenharmony_ci 425e1051a39Sopenharmony_ci EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE); 426e1051a39Sopenharmony_ci } 427e1051a39Sopenharmony_ci 428e1051a39Sopenharmony_ci if (nbytes == 0) 429e1051a39Sopenharmony_ci return 1; 430e1051a39Sopenharmony_ci 431e1051a39Sopenharmony_ci memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE); 432e1051a39Sopenharmony_ci 433e1051a39Sopenharmony_ci if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) { 434e1051a39Sopenharmony_ci if (!padlock_ofb_encrypt(out_arg, in_arg, cdata, chunk)) 435e1051a39Sopenharmony_ci return 0; 436e1051a39Sopenharmony_ci nbytes -= chunk; 437e1051a39Sopenharmony_ci } 438e1051a39Sopenharmony_ci 439e1051a39Sopenharmony_ci if (nbytes) { 440e1051a39Sopenharmony_ci unsigned char *ivp = cdata->iv; 441e1051a39Sopenharmony_ci 442e1051a39Sopenharmony_ci out_arg += chunk; 443e1051a39Sopenharmony_ci in_arg += chunk; 444e1051a39Sopenharmony_ci EVP_CIPHER_CTX_set_num(ctx, nbytes); 445e1051a39Sopenharmony_ci padlock_reload_key(); /* empirically found */ 446e1051a39Sopenharmony_ci padlock_aes_block(ivp, ivp, cdata); 447e1051a39Sopenharmony_ci padlock_reload_key(); /* empirically found */ 448e1051a39Sopenharmony_ci while (nbytes) { 449e1051a39Sopenharmony_ci *(out_arg++) = *(in_arg++) ^ *ivp; 450e1051a39Sopenharmony_ci ivp++, nbytes--; 451e1051a39Sopenharmony_ci } 452e1051a39Sopenharmony_ci } 453e1051a39Sopenharmony_ci 454e1051a39Sopenharmony_ci memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE); 455e1051a39Sopenharmony_ci 456e1051a39Sopenharmony_ci return 1; 457e1051a39Sopenharmony_ci} 458e1051a39Sopenharmony_ci 459e1051a39Sopenharmony_cistatic void padlock_ctr32_encrypt_glue(const unsigned char *in, 460e1051a39Sopenharmony_ci unsigned char *out, size_t blocks, 461e1051a39Sopenharmony_ci struct padlock_cipher_data *ctx, 462e1051a39Sopenharmony_ci const unsigned char *ivec) 463e1051a39Sopenharmony_ci{ 464e1051a39Sopenharmony_ci memcpy(ctx->iv, ivec, AES_BLOCK_SIZE); 465e1051a39Sopenharmony_ci padlock_ctr32_encrypt(out, in, ctx, AES_BLOCK_SIZE * blocks); 466e1051a39Sopenharmony_ci} 467e1051a39Sopenharmony_ci 468e1051a39Sopenharmony_cistatic int 469e1051a39Sopenharmony_cipadlock_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, 470e1051a39Sopenharmony_ci const unsigned char *in_arg, size_t nbytes) 471e1051a39Sopenharmony_ci{ 472e1051a39Sopenharmony_ci struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx); 473e1051a39Sopenharmony_ci int n = EVP_CIPHER_CTX_get_num(ctx); 474e1051a39Sopenharmony_ci unsigned int num; 475e1051a39Sopenharmony_ci 476e1051a39Sopenharmony_ci if (n < 0) 477e1051a39Sopenharmony_ci return 0; 478e1051a39Sopenharmony_ci num = (unsigned int)n; 479e1051a39Sopenharmony_ci 480e1051a39Sopenharmony_ci CRYPTO_ctr128_encrypt_ctr32(in_arg, out_arg, nbytes, 481e1051a39Sopenharmony_ci cdata, EVP_CIPHER_CTX_iv_noconst(ctx), 482e1051a39Sopenharmony_ci EVP_CIPHER_CTX_buf_noconst(ctx), &num, 483e1051a39Sopenharmony_ci (ctr128_f) padlock_ctr32_encrypt_glue); 484e1051a39Sopenharmony_ci 485e1051a39Sopenharmony_ci EVP_CIPHER_CTX_set_num(ctx, (size_t)num); 486e1051a39Sopenharmony_ci return 1; 487e1051a39Sopenharmony_ci} 488e1051a39Sopenharmony_ci 489e1051a39Sopenharmony_ci# define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE 490e1051a39Sopenharmony_ci# define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE 491e1051a39Sopenharmony_ci# define EVP_CIPHER_block_size_OFB 1 492e1051a39Sopenharmony_ci# define EVP_CIPHER_block_size_CFB 1 493e1051a39Sopenharmony_ci# define EVP_CIPHER_block_size_CTR 1 494e1051a39Sopenharmony_ci 495e1051a39Sopenharmony_ci/* 496e1051a39Sopenharmony_ci * Declaring so many ciphers by hand would be a pain. Instead introduce a bit 497e1051a39Sopenharmony_ci * of preprocessor magic :-) 498e1051a39Sopenharmony_ci */ 499e1051a39Sopenharmony_ci# define DECLARE_AES_EVP(ksize,lmode,umode) \ 500e1051a39Sopenharmony_cistatic EVP_CIPHER *_hidden_aes_##ksize##_##lmode = NULL; \ 501e1051a39Sopenharmony_cistatic const EVP_CIPHER *padlock_aes_##ksize##_##lmode(void) \ 502e1051a39Sopenharmony_ci{ \ 503e1051a39Sopenharmony_ci if (_hidden_aes_##ksize##_##lmode == NULL \ 504e1051a39Sopenharmony_ci && ((_hidden_aes_##ksize##_##lmode = \ 505e1051a39Sopenharmony_ci EVP_CIPHER_meth_new(NID_aes_##ksize##_##lmode, \ 506e1051a39Sopenharmony_ci EVP_CIPHER_block_size_##umode, \ 507e1051a39Sopenharmony_ci AES_KEY_SIZE_##ksize)) == NULL \ 508e1051a39Sopenharmony_ci || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_##ksize##_##lmode, \ 509e1051a39Sopenharmony_ci AES_BLOCK_SIZE) \ 510e1051a39Sopenharmony_ci || !EVP_CIPHER_meth_set_flags(_hidden_aes_##ksize##_##lmode, \ 511e1051a39Sopenharmony_ci 0 | EVP_CIPH_##umode##_MODE) \ 512e1051a39Sopenharmony_ci || !EVP_CIPHER_meth_set_init(_hidden_aes_##ksize##_##lmode, \ 513e1051a39Sopenharmony_ci padlock_aes_init_key) \ 514e1051a39Sopenharmony_ci || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_##ksize##_##lmode, \ 515e1051a39Sopenharmony_ci padlock_##lmode##_cipher) \ 516e1051a39Sopenharmony_ci || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_##ksize##_##lmode, \ 517e1051a39Sopenharmony_ci sizeof(struct padlock_cipher_data) + 16) \ 518e1051a39Sopenharmony_ci || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_##ksize##_##lmode, \ 519e1051a39Sopenharmony_ci EVP_CIPHER_set_asn1_iv) \ 520e1051a39Sopenharmony_ci || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_##ksize##_##lmode, \ 521e1051a39Sopenharmony_ci EVP_CIPHER_get_asn1_iv))) { \ 522e1051a39Sopenharmony_ci EVP_CIPHER_meth_free(_hidden_aes_##ksize##_##lmode); \ 523e1051a39Sopenharmony_ci _hidden_aes_##ksize##_##lmode = NULL; \ 524e1051a39Sopenharmony_ci } \ 525e1051a39Sopenharmony_ci return _hidden_aes_##ksize##_##lmode; \ 526e1051a39Sopenharmony_ci} 527e1051a39Sopenharmony_ci 528e1051a39Sopenharmony_ciDECLARE_AES_EVP(128, ecb, ECB) 529e1051a39Sopenharmony_ciDECLARE_AES_EVP(128, cbc, CBC) 530e1051a39Sopenharmony_ciDECLARE_AES_EVP(128, cfb, CFB) 531e1051a39Sopenharmony_ciDECLARE_AES_EVP(128, ofb, OFB) 532e1051a39Sopenharmony_ciDECLARE_AES_EVP(128, ctr, CTR) 533e1051a39Sopenharmony_ci 534e1051a39Sopenharmony_ciDECLARE_AES_EVP(192, ecb, ECB) 535e1051a39Sopenharmony_ciDECLARE_AES_EVP(192, cbc, CBC) 536e1051a39Sopenharmony_ciDECLARE_AES_EVP(192, cfb, CFB) 537e1051a39Sopenharmony_ciDECLARE_AES_EVP(192, ofb, OFB) 538e1051a39Sopenharmony_ciDECLARE_AES_EVP(192, ctr, CTR) 539e1051a39Sopenharmony_ci 540e1051a39Sopenharmony_ciDECLARE_AES_EVP(256, ecb, ECB) 541e1051a39Sopenharmony_ciDECLARE_AES_EVP(256, cbc, CBC) 542e1051a39Sopenharmony_ciDECLARE_AES_EVP(256, cfb, CFB) 543e1051a39Sopenharmony_ciDECLARE_AES_EVP(256, ofb, OFB) 544e1051a39Sopenharmony_ciDECLARE_AES_EVP(256, ctr, CTR) 545e1051a39Sopenharmony_ci 546e1051a39Sopenharmony_cistatic int 547e1051a39Sopenharmony_cipadlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, 548e1051a39Sopenharmony_ci int nid) 549e1051a39Sopenharmony_ci{ 550e1051a39Sopenharmony_ci /* No specific cipher => return a list of supported nids ... */ 551e1051a39Sopenharmony_ci if (!cipher) { 552e1051a39Sopenharmony_ci *nids = padlock_cipher_nids; 553e1051a39Sopenharmony_ci return padlock_cipher_nids_num; 554e1051a39Sopenharmony_ci } 555e1051a39Sopenharmony_ci 556e1051a39Sopenharmony_ci /* ... or the requested "cipher" otherwise */ 557e1051a39Sopenharmony_ci switch (nid) { 558e1051a39Sopenharmony_ci case NID_aes_128_ecb: 559e1051a39Sopenharmony_ci *cipher = padlock_aes_128_ecb(); 560e1051a39Sopenharmony_ci break; 561e1051a39Sopenharmony_ci case NID_aes_128_cbc: 562e1051a39Sopenharmony_ci *cipher = padlock_aes_128_cbc(); 563e1051a39Sopenharmony_ci break; 564e1051a39Sopenharmony_ci case NID_aes_128_cfb: 565e1051a39Sopenharmony_ci *cipher = padlock_aes_128_cfb(); 566e1051a39Sopenharmony_ci break; 567e1051a39Sopenharmony_ci case NID_aes_128_ofb: 568e1051a39Sopenharmony_ci *cipher = padlock_aes_128_ofb(); 569e1051a39Sopenharmony_ci break; 570e1051a39Sopenharmony_ci case NID_aes_128_ctr: 571e1051a39Sopenharmony_ci *cipher = padlock_aes_128_ctr(); 572e1051a39Sopenharmony_ci break; 573e1051a39Sopenharmony_ci 574e1051a39Sopenharmony_ci case NID_aes_192_ecb: 575e1051a39Sopenharmony_ci *cipher = padlock_aes_192_ecb(); 576e1051a39Sopenharmony_ci break; 577e1051a39Sopenharmony_ci case NID_aes_192_cbc: 578e1051a39Sopenharmony_ci *cipher = padlock_aes_192_cbc(); 579e1051a39Sopenharmony_ci break; 580e1051a39Sopenharmony_ci case NID_aes_192_cfb: 581e1051a39Sopenharmony_ci *cipher = padlock_aes_192_cfb(); 582e1051a39Sopenharmony_ci break; 583e1051a39Sopenharmony_ci case NID_aes_192_ofb: 584e1051a39Sopenharmony_ci *cipher = padlock_aes_192_ofb(); 585e1051a39Sopenharmony_ci break; 586e1051a39Sopenharmony_ci case NID_aes_192_ctr: 587e1051a39Sopenharmony_ci *cipher = padlock_aes_192_ctr(); 588e1051a39Sopenharmony_ci break; 589e1051a39Sopenharmony_ci 590e1051a39Sopenharmony_ci case NID_aes_256_ecb: 591e1051a39Sopenharmony_ci *cipher = padlock_aes_256_ecb(); 592e1051a39Sopenharmony_ci break; 593e1051a39Sopenharmony_ci case NID_aes_256_cbc: 594e1051a39Sopenharmony_ci *cipher = padlock_aes_256_cbc(); 595e1051a39Sopenharmony_ci break; 596e1051a39Sopenharmony_ci case NID_aes_256_cfb: 597e1051a39Sopenharmony_ci *cipher = padlock_aes_256_cfb(); 598e1051a39Sopenharmony_ci break; 599e1051a39Sopenharmony_ci case NID_aes_256_ofb: 600e1051a39Sopenharmony_ci *cipher = padlock_aes_256_ofb(); 601e1051a39Sopenharmony_ci break; 602e1051a39Sopenharmony_ci case NID_aes_256_ctr: 603e1051a39Sopenharmony_ci *cipher = padlock_aes_256_ctr(); 604e1051a39Sopenharmony_ci break; 605e1051a39Sopenharmony_ci 606e1051a39Sopenharmony_ci default: 607e1051a39Sopenharmony_ci /* Sorry, we don't support this NID */ 608e1051a39Sopenharmony_ci *cipher = NULL; 609e1051a39Sopenharmony_ci return 0; 610e1051a39Sopenharmony_ci } 611e1051a39Sopenharmony_ci 612e1051a39Sopenharmony_ci return 1; 613e1051a39Sopenharmony_ci} 614e1051a39Sopenharmony_ci 615e1051a39Sopenharmony_ci/* Prepare the encryption key for PadLock usage */ 616e1051a39Sopenharmony_cistatic int 617e1051a39Sopenharmony_cipadlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 618e1051a39Sopenharmony_ci const unsigned char *iv, int enc) 619e1051a39Sopenharmony_ci{ 620e1051a39Sopenharmony_ci struct padlock_cipher_data *cdata; 621e1051a39Sopenharmony_ci int key_len = EVP_CIPHER_CTX_get_key_length(ctx) * 8; 622e1051a39Sopenharmony_ci unsigned long mode = EVP_CIPHER_CTX_get_mode(ctx); 623e1051a39Sopenharmony_ci 624e1051a39Sopenharmony_ci if (key == NULL) 625e1051a39Sopenharmony_ci return 0; /* ERROR */ 626e1051a39Sopenharmony_ci 627e1051a39Sopenharmony_ci cdata = ALIGNED_CIPHER_DATA(ctx); 628e1051a39Sopenharmony_ci memset(cdata, 0, sizeof(*cdata)); 629e1051a39Sopenharmony_ci 630e1051a39Sopenharmony_ci /* Prepare Control word. */ 631e1051a39Sopenharmony_ci if (mode == EVP_CIPH_OFB_MODE || mode == EVP_CIPH_CTR_MODE) 632e1051a39Sopenharmony_ci cdata->cword.b.encdec = 0; 633e1051a39Sopenharmony_ci else 634e1051a39Sopenharmony_ci cdata->cword.b.encdec = (EVP_CIPHER_CTX_is_encrypting(ctx) == 0); 635e1051a39Sopenharmony_ci cdata->cword.b.rounds = 10 + (key_len - 128) / 32; 636e1051a39Sopenharmony_ci cdata->cword.b.ksize = (key_len - 128) / 64; 637e1051a39Sopenharmony_ci 638e1051a39Sopenharmony_ci switch (key_len) { 639e1051a39Sopenharmony_ci case 128: 640e1051a39Sopenharmony_ci /* 641e1051a39Sopenharmony_ci * PadLock can generate an extended key for AES128 in hardware 642e1051a39Sopenharmony_ci */ 643e1051a39Sopenharmony_ci memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128); 644e1051a39Sopenharmony_ci cdata->cword.b.keygen = 0; 645e1051a39Sopenharmony_ci break; 646e1051a39Sopenharmony_ci 647e1051a39Sopenharmony_ci case 192: 648e1051a39Sopenharmony_ci case 256: 649e1051a39Sopenharmony_ci /* 650e1051a39Sopenharmony_ci * Generate an extended AES key in software. Needed for AES192/AES256 651e1051a39Sopenharmony_ci */ 652e1051a39Sopenharmony_ci /* 653e1051a39Sopenharmony_ci * Well, the above applies to Stepping 8 CPUs and is listed as 654e1051a39Sopenharmony_ci * hardware errata. They most likely will fix it at some point and 655e1051a39Sopenharmony_ci * then a check for stepping would be due here. 656e1051a39Sopenharmony_ci */ 657e1051a39Sopenharmony_ci if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) 658e1051a39Sopenharmony_ci && !enc) 659e1051a39Sopenharmony_ci AES_set_decrypt_key(key, key_len, &cdata->ks); 660e1051a39Sopenharmony_ci else 661e1051a39Sopenharmony_ci AES_set_encrypt_key(key, key_len, &cdata->ks); 662e1051a39Sopenharmony_ci /* 663e1051a39Sopenharmony_ci * OpenSSL C functions use byte-swapped extended key. 664e1051a39Sopenharmony_ci */ 665e1051a39Sopenharmony_ci padlock_key_bswap(&cdata->ks); 666e1051a39Sopenharmony_ci cdata->cword.b.keygen = 1; 667e1051a39Sopenharmony_ci break; 668e1051a39Sopenharmony_ci 669e1051a39Sopenharmony_ci default: 670e1051a39Sopenharmony_ci /* ERROR */ 671e1051a39Sopenharmony_ci return 0; 672e1051a39Sopenharmony_ci } 673e1051a39Sopenharmony_ci 674e1051a39Sopenharmony_ci /* 675e1051a39Sopenharmony_ci * This is done to cover for cases when user reuses the 676e1051a39Sopenharmony_ci * context for new key. The catch is that if we don't do 677e1051a39Sopenharmony_ci * this, padlock_eas_cipher might proceed with old key... 678e1051a39Sopenharmony_ci */ 679e1051a39Sopenharmony_ci padlock_reload_key(); 680e1051a39Sopenharmony_ci 681e1051a39Sopenharmony_ci return 1; 682e1051a39Sopenharmony_ci} 683e1051a39Sopenharmony_ci 684e1051a39Sopenharmony_ci/* ===== Random Number Generator ===== */ 685e1051a39Sopenharmony_ci/* 686e1051a39Sopenharmony_ci * This code is not engaged. The reason is that it does not comply 687e1051a39Sopenharmony_ci * with recommendations for VIA RNG usage for secure applications 688e1051a39Sopenharmony_ci * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it 689e1051a39Sopenharmony_ci * provide meaningful error control... 690e1051a39Sopenharmony_ci */ 691e1051a39Sopenharmony_ci/* 692e1051a39Sopenharmony_ci * Wrapper that provides an interface between the API and the raw PadLock 693e1051a39Sopenharmony_ci * RNG 694e1051a39Sopenharmony_ci */ 695e1051a39Sopenharmony_cistatic int padlock_rand_bytes(unsigned char *output, int count) 696e1051a39Sopenharmony_ci{ 697e1051a39Sopenharmony_ci unsigned int eax, buf; 698e1051a39Sopenharmony_ci 699e1051a39Sopenharmony_ci while (count >= 8) { 700e1051a39Sopenharmony_ci eax = padlock_xstore(output, 0); 701e1051a39Sopenharmony_ci if (!(eax & (1 << 6))) 702e1051a39Sopenharmony_ci return 0; /* RNG disabled */ 703e1051a39Sopenharmony_ci /* this ---vv--- covers DC bias, Raw Bits and String Filter */ 704e1051a39Sopenharmony_ci if (eax & (0x1F << 10)) 705e1051a39Sopenharmony_ci return 0; 706e1051a39Sopenharmony_ci if ((eax & 0x1F) == 0) 707e1051a39Sopenharmony_ci continue; /* no data, retry... */ 708e1051a39Sopenharmony_ci if ((eax & 0x1F) != 8) 709e1051a39Sopenharmony_ci return 0; /* fatal failure... */ 710e1051a39Sopenharmony_ci output += 8; 711e1051a39Sopenharmony_ci count -= 8; 712e1051a39Sopenharmony_ci } 713e1051a39Sopenharmony_ci while (count > 0) { 714e1051a39Sopenharmony_ci eax = padlock_xstore(&buf, 3); 715e1051a39Sopenharmony_ci if (!(eax & (1 << 6))) 716e1051a39Sopenharmony_ci return 0; /* RNG disabled */ 717e1051a39Sopenharmony_ci /* this ---vv--- covers DC bias, Raw Bits and String Filter */ 718e1051a39Sopenharmony_ci if (eax & (0x1F << 10)) 719e1051a39Sopenharmony_ci return 0; 720e1051a39Sopenharmony_ci if ((eax & 0x1F) == 0) 721e1051a39Sopenharmony_ci continue; /* no data, retry... */ 722e1051a39Sopenharmony_ci if ((eax & 0x1F) != 1) 723e1051a39Sopenharmony_ci return 0; /* fatal failure... */ 724e1051a39Sopenharmony_ci *output++ = (unsigned char)buf; 725e1051a39Sopenharmony_ci count--; 726e1051a39Sopenharmony_ci } 727e1051a39Sopenharmony_ci OPENSSL_cleanse(&buf, sizeof(buf)); 728e1051a39Sopenharmony_ci 729e1051a39Sopenharmony_ci return 1; 730e1051a39Sopenharmony_ci} 731e1051a39Sopenharmony_ci 732e1051a39Sopenharmony_ci/* Dummy but necessary function */ 733e1051a39Sopenharmony_cistatic int padlock_rand_status(void) 734e1051a39Sopenharmony_ci{ 735e1051a39Sopenharmony_ci return 1; 736e1051a39Sopenharmony_ci} 737e1051a39Sopenharmony_ci 738e1051a39Sopenharmony_ci/* Prepare structure for registration */ 739e1051a39Sopenharmony_cistatic RAND_METHOD padlock_rand = { 740e1051a39Sopenharmony_ci NULL, /* seed */ 741e1051a39Sopenharmony_ci padlock_rand_bytes, /* bytes */ 742e1051a39Sopenharmony_ci NULL, /* cleanup */ 743e1051a39Sopenharmony_ci NULL, /* add */ 744e1051a39Sopenharmony_ci padlock_rand_bytes, /* pseudorand */ 745e1051a39Sopenharmony_ci padlock_rand_status, /* rand status */ 746e1051a39Sopenharmony_ci}; 747e1051a39Sopenharmony_ci 748e1051a39Sopenharmony_ci# endif /* COMPILE_PADLOCKENG */ 749e1051a39Sopenharmony_ci#endif /* !OPENSSL_NO_PADLOCKENG */ 750e1051a39Sopenharmony_ci 751e1051a39Sopenharmony_ci#if defined(OPENSSL_NO_PADLOCKENG) || !defined(COMPILE_PADLOCKENG) 752e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_DYNAMIC_ENGINE 753e1051a39Sopenharmony_ciOPENSSL_EXPORT 754e1051a39Sopenharmony_ci int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); 755e1051a39Sopenharmony_ciOPENSSL_EXPORT 756e1051a39Sopenharmony_ci int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) 757e1051a39Sopenharmony_ci{ 758e1051a39Sopenharmony_ci return 0; 759e1051a39Sopenharmony_ci} 760e1051a39Sopenharmony_ci 761e1051a39Sopenharmony_ciIMPLEMENT_DYNAMIC_CHECK_FN() 762e1051a39Sopenharmony_ci# endif 763e1051a39Sopenharmony_ci#endif 764