Padlock engine update to fix a typo in MSC assembler and to address
potential corruption problem if user manages to inter-leave aligined and misaligned requests [as well as some MSC-specific tweaks].
This commit is contained in:
parent
2ea6abf6e5
commit
b88606c28e
@ -251,13 +251,21 @@ struct padlock_cipher_data
|
|||||||
AES_KEY ks; /* Encryption key */
|
AES_KEY ks; /* Encryption key */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Essentially this variable belongs in thread local storage.
|
||||||
|
* Having this variable global on the other hand can only cause
|
||||||
|
* few bogus key reloads [if any at all on single-CPU system],
|
||||||
|
* so we accept the penatly...
|
||||||
|
*/
|
||||||
|
static volatile struct padlock_cipher_data *padlock_saved_context;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =======================================================
|
* =======================================================
|
||||||
* Inline assembler section(s).
|
* Inline assembler section(s).
|
||||||
* =======================================================
|
* =======================================================
|
||||||
* Order of arguments is chosen to facilitate Windows port
|
* Order of arguments is chosen to facilitate Windows port
|
||||||
* using __fastcall calling convention. If you wish to add
|
* using __fastcall calling convention. If you wish to add
|
||||||
* more routines, keep in mind that in __fastcall first
|
* more routines, keep in mind that first __fastcall
|
||||||
* argument is passed in %ecx and second - in %edx.
|
* argument is passed in %ecx and second - in %edx.
|
||||||
* =======================================================
|
* =======================================================
|
||||||
*/
|
*/
|
||||||
@ -367,16 +375,14 @@ padlock_reload_key(void)
|
|||||||
* 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,
|
||||||
* but it's not actually necessary. Point is that if
|
* but it's not actually necessary. Point is that if
|
||||||
* saved_cdata was changed by another thread after we've
|
* padlock_saved_context was changed by another thread
|
||||||
* read it and before we compare it with cdata, our key
|
* after we've read it and before we compare it with cdata,
|
||||||
* *shall* be reloaded upon thread context switch and
|
* our key *shall* be reloaded upon thread context switch
|
||||||
* we are therefore set in either case...
|
* and we are therefore set in either case...
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
padlock_verify_context(struct padlock_cipher_data *cdata)
|
padlock_verify_context(struct padlock_cipher_data *cdata)
|
||||||
{
|
{
|
||||||
static struct padlock_cipher_data *saved_cdata;
|
|
||||||
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"pushfl\n"
|
"pushfl\n"
|
||||||
" bt $30,(%%esp)\n"
|
" bt $30,(%%esp)\n"
|
||||||
@ -387,7 +393,8 @@ padlock_verify_context(struct padlock_cipher_data *cdata)
|
|||||||
" popfl\n"
|
" popfl\n"
|
||||||
" sub $4,%%esp\n"
|
" sub $4,%%esp\n"
|
||||||
"1: add $4,%%esp"
|
"1: add $4,%%esp"
|
||||||
:"+m"(saved_cdata) : "r"(saved_cdata), "r"(cdata) : "cc");
|
:"+m"(padlock_saved_context)
|
||||||
|
: "r"(padlock_saved_context), "r"(cdata) : "cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Template for padlock_xcrypt_* modes */
|
/* Template for padlock_xcrypt_* modes */
|
||||||
@ -455,8 +462,8 @@ static void * __fastcall \
|
|||||||
name (size_t cnt, void *cdata, \
|
name (size_t cnt, void *cdata, \
|
||||||
void *outp, const void *inp) \
|
void *outp, const void *inp) \
|
||||||
{ _asm mov eax,edx \
|
{ _asm mov eax,edx \
|
||||||
_asm lea ebx,[eax+16] \
|
_asm lea edx,[eax+16] \
|
||||||
_asm lea edx,[eax+32] \
|
_asm lea ebx,[eax+32] \
|
||||||
_asm mov edi,outp \
|
_asm mov edi,outp \
|
||||||
_asm mov esi,inp \
|
_asm mov esi,inp \
|
||||||
REP_XCRYPT(code) \
|
REP_XCRYPT(code) \
|
||||||
@ -479,15 +486,13 @@ padlock_reload_key(void)
|
|||||||
|
|
||||||
static void __fastcall
|
static void __fastcall
|
||||||
padlock_verify_context(void *cdata)
|
padlock_verify_context(void *cdata)
|
||||||
{ static void *saved_cdata;
|
{ _asm {
|
||||||
|
|
||||||
_asm {
|
|
||||||
pushfd
|
pushfd
|
||||||
bt DWORD PTR[esp],30
|
bt DWORD PTR[esp],30
|
||||||
jnc skip
|
jnc skip
|
||||||
cmp ecx,saved_cdata
|
cmp ecx,padlock_saved_context
|
||||||
je skip
|
je skip
|
||||||
mov saved_cdata,ecx
|
mov padlock_saved_context,ecx
|
||||||
popfd
|
popfd
|
||||||
sub esp,4
|
sub esp,4
|
||||||
skip: add esp,4
|
skip: add esp,4
|
||||||
@ -551,8 +556,7 @@ padlock_bswapl(void *key)
|
|||||||
mov esi,ecx
|
mov esi,ecx
|
||||||
mov edi,ecx
|
mov edi,ecx
|
||||||
mov ecx,60
|
mov ecx,60
|
||||||
up:
|
up: lodsd
|
||||||
lodsd
|
|
||||||
bswap eax
|
bswap eax
|
||||||
stosd
|
stosd
|
||||||
loop up
|
loop up
|
||||||
@ -834,7 +838,8 @@ 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, *iv;
|
char *out;
|
||||||
|
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;
|
||||||
|
|
||||||
@ -882,7 +887,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);
|
inp = memcpy(out, in_arg, chunk&~3);
|
||||||
else
|
else
|
||||||
inp = in_arg;
|
inp = in_arg;
|
||||||
in_arg += chunk;
|
in_arg += chunk;
|
||||||
@ -890,7 +895,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) + chunk;
|
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk;
|
||||||
else
|
else
|
||||||
out = out_arg+=chunk;
|
out = out_arg+=chunk;
|
||||||
|
|
||||||
@ -908,7 +913,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);
|
inp = memcpy(out, in_arg, chunk&~3);
|
||||||
else
|
else
|
||||||
inp = in_arg;
|
inp = in_arg;
|
||||||
in_arg += chunk;
|
in_arg += chunk;
|
||||||
@ -916,7 +921,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) + chunk;
|
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk;
|
||||||
else
|
else
|
||||||
out = out_arg+=chunk;
|
out = out_arg+=chunk;
|
||||||
|
|
||||||
@ -933,7 +938,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
|
|||||||
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);
|
inp = memcpy(out, in_arg, chunk&~3);
|
||||||
else
|
else
|
||||||
inp = in_arg;
|
inp = in_arg;
|
||||||
in_arg += chunk;
|
in_arg += chunk;
|
||||||
@ -941,7 +946,7 @@ 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) + chunk;
|
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk;
|
||||||
else
|
else
|
||||||
out = out_arg+=chunk;
|
out = out_arg+=chunk;
|
||||||
|
|
||||||
@ -953,7 +958,7 @@ padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
|
|||||||
memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
|
memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
|
||||||
do {
|
do {
|
||||||
if (inp_misaligned)
|
if (inp_misaligned)
|
||||||
inp = memcpy(out, in_arg, chunk);
|
inp = memcpy(out, in_arg, chunk&~3);
|
||||||
else
|
else
|
||||||
inp = in_arg;
|
inp = in_arg;
|
||||||
in_arg += chunk;
|
in_arg += chunk;
|
||||||
@ -961,7 +966,7 @@ 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) + chunk;
|
out_arg = (char *)memcpy(out_arg, out, chunk&~3) + chunk;
|
||||||
else
|
else
|
||||||
out = out_arg+=chunk;
|
out = out_arg+=chunk;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user