| Index: mozilla/security/nss/lib/freebl/rijndael.c
|
| ===================================================================
|
| --- mozilla/security/nss/lib/freebl/rijndael.c (revision 180567)
|
| +++ mozilla/security/nss/lib/freebl/rijndael.c (working copy)
|
| @@ -1,7 +1,7 @@
|
| /* This Source Code Form is subject to the terms of the Mozilla Public
|
| * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -/* $Id: rijndael.c,v 1.28 2012/09/28 22:46:32 rrelyea%redhat.com Exp $ */
|
| +/* $Id: rijndael.c,v 1.30 2013/01/25 18:02:53 rrelyea%redhat.com Exp $ */
|
|
|
| #ifdef FREEBL_NO_DEPEND
|
| #include "stubs.h"
|
| @@ -20,8 +20,16 @@
|
| #include "gcm.h"
|
|
|
| #if USE_HW_AES
|
| +#include "intel-gcm.h"
|
| #include "intel-aes.h"
|
| #include "mpi.h"
|
| +
|
| +static int has_intel_aes = 0;
|
| +static int has_intel_avx = 0;
|
| +static int has_intel_clmul = 0;
|
| +static PRBool use_hw_aes = PR_FALSE;
|
| +static PRBool use_hw_avx = PR_FALSE;
|
| +static PRBool use_hw_gcm = PR_FALSE;
|
| #endif
|
|
|
| /*
|
| @@ -970,10 +978,6 @@
|
| const unsigned char *iv, int mode, unsigned int encrypt,
|
| unsigned int blocksize)
|
| {
|
| -#if USE_HW_AES
|
| - static int has_intel_aes;
|
| - PRBool use_hw_aes = PR_FALSE;
|
| -#endif
|
| unsigned int Nk;
|
| /* According to Rijndael AES Proposal, section 12.1, block and key
|
| * lengths between 128 and 256 bits are supported, as long as the
|
| @@ -1009,12 +1013,18 @@
|
| if (disable_hw_aes == NULL) {
|
| freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
|
| has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1;
|
| + has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1;
|
| + has_intel_avx = (ecx & (1 << 28)) != 0 ? 1 : -1;
|
| } else {
|
| has_intel_aes = -1;
|
| + has_intel_avx = -1;
|
| + has_intel_clmul = -1;
|
| }
|
| }
|
| use_hw_aes = (PRBool)
|
| (has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);
|
| + use_hw_gcm = (PRBool)
|
| + (use_hw_aes && has_intel_avx>0 && has_intel_clmul>0);
|
| #endif
|
| /* Nb = (block size in bits) / 32 */
|
| cx->Nb = blocksize / 4;
|
| @@ -1100,10 +1110,13 @@
|
| baseencrypt = PR_TRUE;
|
| break;
|
| }
|
| + /* make sure enough is initializes so we can safely call Destroy */
|
| + cx->worker_cx = NULL;
|
| + cx->destroy = NULL;
|
| rv = aes_InitContext(cx, key, keysize, iv, basemode,
|
| baseencrypt, blocksize);
|
| if (rv != SECSuccess) {
|
| - AES_DestroyContext(cx, PR_TRUE);
|
| + AES_DestroyContext(cx, PR_FALSE);
|
| return rv;
|
| }
|
|
|
| @@ -1117,11 +1130,22 @@
|
| cx->isBlock = PR_FALSE;
|
| break;
|
| case NSS_AES_GCM:
|
| +#if USE_HW_AES
|
| + if(use_hw_gcm) {
|
| + cx->worker_cx = intel_AES_GCM_CreateContext(cx, cx->worker, iv, blocksize);
|
| + cx->worker = (freeblCipherFunc)
|
| + (encrypt ? intel_AES_GCM_EncryptUpdate : intel_AES_GCM_DecryptUpdate);
|
| + cx->destroy = (freeblDestroyFunc) intel_AES_GCM_DestroyContext;
|
| + cx->isBlock = PR_FALSE;
|
| + } else
|
| +#endif
|
| + {
|
| cx->worker_cx = GCM_CreateContext(cx, cx->worker, iv, blocksize);
|
| cx->worker = (freeblCipherFunc)
|
| (encrypt ? GCM_EncryptUpdate : GCM_DecryptUpdate);
|
| cx->destroy = (freeblDestroyFunc) GCM_DestroyContext;
|
| cx->isBlock = PR_FALSE;
|
| + }
|
| break;
|
| case NSS_AES_CTR:
|
| cx->worker_cx = CTR_CreateContext(cx, cx->worker, iv, blocksize);
|
| @@ -1139,7 +1163,7 @@
|
| /* no, just destroy the existing context */
|
| cx->destroy = NULL; /* paranoia, though you can see a dozen lines */
|
| /* below that this isn't necessary */
|
| - AES_DestroyContext(cx, PR_TRUE);
|
| + AES_DestroyContext(cx, PR_FALSE);
|
| return SECFailure;
|
| }
|
| return SECSuccess;
|
| @@ -1175,9 +1199,10 @@
|
| void
|
| AES_DestroyContext(AESContext *cx, PRBool freeit)
|
| {
|
| -/* memset(cx, 0, sizeof *cx); */
|
| if (cx->worker_cx && cx->destroy) {
|
| (*cx->destroy)(cx->worker_cx, PR_TRUE);
|
| + cx->worker_cx = NULL;
|
| + cx->destroy = NULL;
|
| }
|
| if (freeit)
|
| PORT_Free(cx);
|
|
|