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