Resolve conflicts after import of OpenSSL 0.9.8b.

This was missed the first time around since eng_padlock.c was not part
of OpenSSL 0.9.7e and therefor did not have the v0_9_7e CVS tag used
during original resolve of conflicts.

Noticed by:	Antoine Brodin <antoine.brodin@laposte.net>
This commit is contained in:
simon 2006-07-30 14:17:54 +00:00
parent 4dff9a1eda
commit 76f00e0285

@ -65,17 +65,17 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#ifdef _MSC_VER
# define alloca _alloca
# define snprintf _snprintf
#endif
#include <openssl/opensslconf.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/dso.h> #include <openssl/dso.h>
#include <openssl/engine.h> #include <openssl/engine.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#ifndef OPENSSL_NO_AES
#include <openssl/aes.h> #include <openssl/aes.h>
#endif
#include <openssl/rand.h>
#include <openssl/err.h>
#ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_HW
#ifndef OPENSSL_NO_HW_PADLOCK #ifndef OPENSSL_NO_HW_PADLOCK
@ -101,13 +101,13 @@
compiler choice is limited to GCC and Microsoft C. */ compiler choice is limited to GCC and Microsoft C. */
#undef COMPILE_HW_PADLOCK #undef COMPILE_HW_PADLOCK
#if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM) #if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM)
# if defined(__i386__) || defined(__i386) || defined(_M_IX86) # if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \
(defined(_MSC_VER) && defined(_M_IX86))
# define COMPILE_HW_PADLOCK # define COMPILE_HW_PADLOCK
static ENGINE *ENGINE_padlock (void);
# endif # endif
#endif #endif
static ENGINE *ENGINE_padlock (void);
void ENGINE_load_padlock (void) void ENGINE_load_padlock (void)
{ {
/* On non-x86 CPUs it just returns. */ /* On non-x86 CPUs it just returns. */
@ -121,6 +121,15 @@ void ENGINE_load_padlock (void)
} }
#ifdef COMPILE_HW_PADLOCK #ifdef COMPILE_HW_PADLOCK
/* We do these includes here to avoid header problems on platforms that
do not have the VIA padlock anyway... */
#ifdef _MSC_VER
# include <malloc.h>
# define alloca _alloca
#else
# include <stdlib.h>
#endif
/* Function for ENGINE detection and control */ /* Function for ENGINE detection and control */
static int padlock_available(void); static int padlock_available(void);
static int padlock_init(ENGINE *e); static int padlock_init(ENGINE *e);
@ -129,7 +138,9 @@ static int padlock_init(ENGINE *e);
static RAND_METHOD padlock_rand; static RAND_METHOD padlock_rand;
/* Cipher Stuff */ /* Cipher Stuff */
#ifndef OPENSSL_NO_AES
static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
#endif
/* Engine names */ /* Engine names */
static const char *padlock_id = "padlock"; static const char *padlock_id = "padlock";
@ -138,7 +149,9 @@ static char padlock_name[100];
/* Available features */ /* Available features */
static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
static int padlock_use_rng = 0; /* Random Number Generator */ static int padlock_use_rng = 0; /* Random Number Generator */
#ifndef OPENSSL_NO_AES
static int padlock_aes_align_required = 1; static int padlock_aes_align_required = 1;
#endif
/* ===== Engine "management" functions ===== */ /* ===== Engine "management" functions ===== */
@ -154,7 +167,8 @@ padlock_bind_helper(ENGINE *e)
#endif #endif
/* Generate a nice engine name with available features */ /* Generate a nice engine name with available features */
snprintf(padlock_name, sizeof(padlock_name), "VIA PadLock (%s, %s)", BIO_snprintf(padlock_name, sizeof(padlock_name),
"VIA PadLock (%s, %s)",
padlock_use_rng ? "RNG" : "no-RNG", padlock_use_rng ? "RNG" : "no-RNG",
padlock_use_ace ? "ACE" : "no-ACE"); padlock_use_ace ? "ACE" : "no-ACE");
@ -163,8 +177,9 @@ padlock_bind_helper(ENGINE *e)
!ENGINE_set_name(e, padlock_name) || !ENGINE_set_name(e, padlock_name) ||
!ENGINE_set_init_function(e, padlock_init) || !ENGINE_set_init_function(e, padlock_init) ||
#ifndef OPENSSL_NO_AES
(padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) || (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
#endif
(padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) { (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
return 0; return 0;
} }
@ -222,6 +237,7 @@ IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn);
/* ===== Here comes the "real" engine ===== */ /* ===== Here comes the "real" engine ===== */
#ifndef OPENSSL_NO_AES
/* Some AES-related constants */ /* Some AES-related constants */
#define AES_BLOCK_SIZE 16 #define AES_BLOCK_SIZE 16
#define AES_KEY_SIZE_128 16 #define AES_KEY_SIZE_128 16
@ -241,10 +257,12 @@ struct padlock_cipher_data
union { unsigned int pad[4]; union { unsigned int pad[4];
struct { struct {
int rounds:4; int rounds:4;
int algo:3; int dgst:1; /* n/a in C3 */
int keygen:1; int align:1; /* n/a in C3 */
int ciphr:1; /* n/a in C3 */
unsigned int keygen:1;
int interm:1; int interm:1;
int encdec:1; unsigned int encdec:1;
int ksize:2; int ksize:2;
} b; } b;
} cword; /* Control word */ } cword; /* Control word */
@ -258,6 +276,7 @@ struct padlock_cipher_data
* so we accept the penatly... * so we accept the penatly...
*/ */
static volatile struct padlock_cipher_data *padlock_saved_context; static volatile struct padlock_cipher_data *padlock_saved_context;
#endif
/* /*
* ======================================================= * =======================================================
@ -349,18 +368,20 @@ padlock_available(void)
return padlock_use_ace + padlock_use_rng; return padlock_use_ace + padlock_use_rng;
} }
#ifndef OPENSSL_NO_AES
/* Our own htonl()/ntohl() */ /* Our own htonl()/ntohl() */
static inline void static inline void
padlock_bswapl(AES_KEY *ks) padlock_bswapl(AES_KEY *ks)
{ {
size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]); size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]);
unsigned long *key = ks->rd_key; unsigned int *key = ks->rd_key;
while (i--) { while (i--) {
asm volatile ("bswapl %0" : "+r"(*key)); asm volatile ("bswapl %0" : "+r"(*key));
key++; key++;
} }
} }
#endif
/* Force key reload from memory to the CPU microcode. /* Force key reload from memory to the CPU microcode.
Loading EFLAGS from the stack clears EFLAGS[30] Loading EFLAGS from the stack clears EFLAGS[30]
@ -371,6 +392,7 @@ padlock_reload_key(void)
asm volatile ("pushfl; popfl"); asm volatile ("pushfl; popfl");
} }
#ifndef OPENSSL_NO_AES
/* /*
* This is heuristic key context tracing. At first one * This is heuristic key context tracing. At first one
* believes that one should use atomic swap instructions, * believes that one should use atomic swap instructions,
@ -385,14 +407,14 @@ padlock_verify_context(struct padlock_cipher_data *cdata)
{ {
asm volatile ( asm volatile (
"pushfl\n" "pushfl\n"
" bt $30,(%%esp)\n" " btl $30,(%%esp)\n"
" jnc 1f\n" " jnc 1f\n"
" cmp %2,%1\n" " cmpl %2,%1\n"
" je 1f\n" " je 1f\n"
" mov %2,%0\n"
" popfl\n" " popfl\n"
" sub $4,%%esp\n" " subl $4,%%esp\n"
"1: add $4,%%esp" "1: addl $4,%%esp\n"
" movl %2,%0"
:"+m"(padlock_saved_context) :"+m"(padlock_saved_context)
: "r"(padlock_saved_context), "r"(cdata) : "cc"); : "r"(padlock_saved_context), "r"(cdata) : "cc");
} }
@ -420,10 +442,11 @@ static inline void *name(size_t cnt, \
} }
/* Generate all functions with appropriate opcodes */ /* Generate all functions with appropriate opcodes */
PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8"); /* rep xcryptecb */ PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0"); /* rep xcryptcbc */ PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0"); /* rep xcryptcfb */ PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8"); /* rep xcryptofb */ PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
#endif
/* The RNG call itself */ /* The RNG call itself */
static inline unsigned int static inline unsigned int
@ -439,6 +462,29 @@ padlock_xstore(void *addr, unsigned int edx_in)
return eax_out; return eax_out;
} }
/* Why not inline 'rep movsd'? I failed to find information on what
* value in Direction Flag one can expect and consequently have to
* apply "better-safe-than-sorry" approach and assume "undefined."
* I could explicitly clear it and restore the original value upon
* return from padlock_aes_cipher, but it's presumably too much
* trouble for too little gain...
*
* In case you wonder 'rep xcrypt*' instructions above are *not*
* affected by the Direction Flag and pointers advance toward
* larger addresses unconditionally.
*/
static inline unsigned char *
padlock_memcpy(void *dst,const void *src,size_t n)
{
long *d=dst;
const long *s=src;
n /= sizeof(*d);
do { *d++ = *s++; } while (--n);
return dst;
}
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
/* /*
* Unlike GCC these are real functions. In order to minimize impact * Unlike GCC these are real functions. In order to minimize impact
@ -492,10 +538,10 @@ padlock_verify_context(void *cdata)
jnc skip jnc skip
cmp ecx,padlock_saved_context cmp ecx,padlock_saved_context
je skip je skip
mov padlock_saved_context,ecx
popfd popfd
sub esp,4 sub esp,4
skip: add esp,4 skip: add esp,4
mov padlock_saved_context,ecx
} }
} }
@ -563,9 +609,15 @@ padlock_bswapl(void *key)
popfd popfd
} }
} }
/* MS actually specifies status of Direction Flag and compiler even
* manages to compile following as 'rep movsd' all by itself...
*/
#define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U))
#endif #endif
/* ===== AES encryption/decryption ===== */ /* ===== AES encryption/decryption ===== */
#ifndef OPENSSL_NO_AES
#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb) #if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
#define NID_aes_128_cfb NID_aes_128_cfb128 #define NID_aes_128_cfb NID_aes_128_cfb128
@ -600,13 +652,13 @@ static int padlock_cipher_nids[] = {
NID_aes_192_ecb, NID_aes_192_ecb,
NID_aes_192_cbc, NID_aes_192_cbc,
// NID_aes_192_cfb, /* FIXME: AES192/256 CFB/OFB don't work. */ NID_aes_192_cfb,
// NID_aes_192_ofb, NID_aes_192_ofb,
NID_aes_256_ecb, NID_aes_256_ecb,
NID_aes_256_cbc, NID_aes_256_cbc,
// NID_aes_256_cfb, NID_aes_256_cfb,
// NID_aes_256_ofb, NID_aes_256_ofb,
}; };
static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/ static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
sizeof(padlock_cipher_nids[0])); sizeof(padlock_cipher_nids[0]));
@ -615,19 +667,24 @@ static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc); const unsigned char *iv, int enc);
static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int nbytes); const unsigned char *in, size_t nbytes);
#define NEAREST_ALIGNED(ptr) ( (char *)(ptr) + \ #define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \
( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) ) ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) )
#define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\ #define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
NEAREST_ALIGNED(ctx->cipher_data)) NEAREST_ALIGNED(ctx->cipher_data))
#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
#define EVP_CIPHER_block_size_OFB 1
#define EVP_CIPHER_block_size_CFB 1
/* Declaring so many ciphers by hand would be a pain. /* Declaring so many ciphers by hand would be a pain.
Instead introduce a bit of preprocessor magic :-) */ Instead introduce a bit of preprocessor magic :-) */
#define DECLARE_AES_EVP(ksize,lmode,umode) \ #define DECLARE_AES_EVP(ksize,lmode,umode) \
static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \ static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \
NID_aes_##ksize##_##lmode, \ NID_aes_##ksize##_##lmode, \
AES_BLOCK_SIZE, \ EVP_CIPHER_block_size_##umode, \
AES_KEY_SIZE_##ksize, \ AES_KEY_SIZE_##ksize, \
AES_BLOCK_SIZE, \ AES_BLOCK_SIZE, \
0 | EVP_CIPH_##umode##_MODE, \ 0 | EVP_CIPH_##umode##_MODE, \
@ -729,7 +786,10 @@ padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
memset(cdata, 0, sizeof(struct padlock_cipher_data)); memset(cdata, 0, sizeof(struct padlock_cipher_data));
/* Prepare Control word. */ /* Prepare Control word. */
cdata->cword.b.encdec = (ctx->encrypt == 0); if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
cdata->cword.b.encdec = 0;
else
cdata->cword.b.encdec = (ctx->encrypt == 0);
cdata->cword.b.rounds = 10 + (key_len - 128) / 32; cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
cdata->cword.b.ksize = (key_len - 128) / 64; cdata->cword.b.ksize = (key_len - 128) / 64;
@ -749,14 +809,16 @@ padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key,
and is listed as hardware errata. They most and is listed as hardware errata. They most
likely will fix it at some point and then likely will fix it at some point and then
a check for stepping would be due here. */ a check for stepping would be due here. */
if (enc) if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE ||
EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE ||
enc)
AES_set_encrypt_key(key, key_len, &cdata->ks); AES_set_encrypt_key(key, key_len, &cdata->ks);
else else
AES_set_decrypt_key(key, key_len, &cdata->ks); AES_set_decrypt_key(key, key_len, &cdata->ks);
#ifndef AES_ASM
/* OpenSSL internal functions use byte-swapped extended key. */ /* OpenSSL C functions use byte-swapped extended key. */
padlock_bswapl(&cdata->ks); padlock_bswapl(&cdata->ks);
#endif
cdata->cword.b.keygen = 1; cdata->cword.b.keygen = 1;
break; break;
@ -824,7 +886,7 @@ padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
} }
#ifndef PADLOCK_CHUNK #ifndef PADLOCK_CHUNK
# define PADLOCK_CHUNK 4096 /* Must be a power of 2 larger than 16 */ # define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */
#endif #endif
#if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1) #if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1)
# error "insane PADLOCK_CHUNK..." # error "insane PADLOCK_CHUNK..."
@ -838,20 +900,68 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
{ {
struct padlock_cipher_data *cdata; struct padlock_cipher_data *cdata;
const void *inp; const void *inp;
char *out; unsigned char *out;
void *iv; void *iv;
int inp_misaligned, out_misaligned, realign_in_loop; int inp_misaligned, out_misaligned, realign_in_loop;
size_t chunk, allocated=0; size_t chunk, allocated=0;
/* ctx->num is maintained in byte-oriented modes,
such as CFB and OFB... */
if ((chunk = ctx->num)) { /* borrow chunk variable */
unsigned char *ivp=ctx->iv;
switch (EVP_CIPHER_CTX_mode(ctx)) {
case EVP_CIPH_CFB_MODE:
if (chunk >= AES_BLOCK_SIZE)
return 0; /* bogus value */
if (ctx->encrypt)
while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
chunk++, nbytes--;
}
else while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
unsigned char c = *(in_arg++);
*(out_arg++) = c ^ ivp[chunk];
ivp[chunk++] = c, nbytes--;
}
ctx->num = chunk%AES_BLOCK_SIZE;
break;
case EVP_CIPH_OFB_MODE:
if (chunk >= AES_BLOCK_SIZE)
return 0; /* bogus value */
while (chunk<AES_BLOCK_SIZE && nbytes!=0) {
*(out_arg++) = *(in_arg++) ^ ivp[chunk];
chunk++, nbytes--;
}
ctx->num = chunk%AES_BLOCK_SIZE;
break;
}
}
if (nbytes == 0) if (nbytes == 0)
return 1; return 1;
#if 0
if (nbytes % AES_BLOCK_SIZE) if (nbytes % AES_BLOCK_SIZE)
return 0; /* are we expected to do tail processing? */ return 0; /* are we expected to do tail processing? */
#else
/* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC
modes and arbitrary value in byte-oriented modes, such as
CFB and OFB... */
#endif
/* VIA promises CPUs that won't require alignment in the future. /* VIA promises CPUs that won't require alignment in the future.
For now padlock_aes_align_required is initialized to 1 and For now padlock_aes_align_required is initialized to 1 and
the condition is never met... */ the condition is never met... */
if (!padlock_aes_align_required) /* C7 core is capable to manage unaligned input in non-ECB[!]
mode, but performance penalties appear to be approximately
same as for software alignment below or ~3x. They promise to
improve it in the future, but for now we can just as well
pretend that it can only handle aligned input... */
if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0)
return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
inp_misaligned = (((size_t)in_arg) & 0x0F); inp_misaligned = (((size_t)in_arg) & 0x0F);
@ -863,7 +973,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
* in order to improve L1 cache utilization... */ * in order to improve L1 cache utilization... */
realign_in_loop = out_misaligned|inp_misaligned; realign_in_loop = out_misaligned|inp_misaligned;
if (!realign_in_loop) if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0)
return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes);
/* this takes one "if" out of the loops */ /* this takes one "if" out of the loops */
@ -887,7 +997,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
case EVP_CIPH_ECB_MODE: case EVP_CIPH_ECB_MODE:
do { do {
if (inp_misaligned) if (inp_misaligned)
inp = memcpy(out, in_arg, chunk&~3); inp = padlock_memcpy(out, in_arg, chunk);
else else
inp = in_arg; inp = in_arg;
in_arg += chunk; in_arg += chunk;
@ -895,7 +1005,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp); padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
if (out_misaligned) if (out_misaligned)
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk; out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
else else
out = out_arg+=chunk; out = out_arg+=chunk;
@ -913,7 +1023,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
chunk = PADLOCK_CHUNK; chunk = PADLOCK_CHUNK;
cbc_shortcut: /* optimize for small input */ cbc_shortcut: /* optimize for small input */
if (inp_misaligned) if (inp_misaligned)
inp = memcpy(out, in_arg, chunk&~3); inp = padlock_memcpy(out, in_arg, chunk);
else else
inp = in_arg; inp = in_arg;
in_arg += chunk; in_arg += chunk;
@ -921,7 +1031,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp); iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp);
if (out_misaligned) if (out_misaligned)
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk; out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
else else
out = out_arg+=chunk; out = out_arg+=chunk;
@ -930,15 +1040,17 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
break; break;
case EVP_CIPH_CFB_MODE: case EVP_CIPH_CFB_MODE:
memcpy (cdata->iv, ctx->iv, AES_BLOCK_SIZE); memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE);
goto cfb_shortcut; chunk &= ~(AES_BLOCK_SIZE-1);
if (chunk) goto cfb_shortcut;
else goto cfb_skiploop;
do { do {
if (iv != cdata->iv) if (iv != cdata->iv)
memcpy(cdata->iv, iv, AES_BLOCK_SIZE); memcpy(cdata->iv, iv, AES_BLOCK_SIZE);
chunk = PADLOCK_CHUNK; chunk = PADLOCK_CHUNK;
cfb_shortcut: /* optimize for small input */ cfb_shortcut: /* optimize for small input */
if (inp_misaligned) if (inp_misaligned)
inp = memcpy(out, in_arg, chunk&~3); inp = padlock_memcpy(out, in_arg, chunk);
else else
inp = in_arg; inp = in_arg;
in_arg += chunk; in_arg += chunk;
@ -946,19 +1058,53 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp); iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
if (out_misaligned) if (out_misaligned)
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk; out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
else else
out = out_arg+=chunk; out = out_arg+=chunk;
} while (nbytes -= chunk); nbytes -= chunk;
} while (nbytes >= AES_BLOCK_SIZE);
cfb_skiploop:
if (nbytes) {
unsigned char *ivp = cdata->iv;
if (iv != ivp) {
memcpy(ivp, iv, AES_BLOCK_SIZE);
iv = ivp;
}
ctx->num = nbytes;
if (cdata->cword.b.encdec) {
cdata->cword.b.encdec=0;
padlock_reload_key();
padlock_xcrypt_ecb(1,cdata,ivp,ivp);
cdata->cword.b.encdec=1;
padlock_reload_key();
while(nbytes) {
unsigned char c = *(in_arg++);
*(out_arg++) = c ^ *ivp;
*(ivp++) = c, nbytes--;
}
}
else { padlock_reload_key();
padlock_xcrypt_ecb(1,cdata,ivp,ivp);
padlock_reload_key();
while (nbytes) {
*ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
ivp++, nbytes--;
}
}
}
memcpy(ctx->iv, iv, AES_BLOCK_SIZE); memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
break; break;
case EVP_CIPH_OFB_MODE: case EVP_CIPH_OFB_MODE:
memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
do { chunk &= ~(AES_BLOCK_SIZE-1);
if (chunk) do {
if (inp_misaligned) if (inp_misaligned)
inp = memcpy(out, in_arg, chunk&~3); inp = padlock_memcpy(out, in_arg, chunk);
else else
inp = in_arg; inp = in_arg;
in_arg += chunk; in_arg += chunk;
@ -966,13 +1112,27 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp); padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp);
if (out_misaligned) if (out_misaligned)
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk; out_arg = padlock_memcpy(out_arg, out, chunk) + chunk;
else else
out = out_arg+=chunk; out = out_arg+=chunk;
nbytes -= chunk; nbytes -= chunk;
chunk = PADLOCK_CHUNK; chunk = PADLOCK_CHUNK;
} while (nbytes); } while (nbytes >= AES_BLOCK_SIZE);
if (nbytes) {
unsigned char *ivp = cdata->iv;
ctx->num = nbytes;
padlock_reload_key(); /* empirically found */
padlock_xcrypt_ecb(1,cdata,ivp,ivp);
padlock_reload_key(); /* empirically found */
while (nbytes) {
*(out_arg++) = *(in_arg++) ^ *ivp;
ivp++, nbytes--;
}
}
memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE);
break; break;
@ -992,6 +1152,8 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
return 1; return 1;
} }
#endif /* OPENSSL_NO_AES */
/* ===== Random Number Generator ===== */ /* ===== Random Number Generator ===== */
/* /*
* This code is not engaged. The reason is that it does not comply * This code is not engaged. The reason is that it does not comply