Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(307)

Side by Side Diff: nss/lib/freebl/intel-gcm-wrap.c

Issue 1155223003: Uprev NSS from 3.18.0 RTM to 3.19.0 RTM (Closed) Base URL: http://src.chromium.org/svn/trunk/deps/third_party/nss
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /* Copyright(c) 2013, Intel Corp. */ 4 /* Copyright(c) 2013, Intel Corp. */
5 5
6 /* Wrapper functions for Intel optimized implementation of AES-GCM */ 6 /* Wrapper functions for Intel optimized implementation of AES-GCM */
7 7
8 #ifdef USE_HW_AES 8 #ifdef USE_HW_AES
9 9
10 #ifdef FREEBL_NO_DEPEND 10 #ifdef FREEBL_NO_DEPEND
(...skipping 21 matching lines...) Expand all
32 unsigned char Htbl[16*AES_BLOCK_SIZE]; 32 unsigned char Htbl[16*AES_BLOCK_SIZE];
33 unsigned char X0[AES_BLOCK_SIZE]; 33 unsigned char X0[AES_BLOCK_SIZE];
34 unsigned char T[AES_BLOCK_SIZE]; 34 unsigned char T[AES_BLOCK_SIZE];
35 unsigned char CTR[AES_BLOCK_SIZE]; 35 unsigned char CTR[AES_BLOCK_SIZE];
36 AESContext *aes_context; 36 AESContext *aes_context;
37 unsigned long tagBits; 37 unsigned long tagBits;
38 unsigned long Alen; 38 unsigned long Alen;
39 unsigned long Mlen; 39 unsigned long Mlen;
40 }; 40 };
41 41
42 intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context, 42 intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
43 freeblCipherFunc cipher, 43 freeblCipherFunc cipher,
44 const unsigned char *params, 44 const unsigned char *params,
45 unsigned int blocksize) 45 unsigned int blocksize)
46 { 46 {
47 intel_AES_GCMContext *gcm = NULL; 47 intel_AES_GCMContext *gcm = NULL;
48 AESContext *aes = (AESContext*)context; 48 AESContext *aes = (AESContext*)context;
49 const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params; 49 const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params;
50 unsigned char buff[AES_BLOCK_SIZE]; /* aux buffer */ 50 unsigned char buff[AES_BLOCK_SIZE]; /* aux buffer */
51 51
52 int IV_whole_len = gcmParams->ulIvLen&(~0xf); 52 unsigned long IV_whole_len = gcmParams->ulIvLen & (~0xful);
53 int IV_remainder_len = gcmParams->ulIvLen&0xf; 53 unsigned int IV_remainder_len = gcmParams->ulIvLen & 0xful;
54 int AAD_whole_len = gcmParams->ulAADLen&(~0xf); 54 unsigned long AAD_whole_len = gcmParams->ulAADLen & (~0xful);
55 int AAD_remainder_len = gcmParams->ulAADLen&0xf; 55 unsigned int AAD_remainder_len = gcmParams->ulAADLen & 0xful;
56 56
57 __m128i BSWAP_MASK = _mm_setr_epi8(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0); 57 __m128i BSWAP_MASK = _mm_setr_epi8(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
58 __m128i ONE = _mm_set_epi32(0,0,0,1); 58 __m128i ONE = _mm_set_epi32(0,0,0,1);
59 unsigned int j; 59 unsigned int j;
60 SECStatus rv; 60 SECStatus rv;
61 61
62 if (blocksize != AES_BLOCK_SIZE) { 62 if (blocksize != AES_BLOCK_SIZE) {
63 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 63 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
64 return NULL; 64 return NULL;
65 } 65 }
66 gcm = PORT_ZNew(intel_AES_GCMContext); 66 gcm = PORT_ZNew(intel_AES_GCMContext);
67 67
68 if (gcm == NULL) { 68 if (gcm == NULL) {
69 return NULL; 69 return NULL;
70 } 70 }
71
71 /* initialize context fields */ 72 /* initialize context fields */
72 gcm->aes_context = aes; 73 gcm->aes_context = aes;
73 gcm->tagBits = gcmParams->ulTagBits; 74 gcm->tagBits = gcmParams->ulTagBits;
74 gcm->Alen = 0; 75 gcm->Alen = 0;
75 gcm->Mlen = 0; 76 gcm->Mlen = 0;
77
76 /* first prepare H and its derivatives for ghash */ 78 /* first prepare H and its derivatives for ghash */
77 intel_aes_gcmINIT(gcm->Htbl, (unsigned char*)aes->expandedKey, aes->Nr); 79 intel_aes_gcmINIT(gcm->Htbl, (unsigned char*)aes->expandedKey, aes->Nr);
78 /* Initial TAG value is zero*/ 80
81 /* Initial TAG value is zero */
79 _mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128()); 82 _mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128());
80 _mm_storeu_si128((__m128i*)gcm->X0, _mm_setzero_si128()); 83 _mm_storeu_si128((__m128i*)gcm->X0, _mm_setzero_si128());
84
81 /* Init the counter */ 85 /* Init the counter */
82 if(gcmParams->ulIvLen == 12) { 86 if (gcmParams->ulIvLen == 12) {
83 _mm_storeu_si128((__m128i*)gcm->CTR, _mm_setr_epi32(((unsigned int*)gcmP arams->pIv)[0], ((unsigned int*)gcmParams->pIv)[1], ((unsigned int*)gcmParams->p Iv)[2], 0x01000000)); 87 _mm_storeu_si128((__m128i*)gcm->CTR,
88 _mm_setr_epi32(((unsigned int*)gcmParams->pIv)[0],
89 ((unsigned int*)gcmParams->pIv)[1],
90 ((unsigned int*)gcmParams->pIv)[2],
91 0x01000000));
84 } else { 92 } else {
85 /* If IV size is not 96 bits, then the initial counter value is GHASH of the IV */ 93 /* If IV size is not 96 bits, then the initial counter value is GHASH
94 * of the IV */
86 intel_aes_gcmAAD(gcm->Htbl, gcmParams->pIv, IV_whole_len, gcm->T); 95 intel_aes_gcmAAD(gcm->Htbl, gcmParams->pIv, IV_whole_len, gcm->T);
96
87 /* Partial block */ 97 /* Partial block */
88 if(IV_remainder_len) { 98 if (IV_remainder_len) {
89 PORT_Memset(buff, 0, AES_BLOCK_SIZE); 99 PORT_Memset(buff, 0, AES_BLOCK_SIZE);
90 PORT_Memcpy(buff, gcmParams->pIv + IV_whole_len, IV_remainder_len); 100 PORT_Memcpy(buff, gcmParams->pIv + IV_whole_len, IV_remainder_len);
91 intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T); 101 intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
92 } 102 }
93 103
94 intel_aes_gcmTAG 104 intel_aes_gcmTAG(
95 (
96 gcm->Htbl, 105 gcm->Htbl,
97 gcm->T, 106 gcm->T,
98 gcmParams->ulIvLen, 107 gcmParams->ulIvLen,
99 0, 108 0,
100 gcm->X0, 109 gcm->X0,
101 gcm->CTR 110 gcm->CTR);
102 ); 111
103 /* TAG should be zero again */ 112 /* TAG should be zero again */
104 _mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128()); 113 _mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128());
105 } 114 }
106 /* Encrypt the initial counter, will be used to encrypt the GHASH value, in the end */ 115
107 rv = (*cipher)(context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR, AES_BLOCK_SIZ E, AES_BLOCK_SIZE); 116 /* Encrypt the initial counter, will be used to encrypt the GHASH value,
117 * in the end */
118 rv = (*cipher)(context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR,
119 AES_BLOCK_SIZE, AES_BLOCK_SIZE);
108 if (rv != SECSuccess) { 120 if (rv != SECSuccess) {
109 goto loser; 121 goto loser;
110 } 122 }
123
111 /* Promote the counter by 1 */ 124 /* Promote the counter by 1 */
112 _mm_storeu_si128((__m128i*)gcm->CTR, _mm_shuffle_epi8(_mm_add_epi32(ONE, _mm _shuffle_epi8(_mm_loadu_si128((__m128i*)gcm->CTR), BSWAP_MASK)), BSWAP_MASK)); 125 _mm_storeu_si128((__m128i*)gcm->CTR, _mm_shuffle_epi8(_mm_add_epi32(ONE, _mm _shuffle_epi8(_mm_loadu_si128((__m128i*)gcm->CTR), BSWAP_MASK)), BSWAP_MASK));
113 126
114 /* Now hash AAD - it would actually make sense to seperate the context creat ion from the AAD, 127 /* Now hash AAD - it would actually make sense to seperate the context
115 * because that would allow to reuse the H, which only changes when the AES key changes, 128 * creation from the AAD, because that would allow to reuse the H, which
116 * and not every package, like the IV and AAD */ 129 * only changes when the AES key changes, and not every package, like the
130 * IV and AAD */
117 intel_aes_gcmAAD(gcm->Htbl, gcmParams->pAAD, AAD_whole_len, gcm->T); 131 intel_aes_gcmAAD(gcm->Htbl, gcmParams->pAAD, AAD_whole_len, gcm->T);
118 if(AAD_remainder_len) { 132 if (AAD_remainder_len) {
119 PORT_Memset(buff, 0, AES_BLOCK_SIZE); 133 PORT_Memset(buff, 0, AES_BLOCK_SIZE);
120 PORT_Memcpy(buff, gcmParams->pAAD + AAD_whole_len, AAD_remainder_len); 134 PORT_Memcpy(buff, gcmParams->pAAD + AAD_whole_len, AAD_remainder_len);
121 intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T); 135 intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
122 } 136 }
123 gcm->Alen += gcmParams->ulAADLen; 137 gcm->Alen += gcmParams->ulAADLen;
124 return gcm; 138 return gcm;
125 139
126 loser: 140 loser:
127 if (gcm) { 141 if (gcm) {
128 PORT_Free(gcm); 142 PORT_Free(gcm);
129 } 143 }
130 return NULL; 144 return NULL;
131 } 145 }
132 146
133 void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit) 147 void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
134 { 148 {
135 if (freeit) { 149 if (freeit) {
136 PORT_Free(gcm); 150 PORT_Free(gcm);
137 } 151 }
138 } 152 }
139 153
140 SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, 154 SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm,
141 unsigned char *outbuf, 155 unsigned char *outbuf,
142 unsigned int *outlen, unsigned int maxout, 156 unsigned int *outlen, unsigned int maxout,
143 const unsigned char *inbuf, unsigned int inlen, 157 const unsigned char *inbuf, unsigned int inlen,
144 unsigned int blocksize) 158 unsigned int blocksize)
145 { 159 {
146 unsigned int tagBytes; 160 unsigned int tagBytes;
147 unsigned char T[AES_BLOCK_SIZE]; 161 unsigned char T[AES_BLOCK_SIZE];
148 int j; 162 unsigned int j;
149 163
150 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE; 164 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
151 if (UINT_MAX - inlen < tagBytes) { 165 if (UINT_MAX - inlen < tagBytes) {
152 PORT_SetError(SEC_ERROR_INPUT_LEN); 166 PORT_SetError(SEC_ERROR_INPUT_LEN);
153 return SECFailure; 167 return SECFailure;
154 } 168 }
155 if (maxout < inlen + tagBytes) { 169 if (maxout < inlen + tagBytes) {
156 *outlen = inlen + tagBytes; 170 *outlen = inlen + tagBytes;
157 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 171 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
158 return SECFailure; 172 return SECFailure;
159 } 173 }
160 174
161 intel_aes_gcmENC( 175 intel_aes_gcmENC(
162 inbuf, 176 inbuf,
163 outbuf, 177 outbuf,
164 gcm, 178 gcm,
165 inlen); 179 inlen);
166 180
167 gcm->Mlen += inlen; 181 gcm->Mlen += inlen;
168 182
169 intel_aes_gcmTAG( 183 intel_aes_gcmTAG(
170 gcm->Htbl, 184 gcm->Htbl,
171 gcm->T, 185 gcm->T,
172 gcm->Mlen, 186 gcm->Mlen,
173 gcm->Alen, 187 gcm->Alen,
174 gcm->X0, 188 gcm->X0,
175 T); 189 T);
176 190
177 *outlen = inlen + tagBytes; 191 *outlen = inlen + tagBytes;
178 192
179 for(j=0; j<tagBytes; j++) 193 for (j = 0; j < tagBytes; j++) {
180 { 194 outbuf[inlen + j] = T[j];
181 outbuf[inlen+j] = T[j];
182 } 195 }
183 return SECSuccess; 196 return SECSuccess;
184 } 197 }
185 198
186 SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, 199 SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm,
187 unsigned char *outbuf, 200 unsigned char *outbuf,
188 unsigned int *outlen, unsigned int maxout, 201 unsigned int *outlen, unsigned int maxout,
189 const unsigned char *inbuf, unsigned int inlen, 202 const unsigned char *inbuf, unsigned int inlen,
190 unsigned int blocksize) 203 unsigned int blocksize)
191 { 204 {
192 unsigned int tagBytes; 205 unsigned int tagBytes;
193 unsigned char T[AES_BLOCK_SIZE]; 206 unsigned char T[AES_BLOCK_SIZE];
194 const unsigned char *intag; 207 const unsigned char *intag;
195 208
196 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE; 209 tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
197 210
198 /* get the authentication block */ 211 /* get the authentication block */
199 if (inlen < tagBytes) { 212 if (inlen < tagBytes) {
200 PORT_SetError(SEC_ERROR_INPUT_LEN); 213 PORT_SetError(SEC_ERROR_INPUT_LEN);
201 return SECFailure; 214 return SECFailure;
202 } 215 }
203 216
204 inlen -= tagBytes; 217 inlen -= tagBytes;
205 intag = inbuf + inlen; 218 intag = inbuf + inlen;
206 219
207 if (maxout < inlen) { 220 if (maxout < inlen) {
(...skipping 23 matching lines...) Expand all
231 /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */ 244 /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
232 PORT_SetError(SEC_ERROR_BAD_DATA); 245 PORT_SetError(SEC_ERROR_BAD_DATA);
233 return SECFailure; 246 return SECFailure;
234 } 247 }
235 *outlen = inlen; 248 *outlen = inlen;
236 249
237 return SECSuccess; 250 return SECSuccess;
238 } 251 }
239 252
240 #endif 253 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698