File: | s/lib/softoken/pkcs11c.c |
Warning: | line 5769, column 39 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |||
4 | /* | |||
5 | * This file implements PKCS 11 on top of our existing security modules | |||
6 | * | |||
7 | * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. | |||
8 | * This implementation has two slots: | |||
9 | * slot 1 is our generic crypto support. It does not require login. | |||
10 | * It supports Public Key ops, and all they bulk ciphers and hashes. | |||
11 | * It can also support Private Key ops for imported Private keys. It does | |||
12 | * not have any token storage. | |||
13 | * slot 2 is our private key support. It requires a login before use. It | |||
14 | * can store Private Keys and Certs as token objects. Currently only private | |||
15 | * keys and their associated Certificates are saved on the token. | |||
16 | * | |||
17 | * In this implementation, session objects are only visible to the session | |||
18 | * that created or generated them. | |||
19 | */ | |||
20 | ||||
21 | #include <limits.h> /* for UINT_MAX and ULONG_MAX */ | |||
22 | ||||
23 | #include "seccomon.h" | |||
24 | #include "secitem.h" | |||
25 | #include "secport.h" | |||
26 | #include "blapi.h" | |||
27 | #include "pkcs11.h" | |||
28 | #include "pkcs11i.h" | |||
29 | #include "pkcs1sig.h" | |||
30 | #include "lowkeyi.h" | |||
31 | #include "secder.h" | |||
32 | #include "secdig.h" | |||
33 | #include "lowpbe.h" /* We do PBE below */ | |||
34 | #include "pkcs11t.h" | |||
35 | #include "secoid.h" | |||
36 | #include "cmac.h" | |||
37 | #include "alghmac.h" | |||
38 | #include "softoken.h" | |||
39 | #include "secasn1.h" | |||
40 | #include "secerr.h" | |||
41 | #include "kem.h" | |||
42 | #include "kyber.h" | |||
43 | ||||
44 | #include "prprf.h" | |||
45 | #include "prenv.h" | |||
46 | ||||
47 | #define __PASTE(x, y)xy x##y | |||
48 | #define BAD_PARAM_CAST(pMech, typeSize)(!pMech->pParameter || pMech->ulParameterLen < typeSize ) (!pMech->pParameter || pMech->ulParameterLen < typeSize) | |||
49 | /* | |||
50 | * we renamed all our internal functions, get the correct | |||
51 | * definitions for them... | |||
52 | */ | |||
53 | #undef CK_PKCS11_FUNCTION_INFO | |||
54 | #undef CK_NEED_ARG_LIST1 | |||
55 | ||||
56 | #define CK_PKCS11_3_01 1 | |||
57 | ||||
58 | #define CK_EXTERNextern extern | |||
59 | #define CK_PKCS11_FUNCTION_INFO(func)CK_RV NSfunc \ | |||
60 | CK_RV __PASTE(NS, func)NSfunc | |||
61 | #define CK_NEED_ARG_LIST1 1 | |||
62 | ||||
63 | #include "pkcs11f.h" | |||
64 | ||||
65 | /* create a definition of SHA1 that's consistent | |||
66 | * with the rest of the CKM_SHAxxx hashes*/ | |||
67 | #define CKM_SHA10x00000220UL CKM_SHA_10x00000220UL | |||
68 | #define CKM_SHA1_HMAC0x00000221UL CKM_SHA_1_HMAC0x00000221UL | |||
69 | #define CKM_SHA1_HMAC_GENERAL0x00000222UL CKM_SHA_1_HMAC_GENERAL0x00000222UL | |||
70 | ||||
71 | typedef struct { | |||
72 | PRUint8 client_version[2]; | |||
73 | PRUint8 random[46]; | |||
74 | } SSL3RSAPreMasterSecret; | |||
75 | ||||
76 | static void | |||
77 | sftk_Null(void *data, PRBool freeit) | |||
78 | { | |||
79 | return; | |||
80 | } | |||
81 | ||||
82 | #ifdef EC_DEBUG | |||
83 | #define SEC_PRINT(str1, str2, num, sitem) \ | |||
84 | printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \ | |||
85 | str1, str2, num, sitem->len); \ | |||
86 | for (i = 0; i < sitem->len; i++) { \ | |||
87 | printf("%02x:", sitem->data[i]); \ | |||
88 | } \ | |||
89 | printf("\n") | |||
90 | #else | |||
91 | #undef EC_DEBUG | |||
92 | #define SEC_PRINT(a, b, c, d) | |||
93 | #endif | |||
94 | ||||
95 | /* | |||
96 | * free routines.... Free local type allocated data, and convert | |||
97 | * other free routines to the destroy signature. | |||
98 | */ | |||
99 | static void | |||
100 | sftk_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit) | |||
101 | { | |||
102 | nsslowkey_DestroyPrivateKey(key); | |||
103 | } | |||
104 | ||||
105 | static void | |||
106 | sftk_Space(void *data, PRBool freeit) | |||
107 | { | |||
108 | PORT_FreePORT_Free_Util(data); | |||
109 | } | |||
110 | ||||
111 | static void | |||
112 | sftk_ZSpace(void *data, PRBool freeit) | |||
113 | { | |||
114 | size_t len = *(size_t *)data; | |||
115 | PORT_ZFreePORT_ZFree_Util(data, len); | |||
116 | } | |||
117 | ||||
118 | /* | |||
119 | * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by | |||
120 | * Deprecating a full des key to 40 bit key strenth. | |||
121 | */ | |||
122 | static CK_RV | |||
123 | sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey) | |||
124 | { | |||
125 | unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae }; | |||
126 | unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 }; | |||
127 | unsigned char enc_src[8]; | |||
128 | unsigned char enc_dest[8]; | |||
129 | unsigned int leng, i; | |||
130 | DESContext *descx; | |||
131 | SECStatus rv; | |||
132 | CK_RV crv = CKR_OK0x00000000UL; | |||
133 | ||||
134 | /* zero the parity bits */ | |||
135 | for (i = 0; i < 8; i++) { | |||
136 | enc_src[i] = cdmfkey[i] & 0xfe; | |||
137 | } | |||
138 | ||||
139 | /* encrypt with key 1 */ | |||
140 | descx = DES_CreateContext(key1, NULL((void*)0), NSS_DES0, PR_TRUE1); | |||
141 | if (descx == NULL((void*)0)) { | |||
142 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
143 | goto done; | |||
144 | } | |||
145 | rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8); | |||
146 | DES_DestroyContext(descx, PR_TRUE1); | |||
147 | if (rv != SECSuccess) { | |||
148 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
149 | goto done; | |||
150 | } | |||
151 | ||||
152 | /* xor source with des, zero the parity bits and deprecate the key*/ | |||
153 | for (i = 0; i < 8; i++) { | |||
154 | if (i & 1) { | |||
155 | enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe; | |||
156 | } else { | |||
157 | enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e; | |||
158 | } | |||
159 | } | |||
160 | ||||
161 | /* encrypt with key 2 */ | |||
162 | descx = DES_CreateContext(key2, NULL((void*)0), NSS_DES0, PR_TRUE1); | |||
163 | if (descx == NULL((void*)0)) { | |||
164 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
165 | goto done; | |||
166 | } | |||
167 | rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8); | |||
168 | DES_DestroyContext(descx, PR_TRUE1); | |||
169 | if (rv != SECSuccess) { | |||
170 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
171 | goto done; | |||
172 | } | |||
173 | ||||
174 | /* set the corret parity on our new des key */ | |||
175 | sftk_FormatDESKey(deskey, 8); | |||
176 | done: | |||
177 | PORT_Memsetmemset(enc_src, 0, sizeof enc_src); | |||
178 | PORT_Memsetmemset(enc_dest, 0, sizeof enc_dest); | |||
179 | return crv; | |||
180 | } | |||
181 | ||||
182 | /* NSC_DestroyObject destroys an object. */ | |||
183 | CK_RV | |||
184 | NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) | |||
185 | { | |||
186 | SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); | |||
187 | SFTKSession *session; | |||
188 | SFTKObject *object; | |||
189 | SFTKFreeStatus status; | |||
190 | ||||
191 | CHECK_FORK(); | |||
192 | ||||
193 | if (slot == NULL((void*)0)) { | |||
194 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
195 | } | |||
196 | /* | |||
197 | * This whole block just makes sure we really can destroy the | |||
198 | * requested object. | |||
199 | */ | |||
200 | session = sftk_SessionFromHandle(hSession); | |||
201 | if (session == NULL((void*)0)) { | |||
202 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
203 | } | |||
204 | ||||
205 | object = sftk_ObjectFromHandle(hObject, session); | |||
206 | if (object == NULL((void*)0)) { | |||
207 | sftk_FreeSession(session); | |||
208 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; | |||
209 | } | |||
210 | ||||
211 | /* don't destroy a private object if we aren't logged in */ | |||
212 | if ((!slot->isLoggedIn) && (slot->needLogin) && | |||
213 | (sftk_isTrue(object, CKA_PRIVATE0x00000002UL))) { | |||
214 | sftk_FreeSession(session); | |||
215 | sftk_FreeObject(object); | |||
216 | return CKR_USER_NOT_LOGGED_IN0x00000101UL; | |||
217 | } | |||
218 | ||||
219 | /* don't destroy a token object if we aren't in a rw session */ | |||
220 | ||||
221 | if (((session->info.flags & CKF_RW_SESSION0x00000002UL) == 0) && | |||
222 | (sftk_isTrue(object, CKA_TOKEN0x00000001UL))) { | |||
223 | sftk_FreeSession(session); | |||
224 | sftk_FreeObject(object); | |||
225 | return CKR_SESSION_READ_ONLY0x000000B5UL; | |||
226 | } | |||
227 | ||||
228 | sftk_DeleteObject(session, object); | |||
229 | ||||
230 | sftk_FreeSession(session); | |||
231 | ||||
232 | /* | |||
233 | * get some indication if the object is destroyed. Note: this is not | |||
234 | * 100%. Someone may have an object reference outstanding (though that | |||
235 | * should not be the case by here. Also note that the object is "half" | |||
236 | * destroyed. Our internal representation is destroyed, but it may still | |||
237 | * be in the data base. | |||
238 | */ | |||
239 | status = sftk_FreeObject(object); | |||
240 | ||||
241 | return (status != SFTK_DestroyFailure) ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL; | |||
242 | } | |||
243 | ||||
244 | /* | |||
245 | * Returns true if "params" contains a valid set of PSS parameters | |||
246 | */ | |||
247 | static PRBool | |||
248 | sftk_ValidatePssParams(const CK_RSA_PKCS_PSS_PARAMS *params) | |||
249 | { | |||
250 | if (!params) { | |||
251 | return PR_FALSE0; | |||
252 | } | |||
253 | if (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL || | |||
254 | sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) { | |||
255 | return PR_FALSE0; | |||
256 | } | |||
257 | return PR_TRUE1; | |||
258 | } | |||
259 | ||||
260 | /* | |||
261 | * Returns true if "params" contains a valid set of OAEP parameters | |||
262 | */ | |||
263 | static PRBool | |||
264 | sftk_ValidateOaepParams(const CK_RSA_PKCS_OAEP_PARAMS *params) | |||
265 | { | |||
266 | if (!params) { | |||
267 | return PR_FALSE0; | |||
268 | } | |||
269 | /* The requirements of ulSourceLen/pSourceData come from PKCS #11, which | |||
270 | * state: | |||
271 | * If the parameter is empty, pSourceData must be NULL and | |||
272 | * ulSourceDataLen must be zero. | |||
273 | */ | |||
274 | if (params->source != CKZ_DATA_SPECIFIED0x00000001UL || | |||
275 | (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) || | |||
276 | (sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) || | |||
277 | (params->ulSourceDataLen == 0 && params->pSourceData != NULL((void*)0)) || | |||
278 | (params->ulSourceDataLen != 0 && params->pSourceData == NULL((void*)0))) { | |||
279 | return PR_FALSE0; | |||
280 | } | |||
281 | return PR_TRUE1; | |||
282 | } | |||
283 | ||||
284 | /* | |||
285 | * return a context based on the SFTKContext type. | |||
286 | */ | |||
287 | SFTKSessionContext * | |||
288 | sftk_ReturnContextByType(SFTKSession *session, SFTKContextType type) | |||
289 | { | |||
290 | switch (type) { | |||
291 | case SFTK_ENCRYPT: | |||
292 | case SFTK_DECRYPT: | |||
293 | case SFTK_MESSAGE_ENCRYPT: | |||
294 | case SFTK_MESSAGE_DECRYPT: | |||
295 | return session->enc_context; | |||
296 | case SFTK_HASH: | |||
297 | return session->hash_context; | |||
298 | case SFTK_SIGN: | |||
299 | case SFTK_SIGN_RECOVER: | |||
300 | case SFTK_VERIFY: | |||
301 | case SFTK_VERIFY_RECOVER: | |||
302 | case SFTK_MESSAGE_SIGN: | |||
303 | case SFTK_MESSAGE_VERIFY: | |||
304 | return session->hash_context; | |||
305 | } | |||
306 | return NULL((void*)0); | |||
307 | } | |||
308 | ||||
309 | /* | |||
310 | * change a context based on the SFTKContext type. | |||
311 | */ | |||
312 | void | |||
313 | sftk_SetContextByType(SFTKSession *session, SFTKContextType type, | |||
314 | SFTKSessionContext *context) | |||
315 | { | |||
316 | switch (type) { | |||
317 | case SFTK_ENCRYPT: | |||
318 | case SFTK_DECRYPT: | |||
319 | case SFTK_MESSAGE_ENCRYPT: | |||
320 | case SFTK_MESSAGE_DECRYPT: | |||
321 | session->enc_context = context; | |||
322 | break; | |||
323 | case SFTK_HASH: | |||
324 | session->hash_context = context; | |||
325 | break; | |||
326 | case SFTK_SIGN: | |||
327 | case SFTK_SIGN_RECOVER: | |||
328 | case SFTK_VERIFY: | |||
329 | case SFTK_VERIFY_RECOVER: | |||
330 | case SFTK_MESSAGE_SIGN: | |||
331 | case SFTK_MESSAGE_VERIFY: | |||
332 | session->hash_context = context; | |||
333 | break; | |||
334 | } | |||
335 | return; | |||
336 | } | |||
337 | ||||
338 | /* | |||
339 | * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal, | |||
340 | * and C_XXX function. The function takes a session handle, the context type, | |||
341 | * and wether or not the session needs to be multipart. It returns the context, | |||
342 | * and optionally returns the session pointer (if sessionPtr != NULL) if session | |||
343 | * pointer is returned, the caller is responsible for freeing it. | |||
344 | */ | |||
345 | CK_RV | |||
346 | sftk_GetContext(CK_SESSION_HANDLE handle, SFTKSessionContext **contextPtr, | |||
347 | SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr) | |||
348 | { | |||
349 | SFTKSession *session; | |||
350 | SFTKSessionContext *context; | |||
351 | ||||
352 | session = sftk_SessionFromHandle(handle); | |||
353 | if (session == NULL((void*)0)) | |||
354 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
355 | context = sftk_ReturnContextByType(session, type); | |||
356 | /* make sure the context is valid */ | |||
357 | if ((context == NULL((void*)0)) || (context->type != type) || (needMulti && !(context->multi))) { | |||
358 | sftk_FreeSession(session); | |||
359 | return CKR_OPERATION_NOT_INITIALIZED0x00000091UL; | |||
360 | } | |||
361 | *contextPtr = context; | |||
362 | if (sessionPtr != NULL((void*)0)) { | |||
363 | *sessionPtr = session; | |||
364 | } else { | |||
365 | sftk_FreeSession(session); | |||
366 | } | |||
367 | return CKR_OK0x00000000UL; | |||
368 | } | |||
369 | ||||
370 | /** Terminate operation (in the PKCS#11 spec sense). | |||
371 | * Intuitive name for FreeContext/SetNullContext pair. | |||
372 | */ | |||
373 | void | |||
374 | sftk_TerminateOp(SFTKSession *session, SFTKContextType ctype, | |||
375 | SFTKSessionContext *context) | |||
376 | { | |||
377 | session->lastOpWasFIPS = context->isFIPS; | |||
378 | sftk_FreeContext(context); | |||
379 | sftk_SetContextByType(session, ctype, NULL((void*)0)); | |||
380 | } | |||
381 | ||||
382 | /* | |||
383 | ************** Crypto Functions: Encrypt ************************ | |||
384 | */ | |||
385 | ||||
386 | /* | |||
387 | * All the NSC_InitXXX functions have a set of common checks and processing they | |||
388 | * all need to do at the beginning. This is done here. | |||
389 | */ | |||
390 | CK_RV | |||
391 | sftk_InitGeneric(SFTKSession *session, CK_MECHANISM *pMechanism, | |||
392 | SFTKSessionContext **contextPtr, | |||
393 | SFTKContextType ctype, SFTKObject **keyPtr, | |||
394 | CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr, | |||
395 | CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation) | |||
396 | { | |||
397 | SFTKObject *key = NULL((void*)0); | |||
398 | SFTKAttribute *att; | |||
399 | SFTKSessionContext *context; | |||
400 | ||||
401 | /* We can only init if there is not current context active */ | |||
402 | if (sftk_ReturnContextByType(session, ctype) != NULL((void*)0)) { | |||
403 | return CKR_OPERATION_ACTIVE0x00000090UL; | |||
404 | } | |||
405 | ||||
406 | /* find the key */ | |||
407 | if (keyPtr) { | |||
408 | key = sftk_ObjectFromHandle(hKey, session); | |||
409 | if (key == NULL((void*)0)) { | |||
410 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
411 | } | |||
412 | ||||
413 | /* make sure it's a valid key for this operation */ | |||
414 | if (((key->objclass != CKO_SECRET_KEY0x00000004UL) && | |||
415 | (key->objclass != pubKeyType)) || | |||
416 | !sftk_isTrue(key, operation)) { | |||
417 | sftk_FreeObject(key); | |||
418 | return CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
419 | } | |||
420 | /* get the key type */ | |||
421 | att = sftk_FindAttribute(key, CKA_KEY_TYPE0x00000100UL); | |||
422 | if (att == NULL((void*)0)) { | |||
423 | sftk_FreeObject(key); | |||
424 | return CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
425 | } | |||
426 | PORT_Assert(att->attrib.ulValueLen == sizeof(CK_KEY_TYPE))((att->attrib.ulValueLen == sizeof(CK_KEY_TYPE))?((void)0) :PR_Assert("att->attrib.ulValueLen == sizeof(CK_KEY_TYPE)" ,"pkcs11c.c",426)); | |||
427 | if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) { | |||
428 | sftk_FreeAttribute(att); | |||
429 | sftk_FreeObject(key); | |||
430 | return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL; | |||
431 | } | |||
432 | PORT_Memcpymemcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE)); | |||
433 | sftk_FreeAttribute(att); | |||
434 | *keyPtr = key; | |||
435 | } | |||
436 | ||||
437 | /* allocate the context structure */ | |||
438 | context = (SFTKSessionContext *)PORT_AllocPORT_Alloc_Util(sizeof(SFTKSessionContext)); | |||
439 | if (context == NULL((void*)0)) { | |||
440 | if (key) | |||
441 | sftk_FreeObject(key); | |||
442 | return CKR_HOST_MEMORY0x00000002UL; | |||
443 | } | |||
444 | context->type = ctype; | |||
445 | context->multi = PR_TRUE1; | |||
446 | context->rsa = PR_FALSE0; | |||
447 | context->cipherInfo = NULL((void*)0); | |||
448 | context->hashInfo = NULL((void*)0); | |||
449 | context->doPad = PR_FALSE0; | |||
450 | context->padDataLength = 0; | |||
451 | context->key = key; | |||
452 | context->blockSize = 0; | |||
453 | context->maxLen = 0; | |||
454 | context->isFIPS = sftk_operationIsFIPS(session->slot, pMechanism, | |||
455 | operation, key); | |||
456 | *contextPtr = context; | |||
457 | return CKR_OK0x00000000UL; | |||
458 | } | |||
459 | ||||
460 | static int | |||
461 | sftk_aes_mode(CK_MECHANISM_TYPE mechanism) | |||
462 | { | |||
463 | switch (mechanism) { | |||
464 | case CKM_AES_CBC_PAD0x00001085UL: | |||
465 | case CKM_AES_CBC0x00001082UL: | |||
466 | return NSS_AES_CBC1; | |||
467 | case CKM_AES_ECB0x00001081UL: | |||
468 | return NSS_AES0; | |||
469 | case CKM_AES_CTS0x00001089UL: | |||
470 | return NSS_AES_CTS2; | |||
471 | case CKM_AES_CTR0x00001086UL: | |||
472 | return NSS_AES_CTR3; | |||
473 | case CKM_AES_GCM0x00001087UL: | |||
474 | return NSS_AES_GCM4; | |||
475 | } | |||
476 | return -1; | |||
477 | } | |||
478 | ||||
479 | static SECStatus | |||
480 | sftk_RSAEncryptRaw(NSSLOWKEYPublicKey *key, unsigned char *output, | |||
481 | unsigned int *outputLen, unsigned int maxLen, | |||
482 | const unsigned char *input, unsigned int inputLen) | |||
483 | { | |||
484 | SECStatus rv = SECFailure; | |||
485 | ||||
486 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",486)); | |||
487 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
488 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
489 | return SECFailure; | |||
490 | } | |||
491 | ||||
492 | rv = RSA_EncryptRaw(&key->u.rsa, output, outputLen, maxLen, input, | |||
493 | inputLen); | |||
494 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
495 | sftk_fatalError = PR_TRUE1; | |||
496 | } | |||
497 | ||||
498 | return rv; | |||
499 | } | |||
500 | ||||
501 | static SECStatus | |||
502 | sftk_RSADecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, | |||
503 | unsigned int *outputLen, unsigned int maxLen, | |||
504 | const unsigned char *input, unsigned int inputLen) | |||
505 | { | |||
506 | SECStatus rv = SECFailure; | |||
507 | ||||
508 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",508)); | |||
509 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
510 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
511 | return SECFailure; | |||
512 | } | |||
513 | ||||
514 | rv = RSA_DecryptRaw(&key->u.rsa, output, outputLen, maxLen, input, | |||
515 | inputLen); | |||
516 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
517 | sftk_fatalError = PR_TRUE1; | |||
518 | } | |||
519 | ||||
520 | return rv; | |||
521 | } | |||
522 | ||||
523 | static SECStatus | |||
524 | sftk_RSAEncrypt(NSSLOWKEYPublicKey *key, unsigned char *output, | |||
525 | unsigned int *outputLen, unsigned int maxLen, | |||
526 | const unsigned char *input, unsigned int inputLen) | |||
527 | { | |||
528 | SECStatus rv = SECFailure; | |||
529 | ||||
530 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",530)); | |||
531 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
532 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
533 | return SECFailure; | |||
534 | } | |||
535 | ||||
536 | rv = RSA_EncryptBlock(&key->u.rsa, output, outputLen, maxLen, input, | |||
537 | inputLen); | |||
538 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
539 | sftk_fatalError = PR_TRUE1; | |||
540 | } | |||
541 | ||||
542 | return rv; | |||
543 | } | |||
544 | ||||
545 | static SECStatus | |||
546 | sftk_RSADecrypt(NSSLOWKEYPrivateKey *key, unsigned char *output, | |||
547 | unsigned int *outputLen, unsigned int maxLen, | |||
548 | const unsigned char *input, unsigned int inputLen) | |||
549 | { | |||
550 | SECStatus rv = SECFailure; | |||
551 | ||||
552 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",552)); | |||
553 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
554 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
555 | return SECFailure; | |||
556 | } | |||
557 | ||||
558 | rv = RSA_DecryptBlock(&key->u.rsa, output, outputLen, maxLen, input, | |||
559 | inputLen); | |||
560 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
561 | sftk_fatalError = PR_TRUE1; | |||
562 | } | |||
563 | ||||
564 | return rv; | |||
565 | } | |||
566 | ||||
567 | static void | |||
568 | sftk_freeRSAOAEPInfo(SFTKOAEPInfo *info, PRBool freeit) | |||
569 | { | |||
570 | PORT_ZFreePORT_ZFree_Util(info->params.pSourceData, info->params.ulSourceDataLen); | |||
571 | PORT_ZFreePORT_ZFree_Util(info, sizeof(SFTKOAEPInfo)); | |||
572 | } | |||
573 | ||||
574 | static SECStatus | |||
575 | sftk_RSAEncryptOAEP(SFTKOAEPInfo *info, unsigned char *output, | |||
576 | unsigned int *outputLen, unsigned int maxLen, | |||
577 | const unsigned char *input, unsigned int inputLen) | |||
578 | { | |||
579 | HASH_HashType hashAlg; | |||
580 | HASH_HashType maskHashAlg; | |||
581 | ||||
582 | PORT_Assert(info->key.pub->keyType == NSSLOWKEYRSAKey)((info->key.pub->keyType == NSSLOWKEYRSAKey)?((void)0): PR_Assert("info->key.pub->keyType == NSSLOWKEYRSAKey","pkcs11c.c" ,582)); | |||
583 | if (info->key.pub->keyType != NSSLOWKEYRSAKey) { | |||
584 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
585 | return SECFailure; | |||
586 | } | |||
587 | ||||
588 | hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg); | |||
589 | maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf); | |||
590 | ||||
591 | return RSA_EncryptOAEP(&info->key.pub->u.rsa, hashAlg, maskHashAlg, | |||
592 | (const unsigned char *)info->params.pSourceData, | |||
593 | info->params.ulSourceDataLen, NULL((void*)0), 0, | |||
594 | output, outputLen, maxLen, input, inputLen); | |||
595 | } | |||
596 | ||||
597 | static SECStatus | |||
598 | sftk_RSADecryptOAEP(SFTKOAEPInfo *info, unsigned char *output, | |||
599 | unsigned int *outputLen, unsigned int maxLen, | |||
600 | const unsigned char *input, unsigned int inputLen) | |||
601 | { | |||
602 | SECStatus rv = SECFailure; | |||
603 | HASH_HashType hashAlg; | |||
604 | HASH_HashType maskHashAlg; | |||
605 | ||||
606 | PORT_Assert(info->key.priv->keyType == NSSLOWKEYRSAKey)((info->key.priv->keyType == NSSLOWKEYRSAKey)?((void)0) :PR_Assert("info->key.priv->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",606)); | |||
607 | if (info->key.priv->keyType != NSSLOWKEYRSAKey) { | |||
608 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
609 | return SECFailure; | |||
610 | } | |||
611 | ||||
612 | hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg); | |||
613 | maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf); | |||
614 | ||||
615 | rv = RSA_DecryptOAEP(&info->key.priv->u.rsa, hashAlg, maskHashAlg, | |||
616 | (const unsigned char *)info->params.pSourceData, | |||
617 | info->params.ulSourceDataLen, | |||
618 | output, outputLen, maxLen, input, inputLen); | |||
619 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
620 | sftk_fatalError = PR_TRUE1; | |||
621 | } | |||
622 | return rv; | |||
623 | } | |||
624 | ||||
625 | static SFTKChaCha20Poly1305Info * | |||
626 | sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key, | |||
627 | unsigned int keyLen, | |||
628 | const CK_NSS_AEAD_PARAMS *params) | |||
629 | { | |||
630 | SFTKChaCha20Poly1305Info *ctx; | |||
631 | ||||
632 | if (params->ulNonceLen != sizeof(ctx->nonce)) { | |||
633 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INPUT_LEN); | |||
634 | return NULL((void*)0); | |||
635 | } | |||
636 | ||||
637 | ctx = PORT_New(SFTKChaCha20Poly1305Info)(SFTKChaCha20Poly1305Info *)PORT_Alloc_Util(sizeof(SFTKChaCha20Poly1305Info )); | |||
638 | if (ctx == NULL((void*)0)) { | |||
639 | return NULL((void*)0); | |||
640 | } | |||
641 | ||||
642 | if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen, | |||
643 | params->ulTagLen) != SECSuccess) { | |||
644 | PORT_FreePORT_Free_Util(ctx); | |||
645 | return NULL((void*)0); | |||
646 | } | |||
647 | ||||
648 | PORT_Memcpymemcpy(ctx->nonce, params->pNonce, sizeof(ctx->nonce)); | |||
649 | ||||
650 | /* AAD data and length must both be null, or both non-null. */ | |||
651 | PORT_Assert((params->pAAD == NULL) == (params->ulAADLen == 0))(((params->pAAD == ((void*)0)) == (params->ulAADLen == 0 ))?((void)0):PR_Assert("(params->pAAD == NULL) == (params->ulAADLen == 0)" ,"pkcs11c.c",651)); | |||
652 | ||||
653 | if (params->ulAADLen > sizeof(ctx->ad)) { | |||
654 | /* Need to allocate an overflow buffer for the additional data. */ | |||
655 | ctx->adOverflow = (unsigned char *)PORT_AllocPORT_Alloc_Util(params->ulAADLen); | |||
656 | if (!ctx->adOverflow) { | |||
657 | PORT_FreePORT_Free_Util(ctx); | |||
658 | return NULL((void*)0); | |||
659 | } | |||
660 | PORT_Memcpymemcpy(ctx->adOverflow, params->pAAD, params->ulAADLen); | |||
661 | } else { | |||
662 | ctx->adOverflow = NULL((void*)0); | |||
663 | if (params->pAAD) { | |||
664 | PORT_Memcpymemcpy(ctx->ad, params->pAAD, params->ulAADLen); | |||
665 | } | |||
666 | } | |||
667 | ctx->adLen = params->ulAADLen; | |||
668 | ||||
669 | return ctx; | |||
670 | } | |||
671 | ||||
672 | static void | |||
673 | sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx, | |||
674 | PRBool freeit) | |||
675 | { | |||
676 | ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE0); | |||
677 | if (ctx->adOverflow != NULL((void*)0)) { | |||
678 | PORT_ZFreePORT_ZFree_Util(ctx->adOverflow, ctx->adLen); | |||
679 | ctx->adOverflow = NULL((void*)0); | |||
680 | } else { | |||
681 | PORT_Memsetmemset(ctx->ad, 0, ctx->adLen); | |||
682 | } | |||
683 | ctx->adLen = 0; | |||
684 | if (freeit) { | |||
685 | PORT_FreePORT_Free_Util(ctx); | |||
686 | } | |||
687 | } | |||
688 | ||||
689 | static SECStatus | |||
690 | sftk_ChaCha20Poly1305_Encrypt(const SFTKChaCha20Poly1305Info *ctx, | |||
691 | unsigned char *output, unsigned int *outputLen, | |||
692 | unsigned int maxOutputLen, | |||
693 | const unsigned char *input, unsigned int inputLen) | |||
694 | { | |||
695 | const unsigned char *ad = ctx->adOverflow; | |||
696 | ||||
697 | if (ad == NULL((void*)0)) { | |||
698 | ad = ctx->ad; | |||
699 | } | |||
700 | ||||
701 | return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen, | |||
702 | maxOutputLen, input, inputLen, ctx->nonce, | |||
703 | sizeof(ctx->nonce), ad, ctx->adLen); | |||
704 | } | |||
705 | ||||
706 | static SECStatus | |||
707 | sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx, | |||
708 | unsigned char *output, unsigned int *outputLen, | |||
709 | unsigned int maxOutputLen, | |||
710 | const unsigned char *input, unsigned int inputLen) | |||
711 | { | |||
712 | const unsigned char *ad = ctx->adOverflow; | |||
713 | ||||
714 | if (ad == NULL((void*)0)) { | |||
715 | ad = ctx->ad; | |||
716 | } | |||
717 | ||||
718 | return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen, | |||
719 | maxOutputLen, input, inputLen, ctx->nonce, | |||
720 | sizeof(ctx->nonce), ad, ctx->adLen); | |||
721 | } | |||
722 | ||||
723 | static SECStatus | |||
724 | sftk_ChaCha20Ctr(const SFTKChaCha20CtrInfo *ctx, | |||
725 | unsigned char *output, unsigned int *outputLen, | |||
726 | unsigned int maxOutputLen, | |||
727 | const unsigned char *input, unsigned int inputLen) | |||
728 | { | |||
729 | if (maxOutputLen < inputLen) { | |||
730 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OUTPUT_LEN); | |||
731 | return SECFailure; | |||
732 | } | |||
733 | ChaCha20_Xor(output, input, inputLen, ctx->key, | |||
734 | ctx->nonce, ctx->counter); | |||
735 | *outputLen = inputLen; | |||
736 | return SECSuccess; | |||
737 | } | |||
738 | ||||
739 | static void | |||
740 | sftk_ChaCha20Ctr_DestroyContext(SFTKChaCha20CtrInfo *ctx, | |||
741 | PRBool freeit) | |||
742 | { | |||
743 | memset(ctx, 0, sizeof(*ctx)); | |||
744 | if (freeit) { | |||
745 | PORT_FreePORT_Free_Util(ctx); | |||
746 | } | |||
747 | } | |||
748 | ||||
749 | /** NSC_CryptInit initializes an encryption/Decryption operation. | |||
750 | * | |||
751 | * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey. | |||
752 | * Called by NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac) only for block | |||
753 | * ciphers MAC'ing. | |||
754 | */ | |||
755 | CK_RV | |||
756 | sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, | |||
757 | CK_OBJECT_HANDLE hKey, | |||
758 | CK_ATTRIBUTE_TYPE mechUsage, CK_ATTRIBUTE_TYPE keyUsage, | |||
759 | SFTKContextType contextType, PRBool isEncrypt) | |||
760 | { | |||
761 | SFTKSession *session; | |||
762 | SFTKObject *key; | |||
763 | SFTKSessionContext *context; | |||
764 | SFTKAttribute *att; | |||
765 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
766 | CK_RC2_CBC_PARAMS *rc2_param; | |||
767 | unsigned effectiveKeyLength; | |||
768 | #endif | |||
769 | #if NSS_SOFTOKEN_DOES_RC5 | |||
770 | CK_RC5_CBC_PARAMS *rc5_param; | |||
771 | SECItem rc5Key; | |||
772 | #endif | |||
773 | CK_NSS_GCM_PARAMS nss_gcm_param; | |||
774 | void *aes_param; | |||
775 | CK_NSS_AEAD_PARAMS nss_aead_params; | |||
776 | CK_NSS_AEAD_PARAMS *nss_aead_params_ptr = NULL((void*)0); | |||
777 | CK_KEY_TYPE key_type; | |||
778 | CK_RV crv = CKR_OK0x00000000UL; | |||
779 | unsigned char newdeskey[24]; | |||
780 | PRBool useNewKey = PR_FALSE0; | |||
781 | int t; | |||
782 | ||||
783 | if (!pMechanism) { | |||
784 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
785 | } | |||
786 | ||||
787 | crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage); | |||
788 | if (crv != CKR_OK0x00000000UL) | |||
789 | return crv; | |||
790 | ||||
791 | session = sftk_SessionFromHandle(hSession); | |||
792 | if (session == NULL((void*)0)) | |||
793 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
794 | ||||
795 | crv = sftk_InitGeneric(session, pMechanism, &context, contextType, &key, | |||
796 | hKey, &key_type, | |||
797 | isEncrypt ? CKO_PUBLIC_KEY0x00000002UL : CKO_PRIVATE_KEY0x00000003UL, | |||
798 | keyUsage); | |||
799 | ||||
800 | if (crv != CKR_OK0x00000000UL) { | |||
801 | sftk_FreeSession(session); | |||
802 | return crv; | |||
803 | } | |||
804 | ||||
805 | context->doPad = PR_FALSE0; | |||
806 | switch (pMechanism->mechanism) { | |||
807 | case CKM_RSA_PKCS0x00000001UL: | |||
808 | case CKM_RSA_X_5090x00000003UL: | |||
809 | if (key_type != CKK_RSA0x00000000UL) { | |||
810 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
811 | break; | |||
812 | } | |||
813 | context->multi = PR_FALSE0; | |||
814 | context->rsa = PR_TRUE1; | |||
815 | if (isEncrypt) { | |||
816 | NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv); | |||
817 | if (pubKey == NULL((void*)0)) { | |||
818 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
819 | break; | |||
820 | } | |||
821 | context->maxLen = nsslowkey_PublicModulusLen(pubKey); | |||
822 | context->cipherInfo = (void *)pubKey; | |||
823 | context->update = (SFTKCipher)(pMechanism->mechanism == CKM_RSA_X_5090x00000003UL | |||
824 | ? sftk_RSAEncryptRaw | |||
825 | : sftk_RSAEncrypt); | |||
826 | } else { | |||
827 | NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv); | |||
828 | if (privKey == NULL((void*)0)) { | |||
829 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
830 | break; | |||
831 | } | |||
832 | context->maxLen = nsslowkey_PrivateModulusLen(privKey); | |||
833 | context->cipherInfo = (void *)privKey; | |||
834 | context->update = (SFTKCipher)(pMechanism->mechanism == CKM_RSA_X_5090x00000003UL | |||
835 | ? sftk_RSADecryptRaw | |||
836 | : sftk_RSADecrypt); | |||
837 | } | |||
838 | context->destroy = sftk_Null; | |||
839 | break; | |||
840 | case CKM_RSA_PKCS_OAEP0x00000009UL: | |||
841 | if (key_type != CKK_RSA0x00000000UL) { | |||
842 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
843 | break; | |||
844 | } | |||
845 | if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS) || | |||
846 | !sftk_ValidateOaepParams((CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter)) { | |||
847 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
848 | break; | |||
849 | } | |||
850 | context->multi = PR_FALSE0; | |||
851 | context->rsa = PR_TRUE1; | |||
852 | { | |||
853 | SFTKOAEPInfo *info; | |||
854 | CK_RSA_PKCS_OAEP_PARAMS *params = | |||
855 | (CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter; | |||
856 | /* make a copy of the source data value for future | |||
857 | * use (once the user has reclaimed his data in pParameter)*/ | |||
858 | void *newSource = NULL((void*)0); | |||
859 | if (params->pSourceData) { | |||
860 | newSource = PORT_AllocPORT_Alloc_Util(params->ulSourceDataLen); | |||
861 | if (newSource == NULL((void*)0)) { | |||
862 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
863 | break; | |||
864 | } | |||
865 | PORT_Memcpymemcpy(newSource, params->pSourceData, params->ulSourceDataLen); | |||
866 | } | |||
867 | info = PORT_New(SFTKOAEPInfo)(SFTKOAEPInfo *)PORT_Alloc_Util(sizeof(SFTKOAEPInfo)); | |||
868 | if (info == NULL((void*)0)) { | |||
869 | PORT_ZFreePORT_ZFree_Util(newSource, params->ulSourceDataLen); | |||
870 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
871 | break; | |||
872 | } | |||
873 | info->params = *params; | |||
874 | info->params.pSourceData = newSource; | |||
875 | info->isEncrypt = isEncrypt; | |||
876 | ||||
877 | /* now setup encryption and decryption contexts */ | |||
878 | if (isEncrypt) { | |||
879 | info->key.pub = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv); | |||
880 | if (info->key.pub == NULL((void*)0)) { | |||
881 | sftk_freeRSAOAEPInfo(info, PR_TRUE1); | |||
882 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
883 | break; | |||
884 | } | |||
885 | context->update = (SFTKCipher)sftk_RSAEncryptOAEP; | |||
886 | context->maxLen = nsslowkey_PublicModulusLen(info->key.pub); | |||
887 | } else { | |||
888 | info->key.priv = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv); | |||
889 | if (info->key.priv == NULL((void*)0)) { | |||
890 | sftk_freeRSAOAEPInfo(info, PR_TRUE1); | |||
891 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
892 | break; | |||
893 | } | |||
894 | context->update = (SFTKCipher)sftk_RSADecryptOAEP; | |||
895 | context->maxLen = nsslowkey_PrivateModulusLen(info->key.priv); | |||
896 | } | |||
897 | context->cipherInfo = info; | |||
898 | } | |||
899 | context->destroy = (SFTKDestroy)sftk_freeRSAOAEPInfo; | |||
900 | break; | |||
901 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
902 | case CKM_RC2_CBC_PAD0x00000105UL: | |||
903 | context->doPad = PR_TRUE1; | |||
904 | /* fall thru */ | |||
905 | case CKM_RC2_ECB0x00000101UL: | |||
906 | case CKM_RC2_CBC0x00000102UL: | |||
907 | context->blockSize = 8; | |||
908 | if (key_type != CKK_RC20x00000011UL) { | |||
909 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
910 | break; | |||
911 | } | |||
912 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
913 | if (att == NULL((void*)0)) { | |||
914 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
915 | break; | |||
916 | } | |||
917 | ||||
918 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_CBC_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_RC2_CBC_PARAMS))) { | |||
919 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
920 | break; | |||
921 | } | |||
922 | rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter; | |||
923 | effectiveKeyLength = (rc2_param->ulEffectiveBits + 7) / 8; | |||
924 | context->cipherInfo = | |||
925 | RC2_CreateContext((unsigned char *)att->attrib.pValue, | |||
926 | att->attrib.ulValueLen, rc2_param->iv, | |||
927 | pMechanism->mechanism == CKM_RC2_ECB0x00000101UL ? NSS_RC20 : NSS_RC2_CBC1, effectiveKeyLength); | |||
928 | sftk_FreeAttribute(att); | |||
929 | if (context->cipherInfo == NULL((void*)0)) { | |||
930 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
931 | break; | |||
932 | } | |||
933 | context->update = (SFTKCipher)(isEncrypt ? RC2_Encrypt : RC2_Decrypt); | |||
934 | context->destroy = (SFTKDestroy)RC2_DestroyContext; | |||
935 | break; | |||
936 | #endif /* NSS_DISABLE_DEPRECATED_RC2 */ | |||
937 | ||||
938 | #if NSS_SOFTOKEN_DOES_RC5 | |||
939 | case CKM_RC5_CBC_PAD0x00000335UL: | |||
940 | context->doPad = PR_TRUE1; | |||
941 | /* fall thru */ | |||
942 | case CKM_RC5_ECB0x00000331UL: | |||
943 | case CKM_RC5_CBC0x00000332UL: | |||
944 | if (key_type != CKK_RC50x00000019UL) { | |||
945 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
946 | break; | |||
947 | } | |||
948 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
949 | if (att == NULL((void*)0)) { | |||
950 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
951 | break; | |||
952 | } | |||
953 | ||||
954 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_CBC_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_RC5_CBC_PARAMS))) { | |||
955 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
956 | break; | |||
957 | } | |||
958 | rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter; | |||
959 | context->blockSize = rc5_param->ulWordsize * 2; | |||
960 | rc5Key.data = (unsigned char *)att->attrib.pValue; | |||
961 | rc5Key.len = att->attrib.ulValueLen; | |||
962 | context->cipherInfo = RC5_CreateContext(&rc5Key, rc5_param->ulRounds, | |||
963 | rc5_param->ulWordsize, rc5_param->pIv, | |||
964 | pMechanism->mechanism == CKM_RC5_ECB0x00000331UL ? NSS_RC50 : NSS_RC5_CBC1); | |||
965 | sftk_FreeAttribute(att); | |||
966 | if (context->cipherInfo == NULL((void*)0)) { | |||
967 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
968 | break; | |||
969 | } | |||
970 | context->update = (SFTKCipher)(isEncrypt ? RC5_Encrypt : RC5_Decrypt); | |||
971 | context->destroy = (SFTKDestroy)RC5_DestroyContext; | |||
972 | break; | |||
973 | #endif | |||
974 | case CKM_RC40x00000111UL: | |||
975 | if (key_type != CKK_RC40x00000012UL) { | |||
976 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
977 | break; | |||
978 | } | |||
979 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
980 | if (att == NULL((void*)0)) { | |||
981 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
982 | break; | |||
983 | } | |||
984 | context->cipherInfo = | |||
985 | RC4_CreateContext((unsigned char *)att->attrib.pValue, | |||
986 | att->attrib.ulValueLen); | |||
987 | sftk_FreeAttribute(att); | |||
988 | if (context->cipherInfo == NULL((void*)0)) { | |||
989 | crv = CKR_HOST_MEMORY0x00000002UL; /* WRONG !!! */ | |||
990 | break; | |||
991 | } | |||
992 | context->update = (SFTKCipher)(isEncrypt ? RC4_Encrypt : RC4_Decrypt); | |||
993 | context->destroy = (SFTKDestroy)RC4_DestroyContext; | |||
994 | break; | |||
995 | case CKM_CDMF_CBC_PAD0x00000145UL: | |||
996 | context->doPad = PR_TRUE1; | |||
997 | /* fall thru */ | |||
998 | case CKM_CDMF_ECB0x00000141UL: | |||
999 | case CKM_CDMF_CBC0x00000142UL: | |||
1000 | if (key_type != CKK_CDMF0x0000001EUL) { | |||
1001 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1002 | break; | |||
1003 | } | |||
1004 | t = (pMechanism->mechanism == CKM_CDMF_ECB0x00000141UL) ? NSS_DES0 : NSS_DES_CBC1; | |||
1005 | goto finish_des; | |||
1006 | case CKM_DES_ECB0x00000121UL: | |||
1007 | if (key_type != CKK_DES0x00000013UL) { | |||
1008 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1009 | break; | |||
1010 | } | |||
1011 | t = NSS_DES0; | |||
1012 | goto finish_des; | |||
1013 | case CKM_DES_CBC_PAD0x00000125UL: | |||
1014 | context->doPad = PR_TRUE1; | |||
1015 | /* fall thru */ | |||
1016 | case CKM_DES_CBC0x00000122UL: | |||
1017 | if (key_type != CKK_DES0x00000013UL) { | |||
1018 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1019 | break; | |||
1020 | } | |||
1021 | t = NSS_DES_CBC1; | |||
1022 | goto finish_des; | |||
1023 | case CKM_DES3_ECB0x00000132UL: | |||
1024 | if ((key_type != CKK_DES20x00000014UL) && (key_type != CKK_DES30x00000015UL)) { | |||
1025 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1026 | break; | |||
1027 | } | |||
1028 | t = NSS_DES_EDE32; | |||
1029 | goto finish_des; | |||
1030 | case CKM_DES3_CBC_PAD0x00000136UL: | |||
1031 | context->doPad = PR_TRUE1; | |||
1032 | /* fall thru */ | |||
1033 | case CKM_DES3_CBC0x00000133UL: | |||
1034 | if ((key_type != CKK_DES20x00000014UL) && (key_type != CKK_DES30x00000015UL)) { | |||
1035 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1036 | break; | |||
1037 | } | |||
1038 | t = NSS_DES_EDE3_CBC3; | |||
1039 | finish_des: | |||
1040 | if ((t != NSS_DES0 && t != NSS_DES_EDE32) && (pMechanism->pParameter == NULL((void*)0) || | |||
1041 | pMechanism->ulParameterLen < 8)) { | |||
1042 | crv = CKR_DOMAIN_PARAMS_INVALID0x00000130UL; | |||
1043 | break; | |||
1044 | } | |||
1045 | context->blockSize = 8; | |||
1046 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
1047 | if (att == NULL((void*)0)) { | |||
1048 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1049 | break; | |||
1050 | } | |||
1051 | if (key_type == CKK_DES20x00000014UL && | |||
1052 | (t == NSS_DES_EDE3_CBC3 || t == NSS_DES_EDE32)) { | |||
1053 | /* extend DES2 key to DES3 key. */ | |||
1054 | memcpy(newdeskey, att->attrib.pValue, 16); | |||
1055 | memcpy(newdeskey + 16, newdeskey, 8); | |||
1056 | useNewKey = PR_TRUE1; | |||
1057 | } else if (key_type == CKK_CDMF0x0000001EUL) { | |||
1058 | crv = sftk_cdmf2des((unsigned char *)att->attrib.pValue, newdeskey); | |||
1059 | if (crv != CKR_OK0x00000000UL) { | |||
1060 | sftk_FreeAttribute(att); | |||
1061 | break; | |||
1062 | } | |||
1063 | useNewKey = PR_TRUE1; | |||
1064 | } | |||
1065 | context->cipherInfo = DES_CreateContext( | |||
1066 | useNewKey ? newdeskey : (unsigned char *)att->attrib.pValue, | |||
1067 | (unsigned char *)pMechanism->pParameter, t, isEncrypt); | |||
1068 | if (useNewKey) | |||
1069 | memset(newdeskey, 0, sizeof newdeskey); | |||
1070 | sftk_FreeAttribute(att); | |||
1071 | if (context->cipherInfo == NULL((void*)0)) { | |||
1072 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
1073 | break; | |||
1074 | } | |||
1075 | context->update = (SFTKCipher)(isEncrypt ? DES_Encrypt : DES_Decrypt); | |||
1076 | context->destroy = (SFTKDestroy)DES_DestroyContext; | |||
1077 | break; | |||
1078 | #ifndef NSS_DISABLE_DEPRECATED_SEED | |||
1079 | case CKM_SEED_CBC_PAD0x00000655UL: | |||
1080 | context->doPad = PR_TRUE1; | |||
1081 | /* fall thru */ | |||
1082 | case CKM_SEED_CBC0x00000652UL: | |||
1083 | if (!pMechanism->pParameter || | |||
1084 | pMechanism->ulParameterLen != 16) { | |||
1085 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1086 | break; | |||
1087 | } | |||
1088 | /* fall thru */ | |||
1089 | case CKM_SEED_ECB0x00000651UL: | |||
1090 | context->blockSize = 16; | |||
1091 | if (key_type != CKK_SEED0x0000002FUL) { | |||
1092 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1093 | break; | |||
1094 | } | |||
1095 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
1096 | if (att == NULL((void*)0)) { | |||
1097 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1098 | break; | |||
1099 | } | |||
1100 | context->cipherInfo = SEED_CreateContext( | |||
1101 | (unsigned char *)att->attrib.pValue, | |||
1102 | (unsigned char *)pMechanism->pParameter, | |||
1103 | pMechanism->mechanism == CKM_SEED_ECB0x00000651UL ? NSS_SEED0 : NSS_SEED_CBC1, | |||
1104 | isEncrypt); | |||
1105 | sftk_FreeAttribute(att); | |||
1106 | if (context->cipherInfo == NULL((void*)0)) { | |||
1107 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
1108 | break; | |||
1109 | } | |||
1110 | context->update = (SFTKCipher)(isEncrypt ? SEED_Encrypt : SEED_Decrypt); | |||
1111 | context->destroy = (SFTKDestroy)SEED_DestroyContext; | |||
1112 | break; | |||
1113 | #endif /* NSS_DISABLE_DEPRECATED_SEED */ | |||
1114 | case CKM_CAMELLIA_CBC_PAD0x00000555UL: | |||
1115 | context->doPad = PR_TRUE1; | |||
1116 | /* fall thru */ | |||
1117 | case CKM_CAMELLIA_CBC0x00000552UL: | |||
1118 | if (!pMechanism->pParameter || | |||
1119 | pMechanism->ulParameterLen != 16) { | |||
1120 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1121 | break; | |||
1122 | } | |||
1123 | /* fall thru */ | |||
1124 | case CKM_CAMELLIA_ECB0x00000551UL: | |||
1125 | context->blockSize = 16; | |||
1126 | if (key_type != CKK_CAMELLIA0x00000025UL) { | |||
1127 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1128 | break; | |||
1129 | } | |||
1130 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
1131 | if (att == NULL((void*)0)) { | |||
1132 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1133 | break; | |||
1134 | } | |||
1135 | context->cipherInfo = Camellia_CreateContext( | |||
1136 | (unsigned char *)att->attrib.pValue, | |||
1137 | (unsigned char *)pMechanism->pParameter, | |||
1138 | pMechanism->mechanism == | |||
1139 | CKM_CAMELLIA_ECB0x00000551UL | |||
1140 | ? NSS_CAMELLIA0 | |||
1141 | : NSS_CAMELLIA_CBC1, | |||
1142 | isEncrypt, att->attrib.ulValueLen); | |||
1143 | sftk_FreeAttribute(att); | |||
1144 | if (context->cipherInfo == NULL((void*)0)) { | |||
1145 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
1146 | break; | |||
1147 | } | |||
1148 | context->update = (SFTKCipher)(isEncrypt ? Camellia_Encrypt : Camellia_Decrypt); | |||
1149 | context->destroy = (SFTKDestroy)Camellia_DestroyContext; | |||
1150 | break; | |||
1151 | ||||
1152 | case CKM_AES_CBC_PAD0x00001085UL: | |||
1153 | context->doPad = PR_TRUE1; | |||
1154 | /* fall thru */ | |||
1155 | case CKM_AES_ECB0x00001081UL: | |||
1156 | case CKM_AES_CBC0x00001082UL: | |||
1157 | context->blockSize = 16; | |||
1158 | case CKM_AES_CTS0x00001089UL: | |||
1159 | case CKM_AES_CTR0x00001086UL: | |||
1160 | case CKM_AES_GCM0x00001087UL: | |||
1161 | aes_param = pMechanism->pParameter; | |||
1162 | /* | |||
1163 | * Due to a mismatch between the documentation and the header | |||
1164 | * file, two different definitions for CK_GCM_PARAMS exist. | |||
1165 | * The header file is normative according to Oasis, but NSS used | |||
1166 | * the documentation. In PKCS #11 v3.0, this was reconciled in | |||
1167 | * favor of the header file definition. To maintain binary | |||
1168 | * compatibility, NSS now defines CK_GCM_PARAMS_V3 as the official | |||
1169 | * version v3 (V2.4 header file) and CK_NSS_GCM_PARAMS as the | |||
1170 | * legacy (V2.4 documentation, NSS version). CK_GCM_PARAMS | |||
1171 | * is defined as CK_GCM_PARAMS_V3 if NSS_PKCS11_2_0_COMPAT is not | |||
1172 | * defined and CK_NSS_GCM_PARAMS if it is. Internally | |||
1173 | * softoken continues to use the legacy version. The code below | |||
1174 | * automatically detects which parameter was passed in and | |||
1175 | * converts CK_GCM_PARAMS_V3 to the CK_NSS_GCM_PARAMS (legacy | |||
1176 | * version) on the fly. NSS proper will eventually start | |||
1177 | * using the CK_GCM_PARAMS_V3 version and fall back to the | |||
1178 | * CK_NSS_GCM_PARAMS if the CK_GCM_PARAMS_V3 version fails with | |||
1179 | * CKR_MECHANISM_PARAM_INVALID. | |||
1180 | */ | |||
1181 | if (pMechanism->mechanism == CKM_AES_GCM0x00001087UL) { | |||
1182 | if (!aes_param) { | |||
1183 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1184 | break; | |||
1185 | } | |||
1186 | if (pMechanism->ulParameterLen == sizeof(CK_GCM_PARAMS_V3)) { | |||
1187 | /* convert the true V3 parameters into the old NSS parameters */ | |||
1188 | CK_GCM_PARAMS_V3 *gcm_params = (CK_GCM_PARAMS_V3 *)aes_param; | |||
1189 | if (gcm_params->ulIvLen * 8 != gcm_params->ulIvBits) { | |||
1190 | /* only support byte aligned IV lengths */ | |||
1191 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1192 | break; | |||
1193 | } | |||
1194 | aes_param = (void *)&nss_gcm_param; | |||
1195 | nss_gcm_param.pIv = gcm_params->pIv; | |||
1196 | nss_gcm_param.ulIvLen = gcm_params->ulIvLen; | |||
1197 | nss_gcm_param.pAAD = gcm_params->pAAD; | |||
1198 | nss_gcm_param.ulAADLen = gcm_params->ulAADLen; | |||
1199 | nss_gcm_param.ulTagBits = gcm_params->ulTagBits; | |||
1200 | } else if (pMechanism->ulParameterLen != sizeof(CK_NSS_GCM_PARAMS)) { | |||
1201 | /* neither old nor new style params, must be invalid */ | |||
1202 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1203 | break; | |||
1204 | } | |||
1205 | } else if ((pMechanism->mechanism == CKM_AES_CTR0x00001086UL && BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CTR_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_AES_CTR_PARAMS))) || | |||
1206 | ((pMechanism->mechanism == CKM_AES_CBC0x00001082UL || pMechanism->mechanism == CKM_AES_CTS0x00001089UL) && BAD_PARAM_CAST(pMechanism, AES_BLOCK_SIZE)(!pMechanism->pParameter || pMechanism->ulParameterLen < 16))) { | |||
1207 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1208 | break; | |||
1209 | } | |||
1210 | ||||
1211 | if (pMechanism->mechanism == CKM_AES_GCM0x00001087UL) { | |||
1212 | context->multi = PR_FALSE0; | |||
1213 | } | |||
1214 | if (key_type != CKK_AES0x0000001FUL) { | |||
1215 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1216 | break; | |||
1217 | } | |||
1218 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
1219 | if (att == NULL((void*)0)) { | |||
1220 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1221 | break; | |||
1222 | } | |||
1223 | context->cipherInfo = AES_CreateContext( | |||
1224 | (unsigned char *)att->attrib.pValue, | |||
1225 | (unsigned char *)aes_param, | |||
1226 | sftk_aes_mode(pMechanism->mechanism), | |||
1227 | isEncrypt, att->attrib.ulValueLen, 16); | |||
1228 | sftk_FreeAttribute(att); | |||
1229 | if (context->cipherInfo == NULL((void*)0)) { | |||
1230 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
1231 | break; | |||
1232 | } | |||
1233 | context->update = (SFTKCipher)(isEncrypt ? AES_Encrypt : AES_Decrypt); | |||
1234 | context->destroy = (SFTKDestroy)AES_DestroyContext; | |||
1235 | break; | |||
1236 | ||||
1237 | case CKM_NSS_CHACHA20_POLY1305((0x80000000UL | 0x4E534350) + 28): | |||
1238 | case CKM_CHACHA20_POLY13050x00004021UL: | |||
1239 | if (pMechanism->mechanism == CKM_NSS_CHACHA20_POLY1305((0x80000000UL | 0x4E534350) + 28)) { | |||
1240 | if (key_type != CKK_NSS_CHACHA20((0x80000000UL | 0x4E534350) + 4)) { | |||
1241 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1242 | break; | |||
1243 | } | |||
1244 | if ((pMechanism->pParameter == NULL((void*)0)) || | |||
1245 | (pMechanism->ulParameterLen != sizeof(CK_NSS_AEAD_PARAMS))) { | |||
1246 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1247 | break; | |||
1248 | } | |||
1249 | nss_aead_params_ptr = (CK_NSS_AEAD_PARAMS *)pMechanism->pParameter; | |||
1250 | } else { | |||
1251 | CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR chacha_poly_params; | |||
1252 | if (key_type != CKK_CHACHA200x00000033UL) { | |||
1253 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1254 | break; | |||
1255 | } | |||
1256 | if ((pMechanism->pParameter == NULL((void*)0)) || | |||
1257 | (pMechanism->ulParameterLen != | |||
1258 | sizeof(CK_SALSA20_CHACHA20_POLY1305_PARAMS))) { | |||
1259 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1260 | break; | |||
1261 | } | |||
1262 | chacha_poly_params = (CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR) | |||
1263 | pMechanism->pParameter; | |||
1264 | nss_aead_params_ptr = &nss_aead_params; | |||
1265 | nss_aead_params.pNonce = chacha_poly_params->pNonce; | |||
1266 | nss_aead_params.ulNonceLen = chacha_poly_params->ulNonceLen; | |||
1267 | nss_aead_params.pAAD = chacha_poly_params->pAAD; | |||
1268 | nss_aead_params.ulAADLen = chacha_poly_params->ulAADLen; | |||
1269 | nss_aead_params.ulTagLen = 16; /* Poly1305 is always 16 */ | |||
1270 | } | |||
1271 | ||||
1272 | context->multi = PR_FALSE0; | |||
1273 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
1274 | if (att == NULL((void*)0)) { | |||
1275 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1276 | break; | |||
1277 | } | |||
1278 | context->cipherInfo = sftk_ChaCha20Poly1305_CreateContext( | |||
1279 | (unsigned char *)att->attrib.pValue, att->attrib.ulValueLen, | |||
1280 | nss_aead_params_ptr); | |||
1281 | sftk_FreeAttribute(att); | |||
1282 | if (context->cipherInfo == NULL((void*)0)) { | |||
1283 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1284 | break; | |||
1285 | } | |||
1286 | context->update = (SFTKCipher)(isEncrypt ? sftk_ChaCha20Poly1305_Encrypt : sftk_ChaCha20Poly1305_Decrypt); | |||
1287 | context->destroy = (SFTKDestroy)sftk_ChaCha20Poly1305_DestroyContext; | |||
1288 | break; | |||
1289 | ||||
1290 | case CKM_NSS_CHACHA20_CTR((0x80000000UL | 0x4E534350) + 33): /* old NSS private version */ | |||
1291 | case CKM_CHACHA200x00001226UL: /* PKCS #11 v3 version */ | |||
1292 | { | |||
1293 | unsigned char *counter; | |||
1294 | unsigned char *nonce; | |||
1295 | unsigned long counter_len; | |||
1296 | unsigned long nonce_len; | |||
1297 | context->multi = PR_FALSE0; | |||
1298 | if (pMechanism->mechanism == CKM_NSS_CHACHA20_CTR((0x80000000UL | 0x4E534350) + 33)) { | |||
1299 | if (key_type != CKK_NSS_CHACHA20((0x80000000UL | 0x4E534350) + 4)) { | |||
1300 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1301 | break; | |||
1302 | } | |||
1303 | if (pMechanism->pParameter == NULL((void*)0) || pMechanism->ulParameterLen != 16) { | |||
1304 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1305 | break; | |||
1306 | } | |||
1307 | counter_len = 4; | |||
1308 | counter = pMechanism->pParameter; | |||
1309 | nonce = counter + 4; | |||
1310 | nonce_len = 12; | |||
1311 | } else { | |||
1312 | CK_CHACHA20_PARAMS_PTR chacha20_param_ptr; | |||
1313 | if (key_type != CKK_CHACHA200x00000033UL) { | |||
1314 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1315 | break; | |||
1316 | } | |||
1317 | if (pMechanism->pParameter == NULL((void*)0) || pMechanism->ulParameterLen != sizeof(CK_CHACHA20_PARAMS)) { | |||
1318 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1319 | break; | |||
1320 | } | |||
1321 | chacha20_param_ptr = (CK_CHACHA20_PARAMS_PTR)pMechanism->pParameter; | |||
1322 | if ((chacha20_param_ptr->blockCounterBits != 32) && | |||
1323 | (chacha20_param_ptr->blockCounterBits != 64)) { | |||
1324 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1325 | break; | |||
1326 | } | |||
1327 | counter_len = chacha20_param_ptr->blockCounterBits / PR_BITS_PER_BYTE8; | |||
1328 | counter = chacha20_param_ptr->pBlockCounter; | |||
1329 | nonce = chacha20_param_ptr->pNonce; | |||
1330 | nonce_len = chacha20_param_ptr->ulNonceBits / PR_BITS_PER_BYTE8; | |||
1331 | } | |||
1332 | ||||
1333 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
1334 | if (att == NULL((void*)0)) { | |||
1335 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1336 | break; | |||
1337 | } | |||
1338 | SFTKChaCha20CtrInfo *ctx = PORT_ZNew(SFTKChaCha20CtrInfo)(SFTKChaCha20CtrInfo *)PORT_ZAlloc_Util(sizeof(SFTKChaCha20CtrInfo )); | |||
1339 | if (!ctx) { | |||
1340 | sftk_FreeAttribute(att); | |||
1341 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
1342 | break; | |||
1343 | } | |||
1344 | if (att->attrib.ulValueLen != sizeof(ctx->key)) { | |||
1345 | sftk_FreeAttribute(att); | |||
1346 | PORT_FreePORT_Free_Util(ctx); | |||
1347 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1348 | break; | |||
1349 | } | |||
1350 | memcpy(ctx->key, att->attrib.pValue, att->attrib.ulValueLen); | |||
1351 | sftk_FreeAttribute(att); | |||
1352 | ||||
1353 | /* make sure we don't overflow our parameters */ | |||
1354 | if ((sizeof(ctx->counter) < counter_len) || | |||
1355 | (sizeof(ctx->nonce) < nonce_len)) { | |||
1356 | PORT_FreePORT_Free_Util(ctx); | |||
1357 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
1358 | break; | |||
1359 | } | |||
1360 | ||||
1361 | /* The counter is little endian. */ | |||
1362 | int i = 0; | |||
1363 | for (; i < counter_len; ++i) { | |||
1364 | ctx->counter |= (PRUint32)counter[i] << (i * 8); | |||
1365 | } | |||
1366 | memcpy(ctx->nonce, nonce, nonce_len); | |||
1367 | context->cipherInfo = ctx; | |||
1368 | context->update = (SFTKCipher)sftk_ChaCha20Ctr; | |||
1369 | context->destroy = (SFTKDestroy)sftk_ChaCha20Ctr_DestroyContext; | |||
1370 | break; | |||
1371 | } | |||
1372 | ||||
1373 | case CKM_NSS_AES_KEY_WRAP_PAD((0x80000000UL | 0x4E534350) + 2): | |||
1374 | case CKM_AES_KEY_WRAP_PAD0x0000210AUL: | |||
1375 | context->doPad = PR_TRUE1; | |||
1376 | /* fall thru */ | |||
1377 | case CKM_NSS_AES_KEY_WRAP((0x80000000UL | 0x4E534350) + 1): | |||
1378 | case CKM_AES_KEY_WRAP0x00002109UL: | |||
1379 | context->blockSize = 8; | |||
1380 | case CKM_AES_KEY_WRAP_KWP0x0000210BUL: | |||
1381 | context->multi = PR_FALSE0; | |||
1382 | if (key_type != CKK_AES0x0000001FUL) { | |||
1383 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
1384 | break; | |||
1385 | } | |||
1386 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
1387 | if (att == NULL((void*)0)) { | |||
1388 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
1389 | break; | |||
1390 | } | |||
1391 | context->cipherInfo = AESKeyWrap_CreateContext( | |||
1392 | (unsigned char *)att->attrib.pValue, | |||
1393 | (unsigned char *)pMechanism->pParameter, | |||
1394 | isEncrypt, att->attrib.ulValueLen); | |||
1395 | sftk_FreeAttribute(att); | |||
1396 | if (context->cipherInfo == NULL((void*)0)) { | |||
1397 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
1398 | break; | |||
1399 | } | |||
1400 | if (pMechanism->mechanism == CKM_AES_KEY_WRAP_KWP0x0000210BUL) { | |||
1401 | context->update = (SFTKCipher)(isEncrypt ? AESKeyWrap_EncryptKWP | |||
1402 | : AESKeyWrap_DecryptKWP); | |||
1403 | } else { | |||
1404 | context->update = (SFTKCipher)(isEncrypt ? AESKeyWrap_Encrypt | |||
1405 | : AESKeyWrap_Decrypt); | |||
1406 | } | |||
1407 | context->destroy = (SFTKDestroy)AESKeyWrap_DestroyContext; | |||
1408 | break; | |||
1409 | ||||
1410 | default: | |||
1411 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
1412 | break; | |||
1413 | } | |||
1414 | ||||
1415 | if (crv != CKR_OK0x00000000UL) { | |||
1416 | sftk_FreeContext(context); | |||
1417 | sftk_FreeSession(session); | |||
1418 | return crv; | |||
1419 | } | |||
1420 | sftk_SetContextByType(session, contextType, context); | |||
1421 | sftk_FreeSession(session); | |||
1422 | return CKR_OK0x00000000UL; | |||
1423 | } | |||
1424 | ||||
1425 | /* NSC_EncryptInit initializes an encryption operation. */ | |||
1426 | CK_RV | |||
1427 | NSC_EncryptInit(CK_SESSION_HANDLE hSession, | |||
1428 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) | |||
1429 | { | |||
1430 | CHECK_FORK(); | |||
1431 | return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT0x00000104UL, CKA_ENCRYPT0x00000104UL, | |||
1432 | SFTK_ENCRYPT, PR_TRUE1); | |||
1433 | } | |||
1434 | ||||
1435 | /* NSC_EncryptUpdate continues a multiple-part encryption operation. */ | |||
1436 | CK_RV | |||
1437 | NSC_EncryptUpdate(CK_SESSION_HANDLE hSession, | |||
1438 | CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, | |||
1439 | CK_ULONG_PTR pulEncryptedPartLen) | |||
1440 | { | |||
1441 | SFTKSessionContext *context; | |||
1442 | unsigned int outlen, i; | |||
1443 | unsigned int padoutlen = 0; | |||
1444 | unsigned int maxout = *pulEncryptedPartLen; | |||
1445 | CK_RV crv; | |||
1446 | SECStatus rv; | |||
1447 | ||||
1448 | CHECK_FORK(); | |||
1449 | ||||
1450 | /* make sure we're legal */ | |||
1451 | crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE1, NULL((void*)0)); | |||
1452 | if (crv != CKR_OK0x00000000UL) | |||
1453 | return crv; | |||
1454 | ||||
1455 | if (!pEncryptedPart) { | |||
1456 | if (context->doPad) { | |||
1457 | CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength; | |||
1458 | CK_ULONG blocksToSend = totalDataAvailable / context->blockSize; | |||
1459 | ||||
1460 | *pulEncryptedPartLen = blocksToSend * context->blockSize; | |||
1461 | return CKR_OK0x00000000UL; | |||
1462 | } | |||
1463 | *pulEncryptedPartLen = ulPartLen; | |||
1464 | return CKR_OK0x00000000UL; | |||
1465 | } | |||
1466 | ||||
1467 | /* do padding */ | |||
1468 | if (context->doPad) { | |||
1469 | /* deal with previous buffered data */ | |||
1470 | if (context->padDataLength != 0) { | |||
1471 | /* fill in the padded to a full block size */ | |||
1472 | for (i = context->padDataLength; | |||
1473 | (ulPartLen != 0) && i < context->blockSize; i++) { | |||
1474 | context->padBuf[i] = *pPart++; | |||
1475 | ulPartLen--; | |||
1476 | context->padDataLength++; | |||
1477 | } | |||
1478 | ||||
1479 | /* not enough data to encrypt yet? then return */ | |||
1480 | if (context->padDataLength != context->blockSize) { | |||
1481 | *pulEncryptedPartLen = 0; | |||
1482 | return CKR_OK0x00000000UL; | |||
1483 | } | |||
1484 | /* encrypt the current padded data */ | |||
1485 | rv = (*context->update)(context->cipherInfo, pEncryptedPart, | |||
1486 | &padoutlen, maxout, context->padBuf, | |||
1487 | context->blockSize); | |||
1488 | if (rv != SECSuccess) { | |||
1489 | return sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1490 | } | |||
1491 | pEncryptedPart += padoutlen; | |||
1492 | maxout -= padoutlen; | |||
1493 | } | |||
1494 | /* save the residual */ | |||
1495 | context->padDataLength = ulPartLen % context->blockSize; | |||
1496 | if (context->padDataLength) { | |||
1497 | PORT_Memcpymemcpy(context->padBuf, | |||
1498 | &pPart[ulPartLen - context->padDataLength], | |||
1499 | context->padDataLength); | |||
1500 | ulPartLen -= context->padDataLength; | |||
1501 | } | |||
1502 | /* if we've exhausted our new buffer, we're done */ | |||
1503 | if (ulPartLen == 0) { | |||
1504 | *pulEncryptedPartLen = padoutlen; | |||
1505 | return CKR_OK0x00000000UL; | |||
1506 | } | |||
1507 | } | |||
1508 | ||||
1509 | /* do it: NOTE: this assumes buf size in is >= buf size out! */ | |||
1510 | rv = (*context->update)(context->cipherInfo, pEncryptedPart, | |||
1511 | &outlen, maxout, pPart, ulPartLen); | |||
1512 | if (rv != SECSuccess) { | |||
1513 | return sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1514 | } | |||
1515 | *pulEncryptedPartLen = (CK_ULONG)(outlen + padoutlen); | |||
1516 | return CKR_OK0x00000000UL; | |||
1517 | } | |||
1518 | ||||
1519 | /* NSC_EncryptFinal finishes a multiple-part encryption operation. */ | |||
1520 | CK_RV | |||
1521 | NSC_EncryptFinal(CK_SESSION_HANDLE hSession, | |||
1522 | CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen) | |||
1523 | { | |||
1524 | SFTKSession *session; | |||
1525 | SFTKSessionContext *context; | |||
1526 | unsigned int outlen, i; | |||
1527 | unsigned int maxout = *pulLastEncryptedPartLen; | |||
1528 | CK_RV crv; | |||
1529 | SECStatus rv = SECSuccess; | |||
1530 | PRBool contextFinished = PR_TRUE1; | |||
1531 | ||||
1532 | CHECK_FORK(); | |||
1533 | ||||
1534 | /* make sure we're legal */ | |||
1535 | crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE1, &session); | |||
1536 | if (crv != CKR_OK0x00000000UL) | |||
1537 | return crv; | |||
1538 | ||||
1539 | *pulLastEncryptedPartLen = 0; | |||
1540 | if (!pLastEncryptedPart) { | |||
1541 | /* caller is checking the amount of remaining data */ | |||
1542 | if (context->blockSize > 0 && context->doPad) { | |||
1543 | *pulLastEncryptedPartLen = context->blockSize; | |||
1544 | contextFinished = PR_FALSE0; /* still have padding to go */ | |||
1545 | } | |||
1546 | goto finish; | |||
1547 | } | |||
1548 | ||||
1549 | /* do padding */ | |||
1550 | if (context->doPad) { | |||
1551 | unsigned char padbyte = (unsigned char)(context->blockSize - context->padDataLength); | |||
1552 | /* fill out rest of pad buffer with pad magic*/ | |||
1553 | for (i = context->padDataLength; i < context->blockSize; i++) { | |||
1554 | context->padBuf[i] = padbyte; | |||
1555 | } | |||
1556 | rv = (*context->update)(context->cipherInfo, pLastEncryptedPart, | |||
1557 | &outlen, maxout, context->padBuf, context->blockSize); | |||
1558 | if (rv == SECSuccess) | |||
1559 | *pulLastEncryptedPartLen = (CK_ULONG)outlen; | |||
1560 | } | |||
1561 | ||||
1562 | finish: | |||
1563 | if (contextFinished) | |||
1564 | sftk_TerminateOp(session, SFTK_ENCRYPT, context); | |||
1565 | sftk_FreeSession(session); | |||
1566 | return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1567 | } | |||
1568 | ||||
1569 | /* NSC_Encrypt encrypts single-part data. */ | |||
1570 | CK_RV | |||
1571 | NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, | |||
1572 | CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, | |||
1573 | CK_ULONG_PTR pulEncryptedDataLen) | |||
1574 | { | |||
1575 | SFTKSession *session; | |||
1576 | SFTKSessionContext *context; | |||
1577 | unsigned int outlen; | |||
1578 | unsigned int maxoutlen = *pulEncryptedDataLen; | |||
1579 | CK_RV crv; | |||
1580 | CK_RV crv2; | |||
1581 | SECStatus rv = SECSuccess; | |||
1582 | SECItem pText; | |||
1583 | ||||
1584 | pText.type = siBuffer; | |||
1585 | pText.data = pData; | |||
1586 | pText.len = ulDataLen; | |||
1587 | ||||
1588 | CHECK_FORK(); | |||
1589 | ||||
1590 | /* make sure we're legal */ | |||
1591 | crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_FALSE0, &session); | |||
1592 | if (crv != CKR_OK0x00000000UL) | |||
1593 | return crv; | |||
1594 | ||||
1595 | if (!pEncryptedData) { | |||
1596 | outlen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize; | |||
1597 | goto done; | |||
1598 | } | |||
1599 | ||||
1600 | if (context->doPad) { | |||
1601 | if (context->multi) { | |||
1602 | CK_ULONG updateLen = maxoutlen; | |||
1603 | CK_ULONG finalLen; | |||
1604 | /* padding is fairly complicated, have the update and final | |||
1605 | * code deal with it */ | |||
1606 | sftk_FreeSession(session); | |||
1607 | crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData, | |||
1608 | &updateLen); | |||
1609 | if (crv != CKR_OK0x00000000UL) { | |||
1610 | updateLen = 0; | |||
1611 | } | |||
1612 | maxoutlen -= updateLen; | |||
1613 | pEncryptedData += updateLen; | |||
1614 | finalLen = maxoutlen; | |||
1615 | crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen); | |||
1616 | if (crv == CKR_OK0x00000000UL && crv2 == CKR_OK0x00000000UL) { | |||
1617 | *pulEncryptedDataLen = updateLen + finalLen; | |||
1618 | } | |||
1619 | return crv == CKR_OK0x00000000UL ? crv2 : crv; | |||
1620 | } | |||
1621 | /* doPad without multi means that padding must be done on the first | |||
1622 | ** and only update. There will be no final. | |||
1623 | */ | |||
1624 | PORT_Assert(context->blockSize > 1)((context->blockSize > 1)?((void)0):PR_Assert("context->blockSize > 1" ,"pkcs11c.c",1624)); | |||
1625 | if (context->blockSize > 1) { | |||
1626 | CK_ULONG remainder = ulDataLen % context->blockSize; | |||
1627 | CK_ULONG padding = context->blockSize - remainder; | |||
1628 | pText.len += padding; | |||
1629 | pText.data = PORT_ZAllocPORT_ZAlloc_Util(pText.len); | |||
1630 | if (pText.data) { | |||
1631 | memcpy(pText.data, pData, ulDataLen); | |||
1632 | memset(pText.data + ulDataLen, padding, padding); | |||
1633 | } else { | |||
1634 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
1635 | goto fail; | |||
1636 | } | |||
1637 | } | |||
1638 | } | |||
1639 | ||||
1640 | /* do it: NOTE: this assumes buf size is big enough. */ | |||
1641 | rv = (*context->update)(context->cipherInfo, pEncryptedData, | |||
1642 | &outlen, maxoutlen, pText.data, pText.len); | |||
1643 | crv = (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1644 | if (pText.data != pData) | |||
1645 | PORT_ZFreePORT_ZFree_Util(pText.data, pText.len); | |||
1646 | fail: | |||
1647 | sftk_TerminateOp(session, SFTK_ENCRYPT, context); | |||
1648 | done: | |||
1649 | sftk_FreeSession(session); | |||
1650 | if (crv == CKR_OK0x00000000UL) { | |||
1651 | *pulEncryptedDataLen = (CK_ULONG)outlen; | |||
1652 | } | |||
1653 | return crv; | |||
1654 | } | |||
1655 | ||||
1656 | /* | |||
1657 | ************** Crypto Functions: Decrypt ************************ | |||
1658 | */ | |||
1659 | ||||
1660 | /* NSC_DecryptInit initializes a decryption operation. */ | |||
1661 | CK_RV | |||
1662 | NSC_DecryptInit(CK_SESSION_HANDLE hSession, | |||
1663 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) | |||
1664 | { | |||
1665 | CHECK_FORK(); | |||
1666 | return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT0x00000105UL, CKA_DECRYPT0x00000105UL, | |||
1667 | SFTK_DECRYPT, PR_FALSE0); | |||
1668 | } | |||
1669 | ||||
1670 | /* NSC_DecryptUpdate continues a multiple-part decryption operation. */ | |||
1671 | CK_RV | |||
1672 | NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, | |||
1673 | CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, | |||
1674 | CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) | |||
1675 | { | |||
1676 | SFTKSessionContext *context; | |||
1677 | unsigned int padoutlen = 0; | |||
1678 | unsigned int outlen; | |||
1679 | unsigned int maxout = *pulPartLen; | |||
1680 | CK_RV crv; | |||
1681 | SECStatus rv; | |||
1682 | ||||
1683 | CHECK_FORK(); | |||
1684 | ||||
1685 | /* make sure we're legal */ | |||
1686 | crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE1, NULL((void*)0)); | |||
1687 | if (crv != CKR_OK0x00000000UL) | |||
1688 | return crv; | |||
1689 | ||||
1690 | /* this can only happen on an NSS programming error */ | |||
1691 | PORT_Assert((context->padDataLength == 0) || context->padDataLength == context->blockSize)(((context->padDataLength == 0) || context->padDataLength == context->blockSize)?((void)0):PR_Assert("(context->padDataLength == 0) || context->padDataLength == context->blockSize" ,"pkcs11c.c",1691)); | |||
1692 | ||||
1693 | if (context->doPad) { | |||
1694 | /* Check the data length for block ciphers. If we are padding, | |||
1695 | * then we must be using a block cipher. In the non-padding case | |||
1696 | * the error will be returned by the underlying decryption | |||
1697 | * function when we do the actual decrypt. We need to do the | |||
1698 | * check here to avoid returning a negative length to the caller | |||
1699 | * or reading before the beginning of the pEncryptedPart buffer. | |||
1700 | */ | |||
1701 | if ((ulEncryptedPartLen == 0) || | |||
1702 | (ulEncryptedPartLen % context->blockSize) != 0) { | |||
1703 | return CKR_ENCRYPTED_DATA_LEN_RANGE0x00000041UL; | |||
1704 | } | |||
1705 | } | |||
1706 | ||||
1707 | if (!pPart) { | |||
1708 | if (context->doPad) { | |||
1709 | *pulPartLen = | |||
1710 | ulEncryptedPartLen + context->padDataLength - context->blockSize; | |||
1711 | return CKR_OK0x00000000UL; | |||
1712 | } | |||
1713 | /* for stream ciphers there is are no constraints on ulEncryptedPartLen. | |||
1714 | * for block ciphers, it must be a multiple of blockSize. The error is | |||
1715 | * detected when this function is called again do decrypt the output. | |||
1716 | */ | |||
1717 | *pulPartLen = ulEncryptedPartLen; | |||
1718 | return CKR_OK0x00000000UL; | |||
1719 | } | |||
1720 | ||||
1721 | if (context->doPad) { | |||
1722 | /* first decrypt our saved buffer */ | |||
1723 | if (context->padDataLength != 0) { | |||
1724 | rv = (*context->update)(context->cipherInfo, pPart, &padoutlen, | |||
1725 | maxout, context->padBuf, context->blockSize); | |||
1726 | if (rv != SECSuccess) | |||
1727 | return sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1728 | pPart += padoutlen; | |||
1729 | maxout -= padoutlen; | |||
1730 | } | |||
1731 | /* now save the final block for the next decrypt or the final */ | |||
1732 | PORT_Memcpymemcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize], | |||
1733 | context->blockSize); | |||
1734 | context->padDataLength = context->blockSize; | |||
1735 | ulEncryptedPartLen -= context->padDataLength; | |||
1736 | } | |||
1737 | ||||
1738 | /* do it: NOTE: this assumes buf size in is >= buf size out! */ | |||
1739 | rv = (*context->update)(context->cipherInfo, pPart, &outlen, | |||
1740 | maxout, pEncryptedPart, ulEncryptedPartLen); | |||
1741 | if (rv != SECSuccess) { | |||
1742 | return sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1743 | } | |||
1744 | *pulPartLen = (CK_ULONG)(outlen + padoutlen); | |||
1745 | return CKR_OK0x00000000UL; | |||
1746 | } | |||
1747 | ||||
1748 | /* NSC_DecryptFinal finishes a multiple-part decryption operation. */ | |||
1749 | CK_RV | |||
1750 | NSC_DecryptFinal(CK_SESSION_HANDLE hSession, | |||
1751 | CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen) | |||
1752 | { | |||
1753 | SFTKSession *session; | |||
1754 | SFTKSessionContext *context; | |||
1755 | unsigned int outlen; | |||
1756 | unsigned int maxout = *pulLastPartLen; | |||
1757 | CK_RV crv; | |||
1758 | SECStatus rv = SECSuccess; | |||
1759 | ||||
1760 | CHECK_FORK(); | |||
1761 | ||||
1762 | /* make sure we're legal */ | |||
1763 | crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE1, &session); | |||
1764 | if (crv != CKR_OK0x00000000UL) | |||
1765 | return crv; | |||
1766 | ||||
1767 | *pulLastPartLen = 0; | |||
1768 | if (!pLastPart) { | |||
1769 | /* caller is checking the amount of remaining data */ | |||
1770 | if (context->padDataLength > 0) { | |||
1771 | *pulLastPartLen = context->padDataLength; | |||
1772 | } | |||
1773 | goto finish; | |||
1774 | } | |||
1775 | ||||
1776 | if (context->doPad) { | |||
1777 | /* decrypt our saved buffer */ | |||
1778 | if (context->padDataLength != 0) { | |||
1779 | /* this assumes that pLastPart is big enough to hold the *whole* | |||
1780 | * buffer!!! */ | |||
1781 | rv = (*context->update)(context->cipherInfo, pLastPart, &outlen, | |||
1782 | maxout, context->padBuf, context->blockSize); | |||
1783 | if (rv != SECSuccess) { | |||
1784 | crv = sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1785 | } else { | |||
1786 | unsigned int padSize = 0; | |||
1787 | crv = sftk_CheckCBCPadding(pLastPart, outlen, | |||
1788 | context->blockSize, &padSize); | |||
1789 | /* Update pulLastPartLen, in constant time, if crv is OK */ | |||
1790 | *pulLastPartLen = PORT_CT_SEL(sftk_CKRVToMask(crv), outlen - padSize, *pulLastPartLen)(((sftk_CKRVToMask(crv)) & (outlen - padSize)) | (~(sftk_CKRVToMask (crv)) & (*pulLastPartLen))); | |||
1791 | } | |||
1792 | } | |||
1793 | } | |||
1794 | ||||
1795 | sftk_TerminateOp(session, SFTK_DECRYPT, context); | |||
1796 | finish: | |||
1797 | sftk_FreeSession(session); | |||
1798 | return crv; | |||
1799 | } | |||
1800 | ||||
1801 | /* NSC_Decrypt decrypts encrypted data in a single part. */ | |||
1802 | CK_RV | |||
1803 | NSC_Decrypt(CK_SESSION_HANDLE hSession, | |||
1804 | CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, | |||
1805 | CK_ULONG_PTR pulDataLen) | |||
1806 | { | |||
1807 | SFTKSession *session; | |||
1808 | SFTKSessionContext *context; | |||
1809 | unsigned int outlen; | |||
1810 | unsigned int maxoutlen = *pulDataLen; | |||
1811 | CK_RV crv; | |||
1812 | CK_RV crv2; | |||
1813 | SECStatus rv = SECSuccess; | |||
1814 | ||||
1815 | CHECK_FORK(); | |||
1816 | ||||
1817 | /* make sure we're legal */ | |||
1818 | crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_FALSE0, &session); | |||
1819 | if (crv != CKR_OK0x00000000UL) | |||
1820 | return crv; | |||
1821 | ||||
1822 | if (!pData) { | |||
1823 | *pulDataLen = (CK_ULONG)(ulEncryptedDataLen + context->blockSize); | |||
1824 | goto done; | |||
1825 | } | |||
1826 | ||||
1827 | if (context->doPad && context->multi) { | |||
1828 | CK_ULONG updateLen = maxoutlen; | |||
1829 | CK_ULONG finalLen; | |||
1830 | /* padding is fairly complicated, have the update and final | |||
1831 | * code deal with it */ | |||
1832 | sftk_FreeSession(session); | |||
1833 | crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen, | |||
1834 | pData, &updateLen); | |||
1835 | if (crv == CKR_OK0x00000000UL) { | |||
1836 | maxoutlen -= updateLen; | |||
1837 | pData += updateLen; | |||
1838 | } | |||
1839 | finalLen = maxoutlen; | |||
1840 | crv2 = NSC_DecryptFinal(hSession, pData, &finalLen); | |||
1841 | if (crv == CKR_OK0x00000000UL) { | |||
1842 | *pulDataLen = PORT_CT_SEL(sftk_CKRVToMask(crv2), updateLen + finalLen, *pulDataLen)(((sftk_CKRVToMask(crv2)) & (updateLen + finalLen)) | (~( sftk_CKRVToMask(crv2)) & (*pulDataLen))); | |||
1843 | return crv2; | |||
1844 | } else { | |||
1845 | return crv; | |||
1846 | } | |||
1847 | } | |||
1848 | ||||
1849 | rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, | |||
1850 | pEncryptedData, ulEncryptedDataLen); | |||
1851 | /* XXX need to do MUCH better error mapping than this. */ | |||
1852 | crv = (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util()); | |||
1853 | if (rv == SECSuccess) { | |||
1854 | if (context->doPad) { | |||
1855 | unsigned int padSize = 0; | |||
1856 | crv = sftk_CheckCBCPadding(pData, outlen, context->blockSize, | |||
1857 | &padSize); | |||
1858 | /* Update pulDataLen, in constant time, if crv is OK */ | |||
1859 | *pulDataLen = PORT_CT_SEL(sftk_CKRVToMask(crv), outlen - padSize, *pulDataLen)(((sftk_CKRVToMask(crv)) & (outlen - padSize)) | (~(sftk_CKRVToMask (crv)) & (*pulDataLen))); | |||
1860 | } else { | |||
1861 | *pulDataLen = (CK_ULONG)outlen; | |||
1862 | } | |||
1863 | } | |||
1864 | sftk_TerminateOp(session, SFTK_DECRYPT, context); | |||
1865 | done: | |||
1866 | sftk_FreeSession(session); | |||
1867 | return crv; | |||
1868 | } | |||
1869 | ||||
1870 | /* | |||
1871 | ************** Crypto Functions: Digest (HASH) ************************ | |||
1872 | */ | |||
1873 | ||||
1874 | /* NSC_DigestInit initializes a message-digesting operation. */ | |||
1875 | CK_RV | |||
1876 | NSC_DigestInit(CK_SESSION_HANDLE hSession, | |||
1877 | CK_MECHANISM_PTR pMechanism) | |||
1878 | { | |||
1879 | SFTKSession *session; | |||
1880 | SFTKSessionContext *context; | |||
1881 | CK_RV crv = CKR_OK0x00000000UL; | |||
1882 | ||||
1883 | CHECK_FORK(); | |||
1884 | ||||
1885 | session = sftk_SessionFromHandle(hSession); | |||
1886 | if (session == NULL((void*)0)) | |||
1887 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
1888 | crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_HASH, | |||
1889 | NULL((void*)0), 0, NULL((void*)0), 0, CKA_DIGEST0x81000000L); | |||
1890 | if (crv != CKR_OK0x00000000UL) { | |||
1891 | sftk_FreeSession(session); | |||
1892 | return crv; | |||
1893 | } | |||
1894 | ||||
1895 | #define INIT_MECH(mmm)case CKM_mmm: { mmmContext *mmm_ctx = mmm_NewContext(); context ->cipherInfo = (void *)mmm_ctx; context->cipherInfoLen = mmm_FlattenSize(mmm_ctx); context->currentMech = CKM_mmm; context->hashUpdate = (SFTKHash)mmm_Update; context->end = (SFTKEnd)mmm_End; context->destroy = (SFTKDestroy)mmm_DestroyContext ; context->maxLen = mmm_LENGTH; if (mmm_ctx) mmm_Begin(mmm_ctx ); else crv = 0x00000002UL; break; } \ | |||
1896 | case CKM_##mmm: { \ | |||
1897 | mmm##Context *mmm##_ctx = mmm##_NewContext(); \ | |||
1898 | context->cipherInfo = (void *)mmm##_ctx; \ | |||
1899 | context->cipherInfoLen = mmm##_FlattenSize(mmm##_ctx); \ | |||
1900 | context->currentMech = CKM_##mmm; \ | |||
1901 | context->hashUpdate = (SFTKHash)mmm##_Update; \ | |||
1902 | context->end = (SFTKEnd)mmm##_End; \ | |||
1903 | context->destroy = (SFTKDestroy)mmm##_DestroyContext; \ | |||
1904 | context->maxLen = mmm##_LENGTH; \ | |||
1905 | if (mmm##_ctx) \ | |||
1906 | mmm##_Begin(mmm##_ctx); \ | |||
1907 | else \ | |||
1908 | crv = CKR_HOST_MEMORY0x00000002UL; \ | |||
1909 | break; \ | |||
1910 | } | |||
1911 | ||||
1912 | switch (pMechanism->mechanism) { | |||
1913 | INIT_MECH(MD2)case 0x00000200UL: { MD2Context *MD2_ctx = MD2_NewContext(); context ->cipherInfo = (void *)MD2_ctx; context->cipherInfoLen = MD2_FlattenSize(MD2_ctx); context->currentMech = 0x00000200UL ; context->hashUpdate = (SFTKHash)MD2_Update; context-> end = (SFTKEnd)MD2_End; context->destroy = (SFTKDestroy)MD2_DestroyContext ; context->maxLen = 16; if (MD2_ctx) MD2_Begin(MD2_ctx); else crv = 0x00000002UL; break; } | |||
1914 | INIT_MECH(MD5)case 0x00000210UL: { MD5Context *MD5_ctx = MD5_NewContext(); context ->cipherInfo = (void *)MD5_ctx; context->cipherInfoLen = MD5_FlattenSize(MD5_ctx); context->currentMech = 0x00000210UL ; context->hashUpdate = (SFTKHash)MD5_Update; context-> end = (SFTKEnd)MD5_End; context->destroy = (SFTKDestroy)MD5_DestroyContext ; context->maxLen = 16; if (MD5_ctx) MD5_Begin(MD5_ctx); else crv = 0x00000002UL; break; } | |||
1915 | INIT_MECH(SHA1)case 0x00000220UL: { SHA1Context *SHA1_ctx = SHA1_NewContext( ); context->cipherInfo = (void *)SHA1_ctx; context->cipherInfoLen = SHA1_FlattenSize(SHA1_ctx); context->currentMech = 0x00000220UL ; context->hashUpdate = (SFTKHash)SHA1_Update; context-> end = (SFTKEnd)SHA1_End; context->destroy = (SFTKDestroy)SHA1_DestroyContext ; context->maxLen = 20; if (SHA1_ctx) SHA1_Begin(SHA1_ctx) ; else crv = 0x00000002UL; break; } | |||
1916 | INIT_MECH(SHA224)case 0x00000255UL: { SHA224Context *SHA224_ctx = SHA224_NewContext (); context->cipherInfo = (void *)SHA224_ctx; context-> cipherInfoLen = SHA224_FlattenSize(SHA224_ctx); context->currentMech = 0x00000255UL; context->hashUpdate = (SFTKHash)SHA224_Update ; context->end = (SFTKEnd)SHA224_End; context->destroy = (SFTKDestroy)SHA224_DestroyContext; context->maxLen = 28; if (SHA224_ctx) SHA224_Begin(SHA224_ctx); else crv = 0x00000002UL ; break; } | |||
1917 | INIT_MECH(SHA256)case 0x00000250UL: { SHA256Context *SHA256_ctx = SHA256_NewContext (); context->cipherInfo = (void *)SHA256_ctx; context-> cipherInfoLen = SHA256_FlattenSize(SHA256_ctx); context->currentMech = 0x00000250UL; context->hashUpdate = (SFTKHash)SHA256_Update ; context->end = (SFTKEnd)SHA256_End; context->destroy = (SFTKDestroy)SHA256_DestroyContext; context->maxLen = 32; if (SHA256_ctx) SHA256_Begin(SHA256_ctx); else crv = 0x00000002UL ; break; } | |||
1918 | INIT_MECH(SHA384)case 0x00000260UL: { SHA384Context *SHA384_ctx = SHA384_NewContext (); context->cipherInfo = (void *)SHA384_ctx; context-> cipherInfoLen = SHA384_FlattenSize(SHA384_ctx); context->currentMech = 0x00000260UL; context->hashUpdate = (SFTKHash)SHA384_Update ; context->end = (SFTKEnd)SHA384_End; context->destroy = (SFTKDestroy)SHA384_DestroyContext; context->maxLen = 48; if (SHA384_ctx) SHA384_Begin(SHA384_ctx); else crv = 0x00000002UL ; break; } | |||
1919 | INIT_MECH(SHA512)case 0x00000270UL: { SHA512Context *SHA512_ctx = SHA512_NewContext (); context->cipherInfo = (void *)SHA512_ctx; context-> cipherInfoLen = SHA512_FlattenSize(SHA512_ctx); context->currentMech = 0x00000270UL; context->hashUpdate = (SFTKHash)SHA512_Update ; context->end = (SFTKEnd)SHA512_End; context->destroy = (SFTKDestroy)SHA512_DestroyContext; context->maxLen = 64; if (SHA512_ctx) SHA512_Begin(SHA512_ctx); else crv = 0x00000002UL ; break; } | |||
1920 | INIT_MECH(SHA3_224)case 0x000002B5UL: { SHA3_224Context *SHA3_224_ctx = SHA3_224_NewContext (); context->cipherInfo = (void *)SHA3_224_ctx; context-> cipherInfoLen = SHA3_224_FlattenSize(SHA3_224_ctx); context-> currentMech = 0x000002B5UL; context->hashUpdate = (SFTKHash )SHA3_224_Update; context->end = (SFTKEnd)SHA3_224_End; context ->destroy = (SFTKDestroy)SHA3_224_DestroyContext; context-> maxLen = 28; if (SHA3_224_ctx) SHA3_224_Begin(SHA3_224_ctx); else crv = 0x00000002UL; break; } | |||
1921 | INIT_MECH(SHA3_256)case 0x000002B0UL: { SHA3_256Context *SHA3_256_ctx = SHA3_256_NewContext (); context->cipherInfo = (void *)SHA3_256_ctx; context-> cipherInfoLen = SHA3_256_FlattenSize(SHA3_256_ctx); context-> currentMech = 0x000002B0UL; context->hashUpdate = (SFTKHash )SHA3_256_Update; context->end = (SFTKEnd)SHA3_256_End; context ->destroy = (SFTKDestroy)SHA3_256_DestroyContext; context-> maxLen = 32; if (SHA3_256_ctx) SHA3_256_Begin(SHA3_256_ctx); else crv = 0x00000002UL; break; } | |||
1922 | INIT_MECH(SHA3_384)case 0x000002C0UL: { SHA3_384Context *SHA3_384_ctx = SHA3_384_NewContext (); context->cipherInfo = (void *)SHA3_384_ctx; context-> cipherInfoLen = SHA3_384_FlattenSize(SHA3_384_ctx); context-> currentMech = 0x000002C0UL; context->hashUpdate = (SFTKHash )SHA3_384_Update; context->end = (SFTKEnd)SHA3_384_End; context ->destroy = (SFTKDestroy)SHA3_384_DestroyContext; context-> maxLen = 48; if (SHA3_384_ctx) SHA3_384_Begin(SHA3_384_ctx); else crv = 0x00000002UL; break; } | |||
1923 | INIT_MECH(SHA3_512)case 0x000002D0UL: { SHA3_512Context *SHA3_512_ctx = SHA3_512_NewContext (); context->cipherInfo = (void *)SHA3_512_ctx; context-> cipherInfoLen = SHA3_512_FlattenSize(SHA3_512_ctx); context-> currentMech = 0x000002D0UL; context->hashUpdate = (SFTKHash )SHA3_512_Update; context->end = (SFTKEnd)SHA3_512_End; context ->destroy = (SFTKDestroy)SHA3_512_DestroyContext; context-> maxLen = 64; if (SHA3_512_ctx) SHA3_512_Begin(SHA3_512_ctx); else crv = 0x00000002UL; break; } | |||
1924 | ||||
1925 | default: | |||
1926 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
1927 | break; | |||
1928 | } | |||
1929 | ||||
1930 | if (crv != CKR_OK0x00000000UL) { | |||
1931 | sftk_FreeContext(context); | |||
1932 | sftk_FreeSession(session); | |||
1933 | return crv; | |||
1934 | } | |||
1935 | sftk_SetContextByType(session, SFTK_HASH, context); | |||
1936 | sftk_FreeSession(session); | |||
1937 | return CKR_OK0x00000000UL; | |||
1938 | } | |||
1939 | ||||
1940 | /* NSC_Digest digests data in a single part. */ | |||
1941 | CK_RV | |||
1942 | NSC_Digest(CK_SESSION_HANDLE hSession, | |||
1943 | CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, | |||
1944 | CK_ULONG_PTR pulDigestLen) | |||
1945 | { | |||
1946 | SFTKSession *session; | |||
1947 | SFTKSessionContext *context; | |||
1948 | unsigned int digestLen; | |||
1949 | unsigned int maxout = *pulDigestLen; | |||
1950 | CK_RV crv; | |||
1951 | ||||
1952 | CHECK_FORK(); | |||
1953 | ||||
1954 | /* make sure we're legal */ | |||
1955 | crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_FALSE0, &session); | |||
1956 | if (crv != CKR_OK0x00000000UL) | |||
1957 | return crv; | |||
1958 | ||||
1959 | if (pDigest == NULL((void*)0)) { | |||
1960 | *pulDigestLen = context->maxLen; | |||
1961 | goto finish; | |||
1962 | } | |||
1963 | ||||
1964 | #if (ULONG_MAX(9223372036854775807L *2UL+1UL) > UINT_MAX(2147483647 *2U +1U)) | |||
1965 | /* The context->hashUpdate function takes an unsigned int for its data | |||
1966 | * length argument, but NSC_Digest takes an unsigned long. */ | |||
1967 | while (ulDataLen > UINT_MAX(2147483647 *2U +1U)) { | |||
1968 | (*context->hashUpdate)(context->cipherInfo, pData, UINT_MAX(2147483647 *2U +1U)); | |||
1969 | pData += UINT_MAX(2147483647 *2U +1U); | |||
1970 | ulDataLen -= UINT_MAX(2147483647 *2U +1U); | |||
1971 | } | |||
1972 | #endif | |||
1973 | (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen); | |||
1974 | ||||
1975 | /* NOTE: this assumes buf size is bigenough for the algorithm */ | |||
1976 | (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout); | |||
1977 | *pulDigestLen = digestLen; | |||
1978 | ||||
1979 | sftk_TerminateOp(session, SFTK_HASH, context); | |||
1980 | finish: | |||
1981 | sftk_FreeSession(session); | |||
1982 | return CKR_OK0x00000000UL; | |||
1983 | } | |||
1984 | ||||
1985 | /* NSC_DigestUpdate continues a multiple-part message-digesting operation. */ | |||
1986 | CK_RV | |||
1987 | NSC_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, | |||
1988 | CK_ULONG ulPartLen) | |||
1989 | { | |||
1990 | SFTKSessionContext *context; | |||
1991 | CK_RV crv; | |||
1992 | ||||
1993 | CHECK_FORK(); | |||
1994 | ||||
1995 | /* make sure we're legal */ | |||
1996 | crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, NULL((void*)0)); | |||
1997 | if (crv != CKR_OK0x00000000UL) | |||
1998 | return crv; | |||
1999 | ||||
2000 | #if (ULONG_MAX(9223372036854775807L *2UL+1UL) > UINT_MAX(2147483647 *2U +1U)) | |||
2001 | /* The context->hashUpdate function takes an unsigned int for its data | |||
2002 | * length argument, but NSC_DigestUpdate takes an unsigned long. */ | |||
2003 | while (ulPartLen > UINT_MAX(2147483647 *2U +1U)) { | |||
2004 | (*context->hashUpdate)(context->cipherInfo, pPart, UINT_MAX(2147483647 *2U +1U)); | |||
2005 | pPart += UINT_MAX(2147483647 *2U +1U); | |||
2006 | ulPartLen -= UINT_MAX(2147483647 *2U +1U); | |||
2007 | } | |||
2008 | #endif | |||
2009 | (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen); | |||
2010 | ||||
2011 | return CKR_OK0x00000000UL; | |||
2012 | } | |||
2013 | ||||
2014 | /* NSC_DigestFinal finishes a multiple-part message-digesting operation. */ | |||
2015 | CK_RV | |||
2016 | NSC_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, | |||
2017 | CK_ULONG_PTR pulDigestLen) | |||
2018 | { | |||
2019 | SFTKSession *session; | |||
2020 | SFTKSessionContext *context; | |||
2021 | unsigned int maxout = *pulDigestLen; | |||
2022 | unsigned int digestLen; | |||
2023 | CK_RV crv; | |||
2024 | ||||
2025 | CHECK_FORK(); | |||
2026 | ||||
2027 | /* make sure we're legal */ | |||
2028 | crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, &session); | |||
2029 | if (crv != CKR_OK0x00000000UL) | |||
2030 | return crv; | |||
2031 | ||||
2032 | if (pDigest != NULL((void*)0)) { | |||
2033 | (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout); | |||
2034 | *pulDigestLen = digestLen; | |||
2035 | sftk_TerminateOp(session, SFTK_HASH, context); | |||
2036 | } else { | |||
2037 | *pulDigestLen = context->maxLen; | |||
2038 | } | |||
2039 | ||||
2040 | sftk_FreeSession(session); | |||
2041 | return CKR_OK0x00000000UL; | |||
2042 | } | |||
2043 | ||||
2044 | /* | |||
2045 | * these helper functions are used by Generic Macing and Signing functions | |||
2046 | * that use hashes as part of their operations. | |||
2047 | */ | |||
2048 | #define DOSUB(mmm)static CK_RV sftk_doSubmmm(SFTKSessionContext *context) { mmmContext *mmm_ctx = mmm_NewContext(); context->hashInfo = (void *) mmm_ctx; context->hashUpdate = (SFTKHash)mmm_Update; context ->end = (SFTKEnd)mmm_End; context->hashdestroy = (SFTKDestroy )mmm_DestroyContext; if (!context->hashInfo) { return 0x00000002UL ; } mmm_Begin(mmm_ctx); return 0x00000000UL; } \ | |||
2049 | static CK_RV \ | |||
2050 | sftk_doSub##mmm(SFTKSessionContext *context) \ | |||
2051 | { \ | |||
2052 | mmm##Context *mmm##_ctx = mmm##_NewContext(); \ | |||
2053 | context->hashInfo = (void *)mmm##_ctx; \ | |||
2054 | context->hashUpdate = (SFTKHash)mmm##_Update; \ | |||
2055 | context->end = (SFTKEnd)mmm##_End; \ | |||
2056 | context->hashdestroy = (SFTKDestroy)mmm##_DestroyContext; \ | |||
2057 | if (!context->hashInfo) { \ | |||
2058 | return CKR_HOST_MEMORY0x00000002UL; \ | |||
2059 | } \ | |||
2060 | mmm##_Begin(mmm##_ctx); \ | |||
2061 | return CKR_OK0x00000000UL; \ | |||
2062 | } | |||
2063 | ||||
2064 | DOSUB(MD2)static CK_RV sftk_doSubMD2(SFTKSessionContext *context) { MD2Context *MD2_ctx = MD2_NewContext(); context->hashInfo = (void *) MD2_ctx; context->hashUpdate = (SFTKHash)MD2_Update; context ->end = (SFTKEnd)MD2_End; context->hashdestroy = (SFTKDestroy )MD2_DestroyContext; if (!context->hashInfo) { return 0x00000002UL ; } MD2_Begin(MD2_ctx); return 0x00000000UL; } | |||
2065 | DOSUB(MD5)static CK_RV sftk_doSubMD5(SFTKSessionContext *context) { MD5Context *MD5_ctx = MD5_NewContext(); context->hashInfo = (void *) MD5_ctx; context->hashUpdate = (SFTKHash)MD5_Update; context ->end = (SFTKEnd)MD5_End; context->hashdestroy = (SFTKDestroy )MD5_DestroyContext; if (!context->hashInfo) { return 0x00000002UL ; } MD5_Begin(MD5_ctx); return 0x00000000UL; } | |||
2066 | DOSUB(SHA1)static CK_RV sftk_doSubSHA1(SFTKSessionContext *context) { SHA1Context *SHA1_ctx = SHA1_NewContext(); context->hashInfo = (void * )SHA1_ctx; context->hashUpdate = (SFTKHash)SHA1_Update; context ->end = (SFTKEnd)SHA1_End; context->hashdestroy = (SFTKDestroy )SHA1_DestroyContext; if (!context->hashInfo) { return 0x00000002UL ; } SHA1_Begin(SHA1_ctx); return 0x00000000UL; } | |||
2067 | DOSUB(SHA224)static CK_RV sftk_doSubSHA224(SFTKSessionContext *context) { SHA224Context *SHA224_ctx = SHA224_NewContext(); context->hashInfo = (void *)SHA224_ctx; context->hashUpdate = (SFTKHash)SHA224_Update ; context->end = (SFTKEnd)SHA224_End; context->hashdestroy = (SFTKDestroy)SHA224_DestroyContext; if (!context->hashInfo ) { return 0x00000002UL; } SHA224_Begin(SHA224_ctx); return 0x00000000UL ; } | |||
2068 | DOSUB(SHA256)static CK_RV sftk_doSubSHA256(SFTKSessionContext *context) { SHA256Context *SHA256_ctx = SHA256_NewContext(); context->hashInfo = (void *)SHA256_ctx; context->hashUpdate = (SFTKHash)SHA256_Update ; context->end = (SFTKEnd)SHA256_End; context->hashdestroy = (SFTKDestroy)SHA256_DestroyContext; if (!context->hashInfo ) { return 0x00000002UL; } SHA256_Begin(SHA256_ctx); return 0x00000000UL ; } | |||
2069 | DOSUB(SHA384)static CK_RV sftk_doSubSHA384(SFTKSessionContext *context) { SHA384Context *SHA384_ctx = SHA384_NewContext(); context->hashInfo = (void *)SHA384_ctx; context->hashUpdate = (SFTKHash)SHA384_Update ; context->end = (SFTKEnd)SHA384_End; context->hashdestroy = (SFTKDestroy)SHA384_DestroyContext; if (!context->hashInfo ) { return 0x00000002UL; } SHA384_Begin(SHA384_ctx); return 0x00000000UL ; } | |||
2070 | DOSUB(SHA512)static CK_RV sftk_doSubSHA512(SFTKSessionContext *context) { SHA512Context *SHA512_ctx = SHA512_NewContext(); context->hashInfo = (void *)SHA512_ctx; context->hashUpdate = (SFTKHash)SHA512_Update ; context->end = (SFTKEnd)SHA512_End; context->hashdestroy = (SFTKDestroy)SHA512_DestroyContext; if (!context->hashInfo ) { return 0x00000002UL; } SHA512_Begin(SHA512_ctx); return 0x00000000UL ; } | |||
2071 | ||||
2072 | static SECStatus | |||
2073 | sftk_SignCopy( | |||
2074 | CK_ULONG *copyLen, | |||
2075 | void *out, unsigned int *outLength, | |||
2076 | unsigned int maxLength, | |||
2077 | const unsigned char *hashResult, | |||
2078 | unsigned int hashResultLength) | |||
2079 | { | |||
2080 | unsigned int toCopy = *copyLen; | |||
2081 | if (toCopy > maxLength) { | |||
2082 | toCopy = maxLength; | |||
2083 | } | |||
2084 | if (toCopy > hashResultLength) { | |||
2085 | toCopy = hashResultLength; | |||
2086 | } | |||
2087 | memcpy(out, hashResult, toCopy); | |||
2088 | if (outLength) { | |||
2089 | *outLength = toCopy; | |||
2090 | } | |||
2091 | return SECSuccess; | |||
2092 | } | |||
2093 | ||||
2094 | /* Verify is just a compare for HMAC */ | |||
2095 | static SECStatus | |||
2096 | sftk_HMACCmp(CK_ULONG *copyLen, unsigned char *sig, unsigned int sigLen, | |||
2097 | unsigned char *hash, unsigned int hashLen) | |||
2098 | { | |||
2099 | if (NSS_SecureMemcmp(sig, hash, *copyLen) == 0) { | |||
2100 | return SECSuccess; | |||
2101 | } | |||
2102 | ||||
2103 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_SIGNATURE); | |||
2104 | return SECFailure; | |||
2105 | } | |||
2106 | ||||
2107 | /* | |||
2108 | * common HMAC + CMAC initialization routine | |||
2109 | */ | |||
2110 | static CK_RV | |||
2111 | sftk_doMACInit(CK_MECHANISM_TYPE mech, SFTKSessionContext *session, | |||
2112 | SFTKObject *key, CK_ULONG mac_size) | |||
2113 | { | |||
2114 | CK_RV crv; | |||
2115 | sftk_MACCtx *context; | |||
2116 | CK_ULONG *intpointer; | |||
2117 | PRBool isFIPS = sftk_isFIPS(key->slot->slotID)(((key->slot->slotID) == 3) || ((key->slot->slotID ) >= 101)); | |||
2118 | ||||
2119 | /* Set up the initial context. */ | |||
2120 | crv = sftk_MAC_Create(mech, key, &context); | |||
2121 | if (crv != CKR_OK0x00000000UL) { | |||
2122 | return crv; | |||
2123 | } | |||
2124 | ||||
2125 | session->hashInfo = context; | |||
2126 | session->multi = PR_TRUE1; | |||
2127 | ||||
2128 | /* Required by FIPS 198 Section 4. Delay this check until after the MAC | |||
2129 | * has been initialized to steal the output size of the MAC. */ | |||
2130 | if (isFIPS && (mac_size < 4 || mac_size < context->mac_size / 2)) { | |||
2131 | sftk_MAC_Destroy(context, PR_TRUE1); | |||
2132 | return CKR_BUFFER_TOO_SMALL0x00000150UL; | |||
2133 | } | |||
2134 | ||||
2135 | /* Configure our helper functions appropriately. Note that these casts | |||
2136 | * ignore the return values. */ | |||
2137 | session->hashUpdate = (SFTKHash)sftk_MAC_Update; | |||
2138 | session->end = (SFTKEnd)sftk_MAC_Finish; | |||
2139 | session->hashdestroy = (SFTKDestroy)sftk_MAC_Destroy; | |||
2140 | ||||
2141 | intpointer = PORT_New(CK_ULONG)(CK_ULONG *)PORT_Alloc_Util(sizeof(CK_ULONG)); | |||
2142 | if (intpointer == NULL((void*)0)) { | |||
2143 | sftk_MAC_Destroy(context, PR_TRUE1); | |||
2144 | return CKR_HOST_MEMORY0x00000002UL; | |||
2145 | } | |||
2146 | *intpointer = mac_size; | |||
2147 | session->cipherInfo = intpointer; | |||
2148 | ||||
2149 | /* Since we're only "hashing", copy the result from session->end to the | |||
2150 | * caller using sftk_SignCopy. */ | |||
2151 | session->update = (SFTKCipher)sftk_SignCopy; | |||
2152 | session->verify = (SFTKVerify)sftk_HMACCmp; | |||
2153 | session->destroy = (SFTKDestroy)sftk_Space; | |||
2154 | ||||
2155 | session->maxLen = context->mac_size; | |||
2156 | ||||
2157 | return CKR_OK0x00000000UL; | |||
2158 | } | |||
2159 | ||||
2160 | /* | |||
2161 | * SSL Macing support. SSL Macs are inited, then update with the base | |||
2162 | * hashing algorithm, then finalized in sign and verify | |||
2163 | */ | |||
2164 | ||||
2165 | /* | |||
2166 | * FROM SSL: | |||
2167 | * 60 bytes is 3 times the maximum length MAC size that is supported. | |||
2168 | * We probably should have one copy of this table. We still need this table | |||
2169 | * in ssl to 'sign' the handshake hashes. | |||
2170 | */ | |||
2171 | static unsigned char ssl_pad_1[60] = { | |||
2172 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | |||
2173 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | |||
2174 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | |||
2175 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | |||
2176 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | |||
2177 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | |||
2178 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | |||
2179 | 0x36, 0x36, 0x36, 0x36 | |||
2180 | }; | |||
2181 | static unsigned char ssl_pad_2[60] = { | |||
2182 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, | |||
2183 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, | |||
2184 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, | |||
2185 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, | |||
2186 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, | |||
2187 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, | |||
2188 | 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, | |||
2189 | 0x5c, 0x5c, 0x5c, 0x5c | |||
2190 | }; | |||
2191 | ||||
2192 | static SECStatus | |||
2193 | sftk_SSLMACSign(SFTKSSLMACInfo *info, unsigned char *sig, unsigned int *sigLen, | |||
2194 | unsigned int maxLen, unsigned char *hash, unsigned int hashLen) | |||
2195 | { | |||
2196 | unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH64]; | |||
2197 | unsigned int out; | |||
2198 | ||||
2199 | info->begin(info->hashContext); | |||
2200 | info->update(info->hashContext, info->key, info->keySize); | |||
2201 | info->update(info->hashContext, ssl_pad_2, info->padSize); | |||
2202 | info->update(info->hashContext, hash, hashLen); | |||
2203 | info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH64); | |||
2204 | PORT_Memcpymemcpy(sig, tmpBuf, info->macSize); | |||
2205 | PORT_Memsetmemset(tmpBuf, 0, info->macSize); | |||
2206 | *sigLen = info->macSize; | |||
2207 | return SECSuccess; | |||
2208 | } | |||
2209 | ||||
2210 | static SECStatus | |||
2211 | sftk_SSLMACVerify(SFTKSSLMACInfo *info, unsigned char *sig, unsigned int sigLen, | |||
2212 | unsigned char *hash, unsigned int hashLen) | |||
2213 | { | |||
2214 | unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH64]; | |||
2215 | unsigned int out; | |||
2216 | int cmp; | |||
2217 | ||||
2218 | info->begin(info->hashContext); | |||
2219 | info->update(info->hashContext, info->key, info->keySize); | |||
2220 | info->update(info->hashContext, ssl_pad_2, info->padSize); | |||
2221 | info->update(info->hashContext, hash, hashLen); | |||
2222 | info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH64); | |||
2223 | cmp = NSS_SecureMemcmp(sig, tmpBuf, info->macSize); | |||
2224 | PORT_Memsetmemset(tmpBuf, 0, info->macSize); | |||
2225 | return (cmp == 0) ? SECSuccess : SECFailure; | |||
2226 | } | |||
2227 | ||||
2228 | /* | |||
2229 | * common HMAC initalization routine | |||
2230 | */ | |||
2231 | static CK_RV | |||
2232 | sftk_doSSLMACInit(SFTKSessionContext *context, SECOidTag oid, | |||
2233 | SFTKObject *key, CK_ULONG mac_size) | |||
2234 | { | |||
2235 | SFTKAttribute *keyval; | |||
2236 | SFTKBegin begin; | |||
2237 | int padSize; | |||
2238 | SFTKSSLMACInfo *sslmacinfo; | |||
2239 | CK_RV crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
2240 | ||||
2241 | if (oid == SEC_OID_SHA1) { | |||
2242 | crv = sftk_doSubSHA1(context); | |||
2243 | if (crv != CKR_OK0x00000000UL) | |||
2244 | return crv; | |||
2245 | begin = (SFTKBegin)SHA1_Begin; | |||
2246 | padSize = 40; | |||
2247 | } else { | |||
2248 | crv = sftk_doSubMD5(context); | |||
2249 | if (crv != CKR_OK0x00000000UL) | |||
2250 | return crv; | |||
2251 | begin = (SFTKBegin)MD5_Begin; | |||
2252 | padSize = 48; | |||
2253 | } | |||
2254 | context->multi = PR_TRUE1; | |||
2255 | ||||
2256 | keyval = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
2257 | if (keyval == NULL((void*)0)) | |||
2258 | return CKR_KEY_SIZE_RANGE0x00000062UL; | |||
2259 | ||||
2260 | context->hashUpdate(context->hashInfo, keyval->attrib.pValue, | |||
2261 | keyval->attrib.ulValueLen); | |||
2262 | context->hashUpdate(context->hashInfo, ssl_pad_1, padSize); | |||
2263 | sslmacinfo = (SFTKSSLMACInfo *)PORT_AllocPORT_Alloc_Util(sizeof(SFTKSSLMACInfo)); | |||
2264 | if (sslmacinfo == NULL((void*)0)) { | |||
2265 | sftk_FreeAttribute(keyval); | |||
2266 | return CKR_HOST_MEMORY0x00000002UL; | |||
2267 | } | |||
2268 | sslmacinfo->size = sizeof(SFTKSSLMACInfo); | |||
2269 | sslmacinfo->macSize = mac_size; | |||
2270 | sslmacinfo->hashContext = context->hashInfo; | |||
2271 | PORT_Memcpymemcpy(sslmacinfo->key, keyval->attrib.pValue, | |||
2272 | keyval->attrib.ulValueLen); | |||
2273 | sslmacinfo->keySize = keyval->attrib.ulValueLen; | |||
2274 | sslmacinfo->begin = begin; | |||
2275 | sslmacinfo->end = context->end; | |||
2276 | sslmacinfo->update = context->hashUpdate; | |||
2277 | sslmacinfo->padSize = padSize; | |||
2278 | sftk_FreeAttribute(keyval); | |||
2279 | context->cipherInfo = (void *)sslmacinfo; | |||
2280 | context->destroy = (SFTKDestroy)sftk_ZSpace; | |||
2281 | context->update = (SFTKCipher)sftk_SSLMACSign; | |||
2282 | context->verify = (SFTKVerify)sftk_SSLMACVerify; | |||
2283 | context->maxLen = mac_size; | |||
2284 | return CKR_OK0x00000000UL; | |||
2285 | } | |||
2286 | ||||
2287 | /* | |||
2288 | ************** Crypto Functions: Sign ************************ | |||
2289 | */ | |||
2290 | ||||
2291 | /** | |||
2292 | * Check if We're using CBCMacing and initialize the session context if we are. | |||
2293 | * @param contextType SFTK_SIGN or SFTK_VERIFY | |||
2294 | * @param keyUsage check whether key allows this usage | |||
2295 | */ | |||
2296 | static CK_RV | |||
2297 | sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, | |||
2298 | CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage, | |||
2299 | SFTKContextType contextType) | |||
2300 | ||||
2301 | { | |||
2302 | CK_MECHANISM cbc_mechanism; | |||
2303 | CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE0xffffffff; | |||
2304 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
2305 | CK_RC2_CBC_PARAMS rc2_params; | |||
2306 | #endif | |||
2307 | #if NSS_SOFTOKEN_DOES_RC5 | |||
2308 | CK_RC5_CBC_PARAMS rc5_params; | |||
2309 | CK_RC5_MAC_GENERAL_PARAMS *rc5_mac; | |||
2310 | #endif | |||
2311 | unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE16]; | |||
2312 | unsigned char k2[SFTK_MAX_BLOCK_SIZE16]; | |||
2313 | unsigned char k3[SFTK_MAX_BLOCK_SIZE16]; | |||
2314 | SFTKSessionContext *context; | |||
2315 | CK_RV crv; | |||
2316 | unsigned int blockSize; | |||
2317 | PRBool isXCBC = PR_FALSE0; | |||
2318 | ||||
2319 | if (!pMechanism) { | |||
2320 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2321 | } | |||
2322 | ||||
2323 | switch (pMechanism->mechanism) { | |||
2324 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
2325 | case CKM_RC2_MAC_GENERAL0x00000104UL: | |||
2326 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_MAC_GENERAL_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_RC2_MAC_GENERAL_PARAMS))) { | |||
2327 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2328 | } | |||
2329 | mac_bytes = | |||
2330 | ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength; | |||
2331 | /* fall through */ | |||
2332 | case CKM_RC2_MAC0x00000103UL: | |||
2333 | /* this works because ulEffectiveBits is in the same place in both the | |||
2334 | * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */ | |||
2335 | rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *) | |||
2336 | pMechanism->pParameter) | |||
2337 | ->ulEffectiveBits; | |||
2338 | PORT_Memsetmemset(rc2_params.iv, 0, sizeof(rc2_params.iv)); | |||
2339 | cbc_mechanism.mechanism = CKM_RC2_CBC0x00000102UL; | |||
2340 | cbc_mechanism.pParameter = &rc2_params; | |||
2341 | cbc_mechanism.ulParameterLen = sizeof(rc2_params); | |||
2342 | blockSize = 8; | |||
2343 | break; | |||
2344 | #endif /* NSS_DISABLE_DEPRECATED_RC2 */ | |||
2345 | ||||
2346 | #if NSS_SOFTOKEN_DOES_RC5 | |||
2347 | case CKM_RC5_MAC_GENERAL0x00000334UL: | |||
2348 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_RC5_MAC_GENERAL_PARAMS))) { | |||
2349 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2350 | } | |||
2351 | mac_bytes = | |||
2352 | ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength; | |||
2353 | /* fall through */ | |||
2354 | case CKM_RC5_MAC0x00000333UL: | |||
2355 | /* this works because ulEffectiveBits is in the same place in both the | |||
2356 | * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */ | |||
2357 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_RC5_MAC_GENERAL_PARAMS))) { | |||
2358 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2359 | } | |||
2360 | rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter; | |||
2361 | rc5_params.ulWordsize = rc5_mac->ulWordsize; | |||
2362 | rc5_params.ulRounds = rc5_mac->ulRounds; | |||
2363 | rc5_params.pIv = ivBlock; | |||
2364 | if ((blockSize = rc5_mac->ulWordsize * 2) > SFTK_MAX_BLOCK_SIZE16) | |||
2365 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2366 | rc5_params.ulIvLen = blockSize; | |||
2367 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2368 | cbc_mechanism.mechanism = CKM_RC5_CBC0x00000332UL; | |||
2369 | cbc_mechanism.pParameter = &rc5_params; | |||
2370 | cbc_mechanism.ulParameterLen = sizeof(rc5_params); | |||
2371 | break; | |||
2372 | #endif | |||
2373 | /* add cast and idea later */ | |||
2374 | case CKM_DES_MAC_GENERAL0x00000124UL: | |||
2375 | mac_bytes = *(CK_ULONG *)pMechanism->pParameter; | |||
2376 | /* fall through */ | |||
2377 | case CKM_DES_MAC0x00000123UL: | |||
2378 | blockSize = 8; | |||
2379 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2380 | cbc_mechanism.mechanism = CKM_DES_CBC0x00000122UL; | |||
2381 | cbc_mechanism.pParameter = &ivBlock; | |||
2382 | cbc_mechanism.ulParameterLen = blockSize; | |||
2383 | break; | |||
2384 | case CKM_DES3_MAC_GENERAL0x00000135UL: | |||
2385 | mac_bytes = *(CK_ULONG *)pMechanism->pParameter; | |||
2386 | /* fall through */ | |||
2387 | case CKM_DES3_MAC0x00000134UL: | |||
2388 | blockSize = 8; | |||
2389 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2390 | cbc_mechanism.mechanism = CKM_DES3_CBC0x00000133UL; | |||
2391 | cbc_mechanism.pParameter = &ivBlock; | |||
2392 | cbc_mechanism.ulParameterLen = blockSize; | |||
2393 | break; | |||
2394 | case CKM_CDMF_MAC_GENERAL0x00000144UL: | |||
2395 | mac_bytes = *(CK_ULONG *)pMechanism->pParameter; | |||
2396 | /* fall through */ | |||
2397 | case CKM_CDMF_MAC0x00000143UL: | |||
2398 | blockSize = 8; | |||
2399 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2400 | cbc_mechanism.mechanism = CKM_CDMF_CBC0x00000142UL; | |||
2401 | cbc_mechanism.pParameter = &ivBlock; | |||
2402 | cbc_mechanism.ulParameterLen = blockSize; | |||
2403 | break; | |||
2404 | #ifndef NSS_DISABLE_DEPRECATED_SEED | |||
2405 | case CKM_SEED_MAC_GENERAL0x00000654UL: | |||
2406 | mac_bytes = *(CK_ULONG *)pMechanism->pParameter; | |||
2407 | /* fall through */ | |||
2408 | case CKM_SEED_MAC0x00000653UL: | |||
2409 | blockSize = 16; | |||
2410 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2411 | cbc_mechanism.mechanism = CKM_SEED_CBC0x00000652UL; | |||
2412 | cbc_mechanism.pParameter = &ivBlock; | |||
2413 | cbc_mechanism.ulParameterLen = blockSize; | |||
2414 | break; | |||
2415 | #endif /* NSS_DISABLE_DEPRECATED_SEED */ | |||
2416 | case CKM_CAMELLIA_MAC_GENERAL0x00000554UL: | |||
2417 | mac_bytes = *(CK_ULONG *)pMechanism->pParameter; | |||
2418 | /* fall through */ | |||
2419 | case CKM_CAMELLIA_MAC0x00000553UL: | |||
2420 | blockSize = 16; | |||
2421 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2422 | cbc_mechanism.mechanism = CKM_CAMELLIA_CBC0x00000552UL; | |||
2423 | cbc_mechanism.pParameter = &ivBlock; | |||
2424 | cbc_mechanism.ulParameterLen = blockSize; | |||
2425 | break; | |||
2426 | case CKM_AES_MAC_GENERAL0x00001084UL: | |||
2427 | mac_bytes = *(CK_ULONG *)pMechanism->pParameter; | |||
2428 | /* fall through */ | |||
2429 | case CKM_AES_MAC0x00001083UL: | |||
2430 | blockSize = 16; | |||
2431 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2432 | cbc_mechanism.mechanism = CKM_AES_CBC0x00001082UL; | |||
2433 | cbc_mechanism.pParameter = &ivBlock; | |||
2434 | cbc_mechanism.ulParameterLen = blockSize; | |||
2435 | break; | |||
2436 | case CKM_AES_XCBC_MAC_960x0000108DUL: | |||
2437 | case CKM_AES_XCBC_MAC0x0000108CUL: | |||
2438 | /* The only difference between CKM_AES_XCBC_MAC | |||
2439 | * and CKM_AES_XCBC_MAC_96 is the size of the returned mac. */ | |||
2440 | mac_bytes = pMechanism->mechanism == CKM_AES_XCBC_MAC_960x0000108DUL ? 12 : 16; | |||
2441 | blockSize = 16; | |||
2442 | PORT_Memsetmemset(ivBlock, 0, blockSize); | |||
2443 | cbc_mechanism.mechanism = CKM_AES_CBC0x00001082UL; | |||
2444 | cbc_mechanism.pParameter = &ivBlock; | |||
2445 | cbc_mechanism.ulParameterLen = blockSize; | |||
2446 | /* is XCBC requires extra processing at the end of the operation */ | |||
2447 | isXCBC = PR_TRUE1; | |||
2448 | /* The input key is used to generate k1, k2, and k3. k2 and k3 | |||
2449 | * are used at the end in the pad step. k1 replaces the input | |||
2450 | * key in the aes cbc mac */ | |||
2451 | crv = sftk_aes_xcbc_new_keys(hSession, hKey, &hKey, k2, k3); | |||
2452 | if (crv != CKR_OK0x00000000UL) { | |||
2453 | return crv; | |||
2454 | } | |||
2455 | break; | |||
2456 | default: | |||
2457 | return CKR_FUNCTION_NOT_SUPPORTED0x00000054UL; | |||
2458 | } | |||
2459 | ||||
2460 | /* if MAC size is externally supplied, it should be checked. | |||
2461 | */ | |||
2462 | if (mac_bytes == SFTK_INVALID_MAC_SIZE0xffffffff) | |||
2463 | mac_bytes = blockSize >> 1; | |||
2464 | else { | |||
2465 | if (mac_bytes > blockSize) { | |||
2466 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2467 | goto fail; | |||
2468 | } | |||
2469 | } | |||
2470 | ||||
2471 | crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey, | |||
2472 | CKA_ENCRYPT0x00000104UL, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */ | |||
2473 | keyUsage, contextType, PR_TRUE1); | |||
2474 | if (crv != CKR_OK0x00000000UL) | |||
2475 | goto fail; | |||
2476 | crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE1, NULL((void*)0)); | |||
2477 | ||||
2478 | /* this shouldn't happen! */ | |||
2479 | PORT_Assert(crv == CKR_OK)((crv == 0x00000000UL)?((void)0):PR_Assert("crv == CKR_OK","pkcs11c.c" ,2479)); | |||
2480 | if (crv != CKR_OK0x00000000UL) | |||
2481 | goto fail; | |||
2482 | context->blockSize = blockSize; | |||
2483 | context->macSize = mac_bytes; | |||
2484 | context->isXCBC = isXCBC; | |||
2485 | if (isXCBC) { | |||
2486 | /* save the xcbc specific parameters */ | |||
2487 | PORT_Memcpymemcpy(context->k2, k2, blockSize); | |||
2488 | PORT_Memcpymemcpy(context->k3, k3, blockSize); | |||
2489 | PORT_Memsetmemset(k2, 0, blockSize); | |||
2490 | PORT_Memsetmemset(k3, 0, blockSize); | |||
2491 | /* get rid of the temp key now that the context has been created */ | |||
2492 | NSC_DestroyObject(hSession, hKey); | |||
2493 | } | |||
2494 | return CKR_OK0x00000000UL; | |||
2495 | fail: | |||
2496 | if (isXCBC) { | |||
2497 | PORT_Memsetmemset(k2, 0, blockSize); | |||
2498 | PORT_Memsetmemset(k3, 0, blockSize); | |||
2499 | NSC_DestroyObject(hSession, hKey); /* get rid of our temp key */ | |||
2500 | } | |||
2501 | return crv; | |||
2502 | } | |||
2503 | ||||
2504 | /* | |||
2505 | * encode RSA PKCS #1 Signature data before signing... | |||
2506 | */ | |||
2507 | static SECStatus | |||
2508 | sftk_RSAHashSign(SFTKHashSignInfo *info, unsigned char *sig, | |||
2509 | unsigned int *sigLen, unsigned int maxLen, | |||
2510 | const unsigned char *hash, unsigned int hashLen) | |||
2511 | { | |||
2512 | PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert ("info->key->keyType == NSSLOWKEYRSAKey","pkcs11c.c",2512 )); | |||
2513 | if (info->key->keyType != NSSLOWKEYRSAKey) { | |||
2514 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
2515 | return SECFailure; | |||
2516 | } | |||
2517 | ||||
2518 | return RSA_HashSign(info->hashOid, info->key, sig, sigLen, maxLen, | |||
2519 | hash, hashLen); | |||
2520 | } | |||
2521 | ||||
2522 | /* XXX Old template; want to expunge it eventually. */ | |||
2523 | static DERTemplate SECAlgorithmIDTemplate[] = { | |||
2524 | { DER_SEQUENCE0x10, | |||
2525 | 0, NULL((void*)0), sizeof(SECAlgorithmID) }, | |||
2526 | { DER_OBJECT_ID0x06, | |||
2527 | offsetof(SECAlgorithmID, algorithm)__builtin_offsetof(SECAlgorithmID, algorithm) }, | |||
2528 | { DER_OPTIONAL0x00100 | DER_ANY0x00400, | |||
2529 | offsetof(SECAlgorithmID, parameters)__builtin_offsetof(SECAlgorithmID, parameters) }, | |||
2530 | { 0 } | |||
2531 | }; | |||
2532 | ||||
2533 | /* | |||
2534 | * XXX OLD Template. Once all uses have been switched over to new one, | |||
2535 | * remove this. | |||
2536 | */ | |||
2537 | static DERTemplate SGNDigestInfoTemplate[] = { | |||
2538 | { DER_SEQUENCE0x10, | |||
2539 | 0, NULL((void*)0), sizeof(SGNDigestInfo) }, | |||
2540 | { DER_INLINE0x00800, | |||
2541 | offsetof(SGNDigestInfo, digestAlgorithm)__builtin_offsetof(SGNDigestInfo, digestAlgorithm), | |||
2542 | SECAlgorithmIDTemplate }, | |||
2543 | { DER_OCTET_STRING0x04, | |||
2544 | offsetof(SGNDigestInfo, digest)__builtin_offsetof(SGNDigestInfo, digest) }, | |||
2545 | { 0 } | |||
2546 | }; | |||
2547 | ||||
2548 | /* | |||
2549 | * encode RSA PKCS #1 Signature data before signing... | |||
2550 | */ | |||
2551 | SECStatus | |||
2552 | RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key, | |||
2553 | unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, | |||
2554 | const unsigned char *hash, unsigned int hashLen) | |||
2555 | { | |||
2556 | SECStatus rv = SECFailure; | |||
2557 | SECItem digder; | |||
2558 | PLArenaPool *arena = NULL((void*)0); | |||
2559 | SGNDigestInfo *di = NULL((void*)0); | |||
2560 | ||||
2561 | digder.data = NULL((void*)0); | |||
2562 | ||||
2563 | arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); | |||
2564 | if (!arena) { | |||
2565 | goto loser; | |||
2566 | } | |||
2567 | ||||
2568 | /* Construct digest info */ | |||
2569 | di = SGN_CreateDigestInfoSGN_CreateDigestInfo_Util(hashOid, hash, hashLen); | |||
2570 | if (!di) { | |||
2571 | goto loser; | |||
2572 | } | |||
2573 | ||||
2574 | /* Der encode the digest as a DigestInfo */ | |||
2575 | rv = DER_EncodeDER_Encode_Util(arena, &digder, SGNDigestInfoTemplate, di); | |||
2576 | if (rv != SECSuccess) { | |||
2577 | goto loser; | |||
2578 | } | |||
2579 | ||||
2580 | /* | |||
2581 | ** Encrypt signature after constructing appropriate PKCS#1 signature | |||
2582 | ** block | |||
2583 | */ | |||
2584 | rv = RSA_Sign(&key->u.rsa, sig, sigLen, maxLen, digder.data, | |||
2585 | digder.len); | |||
2586 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
2587 | sftk_fatalError = PR_TRUE1; | |||
2588 | } | |||
2589 | ||||
2590 | loser: | |||
2591 | SGN_DestroyDigestInfoSGN_DestroyDigestInfo_Util(di); | |||
2592 | if (arena != NULL((void*)0)) { | |||
2593 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
2594 | } | |||
2595 | return rv; | |||
2596 | } | |||
2597 | ||||
2598 | static SECStatus | |||
2599 | sftk_RSASign(NSSLOWKEYPrivateKey *key, unsigned char *output, | |||
2600 | unsigned int *outputLen, unsigned int maxOutputLen, | |||
2601 | const unsigned char *input, unsigned int inputLen) | |||
2602 | { | |||
2603 | SECStatus rv = SECFailure; | |||
2604 | ||||
2605 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",2605)); | |||
2606 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
2607 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
2608 | return SECFailure; | |||
2609 | } | |||
2610 | ||||
2611 | rv = RSA_Sign(&key->u.rsa, output, outputLen, maxOutputLen, input, | |||
2612 | inputLen); | |||
2613 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
2614 | sftk_fatalError = PR_TRUE1; | |||
2615 | } | |||
2616 | return rv; | |||
2617 | } | |||
2618 | ||||
2619 | static SECStatus | |||
2620 | sftk_RSASignRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, | |||
2621 | unsigned int *outputLen, unsigned int maxOutputLen, | |||
2622 | const unsigned char *input, unsigned int inputLen) | |||
2623 | { | |||
2624 | SECStatus rv = SECFailure; | |||
2625 | ||||
2626 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",2626)); | |||
2627 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
2628 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
2629 | return SECFailure; | |||
2630 | } | |||
2631 | ||||
2632 | rv = RSA_SignRaw(&key->u.rsa, output, outputLen, maxOutputLen, input, | |||
2633 | inputLen); | |||
2634 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
2635 | sftk_fatalError = PR_TRUE1; | |||
2636 | } | |||
2637 | return rv; | |||
2638 | } | |||
2639 | ||||
2640 | static SECStatus | |||
2641 | sftk_RSASignPSS(SFTKPSSSignInfo *info, unsigned char *sig, | |||
2642 | unsigned int *sigLen, unsigned int maxLen, | |||
2643 | const unsigned char *hash, unsigned int hashLen) | |||
2644 | { | |||
2645 | SECStatus rv = SECFailure; | |||
2646 | HASH_HashType hashAlg; | |||
2647 | HASH_HashType maskHashAlg; | |||
2648 | CK_RSA_PKCS_PSS_PARAMS *params = &info->params; | |||
2649 | ||||
2650 | PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert ("info->key->keyType == NSSLOWKEYRSAKey","pkcs11c.c",2650 )); | |||
2651 | if (info->key->keyType != NSSLOWKEYRSAKey) { | |||
2652 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
2653 | return SECFailure; | |||
2654 | } | |||
2655 | ||||
2656 | hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg); | |||
2657 | maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf); | |||
2658 | ||||
2659 | rv = RSA_SignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, NULL((void*)0), | |||
2660 | params->sLen, sig, sigLen, maxLen, hash, hashLen); | |||
2661 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
2662 | sftk_fatalError = PR_TRUE1; | |||
2663 | } | |||
2664 | return rv; | |||
2665 | } | |||
2666 | ||||
2667 | static SECStatus | |||
2668 | nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen, | |||
2669 | void *dataBuf, unsigned int dataLen) | |||
2670 | { | |||
2671 | SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen }; | |||
2672 | SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; | |||
2673 | NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx; | |||
2674 | return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest); | |||
2675 | } | |||
2676 | ||||
2677 | static SECStatus | |||
2678 | nsc_DSA_Sign_Stub(void *ctx, void *sigBuf, | |||
2679 | unsigned int *sigLen, unsigned int maxSigLen, | |||
2680 | void *dataBuf, unsigned int dataLen) | |||
2681 | { | |||
2682 | NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx; | |||
2683 | SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen }; | |||
2684 | SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; | |||
2685 | SECStatus rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest); | |||
2686 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
2687 | sftk_fatalError = PR_TRUE1; | |||
2688 | } | |||
2689 | *sigLen = signature.len; | |||
2690 | return rv; | |||
2691 | } | |||
2692 | ||||
2693 | static SECStatus | |||
2694 | nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen, | |||
2695 | void *dataBuf, unsigned int dataLen) | |||
2696 | { | |||
2697 | SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen }; | |||
2698 | SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; | |||
2699 | NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx; | |||
2700 | return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest); | |||
2701 | } | |||
2702 | ||||
2703 | static SECStatus | |||
2704 | nsc_ECDSASignStub(void *ctx, void *sigBuf, | |||
2705 | unsigned int *sigLen, unsigned int maxSigLen, | |||
2706 | void *dataBuf, unsigned int dataLen) | |||
2707 | { | |||
2708 | NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx; | |||
2709 | SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen }; | |||
2710 | SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; | |||
2711 | ||||
2712 | SECStatus rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest); | |||
2713 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
2714 | sftk_fatalError = PR_TRUE1; | |||
2715 | } | |||
2716 | *sigLen = signature.len; | |||
2717 | return rv; | |||
2718 | } | |||
2719 | ||||
2720 | static SECStatus | |||
2721 | nsc_EDDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen, | |||
2722 | void *dataBuf, unsigned int dataLen) | |||
2723 | { | |||
2724 | SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen }; | |||
2725 | SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; | |||
2726 | NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx; | |||
2727 | return ED_VerifyMessage(&(key->u.ec), &signature, &digest); | |||
2728 | } | |||
2729 | ||||
2730 | static SECStatus | |||
2731 | nsc_EDDSASignStub(void *ctx, void *sigBuf, | |||
2732 | unsigned int *sigLen, unsigned int maxSigLen, | |||
2733 | void *dataBuf, unsigned int dataLen) | |||
2734 | { | |||
2735 | NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx; | |||
2736 | SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen }; | |||
2737 | SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; | |||
2738 | ||||
2739 | SECStatus rv = ED_SignMessage(&(key->u.ec), &signature, &digest); | |||
2740 | if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
2741 | sftk_fatalError = PR_TRUE1; | |||
2742 | } | |||
2743 | *sigLen = signature.len; | |||
2744 | return rv; | |||
2745 | } | |||
2746 | ||||
2747 | /* NSC_SignInit setups up the signing operations. There are three basic | |||
2748 | * types of signing: | |||
2749 | * (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied | |||
2750 | * to data in a single Sign operation (which often looks a lot like an | |||
2751 | * encrypt, with data coming in and data going out). | |||
2752 | * (2) Hash based signing, where we continually hash the data, then apply | |||
2753 | * some sort of signature to the end. | |||
2754 | * (3) Block Encryption CBC MAC's, where the Data is encrypted with a key, | |||
2755 | * and only the final block is part of the mac. | |||
2756 | * | |||
2757 | * For case number 3, we initialize a context much like the Encryption Context | |||
2758 | * (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and | |||
2759 | * C_Final by the following method... if it's not multi-part, and it's doesn't | |||
2760 | * have a hash context, it must be a block Encryption CBC MAC. | |||
2761 | * | |||
2762 | * For case number 2, we initialize a hash structure, as well as make it | |||
2763 | * multi-part. Updates are simple calls to the hash update function. Final | |||
2764 | * calls the hashend, then passes the result to the 'update' function (which | |||
2765 | * operates as a final signature function). In some hash based MAC'ing (as | |||
2766 | * opposed to hash base signatures), the update function is can be simply a | |||
2767 | * copy (as is the case with HMAC). | |||
2768 | */ | |||
2769 | CK_RV | |||
2770 | NSC_SignInit(CK_SESSION_HANDLE hSession, | |||
2771 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) | |||
2772 | { | |||
2773 | SFTKSession *session; | |||
2774 | SFTKObject *key; | |||
2775 | SFTKSessionContext *context; | |||
2776 | CK_KEY_TYPE key_type; | |||
2777 | CK_RV crv = CKR_OK0x00000000UL; | |||
2778 | NSSLOWKEYPrivateKey *privKey; | |||
2779 | SFTKHashSignInfo *info = NULL((void*)0); | |||
2780 | SFTKPSSSignInfo *pinfo = NULL((void*)0); | |||
2781 | ||||
2782 | CHECK_FORK(); | |||
2783 | ||||
2784 | /* Block Cipher MACing Algorithms use a different Context init method..*/ | |||
2785 | crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN0x00000108UL, SFTK_SIGN); | |||
2786 | if (crv != CKR_FUNCTION_NOT_SUPPORTED0x00000054UL) | |||
2787 | return crv; | |||
2788 | ||||
2789 | /* we're not using a block cipher mac */ | |||
2790 | session = sftk_SessionFromHandle(hSession); | |||
2791 | if (session == NULL((void*)0)) | |||
2792 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
2793 | crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_SIGN, &key, | |||
2794 | hKey, &key_type, CKO_PRIVATE_KEY0x00000003UL, CKA_SIGN0x00000108UL); | |||
2795 | if (crv != CKR_OK0x00000000UL) { | |||
2796 | sftk_FreeSession(session); | |||
2797 | return crv; | |||
2798 | } | |||
2799 | ||||
2800 | context->multi = PR_FALSE0; | |||
2801 | ||||
2802 | #define INIT_RSA_SIGN_MECH(mmm)case CKM_mmm_RSA_PKCS: context->multi = 1; crv = sftk_doSubmmm (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_mmm; goto finish_rsa; \ | |||
2803 | case CKM_##mmm##_RSA_PKCS: \ | |||
2804 | context->multi = PR_TRUE1; \ | |||
2805 | crv = sftk_doSub##mmm(context); \ | |||
2806 | if (crv != CKR_OK0x00000000UL) \ | |||
2807 | break; \ | |||
2808 | context->update = (SFTKCipher)sftk_RSAHashSign; \ | |||
2809 | info = PORT_New(SFTKHashSignInfo)(SFTKHashSignInfo *)PORT_Alloc_Util(sizeof(SFTKHashSignInfo)); \ | |||
2810 | if (info == NULL((void*)0)) { \ | |||
2811 | crv = CKR_HOST_MEMORY0x00000002UL; \ | |||
2812 | break; \ | |||
2813 | } \ | |||
2814 | info->hashOid = SEC_OID_##mmm; \ | |||
2815 | goto finish_rsa; | |||
2816 | ||||
2817 | switch (pMechanism->mechanism) { | |||
2818 | INIT_RSA_SIGN_MECH(MD5)case 0x00000005UL: context->multi = 1; crv = sftk_doSubMD5 (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_MD5; goto finish_rsa; | |||
2819 | INIT_RSA_SIGN_MECH(MD2)case 0x00000004UL: context->multi = 1; crv = sftk_doSubMD2 (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_MD2; goto finish_rsa; | |||
2820 | INIT_RSA_SIGN_MECH(SHA1)case 0x00000006UL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_SHA1; goto finish_rsa; | |||
2821 | INIT_RSA_SIGN_MECH(SHA224)case 0x00000046UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_SHA224; goto finish_rsa ; | |||
2822 | INIT_RSA_SIGN_MECH(SHA256)case 0x00000040UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_SHA256; goto finish_rsa ; | |||
2823 | INIT_RSA_SIGN_MECH(SHA384)case 0x00000041UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_SHA384; goto finish_rsa ; | |||
2824 | INIT_RSA_SIGN_MECH(SHA512)case 0x00000042UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; context->update = (SFTKCipher)sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util (sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL ; break; } info->hashOid = SEC_OID_SHA512; goto finish_rsa ; | |||
2825 | ||||
2826 | case CKM_RSA_PKCS0x00000001UL: | |||
2827 | context->update = (SFTKCipher)sftk_RSASign; | |||
2828 | goto finish_rsa; | |||
2829 | case CKM_RSA_X_5090x00000003UL: | |||
2830 | context->update = (SFTKCipher)sftk_RSASignRaw; | |||
2831 | finish_rsa: | |||
2832 | if (key_type != CKK_RSA0x00000000UL) { | |||
2833 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
2834 | break; | |||
2835 | } | |||
2836 | context->rsa = PR_TRUE1; | |||
2837 | privKey = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv); | |||
2838 | if (privKey == NULL((void*)0)) { | |||
2839 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
2840 | break; | |||
2841 | } | |||
2842 | /* OK, info is allocated only if we're doing hash and sign mechanism. | |||
2843 | * It's necessary to be able to set the correct OID in the final | |||
2844 | * signature. | |||
2845 | */ | |||
2846 | if (info) { | |||
2847 | info->key = privKey; | |||
2848 | context->cipherInfo = info; | |||
2849 | context->destroy = (SFTKDestroy)sftk_Space; | |||
2850 | } else { | |||
2851 | context->cipherInfo = privKey; | |||
2852 | context->destroy = (SFTKDestroy)sftk_Null; | |||
2853 | } | |||
2854 | context->maxLen = nsslowkey_PrivateModulusLen(privKey); | |||
2855 | break; | |||
2856 | ||||
2857 | #define INIT_RSA_PSS_SIG_MECH(mmm)case CKM_mmm_RSA_PKCS_PSS: context->multi = 1; crv = sftk_doSubmmm (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != CKM_mmm) { crv = 0x00000071UL; break ; } goto finish_rsa_pss; \ | |||
2858 | case CKM_##mmm##_RSA_PKCS_PSS: \ | |||
2859 | context->multi = PR_TRUE1; \ | |||
2860 | crv = sftk_doSub##mmm(context); \ | |||
2861 | if (crv != CKR_OK0x00000000UL) \ | |||
2862 | break; \ | |||
2863 | if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { \ | |||
2864 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; \ | |||
2865 | break; \ | |||
2866 | } \ | |||
2867 | if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)->hashAlg != CKM_##mmm) { \ | |||
2868 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; \ | |||
2869 | break; \ | |||
2870 | } \ | |||
2871 | goto finish_rsa_pss; | |||
2872 | INIT_RSA_PSS_SIG_MECH(SHA1)case 0x0000000EUL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000220UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
2873 | INIT_RSA_PSS_SIG_MECH(SHA224)case 0x00000047UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000255UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
2874 | INIT_RSA_PSS_SIG_MECH(SHA256)case 0x00000043UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000250UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
2875 | INIT_RSA_PSS_SIG_MECH(SHA384)case 0x00000044UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000260UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
2876 | INIT_RSA_PSS_SIG_MECH(SHA512)case 0x00000045UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000270UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
2877 | case CKM_RSA_PKCS_PSS0x0000000DUL: | |||
2878 | finish_rsa_pss: | |||
2879 | if (key_type != CKK_RSA0x00000000UL) { | |||
2880 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
2881 | break; | |||
2882 | } | |||
2883 | context->rsa = PR_TRUE1; | |||
2884 | if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) || | |||
2885 | !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) { | |||
2886 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2887 | break; | |||
2888 | } | |||
2889 | pinfo = PORT_New(SFTKPSSSignInfo)(SFTKPSSSignInfo *)PORT_Alloc_Util(sizeof(SFTKPSSSignInfo)); | |||
2890 | if (pinfo == NULL((void*)0)) { | |||
2891 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
2892 | break; | |||
2893 | } | |||
2894 | pinfo->size = sizeof(SFTKPSSSignInfo); | |||
2895 | pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; | |||
2896 | pinfo->key = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv); | |||
2897 | if (pinfo->key == NULL((void*)0)) { | |||
2898 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
2899 | break; | |||
2900 | } | |||
2901 | context->cipherInfo = pinfo; | |||
2902 | context->destroy = (SFTKDestroy)sftk_ZSpace; | |||
2903 | context->update = (SFTKCipher)sftk_RSASignPSS; | |||
2904 | context->maxLen = nsslowkey_PrivateModulusLen(pinfo->key); | |||
2905 | break; | |||
2906 | ||||
2907 | #define INIT_DSA_SIG_MECH(mmm)case CKM_DSA_mmm: context->multi = 1; crv = sftk_doSubmmm( context); if (crv != 0x00000000UL) break; goto finish_dsa; \ | |||
2908 | case CKM_DSA_##mmm: \ | |||
2909 | context->multi = PR_TRUE1; \ | |||
2910 | crv = sftk_doSub##mmm(context); \ | |||
2911 | if (crv != CKR_OK0x00000000UL) \ | |||
2912 | break; \ | |||
2913 | goto finish_dsa; | |||
2914 | INIT_DSA_SIG_MECH(SHA1)case 0x00000012UL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
2915 | INIT_DSA_SIG_MECH(SHA224)case 0x00000013UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
2916 | INIT_DSA_SIG_MECH(SHA256)case 0x00000014UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
2917 | INIT_DSA_SIG_MECH(SHA384)case 0x00000015UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
2918 | INIT_DSA_SIG_MECH(SHA512)case 0x00000016UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
2919 | case CKM_DSA0x00000011UL: | |||
2920 | finish_dsa: | |||
2921 | if (key_type != CKK_DSA0x00000001UL) { | |||
2922 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
2923 | break; | |||
2924 | } | |||
2925 | privKey = sftk_GetPrivKey(key, CKK_DSA0x00000001UL, &crv); | |||
2926 | if (privKey == NULL((void*)0)) { | |||
2927 | break; | |||
2928 | } | |||
2929 | context->cipherInfo = privKey; | |||
2930 | context->update = (SFTKCipher)nsc_DSA_Sign_Stub; | |||
2931 | context->destroy = (privKey == key->objectInfo) ? (SFTKDestroy)sftk_Null : (SFTKDestroy)sftk_FreePrivKey; | |||
2932 | context->maxLen = DSA_MAX_SIGNATURE_LEN(32 * 2); | |||
2933 | ||||
2934 | break; | |||
2935 | ||||
2936 | #define INIT_ECDSA_SIG_MECH(mmm)case CKM_ECDSA_mmm: context->multi = 1; crv = sftk_doSubmmm (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; \ | |||
2937 | case CKM_ECDSA_##mmm: \ | |||
2938 | context->multi = PR_TRUE1; \ | |||
2939 | crv = sftk_doSub##mmm(context); \ | |||
2940 | if (crv != CKR_OK0x00000000UL) \ | |||
2941 | break; \ | |||
2942 | goto finish_ecdsa; | |||
2943 | INIT_ECDSA_SIG_MECH(SHA1)case 0x00001042UL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
2944 | INIT_ECDSA_SIG_MECH(SHA224)case 0x00001043UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
2945 | INIT_ECDSA_SIG_MECH(SHA256)case 0x00001044UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
2946 | INIT_ECDSA_SIG_MECH(SHA384)case 0x00001045UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
2947 | INIT_ECDSA_SIG_MECH(SHA512)case 0x00001046UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
2948 | case CKM_ECDSA0x00001041UL: | |||
2949 | finish_ecdsa: | |||
2950 | if (key_type != CKK_EC0x00000003UL) { | |||
2951 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
2952 | break; | |||
2953 | } | |||
2954 | privKey = sftk_GetPrivKey(key, CKK_EC0x00000003UL, &crv); | |||
2955 | if (privKey == NULL((void*)0)) { | |||
2956 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
2957 | break; | |||
2958 | } | |||
2959 | context->cipherInfo = privKey; | |||
2960 | context->update = (SFTKCipher)nsc_ECDSASignStub; | |||
2961 | context->destroy = (privKey == key->objectInfo) ? (SFTKDestroy)sftk_Null : (SFTKDestroy)sftk_FreePrivKey; | |||
2962 | context->maxLen = MAX_ECKEY_LEN72 * 2; | |||
2963 | ||||
2964 | break; | |||
2965 | ||||
2966 | case CKM_EDDSA0x00001057UL: | |||
2967 | if (key_type != CKK_EC_EDWARDS0x00000040UL) { | |||
2968 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
2969 | break; | |||
2970 | } | |||
2971 | ||||
2972 | if (pMechanism->pParameter) { | |||
2973 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
2974 | break; | |||
2975 | } | |||
2976 | ||||
2977 | privKey = sftk_GetPrivKey(key, CKK_EC_EDWARDS0x00000040UL, &crv); | |||
2978 | if (privKey == NULL((void*)0)) { | |||
2979 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
2980 | break; | |||
2981 | } | |||
2982 | context->cipherInfo = privKey; | |||
2983 | context->update = (SFTKCipher)nsc_EDDSASignStub; | |||
2984 | context->destroy = (privKey == key->objectInfo) ? (SFTKDestroy)sftk_Null : (SFTKDestroy)sftk_FreePrivKey; | |||
2985 | context->maxLen = MAX_ECKEY_LEN72 * 2; | |||
2986 | ||||
2987 | break; | |||
2988 | ||||
2989 | #define INIT_HMAC_MECH(mmm)case CKM_mmm_HMAC_GENERAL: ((pMechanism->pParameter)?((void )0):PR_Assert("pMechanism->pParameter","pkcs11c.c",2989)); if (!pMechanism->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit(pMechanism->mechanism, context, key , *(CK_ULONG *)pMechanism->pParameter); break; case CKM_mmm_HMAC : crv = sftk_doMACInit(pMechanism->mechanism, context, key , mmm_LENGTH); break; \ | |||
2990 | case CKM_##mmm##_HMAC_GENERAL: \ | |||
2991 | PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter)?((void)0):PR_Assert("pMechanism->pParameter" ,"pkcs11c.c",2991)); \ | |||
2992 | if (!pMechanism->pParameter) { \ | |||
2993 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; \ | |||
2994 | break; \ | |||
2995 | } \ | |||
2996 | crv = sftk_doMACInit(pMechanism->mechanism, context, key, \ | |||
2997 | *(CK_ULONG *)pMechanism->pParameter); \ | |||
2998 | break; \ | |||
2999 | case CKM_##mmm##_HMAC: \ | |||
3000 | crv = sftk_doMACInit(pMechanism->mechanism, context, key, \ | |||
3001 | mmm##_LENGTH); \ | |||
3002 | break; | |||
3003 | ||||
3004 | INIT_HMAC_MECH(MD2)case 0x00000202UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3004)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000201UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 16); break; | |||
3005 | INIT_HMAC_MECH(MD5)case 0x00000212UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3005)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000211UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 16); break; | |||
3006 | INIT_HMAC_MECH(SHA1)case 0x00000222UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3006)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000221UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 20); break; | |||
3007 | INIT_HMAC_MECH(SHA224)case 0x00000257UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3007)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000256UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 28); break; | |||
3008 | INIT_HMAC_MECH(SHA256)case 0x00000252UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3008)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000251UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 32); break; | |||
3009 | INIT_HMAC_MECH(SHA384)case 0x00000262UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3009)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000261UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 48); break; | |||
3010 | INIT_HMAC_MECH(SHA512)case 0x00000272UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3010)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000271UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 64); break; | |||
3011 | INIT_HMAC_MECH(SHA3_224)case 0x000002B7UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3011)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002B6UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 28); break; | |||
3012 | INIT_HMAC_MECH(SHA3_256)case 0x000002B2UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3012)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002B1UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 32); break; | |||
3013 | INIT_HMAC_MECH(SHA3_384)case 0x000002C2UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3013)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002C1UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 48); break; | |||
3014 | INIT_HMAC_MECH(SHA3_512)case 0x000002D2UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3014)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002D1UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 64); break; | |||
3015 | ||||
3016 | case CKM_AES_CMAC_GENERAL0x0000108BUL: | |||
3017 | PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter)?((void)0):PR_Assert("pMechanism->pParameter" ,"pkcs11c.c",3017)); | |||
3018 | if (!pMechanism->pParameter || pMechanism->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)) { | |||
3019 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3020 | break; | |||
3021 | } | |||
3022 | crv = sftk_doMACInit(pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism->pParameter); | |||
3023 | break; | |||
3024 | case CKM_AES_CMAC0x0000108AUL: | |||
3025 | crv = sftk_doMACInit(pMechanism->mechanism, context, key, AES_BLOCK_SIZE16); | |||
3026 | break; | |||
3027 | case CKM_SSL3_MD5_MAC0x00000380UL: | |||
3028 | PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter)?((void)0):PR_Assert("pMechanism->pParameter" ,"pkcs11c.c",3028)); | |||
3029 | if (!pMechanism->pParameter) { | |||
3030 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3031 | break; | |||
3032 | } | |||
3033 | crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key, | |||
3034 | *(CK_ULONG *)pMechanism->pParameter); | |||
3035 | break; | |||
3036 | case CKM_SSL3_SHA1_MAC0x00000381UL: | |||
3037 | PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter)?((void)0):PR_Assert("pMechanism->pParameter" ,"pkcs11c.c",3037)); | |||
3038 | if (!pMechanism->pParameter) { | |||
3039 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3040 | break; | |||
3041 | } | |||
3042 | crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key, | |||
3043 | *(CK_ULONG *)pMechanism->pParameter); | |||
3044 | break; | |||
3045 | case CKM_TLS_PRF_GENERAL0x80000373UL: | |||
3046 | crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0); | |||
3047 | break; | |||
3048 | case CKM_TLS_MAC0x000003E4UL: { | |||
3049 | CK_TLS_MAC_PARAMS *tls12_mac_params; | |||
3050 | HASH_HashType tlsPrfHash; | |||
3051 | const char *label; | |||
3052 | ||||
3053 | if (pMechanism->ulParameterLen != sizeof(CK_TLS_MAC_PARAMS)) { | |||
3054 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3055 | break; | |||
3056 | } | |||
3057 | tls12_mac_params = (CK_TLS_MAC_PARAMS *)pMechanism->pParameter; | |||
3058 | if (tls12_mac_params->prfHashMechanism == CKM_TLS_PRF0x00000378UL) { | |||
3059 | /* The TLS 1.0 and 1.1 PRF */ | |||
3060 | tlsPrfHash = HASH_AlgNULL; | |||
3061 | if (tls12_mac_params->ulMacLength != 12) { | |||
3062 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3063 | break; | |||
3064 | } | |||
3065 | } else { | |||
3066 | /* The hash function for the TLS 1.2 PRF */ | |||
3067 | tlsPrfHash = | |||
3068 | sftk_GetHashTypeFromMechanism(tls12_mac_params->prfHashMechanism); | |||
3069 | if (tlsPrfHash == HASH_AlgNULL || | |||
3070 | tls12_mac_params->ulMacLength < 12) { | |||
3071 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3072 | break; | |||
3073 | } | |||
3074 | } | |||
3075 | if (tls12_mac_params->ulServerOrClient == 1) { | |||
3076 | label = "server finished"; | |||
3077 | } else if (tls12_mac_params->ulServerOrClient == 2) { | |||
3078 | label = "client finished"; | |||
3079 | } else { | |||
3080 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3081 | break; | |||
3082 | } | |||
3083 | crv = sftk_TLSPRFInit(context, key, key_type, tlsPrfHash, | |||
3084 | tls12_mac_params->ulMacLength); | |||
3085 | if (crv == CKR_OK0x00000000UL) { | |||
3086 | context->hashUpdate(context->hashInfo, label, 15); | |||
3087 | } | |||
3088 | break; | |||
3089 | } | |||
3090 | case CKM_NSS_TLS_PRF_GENERAL_SHA256((0x80000000UL | 0x4E534350) + 21): | |||
3091 | crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0); | |||
3092 | break; | |||
3093 | ||||
3094 | case CKM_NSS_HMAC_CONSTANT_TIME((0x80000000UL | 0x4E534350) + 19): { | |||
3095 | sftk_MACConstantTimeCtx *ctx = | |||
3096 | sftk_HMACConstantTime_New(pMechanism, key); | |||
3097 | CK_ULONG *intpointer; | |||
3098 | ||||
3099 | if (ctx == NULL((void*)0)) { | |||
3100 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
3101 | break; | |||
3102 | } | |||
3103 | intpointer = PORT_New(CK_ULONG)(CK_ULONG *)PORT_Alloc_Util(sizeof(CK_ULONG)); | |||
3104 | if (intpointer == NULL((void*)0)) { | |||
3105 | PORT_FreePORT_Free_Util(ctx); | |||
3106 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
3107 | break; | |||
3108 | } | |||
3109 | *intpointer = ctx->hash->length; | |||
3110 | ||||
3111 | context->cipherInfo = intpointer; | |||
3112 | context->hashInfo = ctx; | |||
3113 | context->currentMech = pMechanism->mechanism; | |||
3114 | context->hashUpdate = sftk_HMACConstantTime_Update; | |||
3115 | context->hashdestroy = sftk_MACConstantTime_DestroyContext; | |||
3116 | context->end = sftk_MACConstantTime_EndHash; | |||
3117 | context->update = (SFTKCipher)sftk_SignCopy; | |||
3118 | context->destroy = sftk_Space; | |||
3119 | context->maxLen = 64; | |||
3120 | context->multi = PR_TRUE1; | |||
3121 | break; | |||
3122 | } | |||
3123 | ||||
3124 | case CKM_NSS_SSL3_MAC_CONSTANT_TIME((0x80000000UL | 0x4E534350) + 20): { | |||
3125 | sftk_MACConstantTimeCtx *ctx = | |||
3126 | sftk_SSLv3MACConstantTime_New(pMechanism, key); | |||
3127 | CK_ULONG *intpointer; | |||
3128 | ||||
3129 | if (ctx == NULL((void*)0)) { | |||
3130 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
3131 | break; | |||
3132 | } | |||
3133 | intpointer = PORT_New(CK_ULONG)(CK_ULONG *)PORT_Alloc_Util(sizeof(CK_ULONG)); | |||
3134 | if (intpointer == NULL((void*)0)) { | |||
3135 | PORT_FreePORT_Free_Util(ctx); | |||
3136 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
3137 | break; | |||
3138 | } | |||
3139 | *intpointer = ctx->hash->length; | |||
3140 | ||||
3141 | context->cipherInfo = intpointer; | |||
3142 | context->hashInfo = ctx; | |||
3143 | context->currentMech = pMechanism->mechanism; | |||
3144 | context->hashUpdate = sftk_SSLv3MACConstantTime_Update; | |||
3145 | context->hashdestroy = sftk_MACConstantTime_DestroyContext; | |||
3146 | context->end = sftk_MACConstantTime_EndHash; | |||
3147 | context->update = (SFTKCipher)sftk_SignCopy; | |||
3148 | context->destroy = sftk_Space; | |||
3149 | context->maxLen = 64; | |||
3150 | context->multi = PR_TRUE1; | |||
3151 | break; | |||
3152 | } | |||
3153 | ||||
3154 | default: | |||
3155 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
3156 | break; | |||
3157 | } | |||
3158 | ||||
3159 | if (crv != CKR_OK0x00000000UL) { | |||
3160 | if (info) | |||
3161 | PORT_FreePORT_Free_Util(info); | |||
3162 | if (pinfo) | |||
3163 | PORT_ZFreePORT_ZFree_Util(pinfo, pinfo->size); | |||
3164 | sftk_FreeContext(context); | |||
3165 | sftk_FreeSession(session); | |||
3166 | return crv; | |||
3167 | } | |||
3168 | sftk_SetContextByType(session, SFTK_SIGN, context); | |||
3169 | sftk_FreeSession(session); | |||
3170 | return CKR_OK0x00000000UL; | |||
3171 | } | |||
3172 | ||||
3173 | /** MAC one block of data by block cipher | |||
3174 | */ | |||
3175 | static CK_RV | |||
3176 | sftk_MACBlock(SFTKSessionContext *ctx, void *blk) | |||
3177 | { | |||
3178 | unsigned int outlen; | |||
3179 | return (SECSuccess == (ctx->update)(ctx->cipherInfo, ctx->macBuf, &outlen, | |||
3180 | SFTK_MAX_BLOCK_SIZE16, blk, ctx->blockSize)) | |||
3181 | ? CKR_OK0x00000000UL | |||
3182 | : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
3183 | } | |||
3184 | ||||
3185 | /** MAC last (incomplete) block of data by block cipher | |||
3186 | * | |||
3187 | * Call once, then terminate MACing operation. | |||
3188 | */ | |||
3189 | static CK_RV | |||
3190 | sftk_MACFinal(SFTKSessionContext *ctx) | |||
3191 | { | |||
3192 | unsigned int padLen = ctx->padDataLength; | |||
3193 | /* pad and proceed the residual */ | |||
3194 | if (ctx->isXCBC) { | |||
3195 | CK_RV crv = sftk_xcbc_mac_pad(ctx->padBuf, padLen, ctx->blockSize, | |||
3196 | ctx->k2, ctx->k3); | |||
3197 | if (crv != CKR_OK0x00000000UL) | |||
3198 | return crv; | |||
3199 | return sftk_MACBlock(ctx, ctx->padBuf); | |||
3200 | } | |||
3201 | if (padLen) { | |||
3202 | /* shd clr ctx->padLen to make sftk_MACFinal idempotent */ | |||
3203 | PORT_Memsetmemset(ctx->padBuf + padLen, 0, ctx->blockSize - padLen); | |||
3204 | return sftk_MACBlock(ctx, ctx->padBuf); | |||
3205 | } else | |||
3206 | return CKR_OK0x00000000UL; | |||
3207 | } | |||
3208 | ||||
3209 | /** The common implementation for {Sign,Verify}Update. (S/V only vary in their | |||
3210 | * setup and final operations). | |||
3211 | * | |||
3212 | * A call which results in an error terminates the operation [PKCS#11,v2.11] | |||
3213 | */ | |||
3214 | static CK_RV | |||
3215 | sftk_MACUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, | |||
3216 | CK_ULONG ulPartLen, SFTKContextType type) | |||
3217 | { | |||
3218 | SFTKSession *session; | |||
3219 | SFTKSessionContext *context; | |||
3220 | CK_RV crv; | |||
3221 | ||||
3222 | /* make sure we're legal */ | |||
3223 | crv = sftk_GetContext(hSession, &context, type, PR_TRUE1, &session); | |||
3224 | if (crv != CKR_OK0x00000000UL) | |||
3225 | return crv; | |||
3226 | ||||
3227 | if (context->hashInfo) { | |||
3228 | #if (ULONG_MAX(9223372036854775807L *2UL+1UL) > UINT_MAX(2147483647 *2U +1U)) | |||
3229 | while (ulPartLen > UINT_MAX(2147483647 *2U +1U)) { | |||
3230 | (*context->hashUpdate)(context->cipherInfo, pPart, UINT_MAX(2147483647 *2U +1U)); | |||
3231 | pPart += UINT_MAX(2147483647 *2U +1U); | |||
3232 | ulPartLen -= UINT_MAX(2147483647 *2U +1U); | |||
3233 | } | |||
3234 | #endif | |||
3235 | (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen); | |||
3236 | } else { | |||
3237 | /* must be block cipher MACing */ | |||
3238 | ||||
3239 | unsigned int blkSize = context->blockSize; | |||
3240 | unsigned char *residual = /* free room in context->padBuf */ | |||
3241 | context->padBuf + context->padDataLength; | |||
3242 | unsigned int minInput = /* min input for MACing at least one block */ | |||
3243 | blkSize - context->padDataLength; | |||
3244 | ||||
3245 | /* not enough data even for one block */ | |||
3246 | if (ulPartLen <= minInput) { | |||
3247 | PORT_Memcpymemcpy(residual, pPart, ulPartLen); | |||
3248 | context->padDataLength += ulPartLen; | |||
3249 | goto cleanup; | |||
3250 | } | |||
3251 | /* MACing residual */ | |||
3252 | if (context->padDataLength) { | |||
3253 | PORT_Memcpymemcpy(residual, pPart, minInput); | |||
3254 | ulPartLen -= minInput; | |||
3255 | pPart += minInput; | |||
3256 | if (CKR_OK0x00000000UL != (crv = sftk_MACBlock(context, context->padBuf))) | |||
3257 | goto terminate; | |||
3258 | } | |||
3259 | /* MACing full blocks */ | |||
3260 | while (ulPartLen > blkSize) { | |||
3261 | if (CKR_OK0x00000000UL != (crv = sftk_MACBlock(context, pPart))) | |||
3262 | goto terminate; | |||
3263 | ulPartLen -= blkSize; | |||
3264 | pPart += blkSize; | |||
3265 | } | |||
3266 | /* save the residual */ | |||
3267 | if ((context->padDataLength = ulPartLen)) | |||
3268 | PORT_Memcpymemcpy(context->padBuf, pPart, ulPartLen); | |||
3269 | } /* blk cipher MACing */ | |||
3270 | ||||
3271 | goto cleanup; | |||
3272 | ||||
3273 | terminate: | |||
3274 | sftk_TerminateOp(session, type, context); | |||
3275 | cleanup: | |||
3276 | sftk_FreeSession(session); | |||
3277 | return crv; | |||
3278 | } | |||
3279 | ||||
3280 | /* NSC_SignUpdate continues a multiple-part signature operation, | |||
3281 | * where the signature is (will be) an appendix to the data, | |||
3282 | * and plaintext cannot be recovered from the signature | |||
3283 | * | |||
3284 | * A call which results in an error terminates the operation [PKCS#11,v2.11] | |||
3285 | */ | |||
3286 | CK_RV | |||
3287 | NSC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, | |||
3288 | CK_ULONG ulPartLen) | |||
3289 | { | |||
3290 | CHECK_FORK(); | |||
3291 | return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN); | |||
3292 | } | |||
3293 | ||||
3294 | struct SFTK_SESSION_FLAGS { | |||
3295 | CK_FLAGS flag; | |||
3296 | SFTKContextType type; | |||
3297 | }; | |||
3298 | ||||
3299 | const static struct SFTK_SESSION_FLAGS sftk_session_flags[] = { | |||
3300 | { CKF_ENCRYPT0x00000100UL, SFTK_ENCRYPT }, | |||
3301 | { CKF_DECRYPT0x00000200UL, SFTK_DECRYPT }, | |||
3302 | { CKF_DIGEST0x00000400UL, SFTK_HASH }, | |||
3303 | { CKF_SIGN0x00000800UL, SFTK_SIGN }, | |||
3304 | { CKF_SIGN_RECOVER0x00001000UL, SFTK_SIGN_RECOVER }, | |||
3305 | { CKF_VERIFY0x00002000, SFTK_VERIFY }, | |||
3306 | { CKF_VERIFY_RECOVER0x00004000UL, SFTK_VERIFY_RECOVER }, | |||
3307 | { CKF_MESSAGE_ENCRYPT0x00000002UL, SFTK_MESSAGE_ENCRYPT }, | |||
3308 | { CKF_MESSAGE_DECRYPT0x00000004UL, SFTK_MESSAGE_DECRYPT }, | |||
3309 | { CKF_MESSAGE_SIGN0x00000008UL, SFTK_MESSAGE_SIGN }, | |||
3310 | { CKF_MESSAGE_VERIFY0x00000010UL, SFTK_MESSAGE_VERIFY }, | |||
3311 | }; | |||
3312 | const static int sftk_flag_count = PR_ARRAY_SIZE(sftk_session_flags)(sizeof(sftk_session_flags)/sizeof((sftk_session_flags)[0])); | |||
3313 | ||||
3314 | /* | |||
3315 | * Cancel one or more operations running on the existing session. | |||
3316 | */ | |||
3317 | CK_RV | |||
3318 | NSC_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags) | |||
3319 | { | |||
3320 | SFTKSession *session; | |||
3321 | SFTKSessionContext *context; | |||
3322 | CK_RV gcrv = CKR_OK0x00000000UL; | |||
3323 | CK_RV crv; | |||
3324 | int i; | |||
3325 | ||||
3326 | for (i = 0; i < sftk_flag_count; i++) { | |||
3327 | if (flags & sftk_session_flags[i].flag) { | |||
3328 | flags &= ~sftk_session_flags[i].flag; | |||
3329 | crv = sftk_GetContext(hSession, &context, sftk_session_flags[i].type, PR_TRUE1, &session); | |||
3330 | if (crv != CKR_OK0x00000000UL) { | |||
3331 | gcrv = CKR_OPERATION_CANCEL_FAILED0x00000202UL; | |||
3332 | continue; | |||
3333 | } | |||
3334 | sftk_TerminateOp(session, sftk_session_flags[i].type, context); | |||
3335 | } | |||
3336 | } | |||
3337 | if (flags & CKF_FIND_OBJECTS0x00000040UL) { | |||
3338 | flags &= ~CKF_FIND_OBJECTS0x00000040UL; | |||
3339 | crv = NSC_FindObjectsFinal(hSession); | |||
3340 | if (crv != CKR_OK0x00000000UL) { | |||
3341 | gcrv = CKR_OPERATION_CANCEL_FAILED0x00000202UL; | |||
3342 | } | |||
3343 | } | |||
3344 | if (flags) { | |||
3345 | gcrv = CKR_OPERATION_CANCEL_FAILED0x00000202UL; | |||
3346 | } | |||
3347 | return gcrv; | |||
3348 | } | |||
3349 | ||||
3350 | /* NSC_SignFinal finishes a multiple-part signature operation, | |||
3351 | * returning the signature. */ | |||
3352 | CK_RV | |||
3353 | NSC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, | |||
3354 | CK_ULONG_PTR pulSignatureLen) | |||
3355 | { | |||
3356 | SFTKSession *session; | |||
3357 | SFTKSessionContext *context; | |||
3358 | unsigned int outlen; | |||
3359 | unsigned int maxoutlen = *pulSignatureLen; | |||
3360 | CK_RV crv; | |||
3361 | ||||
3362 | CHECK_FORK(); | |||
3363 | ||||
3364 | /* make sure we're legal */ | |||
3365 | crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_TRUE1, &session); | |||
3366 | if (crv != CKR_OK0x00000000UL) | |||
3367 | return crv; | |||
3368 | ||||
3369 | if (context->hashInfo) { | |||
3370 | unsigned int digestLen; | |||
3371 | unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH64]; | |||
3372 | ||||
3373 | if (!pSignature) { | |||
3374 | outlen = context->maxLen; | |||
3375 | goto finish; | |||
3376 | } | |||
3377 | (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf)); | |||
3378 | if (SECSuccess != (context->update)(context->cipherInfo, pSignature, | |||
3379 | &outlen, maxoutlen, tmpbuf, digestLen)) | |||
3380 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
3381 | /* CKR_BUFFER_TOO_SMALL here isn't continuable, let operation terminate. | |||
3382 | * Keeping "too small" CK_RV intact is a standard violation, but allows | |||
3383 | * application read EXACT signature length */ | |||
3384 | PORT_Memsetmemset(tmpbuf, 0, sizeof tmpbuf); | |||
3385 | } else { | |||
3386 | /* must be block cipher MACing */ | |||
3387 | outlen = context->macSize; | |||
3388 | /* null or "too small" buf doesn't terminate operation [PKCS#11,v2.11]*/ | |||
3389 | if (!pSignature || maxoutlen < outlen) { | |||
3390 | if (pSignature) | |||
3391 | crv = CKR_BUFFER_TOO_SMALL0x00000150UL; | |||
3392 | goto finish; | |||
3393 | } | |||
3394 | if (CKR_OK0x00000000UL == (crv = sftk_MACFinal(context))) | |||
3395 | PORT_Memcpymemcpy(pSignature, context->macBuf, outlen); | |||
3396 | } | |||
3397 | ||||
3398 | sftk_TerminateOp(session, SFTK_SIGN, context); | |||
3399 | finish: | |||
3400 | *pulSignatureLen = outlen; | |||
3401 | sftk_FreeSession(session); | |||
3402 | return crv; | |||
3403 | } | |||
3404 | ||||
3405 | /* NSC_Sign signs (encrypts with private key) data in a single part, | |||
3406 | * where the signature is (will be) an appendix to the data, | |||
3407 | * and plaintext cannot be recovered from the signature */ | |||
3408 | CK_RV | |||
3409 | NSC_Sign(CK_SESSION_HANDLE hSession, | |||
3410 | CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, | |||
3411 | CK_ULONG_PTR pulSignatureLen) | |||
3412 | { | |||
3413 | SFTKSession *session; | |||
3414 | SFTKSessionContext *context; | |||
3415 | CK_RV crv; | |||
3416 | ||||
3417 | CHECK_FORK(); | |||
3418 | ||||
3419 | /* make sure we're legal */ | |||
3420 | crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_FALSE0, &session); | |||
3421 | if (crv != CKR_OK0x00000000UL) | |||
3422 | return crv; | |||
3423 | ||||
3424 | if (!pSignature) { | |||
3425 | /* see also how C_SignUpdate implements this */ | |||
3426 | *pulSignatureLen = (!context->multi || context->hashInfo) | |||
3427 | ? context->maxLen | |||
3428 | : context->macSize; /* must be block cipher MACing */ | |||
3429 | goto finish; | |||
3430 | } | |||
3431 | ||||
3432 | /* multi part Signing are completely implemented by SignUpdate and | |||
3433 | * sign Final */ | |||
3434 | if (context->multi) { | |||
3435 | /* SignFinal can't follow failed SignUpdate */ | |||
3436 | if (CKR_OK0x00000000UL == (crv = NSC_SignUpdate(hSession, pData, ulDataLen))) | |||
3437 | crv = NSC_SignFinal(hSession, pSignature, pulSignatureLen); | |||
3438 | } else { | |||
3439 | /* single-part PKC signature (e.g. CKM_ECDSA) */ | |||
3440 | unsigned int outlen; | |||
3441 | unsigned int maxoutlen = *pulSignatureLen; | |||
3442 | if (SECSuccess != (*context->update)(context->cipherInfo, pSignature, | |||
3443 | &outlen, maxoutlen, pData, ulDataLen)) | |||
3444 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
3445 | *pulSignatureLen = (CK_ULONG)outlen; | |||
3446 | /* "too small" here is certainly continuable */ | |||
3447 | if (crv != CKR_BUFFER_TOO_SMALL0x00000150UL) | |||
3448 | sftk_TerminateOp(session, SFTK_SIGN, context); | |||
3449 | } /* single-part */ | |||
3450 | ||||
3451 | finish: | |||
3452 | sftk_FreeSession(session); | |||
3453 | return crv; | |||
3454 | } | |||
3455 | ||||
3456 | /* | |||
3457 | ************** Crypto Functions: Sign Recover ************************ | |||
3458 | */ | |||
3459 | /* NSC_SignRecoverInit initializes a signature operation, | |||
3460 | * where the (digest) data can be recovered from the signature. | |||
3461 | * E.g. encryption with the user's private key */ | |||
3462 | CK_RV | |||
3463 | NSC_SignRecoverInit(CK_SESSION_HANDLE hSession, | |||
3464 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) | |||
3465 | { | |||
3466 | CHECK_FORK(); | |||
3467 | ||||
3468 | switch (pMechanism->mechanism) { | |||
3469 | case CKM_RSA_PKCS0x00000001UL: | |||
3470 | case CKM_RSA_X_5090x00000003UL: | |||
3471 | return NSC_SignInit(hSession, pMechanism, hKey); | |||
3472 | default: | |||
3473 | break; | |||
3474 | } | |||
3475 | return CKR_MECHANISM_INVALID0x00000070UL; | |||
3476 | } | |||
3477 | ||||
3478 | /* NSC_SignRecover signs data in a single operation | |||
3479 | * where the (digest) data can be recovered from the signature. | |||
3480 | * E.g. encryption with the user's private key */ | |||
3481 | CK_RV | |||
3482 | NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, | |||
3483 | CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) | |||
3484 | { | |||
3485 | CHECK_FORK(); | |||
3486 | ||||
3487 | return NSC_Sign(hSession, pData, ulDataLen, pSignature, pulSignatureLen); | |||
3488 | } | |||
3489 | ||||
3490 | /* | |||
3491 | ************** Crypto Functions: verify ************************ | |||
3492 | */ | |||
3493 | ||||
3494 | /* Handle RSA Signature formatting */ | |||
3495 | static SECStatus | |||
3496 | sftk_hashCheckSign(SFTKHashVerifyInfo *info, const unsigned char *sig, | |||
3497 | unsigned int sigLen, const unsigned char *digest, | |||
3498 | unsigned int digestLen) | |||
3499 | { | |||
3500 | PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert ("info->key->keyType == NSSLOWKEYRSAKey","pkcs11c.c",3500 )); | |||
3501 | if (info->key->keyType != NSSLOWKEYRSAKey) { | |||
3502 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
3503 | return SECFailure; | |||
3504 | } | |||
3505 | ||||
3506 | return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, digest, | |||
3507 | digestLen); | |||
3508 | } | |||
3509 | ||||
3510 | SECStatus | |||
3511 | RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key, | |||
3512 | const unsigned char *sig, unsigned int sigLen, | |||
3513 | const unsigned char *digestData, unsigned int digestLen) | |||
3514 | { | |||
3515 | unsigned char *pkcs1DigestInfoData; | |||
3516 | SECItem pkcs1DigestInfo; | |||
3517 | SECItem digest; | |||
3518 | unsigned int bufferSize; | |||
3519 | SECStatus rv; | |||
3520 | ||||
3521 | /* pkcs1DigestInfo.data must be less than key->u.rsa.modulus.len */ | |||
3522 | bufferSize = key->u.rsa.modulus.len; | |||
3523 | pkcs1DigestInfoData = PORT_ZAllocPORT_ZAlloc_Util(bufferSize); | |||
3524 | if (!pkcs1DigestInfoData) { | |||
3525 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MEMORY); | |||
3526 | return SECFailure; | |||
3527 | } | |||
3528 | ||||
3529 | pkcs1DigestInfo.data = pkcs1DigestInfoData; | |||
3530 | pkcs1DigestInfo.len = bufferSize; | |||
3531 | ||||
3532 | /* decrypt the block */ | |||
3533 | rv = RSA_CheckSignRecover(&key->u.rsa, pkcs1DigestInfo.data, | |||
3534 | &pkcs1DigestInfo.len, pkcs1DigestInfo.len, | |||
3535 | sig, sigLen); | |||
3536 | if (rv != SECSuccess) { | |||
3537 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_SIGNATURE); | |||
3538 | } else { | |||
3539 | digest.data = (PRUint8 *)digestData; | |||
3540 | digest.len = digestLen; | |||
3541 | rv = _SGN_VerifyPKCS1DigestInfo( | |||
3542 | digestOid, &digest, &pkcs1DigestInfo, | |||
3543 | PR_FALSE0 /*XXX: unsafeAllowMissingParameters*/); | |||
3544 | } | |||
3545 | ||||
3546 | PORT_ZFreePORT_ZFree_Util(pkcs1DigestInfoData, bufferSize); | |||
3547 | return rv; | |||
3548 | } | |||
3549 | ||||
3550 | static SECStatus | |||
3551 | sftk_RSACheckSign(NSSLOWKEYPublicKey *key, const unsigned char *sig, | |||
3552 | unsigned int sigLen, const unsigned char *digest, | |||
3553 | unsigned int digestLen) | |||
3554 | { | |||
3555 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",3555)); | |||
3556 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
3557 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
3558 | return SECFailure; | |||
3559 | } | |||
3560 | ||||
3561 | return RSA_CheckSign(&key->u.rsa, sig, sigLen, digest, digestLen); | |||
3562 | } | |||
3563 | ||||
3564 | static SECStatus | |||
3565 | sftk_RSACheckSignRaw(NSSLOWKEYPublicKey *key, const unsigned char *sig, | |||
3566 | unsigned int sigLen, const unsigned char *digest, | |||
3567 | unsigned int digestLen) | |||
3568 | { | |||
3569 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",3569)); | |||
3570 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
3571 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
3572 | return SECFailure; | |||
3573 | } | |||
3574 | ||||
3575 | return RSA_CheckSignRaw(&key->u.rsa, sig, sigLen, digest, digestLen); | |||
3576 | } | |||
3577 | ||||
3578 | static SECStatus | |||
3579 | sftk_RSACheckSignPSS(SFTKPSSVerifyInfo *info, const unsigned char *sig, | |||
3580 | unsigned int sigLen, const unsigned char *digest, | |||
3581 | unsigned int digestLen) | |||
3582 | { | |||
3583 | HASH_HashType hashAlg; | |||
3584 | HASH_HashType maskHashAlg; | |||
3585 | CK_RSA_PKCS_PSS_PARAMS *params = &info->params; | |||
3586 | ||||
3587 | PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert ("info->key->keyType == NSSLOWKEYRSAKey","pkcs11c.c",3587 )); | |||
3588 | if (info->key->keyType != NSSLOWKEYRSAKey) { | |||
3589 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
3590 | return SECFailure; | |||
3591 | } | |||
3592 | ||||
3593 | hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg); | |||
3594 | maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf); | |||
3595 | ||||
3596 | return RSA_CheckSignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, | |||
3597 | params->sLen, sig, sigLen, digest, digestLen); | |||
3598 | } | |||
3599 | ||||
3600 | /* NSC_VerifyInit initializes a verification operation, | |||
3601 | * where the signature is an appendix to the data, | |||
3602 | * and plaintext cannot be recovered from the signature (e.g. DSA) */ | |||
3603 | CK_RV | |||
3604 | NSC_VerifyInit(CK_SESSION_HANDLE hSession, | |||
3605 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) | |||
3606 | { | |||
3607 | SFTKSession *session; | |||
3608 | SFTKObject *key; | |||
3609 | SFTKSessionContext *context; | |||
3610 | CK_KEY_TYPE key_type; | |||
3611 | CK_RV crv = CKR_OK0x00000000UL; | |||
3612 | NSSLOWKEYPublicKey *pubKey; | |||
3613 | SFTKHashVerifyInfo *info = NULL((void*)0); | |||
3614 | SFTKPSSVerifyInfo *pinfo = NULL((void*)0); | |||
3615 | ||||
3616 | CHECK_FORK(); | |||
3617 | ||||
3618 | /* Block Cipher MACing Algorithms use a different Context init method..*/ | |||
3619 | crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY0x0000010AUL, SFTK_VERIFY); | |||
3620 | if (crv != CKR_FUNCTION_NOT_SUPPORTED0x00000054UL) | |||
3621 | return crv; | |||
3622 | ||||
3623 | session = sftk_SessionFromHandle(hSession); | |||
3624 | if (session == NULL((void*)0)) | |||
3625 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
3626 | crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_VERIFY, &key, | |||
3627 | hKey, &key_type, CKO_PUBLIC_KEY0x00000002UL, CKA_VERIFY0x0000010AUL); | |||
3628 | if (crv != CKR_OK0x00000000UL) { | |||
3629 | sftk_FreeSession(session); | |||
3630 | return crv; | |||
3631 | } | |||
3632 | ||||
3633 | context->multi = PR_FALSE0; | |||
3634 | ||||
3635 | #define INIT_RSA_VFY_MECH(mmm)case CKM_mmm_RSA_PKCS: context->multi = 1; crv = sftk_doSubmmm (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_mmm ; goto finish_rsa; \ | |||
3636 | case CKM_##mmm##_RSA_PKCS: \ | |||
3637 | context->multi = PR_TRUE1; \ | |||
3638 | crv = sftk_doSub##mmm(context); \ | |||
3639 | if (crv != CKR_OK0x00000000UL) \ | |||
3640 | break; \ | |||
3641 | context->verify = (SFTKVerify)sftk_hashCheckSign; \ | |||
3642 | info = PORT_New(SFTKHashVerifyInfo)(SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo )); \ | |||
3643 | if (info == NULL((void*)0)) { \ | |||
3644 | crv = CKR_HOST_MEMORY0x00000002UL; \ | |||
3645 | break; \ | |||
3646 | } \ | |||
3647 | info->hashOid = SEC_OID_##mmm; \ | |||
3648 | goto finish_rsa; | |||
3649 | ||||
3650 | switch (pMechanism->mechanism) { | |||
3651 | INIT_RSA_VFY_MECH(MD5)case 0x00000005UL: context->multi = 1; crv = sftk_doSubMD5 (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_MD5 ; goto finish_rsa; | |||
3652 | INIT_RSA_VFY_MECH(MD2)case 0x00000004UL: context->multi = 1; crv = sftk_doSubMD2 (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_MD2 ; goto finish_rsa; | |||
3653 | INIT_RSA_VFY_MECH(SHA1)case 0x00000006UL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_SHA1 ; goto finish_rsa; | |||
3654 | INIT_RSA_VFY_MECH(SHA224)case 0x00000046UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_SHA224 ; goto finish_rsa; | |||
3655 | INIT_RSA_VFY_MECH(SHA256)case 0x00000040UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_SHA256 ; goto finish_rsa; | |||
3656 | INIT_RSA_VFY_MECH(SHA384)case 0x00000041UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_SHA384 ; goto finish_rsa; | |||
3657 | INIT_RSA_VFY_MECH(SHA512)case 0x00000042UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; context->verify = (SFTKVerify)sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo)); if (info == ( (void*)0)) { crv = 0x00000002UL; break; } info->hashOid = SEC_OID_SHA512 ; goto finish_rsa; | |||
3658 | ||||
3659 | case CKM_RSA_PKCS0x00000001UL: | |||
3660 | context->verify = (SFTKVerify)sftk_RSACheckSign; | |||
3661 | goto finish_rsa; | |||
3662 | case CKM_RSA_X_5090x00000003UL: | |||
3663 | context->verify = (SFTKVerify)sftk_RSACheckSignRaw; | |||
3664 | finish_rsa: | |||
3665 | if (key_type != CKK_RSA0x00000000UL) { | |||
3666 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3667 | break; | |||
3668 | } | |||
3669 | context->rsa = PR_TRUE1; | |||
3670 | pubKey = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv); | |||
3671 | if (pubKey == NULL((void*)0)) { | |||
3672 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3673 | break; | |||
3674 | } | |||
3675 | if (info) { | |||
3676 | info->key = pubKey; | |||
3677 | context->cipherInfo = info; | |||
3678 | context->destroy = sftk_Space; | |||
3679 | } else { | |||
3680 | context->cipherInfo = pubKey; | |||
3681 | context->destroy = sftk_Null; | |||
3682 | } | |||
3683 | break; | |||
3684 | ||||
3685 | INIT_RSA_PSS_SIG_MECH(SHA1)case 0x0000000EUL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000220UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
3686 | INIT_RSA_PSS_SIG_MECH(SHA224)case 0x00000047UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000255UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
3687 | INIT_RSA_PSS_SIG_MECH(SHA256)case 0x00000043UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000250UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
3688 | INIT_RSA_PSS_SIG_MECH(SHA384)case 0x00000044UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000260UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
3689 | INIT_RSA_PSS_SIG_MECH(SHA512)case 0x00000045UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; if (pMechanism-> ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { crv = 0x00000071UL ; break; } if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism-> pParameter)->hashAlg != 0x00000270UL) { crv = 0x00000071UL ; break; } goto finish_rsa_pss; | |||
3690 | case CKM_RSA_PKCS_PSS0x0000000DUL: | |||
3691 | finish_rsa_pss: | |||
3692 | if (key_type != CKK_RSA0x00000000UL) { | |||
3693 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3694 | break; | |||
3695 | } | |||
3696 | context->rsa = PR_TRUE1; | |||
3697 | if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) || | |||
3698 | !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) { | |||
3699 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3700 | break; | |||
3701 | } | |||
3702 | pinfo = PORT_New(SFTKPSSVerifyInfo)(SFTKPSSVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKPSSVerifyInfo )); | |||
3703 | if (pinfo == NULL((void*)0)) { | |||
3704 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
3705 | break; | |||
3706 | } | |||
3707 | pinfo->size = sizeof(SFTKPSSVerifyInfo); | |||
3708 | pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; | |||
3709 | pinfo->key = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv); | |||
3710 | if (pinfo->key == NULL((void*)0)) { | |||
3711 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3712 | break; | |||
3713 | } | |||
3714 | context->cipherInfo = pinfo; | |||
3715 | context->destroy = (SFTKDestroy)sftk_ZSpace; | |||
3716 | context->verify = (SFTKVerify)sftk_RSACheckSignPSS; | |||
3717 | break; | |||
3718 | ||||
3719 | INIT_DSA_SIG_MECH(SHA1)case 0x00000012UL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
3720 | INIT_DSA_SIG_MECH(SHA224)case 0x00000013UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
3721 | INIT_DSA_SIG_MECH(SHA256)case 0x00000014UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
3722 | INIT_DSA_SIG_MECH(SHA384)case 0x00000015UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
3723 | INIT_DSA_SIG_MECH(SHA512)case 0x00000016UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; goto finish_dsa; | |||
3724 | case CKM_DSA0x00000011UL: | |||
3725 | finish_dsa: | |||
3726 | if (key_type != CKK_DSA0x00000001UL) { | |||
3727 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3728 | break; | |||
3729 | } | |||
3730 | pubKey = sftk_GetPubKey(key, CKK_DSA0x00000001UL, &crv); | |||
3731 | if (pubKey == NULL((void*)0)) { | |||
3732 | break; | |||
3733 | } | |||
3734 | context->cipherInfo = pubKey; | |||
3735 | context->verify = (SFTKVerify)nsc_DSA_Verify_Stub; | |||
3736 | context->destroy = sftk_Null; | |||
3737 | break; | |||
3738 | ||||
3739 | INIT_ECDSA_SIG_MECH(SHA1)case 0x00001042UL: context->multi = 1; crv = sftk_doSubSHA1 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
3740 | INIT_ECDSA_SIG_MECH(SHA224)case 0x00001043UL: context->multi = 1; crv = sftk_doSubSHA224 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
3741 | INIT_ECDSA_SIG_MECH(SHA256)case 0x00001044UL: context->multi = 1; crv = sftk_doSubSHA256 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
3742 | INIT_ECDSA_SIG_MECH(SHA384)case 0x00001045UL: context->multi = 1; crv = sftk_doSubSHA384 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
3743 | INIT_ECDSA_SIG_MECH(SHA512)case 0x00001046UL: context->multi = 1; crv = sftk_doSubSHA512 (context); if (crv != 0x00000000UL) break; goto finish_ecdsa; | |||
3744 | case CKM_ECDSA0x00001041UL: | |||
3745 | finish_ecdsa: | |||
3746 | if (key_type != CKK_EC0x00000003UL) { | |||
3747 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3748 | break; | |||
3749 | } | |||
3750 | pubKey = sftk_GetPubKey(key, CKK_EC0x00000003UL, &crv); | |||
3751 | if (pubKey == NULL((void*)0)) { | |||
3752 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
3753 | break; | |||
3754 | } | |||
3755 | context->cipherInfo = pubKey; | |||
3756 | context->verify = (SFTKVerify)nsc_ECDSAVerifyStub; | |||
3757 | context->destroy = sftk_Null; | |||
3758 | break; | |||
3759 | ||||
3760 | INIT_HMAC_MECH(MD2)case 0x00000202UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3760)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000201UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 16); break; | |||
3761 | INIT_HMAC_MECH(MD5)case 0x00000212UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3761)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000211UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 16); break; | |||
3762 | INIT_HMAC_MECH(SHA1)case 0x00000222UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3762)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000221UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 20); break; | |||
3763 | INIT_HMAC_MECH(SHA224)case 0x00000257UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3763)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000256UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 28); break; | |||
3764 | INIT_HMAC_MECH(SHA256)case 0x00000252UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3764)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000251UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 32); break; | |||
3765 | INIT_HMAC_MECH(SHA384)case 0x00000262UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3765)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000261UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 48); break; | |||
3766 | INIT_HMAC_MECH(SHA512)case 0x00000272UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3766)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x00000271UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 64); break; | |||
3767 | INIT_HMAC_MECH(SHA3_224)case 0x000002B7UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3767)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002B6UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 28); break; | |||
3768 | INIT_HMAC_MECH(SHA3_256)case 0x000002B2UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3768)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002B1UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 32); break; | |||
3769 | INIT_HMAC_MECH(SHA3_384)case 0x000002C2UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3769)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002C1UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 48); break; | |||
3770 | INIT_HMAC_MECH(SHA3_512)case 0x000002D2UL: ((pMechanism->pParameter)?((void)0):PR_Assert ("pMechanism->pParameter","pkcs11c.c",3770)); if (!pMechanism ->pParameter) { crv = 0x00000071UL; break; } crv = sftk_doMACInit (pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism ->pParameter); break; case 0x000002D1UL: crv = sftk_doMACInit (pMechanism->mechanism, context, key, 64); break; | |||
3771 | ||||
3772 | case CKM_EDDSA0x00001057UL: | |||
3773 | if (key_type != CKK_EC_EDWARDS0x00000040UL) { | |||
3774 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3775 | break; | |||
3776 | } | |||
3777 | pubKey = sftk_GetPubKey(key, CKK_EC_EDWARDS0x00000040UL, &crv); | |||
3778 | if (pubKey == NULL((void*)0)) { | |||
3779 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
3780 | break; | |||
3781 | } | |||
3782 | ||||
3783 | if (pMechanism->pParameter) { | |||
3784 | crv = CKR_FUNCTION_NOT_SUPPORTED0x00000054UL; | |||
3785 | break; | |||
3786 | } | |||
3787 | ||||
3788 | context->cipherInfo = pubKey; | |||
3789 | context->verify = (SFTKVerify)nsc_EDDSAVerifyStub; | |||
3790 | context->destroy = sftk_Null; | |||
3791 | break; | |||
3792 | ||||
3793 | case CKM_SSL3_MD5_MAC0x00000380UL: | |||
3794 | PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter)?((void)0):PR_Assert("pMechanism->pParameter" ,"pkcs11c.c",3794)); | |||
3795 | if (!pMechanism->pParameter) { | |||
3796 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3797 | break; | |||
3798 | } | |||
3799 | crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key, | |||
3800 | *(CK_ULONG *)pMechanism->pParameter); | |||
3801 | break; | |||
3802 | case CKM_SSL3_SHA1_MAC0x00000381UL: | |||
3803 | PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter)?((void)0):PR_Assert("pMechanism->pParameter" ,"pkcs11c.c",3803)); | |||
3804 | if (!pMechanism->pParameter) { | |||
3805 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
3806 | break; | |||
3807 | } | |||
3808 | crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key, | |||
3809 | *(CK_ULONG *)pMechanism->pParameter); | |||
3810 | break; | |||
3811 | case CKM_TLS_PRF_GENERAL0x80000373UL: | |||
3812 | crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0); | |||
3813 | break; | |||
3814 | case CKM_NSS_TLS_PRF_GENERAL_SHA256((0x80000000UL | 0x4E534350) + 21): | |||
3815 | crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0); | |||
3816 | break; | |||
3817 | ||||
3818 | default: | |||
3819 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
3820 | break; | |||
3821 | } | |||
3822 | ||||
3823 | if (crv != CKR_OK0x00000000UL) { | |||
3824 | if (info) | |||
3825 | PORT_FreePORT_Free_Util(info); | |||
3826 | if (pinfo) | |||
3827 | PORT_ZFreePORT_ZFree_Util(pinfo, pinfo->size); | |||
3828 | sftk_FreeContext(context); | |||
3829 | sftk_FreeSession(session); | |||
3830 | return crv; | |||
3831 | } | |||
3832 | sftk_SetContextByType(session, SFTK_VERIFY, context); | |||
3833 | sftk_FreeSession(session); | |||
3834 | return CKR_OK0x00000000UL; | |||
3835 | } | |||
3836 | ||||
3837 | /* NSC_Verify verifies a signature in a single-part operation, | |||
3838 | * where the signature is an appendix to the data, | |||
3839 | * and plaintext cannot be recovered from the signature */ | |||
3840 | CK_RV | |||
3841 | NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, | |||
3842 | CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) | |||
3843 | { | |||
3844 | SFTKSession *session; | |||
3845 | SFTKSessionContext *context; | |||
3846 | CK_RV crv; | |||
3847 | ||||
3848 | CHECK_FORK(); | |||
3849 | ||||
3850 | /* make sure we're legal */ | |||
3851 | crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE0, &session); | |||
3852 | if (crv != CKR_OK0x00000000UL) | |||
3853 | return crv; | |||
3854 | ||||
3855 | /* multi part Verifying are completely implemented by VerifyUpdate and | |||
3856 | * VerifyFinal */ | |||
3857 | if (context->multi) { | |||
3858 | /* VerifyFinal can't follow failed VerifyUpdate */ | |||
3859 | if (CKR_OK0x00000000UL == (crv = NSC_VerifyUpdate(hSession, pData, ulDataLen))) | |||
3860 | crv = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen); | |||
3861 | } else { | |||
3862 | if (SECSuccess != (*context->verify)(context->cipherInfo, pSignature, | |||
3863 | ulSignatureLen, pData, ulDataLen)) | |||
3864 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
3865 | ||||
3866 | sftk_TerminateOp(session, SFTK_VERIFY, context); | |||
3867 | } | |||
3868 | sftk_FreeSession(session); | |||
3869 | return crv; | |||
3870 | } | |||
3871 | ||||
3872 | /* NSC_VerifyUpdate continues a multiple-part verification operation, | |||
3873 | * where the signature is an appendix to the data, | |||
3874 | * and plaintext cannot be recovered from the signature | |||
3875 | * | |||
3876 | * A call which results in an error terminates the operation [PKCS#11,v2.11] | |||
3877 | */ | |||
3878 | CK_RV | |||
3879 | NSC_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, | |||
3880 | CK_ULONG ulPartLen) | |||
3881 | { | |||
3882 | CHECK_FORK(); | |||
3883 | return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY); | |||
3884 | } | |||
3885 | ||||
3886 | /* NSC_VerifyFinal finishes a multiple-part verification operation, | |||
3887 | * checking the signature. */ | |||
3888 | CK_RV | |||
3889 | NSC_VerifyFinal(CK_SESSION_HANDLE hSession, | |||
3890 | CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) | |||
3891 | { | |||
3892 | SFTKSession *session; | |||
3893 | SFTKSessionContext *context; | |||
3894 | CK_RV crv; | |||
3895 | ||||
3896 | CHECK_FORK(); | |||
3897 | ||||
3898 | if (!pSignature) | |||
3899 | return CKR_ARGUMENTS_BAD0x00000007UL; | |||
3900 | ||||
3901 | /* make sure we're legal */ | |||
3902 | crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE1, &session); | |||
3903 | if (crv != CKR_OK0x00000000UL) | |||
3904 | return crv; | |||
3905 | ||||
3906 | if (context->hashInfo) { | |||
3907 | unsigned int digestLen; | |||
3908 | unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH64]; | |||
3909 | ||||
3910 | (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf)); | |||
3911 | if (SECSuccess != (context->verify)(context->cipherInfo, pSignature, | |||
3912 | ulSignatureLen, tmpbuf, digestLen)) | |||
3913 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
3914 | PORT_Memsetmemset(tmpbuf, 0, sizeof tmpbuf); | |||
3915 | } else if (ulSignatureLen != context->macSize) { | |||
3916 | /* must be block cipher MACing */ | |||
3917 | crv = CKR_SIGNATURE_LEN_RANGE0x000000C1UL; | |||
3918 | } else if (CKR_OK0x00000000UL == (crv = sftk_MACFinal(context))) { | |||
3919 | if (NSS_SecureMemcmp(pSignature, context->macBuf, ulSignatureLen)) | |||
3920 | crv = CKR_SIGNATURE_INVALID0x000000C0UL; | |||
3921 | } | |||
3922 | ||||
3923 | sftk_TerminateOp(session, SFTK_VERIFY, context); | |||
3924 | sftk_FreeSession(session); | |||
3925 | return crv; | |||
3926 | } | |||
3927 | ||||
3928 | /* | |||
3929 | ************** Crypto Functions: Verify Recover ************************ | |||
3930 | */ | |||
3931 | static SECStatus | |||
3932 | sftk_RSACheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data, | |||
3933 | unsigned int *dataLen, unsigned int maxDataLen, | |||
3934 | const unsigned char *sig, unsigned int sigLen) | |||
3935 | { | |||
3936 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",3936)); | |||
3937 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
3938 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
3939 | return SECFailure; | |||
3940 | } | |||
3941 | ||||
3942 | return RSA_CheckSignRecover(&key->u.rsa, data, dataLen, maxDataLen, | |||
3943 | sig, sigLen); | |||
3944 | } | |||
3945 | ||||
3946 | static SECStatus | |||
3947 | sftk_RSACheckSignRecoverRaw(NSSLOWKEYPublicKey *key, unsigned char *data, | |||
3948 | unsigned int *dataLen, unsigned int maxDataLen, | |||
3949 | const unsigned char *sig, unsigned int sigLen) | |||
3950 | { | |||
3951 | PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey)?((void)0):PR_Assert("key->keyType == NSSLOWKEYRSAKey" ,"pkcs11c.c",3951)); | |||
3952 | if (key->keyType != NSSLOWKEYRSAKey) { | |||
3953 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
3954 | return SECFailure; | |||
3955 | } | |||
3956 | ||||
3957 | return RSA_CheckSignRecoverRaw(&key->u.rsa, data, dataLen, maxDataLen, | |||
3958 | sig, sigLen); | |||
3959 | } | |||
3960 | ||||
3961 | /* NSC_VerifyRecoverInit initializes a signature verification operation, | |||
3962 | * where the data is recovered from the signature. | |||
3963 | * E.g. Decryption with the user's public key */ | |||
3964 | CK_RV | |||
3965 | NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, | |||
3966 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) | |||
3967 | { | |||
3968 | SFTKSession *session; | |||
3969 | SFTKObject *key; | |||
3970 | SFTKSessionContext *context; | |||
3971 | CK_KEY_TYPE key_type; | |||
3972 | CK_RV crv = CKR_OK0x00000000UL; | |||
3973 | NSSLOWKEYPublicKey *pubKey; | |||
3974 | ||||
3975 | CHECK_FORK(); | |||
3976 | ||||
3977 | session = sftk_SessionFromHandle(hSession); | |||
3978 | if (session == NULL((void*)0)) | |||
3979 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
3980 | crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_VERIFY_RECOVER, | |||
3981 | &key, hKey, &key_type, CKO_PUBLIC_KEY0x00000002UL, CKA_VERIFY_RECOVER0x0000010BUL); | |||
3982 | if (crv != CKR_OK0x00000000UL) { | |||
3983 | sftk_FreeSession(session); | |||
3984 | return crv; | |||
3985 | } | |||
3986 | ||||
3987 | context->multi = PR_TRUE1; | |||
3988 | ||||
3989 | switch (pMechanism->mechanism) { | |||
3990 | case CKM_RSA_PKCS0x00000001UL: | |||
3991 | case CKM_RSA_X_5090x00000003UL: | |||
3992 | if (key_type != CKK_RSA0x00000000UL) { | |||
3993 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
3994 | break; | |||
3995 | } | |||
3996 | context->multi = PR_FALSE0; | |||
3997 | context->rsa = PR_TRUE1; | |||
3998 | pubKey = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv); | |||
3999 | if (pubKey == NULL((void*)0)) { | |||
4000 | break; | |||
4001 | } | |||
4002 | context->cipherInfo = pubKey; | |||
4003 | context->update = (SFTKCipher)(pMechanism->mechanism == CKM_RSA_X_5090x00000003UL | |||
4004 | ? sftk_RSACheckSignRecoverRaw | |||
4005 | : sftk_RSACheckSignRecover); | |||
4006 | context->destroy = sftk_Null; | |||
4007 | break; | |||
4008 | default: | |||
4009 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
4010 | break; | |||
4011 | } | |||
4012 | ||||
4013 | if (crv != CKR_OK0x00000000UL) { | |||
4014 | PORT_FreePORT_Free_Util(context); | |||
4015 | sftk_FreeSession(session); | |||
4016 | return crv; | |||
4017 | } | |||
4018 | sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, context); | |||
4019 | sftk_FreeSession(session); | |||
4020 | return CKR_OK0x00000000UL; | |||
4021 | } | |||
4022 | ||||
4023 | /* NSC_VerifyRecover verifies a signature in a single-part operation, | |||
4024 | * where the data is recovered from the signature. | |||
4025 | * E.g. Decryption with the user's public key */ | |||
4026 | CK_RV | |||
4027 | NSC_VerifyRecover(CK_SESSION_HANDLE hSession, | |||
4028 | CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, | |||
4029 | CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) | |||
4030 | { | |||
4031 | SFTKSession *session; | |||
4032 | SFTKSessionContext *context; | |||
4033 | unsigned int outlen; | |||
4034 | unsigned int maxoutlen = *pulDataLen; | |||
4035 | CK_RV crv; | |||
4036 | SECStatus rv; | |||
4037 | ||||
4038 | CHECK_FORK(); | |||
4039 | ||||
4040 | /* make sure we're legal */ | |||
4041 | crv = sftk_GetContext(hSession, &context, SFTK_VERIFY_RECOVER, | |||
4042 | PR_FALSE0, &session); | |||
4043 | if (crv != CKR_OK0x00000000UL) | |||
4044 | return crv; | |||
4045 | if (pData == NULL((void*)0)) { | |||
4046 | /* to return the actual size, we need to do the decrypt, just return | |||
4047 | * the max size, which is the size of the input signature. */ | |||
4048 | *pulDataLen = ulSignatureLen; | |||
4049 | rv = SECSuccess; | |||
4050 | goto finish; | |||
4051 | } | |||
4052 | ||||
4053 | rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, | |||
4054 | pSignature, ulSignatureLen); | |||
4055 | *pulDataLen = (CK_ULONG)outlen; | |||
4056 | ||||
4057 | sftk_TerminateOp(session, SFTK_VERIFY_RECOVER, context); | |||
4058 | finish: | |||
4059 | sftk_FreeSession(session); | |||
4060 | return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapVerifyError(PORT_GetErrorPORT_GetError_Util()); | |||
4061 | } | |||
4062 | ||||
4063 | /* | |||
4064 | **************************** Random Functions: ************************ | |||
4065 | */ | |||
4066 | ||||
4067 | /* NSC_SeedRandom mixes additional seed material into the token's random number | |||
4068 | * generator. */ | |||
4069 | CK_RV | |||
4070 | NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, | |||
4071 | CK_ULONG ulSeedLen) | |||
4072 | { | |||
4073 | SECStatus rv; | |||
4074 | ||||
4075 | CHECK_FORK(); | |||
4076 | ||||
4077 | rv = RNG_RandomUpdate(pSeed, ulSeedLen); | |||
4078 | return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
4079 | } | |||
4080 | ||||
4081 | /* NSC_GenerateRandom generates random data. */ | |||
4082 | CK_RV | |||
4083 | NSC_GenerateRandom(CK_SESSION_HANDLE hSession, | |||
4084 | CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) | |||
4085 | { | |||
4086 | SECStatus rv; | |||
4087 | ||||
4088 | CHECK_FORK(); | |||
4089 | ||||
4090 | rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen); | |||
4091 | /* | |||
4092 | * This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't | |||
4093 | * seeded with enough entropy. | |||
4094 | */ | |||
4095 | return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
4096 | } | |||
4097 | ||||
4098 | /* | |||
4099 | **************************** Key Functions: ************************ | |||
4100 | */ | |||
4101 | ||||
4102 | /* | |||
4103 | * generate a password based encryption key. This code uses | |||
4104 | * PKCS5 to do the work. | |||
4105 | */ | |||
4106 | static CK_RV | |||
4107 | nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism, | |||
4108 | void *buf, CK_ULONG *key_length, PRBool faulty3DES) | |||
4109 | { | |||
4110 | SECItem *pbe_key = NULL((void*)0), iv, pwitem; | |||
4111 | CK_PBE_PARAMS *pbe_params = NULL((void*)0); | |||
4112 | CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL((void*)0); | |||
4113 | ||||
4114 | *key_length = 0; | |||
4115 | iv.data = NULL((void*)0); | |||
4116 | iv.len = 0; | |||
4117 | ||||
4118 | if (pMechanism->mechanism == CKM_PKCS5_PBKD20x000003B0UL) { | |||
4119 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PKCS5_PBKD2_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_PKCS5_PBKD2_PARAMS))) { | |||
4120 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4121 | } | |||
4122 | pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter; | |||
4123 | pwitem.data = (unsigned char *)pbkd2_params->pPassword; | |||
4124 | /* was this a typo in the PKCS #11 spec? */ | |||
4125 | pwitem.len = *pbkd2_params->ulPasswordLen; | |||
4126 | } else { | |||
4127 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_PBE_PARAMS))) { | |||
4128 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4129 | } | |||
4130 | pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; | |||
4131 | pwitem.data = (unsigned char *)pbe_params->pPassword; | |||
4132 | pwitem.len = pbe_params->ulPasswordLen; | |||
4133 | } | |||
4134 | pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES); | |||
4135 | if (pbe_key == NULL((void*)0)) { | |||
4136 | return CKR_HOST_MEMORY0x00000002UL; | |||
4137 | } | |||
4138 | ||||
4139 | PORT_Memcpymemcpy(buf, pbe_key->data, pbe_key->len); | |||
4140 | *key_length = pbe_key->len; | |||
4141 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(pbe_key, PR_TRUE1); | |||
4142 | pbe_key = NULL((void*)0); | |||
4143 | ||||
4144 | if (iv.data) { | |||
4145 | if (pbe_params && pbe_params->pInitVector != NULL((void*)0)) { | |||
4146 | PORT_Memcpymemcpy(pbe_params->pInitVector, iv.data, iv.len); | |||
4147 | } | |||
4148 | PORT_FreePORT_Free_Util(iv.data); | |||
4149 | } | |||
4150 | ||||
4151 | return CKR_OK0x00000000UL; | |||
4152 | } | |||
4153 | ||||
4154 | /* | |||
4155 | * this is coded for "full" support. These selections will be limitted to | |||
4156 | * the official subset by freebl. | |||
4157 | */ | |||
4158 | static unsigned int | |||
4159 | sftk_GetSubPrimeFromPrime(unsigned int primeBits) | |||
4160 | { | |||
4161 | if (primeBits <= 1024) { | |||
4162 | return 160; | |||
4163 | } else if (primeBits <= 2048) { | |||
4164 | return 224; | |||
4165 | } else if (primeBits <= 3072) { | |||
4166 | return 256; | |||
4167 | } else if (primeBits <= 7680) { | |||
4168 | return 384; | |||
4169 | } else { | |||
4170 | return 512; | |||
4171 | } | |||
4172 | } | |||
4173 | ||||
4174 | static CK_RV | |||
4175 | nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key) | |||
4176 | { | |||
4177 | SFTKAttribute *attribute; | |||
4178 | CK_ULONG counter; | |||
4179 | unsigned int seedBits = 0; | |||
4180 | unsigned int subprimeBits = 0; | |||
4181 | unsigned int primeBits; | |||
4182 | unsigned int j = 8; /* default to 1024 bits */ | |||
4183 | CK_RV crv = CKR_OK0x00000000UL; | |||
4184 | PQGParams *params = NULL((void*)0); | |||
4185 | PQGVerify *vfy = NULL((void*)0); | |||
4186 | SECStatus rv; | |||
4187 | ||||
4188 | attribute = sftk_FindAttribute(key, CKA_PRIME_BITS0x00000133UL); | |||
4189 | if (attribute == NULL((void*)0)) { | |||
4190 | attribute = sftk_FindAttribute(key, CKA_PRIME0x00000130UL); | |||
4191 | if (attribute == NULL((void*)0)) { | |||
4192 | return CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4193 | } else { | |||
4194 | primeBits = attribute->attrib.ulValueLen; | |||
4195 | sftk_FreeAttribute(attribute); | |||
4196 | } | |||
4197 | } else { | |||
4198 | primeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue; | |||
4199 | sftk_FreeAttribute(attribute); | |||
4200 | } | |||
4201 | if (primeBits < 1024) { | |||
4202 | j = PQG_PBITS_TO_INDEX(primeBits)(((primeBits) < 512 || (primeBits) > 1024 || (primeBits ) % 64) ? -1 : (int)((primeBits)-512) / 64); | |||
4203 | if (j == (unsigned int)-1) { | |||
4204 | return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL; | |||
4205 | } | |||
4206 | } | |||
4207 | ||||
4208 | attribute = sftk_FindAttribute(key, CKA_NSS_PQG_SEED_BITS((0x80000000UL | 0x4E534350) + 23)); | |||
4209 | if (attribute != NULL((void*)0)) { | |||
4210 | seedBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue; | |||
4211 | sftk_FreeAttribute(attribute); | |||
4212 | } | |||
4213 | ||||
4214 | attribute = sftk_FindAttribute(key, CKA_SUBPRIME_BITS0x00000134UL); | |||
4215 | if (attribute != NULL((void*)0)) { | |||
4216 | subprimeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue; | |||
4217 | sftk_FreeAttribute(attribute); | |||
4218 | } | |||
4219 | ||||
4220 | /* if P and Q are supplied, we want to generate a new G */ | |||
4221 | attribute = sftk_FindAttribute(key, CKA_PRIME0x00000130UL); | |||
4222 | if (attribute != NULL((void*)0)) { | |||
4223 | PLArenaPool *arena; | |||
4224 | ||||
4225 | sftk_FreeAttribute(attribute); | |||
4226 | arena = PORT_NewArenaPORT_NewArena_Util(1024); | |||
4227 | if (arena == NULL((void*)0)) { | |||
4228 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
4229 | goto loser; | |||
4230 | } | |||
4231 | params = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, sizeof(*params)); | |||
4232 | if (params == NULL((void*)0)) { | |||
4233 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
4234 | goto loser; | |||
4235 | } | |||
4236 | params->arena = arena; | |||
4237 | crv = sftk_Attribute2SSecItem(arena, ¶ms->prime, key, CKA_PRIME0x00000130UL); | |||
4238 | if (crv != CKR_OK0x00000000UL) { | |||
4239 | goto loser; | |||
4240 | } | |||
4241 | crv = sftk_Attribute2SSecItem(arena, ¶ms->subPrime, | |||
4242 | key, CKA_SUBPRIME0x00000131UL); | |||
4243 | if (crv != CKR_OK0x00000000UL) { | |||
4244 | goto loser; | |||
4245 | } | |||
4246 | ||||
4247 | arena = PORT_NewArenaPORT_NewArena_Util(1024); | |||
4248 | if (arena == NULL((void*)0)) { | |||
4249 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
4250 | goto loser; | |||
4251 | } | |||
4252 | vfy = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, sizeof(*vfy)); | |||
4253 | if (vfy == NULL((void*)0)) { | |||
4254 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
4255 | goto loser; | |||
4256 | } | |||
4257 | vfy->arena = arena; | |||
4258 | crv = sftk_Attribute2SSecItem(arena, &vfy->seed, key, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21)); | |||
4259 | if (crv != CKR_OK0x00000000UL) { | |||
4260 | goto loser; | |||
4261 | } | |||
4262 | crv = sftk_Attribute2SSecItem(arena, &vfy->h, key, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22)); | |||
4263 | if (crv != CKR_OK0x00000000UL) { | |||
4264 | goto loser; | |||
4265 | } | |||
4266 | sftk_DeleteAttributeType(key, CKA_PRIME0x00000130UL); | |||
4267 | sftk_DeleteAttributeType(key, CKA_SUBPRIME0x00000131UL); | |||
4268 | sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21)); | |||
4269 | sftk_DeleteAttributeType(key, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22)); | |||
4270 | } | |||
4271 | ||||
4272 | sftk_DeleteAttributeType(key, CKA_PRIME_BITS0x00000133UL); | |||
4273 | sftk_DeleteAttributeType(key, CKA_SUBPRIME_BITS0x00000134UL); | |||
4274 | sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED_BITS((0x80000000UL | 0x4E534350) + 23)); | |||
4275 | ||||
4276 | /* use the old PQG interface if we have old input data */ | |||
4277 | if ((primeBits < 1024) || ((primeBits == 1024) && (subprimeBits == 0))) { | |||
4278 | if (seedBits == 0) { | |||
4279 | rv = PQG_ParamGen(j, ¶ms, &vfy); | |||
4280 | } else { | |||
4281 | rv = PQG_ParamGenSeedLen(j, seedBits / 8, ¶ms, &vfy); | |||
4282 | } | |||
4283 | } else { | |||
4284 | if (subprimeBits == 0) { | |||
4285 | subprimeBits = sftk_GetSubPrimeFromPrime(primeBits); | |||
4286 | } | |||
4287 | if (seedBits == 0) { | |||
4288 | seedBits = primeBits; | |||
4289 | } | |||
4290 | rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits / 8, ¶ms, &vfy); | |||
4291 | } | |||
4292 | ||||
4293 | if (rv != SECSuccess) { | |||
4294 | if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
4295 | sftk_fatalError = PR_TRUE1; | |||
4296 | } | |||
4297 | return sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
4298 | } | |||
4299 | crv = sftk_AddAttributeType(key, CKA_PRIME0x00000130UL, | |||
4300 | params->prime.data, params->prime.len); | |||
4301 | if (crv != CKR_OK0x00000000UL) | |||
4302 | goto loser; | |||
4303 | crv = sftk_AddAttributeType(key, CKA_SUBPRIME0x00000131UL, | |||
4304 | params->subPrime.data, params->subPrime.len); | |||
4305 | if (crv != CKR_OK0x00000000UL) | |||
4306 | goto loser; | |||
4307 | crv = sftk_AddAttributeType(key, CKA_BASE0x00000132UL, | |||
4308 | params->base.data, params->base.len); | |||
4309 | if (crv != CKR_OK0x00000000UL) | |||
4310 | goto loser; | |||
4311 | counter = vfy->counter; | |||
4312 | crv = sftk_AddAttributeType(key, CKA_NSS_PQG_COUNTER((0x80000000UL | 0x4E534350) + 20), | |||
4313 | &counter, sizeof(counter)); | |||
4314 | crv = sftk_AddAttributeType(key, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21), | |||
4315 | vfy->seed.data, vfy->seed.len); | |||
4316 | if (crv != CKR_OK0x00000000UL) | |||
4317 | goto loser; | |||
4318 | crv = sftk_AddAttributeType(key, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22), | |||
4319 | vfy->h.data, vfy->h.len); | |||
4320 | if (crv != CKR_OK0x00000000UL) | |||
4321 | goto loser; | |||
4322 | ||||
4323 | loser: | |||
4324 | if (params) { | |||
4325 | PQG_DestroyParams(params); | |||
4326 | } | |||
4327 | ||||
4328 | if (vfy) { | |||
4329 | PQG_DestroyVerify(vfy); | |||
4330 | } | |||
4331 | return crv; | |||
4332 | } | |||
4333 | ||||
4334 | static CK_RV | |||
4335 | nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type, | |||
4336 | CK_ULONG *key_length) | |||
4337 | { | |||
4338 | CK_RV crv = CKR_OK0x00000000UL; | |||
4339 | ||||
4340 | switch (mechanism) { | |||
4341 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
4342 | case CKM_RC2_KEY_GEN0x00000100UL: | |||
4343 | *key_type = CKK_RC20x00000011UL; | |||
4344 | if (*key_length == 0) | |||
4345 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4346 | break; | |||
4347 | #endif /* NSS_DISABLE_DEPRECATED_RC2 */ | |||
4348 | #if NSS_SOFTOKEN_DOES_RC5 | |||
4349 | case CKM_RC5_KEY_GEN0x00000330UL: | |||
4350 | *key_type = CKK_RC50x00000019UL; | |||
4351 | if (*key_length == 0) | |||
4352 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4353 | break; | |||
4354 | #endif | |||
4355 | case CKM_RC4_KEY_GEN0x00000110UL: | |||
4356 | *key_type = CKK_RC40x00000012UL; | |||
4357 | if (*key_length == 0) | |||
4358 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4359 | break; | |||
4360 | case CKM_GENERIC_SECRET_KEY_GEN0x00000350UL: | |||
4361 | *key_type = CKK_GENERIC_SECRET0x00000010UL; | |||
4362 | if (*key_length == 0) | |||
4363 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4364 | break; | |||
4365 | case CKM_CDMF_KEY_GEN0x00000140UL: | |||
4366 | *key_type = CKK_CDMF0x0000001EUL; | |||
4367 | *key_length = 8; | |||
4368 | break; | |||
4369 | case CKM_DES_KEY_GEN0x00000120UL: | |||
4370 | *key_type = CKK_DES0x00000013UL; | |||
4371 | *key_length = 8; | |||
4372 | break; | |||
4373 | case CKM_DES2_KEY_GEN0x00000130UL: | |||
4374 | *key_type = CKK_DES20x00000014UL; | |||
4375 | *key_length = 16; | |||
4376 | break; | |||
4377 | case CKM_DES3_KEY_GEN0x00000131UL: | |||
4378 | *key_type = CKK_DES30x00000015UL; | |||
4379 | *key_length = 24; | |||
4380 | break; | |||
4381 | #ifndef NSS_DISABLE_DEPRECATED_SEED | |||
4382 | case CKM_SEED_KEY_GEN0x00000650UL: | |||
4383 | *key_type = CKK_SEED0x0000002FUL; | |||
4384 | *key_length = 16; | |||
4385 | break; | |||
4386 | #endif /* NSS_DISABLE_DEPRECATED_SEED */ | |||
4387 | case CKM_CAMELLIA_KEY_GEN0x00000550UL: | |||
4388 | *key_type = CKK_CAMELLIA0x00000025UL; | |||
4389 | if (*key_length == 0) | |||
4390 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4391 | break; | |||
4392 | case CKM_AES_KEY_GEN0x00001080UL: | |||
4393 | *key_type = CKK_AES0x0000001FUL; | |||
4394 | if (*key_length == 0) | |||
4395 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4396 | break; | |||
4397 | case CKM_NSS_CHACHA20_KEY_GEN((0x80000000UL | 0x4E534350) + 27): | |||
4398 | *key_type = CKK_NSS_CHACHA20((0x80000000UL | 0x4E534350) + 4); | |||
4399 | *key_length = 32; | |||
4400 | break; | |||
4401 | case CKM_CHACHA20_KEY_GEN0x00001225UL: | |||
4402 | *key_type = CKK_CHACHA200x00000033UL; | |||
4403 | *key_length = 32; | |||
4404 | break; | |||
4405 | case CKM_HKDF_KEY_GEN0x0000402cUL: | |||
4406 | *key_type = CKK_HKDF0x00000042UL; | |||
4407 | if (*key_length == 0) | |||
4408 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4409 | break; | |||
4410 | default: | |||
4411 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","pkcs11c.c",4411)); | |||
4412 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
4413 | break; | |||
4414 | } | |||
4415 | ||||
4416 | return crv; | |||
4417 | } | |||
4418 | ||||
4419 | CK_RV | |||
4420 | nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe) | |||
4421 | { | |||
4422 | SECItem salt; | |||
4423 | CK_PBE_PARAMS *pbe_params = NULL((void*)0); | |||
4424 | NSSPKCS5PBEParameter *params; | |||
4425 | PLArenaPool *arena = NULL((void*)0); | |||
4426 | SECStatus rv; | |||
4427 | ||||
4428 | *pbe = NULL((void*)0); | |||
4429 | ||||
4430 | arena = PORT_NewArenaPORT_NewArena_Util(SEC_ASN1_DEFAULT_ARENA_SIZE(2048)); | |||
4431 | if (arena == NULL((void*)0)) { | |||
4432 | return CKR_HOST_MEMORY0x00000002UL; | |||
4433 | } | |||
4434 | ||||
4435 | params = (NSSPKCS5PBEParameter *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, | |||
4436 | sizeof(NSSPKCS5PBEParameter)); | |||
4437 | if (params == NULL((void*)0)) { | |||
4438 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
4439 | return CKR_HOST_MEMORY0x00000002UL; | |||
4440 | } | |||
4441 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_PBE_PARAMS))) { | |||
4442 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
4443 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4444 | } | |||
4445 | ||||
4446 | params->poolp = arena; | |||
4447 | params->ivLen = 0; | |||
4448 | params->pbeType = NSSPKCS5_PKCS12_V2; | |||
4449 | params->hashType = HASH_AlgSHA1; | |||
4450 | params->encAlg = SEC_OID_SHA1; /* any invalid value */ | |||
4451 | params->is2KeyDES = PR_FALSE0; | |||
4452 | params->keyID = pbeBitGenIntegrityKey; | |||
4453 | pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; | |||
4454 | params->iter = pbe_params->ulIteration; | |||
4455 | ||||
4456 | salt.data = (unsigned char *)pbe_params->pSalt; | |||
4457 | salt.len = (unsigned int)pbe_params->ulSaltLen; | |||
4458 | salt.type = siBuffer; | |||
4459 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, ¶ms->salt, &salt); | |||
4460 | if (rv != SECSuccess) { | |||
4461 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
4462 | return CKR_HOST_MEMORY0x00000002UL; | |||
4463 | } | |||
4464 | switch (pMechanism->mechanism) { | |||
4465 | case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN0x80000009UL: | |||
4466 | case CKM_PBA_SHA1_WITH_SHA1_HMAC0x000003C0UL: | |||
4467 | params->hashType = HASH_AlgSHA1; | |||
4468 | params->keyLen = 20; | |||
4469 | break; | |||
4470 | case CKM_NSS_PBE_MD5_HMAC_KEY_GEN0x8000000aUL: | |||
4471 | params->hashType = HASH_AlgMD5; | |||
4472 | params->keyLen = 16; | |||
4473 | break; | |||
4474 | case CKM_NSS_PBE_MD2_HMAC_KEY_GEN0x8000000bUL: | |||
4475 | params->hashType = HASH_AlgMD2; | |||
4476 | params->keyLen = 16; | |||
4477 | break; | |||
4478 | case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 29): | |||
4479 | params->hashType = HASH_AlgSHA224; | |||
4480 | params->keyLen = 28; | |||
4481 | break; | |||
4482 | case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 30): | |||
4483 | params->hashType = HASH_AlgSHA256; | |||
4484 | params->keyLen = 32; | |||
4485 | break; | |||
4486 | case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 31): | |||
4487 | params->hashType = HASH_AlgSHA384; | |||
4488 | params->keyLen = 48; | |||
4489 | break; | |||
4490 | case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 32): | |||
4491 | params->hashType = HASH_AlgSHA512; | |||
4492 | params->keyLen = 64; | |||
4493 | break; | |||
4494 | default: | |||
4495 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
4496 | return CKR_MECHANISM_INVALID0x00000070UL; | |||
4497 | } | |||
4498 | *pbe = params; | |||
4499 | return CKR_OK0x00000000UL; | |||
4500 | } | |||
4501 | ||||
4502 | /* maybe this should be table driven? */ | |||
4503 | static CK_RV | |||
4504 | nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe, | |||
4505 | CK_KEY_TYPE *key_type, CK_ULONG *key_length) | |||
4506 | { | |||
4507 | CK_RV crv = CKR_OK0x00000000UL; | |||
4508 | SECOidData *oid; | |||
4509 | CK_PBE_PARAMS *pbe_params = NULL((void*)0); | |||
4510 | NSSPKCS5PBEParameter *params = NULL((void*)0); | |||
4511 | HASH_HashType hashType = HASH_AlgSHA1; | |||
4512 | CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL((void*)0); | |||
4513 | SECItem salt; | |||
4514 | CK_ULONG iteration = 0; | |||
4515 | ||||
4516 | *pbe = NULL((void*)0); | |||
4517 | ||||
4518 | oid = SECOID_FindOIDByMechanism(pMechanism->mechanism); | |||
4519 | if (oid == NULL((void*)0)) { | |||
4520 | return CKR_MECHANISM_INVALID0x00000070UL; | |||
4521 | } | |||
4522 | ||||
4523 | if (pMechanism->mechanism == CKM_PKCS5_PBKD20x000003B0UL) { | |||
4524 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PKCS5_PBKD2_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_PKCS5_PBKD2_PARAMS))) { | |||
4525 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4526 | } | |||
4527 | pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter; | |||
4528 | switch (pbkd2_params->prf) { | |||
4529 | case CKP_PKCS5_PBKD2_HMAC_SHA10x00000001UL: | |||
4530 | hashType = HASH_AlgSHA1; | |||
4531 | break; | |||
4532 | case CKP_PKCS5_PBKD2_HMAC_SHA2240x00000003UL: | |||
4533 | hashType = HASH_AlgSHA224; | |||
4534 | break; | |||
4535 | case CKP_PKCS5_PBKD2_HMAC_SHA2560x00000004UL: | |||
4536 | hashType = HASH_AlgSHA256; | |||
4537 | break; | |||
4538 | case CKP_PKCS5_PBKD2_HMAC_SHA3840x00000005UL: | |||
4539 | hashType = HASH_AlgSHA384; | |||
4540 | break; | |||
4541 | case CKP_PKCS5_PBKD2_HMAC_SHA5120x00000006UL: | |||
4542 | hashType = HASH_AlgSHA512; | |||
4543 | break; | |||
4544 | default: | |||
4545 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4546 | } | |||
4547 | if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED0x00000001UL) { | |||
4548 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4549 | } | |||
4550 | salt.data = (unsigned char *)pbkd2_params->pSaltSourceData; | |||
4551 | salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen; | |||
4552 | iteration = pbkd2_params->iterations; | |||
4553 | } else { | |||
4554 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_PBE_PARAMS))) { | |||
4555 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4556 | } | |||
4557 | pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; | |||
4558 | salt.data = (unsigned char *)pbe_params->pSalt; | |||
4559 | salt.len = (unsigned int)pbe_params->ulSaltLen; | |||
4560 | iteration = pbe_params->ulIteration; | |||
4561 | } | |||
4562 | params = nsspkcs5_NewParam(oid->offset, hashType, &salt, iteration); | |||
4563 | if (params == NULL((void*)0)) { | |||
4564 | return CKR_MECHANISM_INVALID0x00000070UL; | |||
4565 | } | |||
4566 | ||||
4567 | switch (params->encAlg) { | |||
4568 | case SEC_OID_DES_CBC: | |||
4569 | *key_type = CKK_DES0x00000013UL; | |||
4570 | *key_length = params->keyLen; | |||
4571 | break; | |||
4572 | case SEC_OID_DES_EDE3_CBC: | |||
4573 | *key_type = params->is2KeyDES ? CKK_DES20x00000014UL : CKK_DES30x00000015UL; | |||
4574 | *key_length = params->keyLen; | |||
4575 | break; | |||
4576 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
4577 | case SEC_OID_RC2_CBC: | |||
4578 | *key_type = CKK_RC20x00000011UL; | |||
4579 | *key_length = params->keyLen; | |||
4580 | break; | |||
4581 | #endif /* NSS_DISABLE_DEPRECATED_RC2 */ | |||
4582 | case SEC_OID_RC4: | |||
4583 | *key_type = CKK_RC40x00000012UL; | |||
4584 | *key_length = params->keyLen; | |||
4585 | break; | |||
4586 | case SEC_OID_PKCS5_PBKDF2: | |||
4587 | /* key type must already be set */ | |||
4588 | if (*key_type == CKK_INVALID_KEY_TYPE0xffffffffUL) { | |||
4589 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4590 | break; | |||
4591 | } | |||
4592 | /* PBKDF2 needs to calculate the key length from the other parameters | |||
4593 | */ | |||
4594 | if (*key_length == 0) { | |||
4595 | *key_length = sftk_MapKeySize(*key_type); | |||
4596 | } | |||
4597 | if (*key_length == 0) { | |||
4598 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
4599 | break; | |||
4600 | } | |||
4601 | params->keyLen = *key_length; | |||
4602 | break; | |||
4603 | default: | |||
4604 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
4605 | break; | |||
4606 | } | |||
4607 | if (crv == CKR_OK0x00000000UL) { | |||
4608 | *pbe = params; | |||
4609 | } else { | |||
4610 | nsspkcs5_DestroyPBEParameter(params); | |||
4611 | } | |||
4612 | return crv; | |||
4613 | } | |||
4614 | ||||
4615 | /* NSC_GenerateKey generates a secret key, creating a new key object. */ | |||
4616 | CK_RV | |||
4617 | NSC_GenerateKey(CK_SESSION_HANDLE hSession, | |||
4618 | CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, | |||
4619 | CK_OBJECT_HANDLE_PTR phKey) | |||
4620 | { | |||
4621 | SFTKObject *key; | |||
4622 | SFTKSession *session; | |||
4623 | PRBool checkWeak = PR_FALSE0; | |||
4624 | CK_ULONG key_length = 0; | |||
4625 | CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE0xffffffffUL; | |||
4626 | CK_OBJECT_CLASS objclass = CKO_SECRET_KEY0x00000004UL; | |||
4627 | CK_RV crv = CKR_OK0x00000000UL; | |||
4628 | CK_BBOOL cktrue = CK_TRUE1; | |||
4629 | NSSPKCS5PBEParameter *pbe_param = NULL((void*)0); | |||
4630 | int i; | |||
4631 | SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); | |||
4632 | unsigned char buf[MAX_KEY_LEN256]; | |||
4633 | enum { nsc_pbe, | |||
4634 | nsc_ssl, | |||
4635 | nsc_bulk, | |||
4636 | nsc_param, | |||
4637 | nsc_jpake } key_gen_type; | |||
4638 | SSL3RSAPreMasterSecret *rsa_pms; | |||
4639 | CK_VERSION *version; | |||
4640 | /* in very old versions of NSS, there were implementation errors with key | |||
4641 | * generation methods. We want to beable to read these, but not | |||
4642 | * produce them any more. The affected algorithm was 3DES. | |||
4643 | */ | |||
4644 | PRBool faultyPBE3DES = PR_FALSE0; | |||
4645 | HASH_HashType hashType = HASH_AlgNULL; | |||
4646 | ||||
4647 | CHECK_FORK(); | |||
4648 | ||||
4649 | if (!slot) { | |||
4650 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
4651 | } | |||
4652 | /* | |||
4653 | * now lets create an object to hang the attributes off of | |||
4654 | */ | |||
4655 | key = sftk_NewObject(slot); /* fill in the handle later */ | |||
4656 | if (key == NULL((void*)0)) { | |||
4657 | return CKR_HOST_MEMORY0x00000002UL; | |||
4658 | } | |||
4659 | ||||
4660 | /* | |||
4661 | * load the template values into the object | |||
4662 | */ | |||
4663 | for (i = 0; i < (int)ulCount; i++) { | |||
4664 | if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) { | |||
4665 | key_length = *(CK_ULONG *)pTemplate[i].pValue; | |||
4666 | continue; | |||
4667 | } | |||
4668 | /* some algorithms need keytype specified */ | |||
4669 | if (pTemplate[i].type == CKA_KEY_TYPE0x00000100UL) { | |||
4670 | key_type = *(CK_ULONG *)pTemplate[i].pValue; | |||
4671 | continue; | |||
4672 | } | |||
4673 | ||||
4674 | crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue, (&pTemplate[i])->ulValueLen); | |||
4675 | if (crv != CKR_OK0x00000000UL) { | |||
4676 | break; | |||
4677 | } | |||
4678 | } | |||
4679 | if (crv != CKR_OK0x00000000UL) { | |||
4680 | goto loser; | |||
4681 | } | |||
4682 | ||||
4683 | /* make sure we don't have any class, key_type, or value fields */ | |||
4684 | sftk_DeleteAttributeType(key, CKA_CLASS0x00000000UL); | |||
4685 | sftk_DeleteAttributeType(key, CKA_KEY_TYPE0x00000100UL); | |||
4686 | sftk_DeleteAttributeType(key, CKA_VALUE0x00000011UL); | |||
4687 | ||||
4688 | /* Now Set up the parameters to generate the key (based on mechanism) */ | |||
4689 | key_gen_type = nsc_bulk; /* bulk key by default */ | |||
4690 | switch (pMechanism->mechanism) { | |||
4691 | case CKM_CDMF_KEY_GEN0x00000140UL: | |||
4692 | case CKM_DES_KEY_GEN0x00000120UL: | |||
4693 | case CKM_DES2_KEY_GEN0x00000130UL: | |||
4694 | case CKM_DES3_KEY_GEN0x00000131UL: | |||
4695 | checkWeak = PR_TRUE1; | |||
4696 | /* fall through */ | |||
4697 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
4698 | case CKM_RC2_KEY_GEN0x00000100UL: | |||
4699 | #endif | |||
4700 | case CKM_RC4_KEY_GEN0x00000110UL: | |||
4701 | case CKM_GENERIC_SECRET_KEY_GEN0x00000350UL: | |||
4702 | #ifndef NSS_DISABLE_DEPRECATED_SEED | |||
4703 | case CKM_SEED_KEY_GEN0x00000650UL: | |||
4704 | #endif | |||
4705 | case CKM_CAMELLIA_KEY_GEN0x00000550UL: | |||
4706 | case CKM_AES_KEY_GEN0x00001080UL: | |||
4707 | case CKM_NSS_CHACHA20_KEY_GEN((0x80000000UL | 0x4E534350) + 27): | |||
4708 | case CKM_CHACHA20_KEY_GEN0x00001225UL: | |||
4709 | #if NSS_SOFTOKEN_DOES_RC5 | |||
4710 | case CKM_RC5_KEY_GEN0x00000330UL: | |||
4711 | #endif | |||
4712 | crv = nsc_SetupBulkKeyGen(pMechanism->mechanism, &key_type, &key_length); | |||
4713 | break; | |||
4714 | case CKM_SSL3_PRE_MASTER_KEY_GEN0x00000370UL: | |||
4715 | key_type = CKK_GENERIC_SECRET0x00000010UL; | |||
4716 | key_length = 48; | |||
4717 | key_gen_type = nsc_ssl; | |||
4718 | break; | |||
4719 | case CKM_PBA_SHA1_WITH_SHA1_HMAC0x000003C0UL: | |||
4720 | case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN0x80000009UL: | |||
4721 | case CKM_NSS_PBE_MD5_HMAC_KEY_GEN0x8000000aUL: | |||
4722 | case CKM_NSS_PBE_MD2_HMAC_KEY_GEN0x8000000bUL: | |||
4723 | case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 29): | |||
4724 | case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 30): | |||
4725 | case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 31): | |||
4726 | case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 32): | |||
4727 | key_gen_type = nsc_pbe; | |||
4728 | key_type = CKK_GENERIC_SECRET0x00000010UL; | |||
4729 | crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param); | |||
4730 | break; | |||
4731 | case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC0x80000008UL: | |||
4732 | faultyPBE3DES = PR_TRUE1; | |||
4733 | /* fall through */ | |||
4734 | case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC0x80000003UL: | |||
4735 | #ifndef NSS_DISABLE_DEPRECATED_RC2 | |||
4736 | case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC0x80000004UL: | |||
4737 | case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC0x80000005UL: | |||
4738 | case CKM_PBE_SHA1_RC2_128_CBC0x000003AAUL: | |||
4739 | case CKM_PBE_SHA1_RC2_40_CBC0x000003ABUL: | |||
4740 | #endif | |||
4741 | case CKM_NSS_PBE_SHA1_DES_CBC0x80000002UL: | |||
4742 | case CKM_NSS_PBE_SHA1_40_BIT_RC40x80000006UL: | |||
4743 | case CKM_NSS_PBE_SHA1_128_BIT_RC40x80000007UL: | |||
4744 | case CKM_PBE_SHA1_DES3_EDE_CBC0x000003A8UL: | |||
4745 | case CKM_PBE_SHA1_DES2_EDE_CBC0x000003A9UL: | |||
4746 | case CKM_PBE_SHA1_RC4_1280x000003A6UL: | |||
4747 | case CKM_PBE_SHA1_RC4_400x000003A7UL: | |||
4748 | case CKM_PBE_MD5_DES_CBC0x000003A1UL: | |||
4749 | case CKM_PBE_MD2_DES_CBC0x000003A0UL: | |||
4750 | case CKM_PKCS5_PBKD20x000003B0UL: | |||
4751 | key_gen_type = nsc_pbe; | |||
4752 | crv = nsc_SetupPBEKeyGen(pMechanism, &pbe_param, &key_type, &key_length); | |||
4753 | break; | |||
4754 | case CKM_DSA_PARAMETER_GEN0x00002000UL: | |||
4755 | key_gen_type = nsc_param; | |||
4756 | key_type = CKK_DSA0x00000001UL; | |||
4757 | objclass = CKO_DOMAIN_PARAMETERS0x00000006UL; | |||
4758 | crv = CKR_OK0x00000000UL; | |||
4759 | break; | |||
4760 | case CKM_NSS_JPAKE_ROUND1_SHA1((0x80000000UL | 0x4E534350) + 7): | |||
4761 | hashType = HASH_AlgSHA1; | |||
4762 | goto jpake1; | |||
4763 | case CKM_NSS_JPAKE_ROUND1_SHA256((0x80000000UL | 0x4E534350) + 8): | |||
4764 | hashType = HASH_AlgSHA256; | |||
4765 | goto jpake1; | |||
4766 | case CKM_NSS_JPAKE_ROUND1_SHA384((0x80000000UL | 0x4E534350) + 9): | |||
4767 | hashType = HASH_AlgSHA384; | |||
4768 | goto jpake1; | |||
4769 | case CKM_NSS_JPAKE_ROUND1_SHA512((0x80000000UL | 0x4E534350) + 10): | |||
4770 | hashType = HASH_AlgSHA512; | |||
4771 | goto jpake1; | |||
4772 | jpake1: | |||
4773 | key_gen_type = nsc_jpake; | |||
4774 | key_type = CKK_NSS_JPAKE_ROUND1((0x80000000UL | 0x4E534350) + 2); | |||
4775 | objclass = CKO_PRIVATE_KEY0x00000003UL; | |||
4776 | if (pMechanism->pParameter == NULL((void*)0) || | |||
4777 | pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound1Params)) { | |||
4778 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4779 | break; | |||
4780 | } | |||
4781 | if (sftk_isTrue(key, CKA_TOKEN0x00000001UL)) { | |||
4782 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
4783 | break; | |||
4784 | } | |||
4785 | crv = CKR_OK0x00000000UL; | |||
4786 | break; | |||
4787 | default: | |||
4788 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
4789 | break; | |||
4790 | } | |||
4791 | ||||
4792 | /* make sure we aren't going to overflow the buffer */ | |||
4793 | if (sizeof(buf) < key_length) { | |||
4794 | /* someone is getting pretty optimistic about how big their key can | |||
4795 | * be... */ | |||
4796 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
4797 | } | |||
4798 | ||||
4799 | if (crv != CKR_OK0x00000000UL) { | |||
4800 | if (pbe_param) { | |||
4801 | nsspkcs5_DestroyPBEParameter(pbe_param); | |||
4802 | } | |||
4803 | goto loser; | |||
4804 | } | |||
4805 | ||||
4806 | /* if there was no error, | |||
4807 | * key_type *MUST* be set in the switch statement above */ | |||
4808 | PORT_Assert(key_type != CKK_INVALID_KEY_TYPE)((key_type != 0xffffffffUL)?((void)0):PR_Assert("key_type != CKK_INVALID_KEY_TYPE" ,"pkcs11c.c",4808)); | |||
4809 | ||||
4810 | /* | |||
4811 | * now to the actual key gen. | |||
4812 | */ | |||
4813 | switch (key_gen_type) { | |||
4814 | case nsc_pbe: | |||
4815 | crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length, | |||
4816 | faultyPBE3DES); | |||
4817 | nsspkcs5_DestroyPBEParameter(pbe_param); | |||
4818 | break; | |||
4819 | case nsc_ssl: | |||
4820 | rsa_pms = (SSL3RSAPreMasterSecret *)buf; | |||
4821 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_VERSION))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_VERSION))) { | |||
4822 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4823 | goto loser; | |||
4824 | } | |||
4825 | version = (CK_VERSION *)pMechanism->pParameter; | |||
4826 | rsa_pms->client_version[0] = version->major; | |||
4827 | rsa_pms->client_version[1] = version->minor; | |||
4828 | crv = | |||
4829 | NSC_GenerateRandom(0, &rsa_pms->random[0], sizeof(rsa_pms->random)); | |||
4830 | break; | |||
4831 | case nsc_bulk: | |||
4832 | /* get the key, check for weak keys and repeat if found */ | |||
4833 | do { | |||
4834 | crv = NSC_GenerateRandom(0, buf, key_length); | |||
4835 | } while (crv == CKR_OK0x00000000UL && checkWeak && sftk_IsWeakKey(buf, key_type)); | |||
4836 | break; | |||
4837 | case nsc_param: | |||
4838 | /* generate parameters */ | |||
4839 | *buf = 0; | |||
4840 | crv = nsc_parameter_gen(key_type, key); | |||
4841 | break; | |||
4842 | case nsc_jpake: | |||
4843 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_NSS_JPAKERound1Params))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_NSS_JPAKERound1Params))) { | |||
4844 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
4845 | goto loser; | |||
4846 | } | |||
4847 | crv = jpake_Round1(hashType, | |||
4848 | (CK_NSS_JPAKERound1Params *)pMechanism->pParameter, | |||
4849 | key); | |||
4850 | break; | |||
4851 | } | |||
4852 | ||||
4853 | if (crv != CKR_OK0x00000000UL) { | |||
4854 | goto loser; | |||
4855 | } | |||
4856 | ||||
4857 | /* Add the class, key_type, and value */ | |||
4858 | crv = sftk_AddAttributeType(key, CKA_CLASS0x00000000UL, &objclass, sizeof(CK_OBJECT_CLASS)); | |||
4859 | if (crv != CKR_OK0x00000000UL) { | |||
4860 | goto loser; | |||
4861 | } | |||
4862 | crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &key_type, sizeof(CK_KEY_TYPE)); | |||
4863 | if (crv != CKR_OK0x00000000UL) { | |||
4864 | goto loser; | |||
4865 | } | |||
4866 | if (key_length != 0) { | |||
4867 | crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL, buf, key_length); | |||
4868 | if (crv != CKR_OK0x00000000UL) { | |||
4869 | goto loser; | |||
4870 | } | |||
4871 | } | |||
4872 | ||||
4873 | /* get the session */ | |||
4874 | session = sftk_SessionFromHandle(hSession); | |||
4875 | if (session == NULL((void*)0)) { | |||
4876 | crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
4877 | goto loser; | |||
4878 | } | |||
4879 | ||||
4880 | /* | |||
4881 | * handle the base object stuff | |||
4882 | */ | |||
4883 | crv = sftk_handleObject(key, session); | |||
4884 | sftk_FreeSession(session); | |||
4885 | if (crv == CKR_OK0x00000000UL && sftk_isTrue(key, CKA_SENSITIVE0x00000103UL)) { | |||
4886 | crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE0x00000165UL, &cktrue, sizeof(CK_BBOOL)); | |||
4887 | } | |||
4888 | if (crv == CKR_OK0x00000000UL && !sftk_isTrue(key, CKA_EXTRACTABLE0x00000162UL)) { | |||
4889 | crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE0x00000164UL, &cktrue, sizeof(CK_BBOOL)); | |||
4890 | } | |||
4891 | if (crv == CKR_OK0x00000000UL) { | |||
4892 | *phKey = key->handle; | |||
4893 | } | |||
4894 | loser: | |||
4895 | PORT_Memsetmemset(buf, 0, sizeof buf); | |||
4896 | sftk_FreeObject(key); | |||
4897 | return crv; | |||
4898 | } | |||
4899 | ||||
4900 | #define PAIRWISE_DIGEST_LENGTH20 SHA1_LENGTH20 /* 160-bits */ | |||
4901 | #define PAIRWISE_MESSAGE_LENGTH20 20 /* 160-bits */ | |||
4902 | ||||
4903 | /* | |||
4904 | * FIPS 140-2 pairwise consistency check utilized to validate key pair. | |||
4905 | * | |||
4906 | * This function returns | |||
4907 | * CKR_OK if pairwise consistency check passed | |||
4908 | * CKR_GENERAL_ERROR if pairwise consistency check failed | |||
4909 | * other error codes if paiswise consistency check could not be | |||
4910 | * performed, for example, CKR_HOST_MEMORY. | |||
4911 | */ | |||
4912 | static CK_RV | |||
4913 | sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, SFTKSlot *slot, | |||
4914 | SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType) | |||
4915 | { | |||
4916 | /* | |||
4917 | * Key type Mechanism type | |||
4918 | * -------------------------------- | |||
4919 | * For encrypt/decrypt: CKK_RSA => CKM_RSA_PKCS | |||
4920 | * others => CKM_INVALID_MECHANISM | |||
4921 | * | |||
4922 | * For sign/verify: CKK_RSA => CKM_RSA_PKCS | |||
4923 | * CKK_DSA => CKM_DSA | |||
4924 | * CKK_EC => CKM_ECDSA | |||
4925 | * others => CKM_INVALID_MECHANISM | |||
4926 | * | |||
4927 | * None of these mechanisms has a parameter. | |||
4928 | * | |||
4929 | * For derive CKK_DH => CKM_DH_PKCS_DERIVE | |||
4930 | * CKK_EC => CKM_ECDH1_DERIVE | |||
4931 | * others => CKM_INVALID_MECHANISM | |||
4932 | * | |||
4933 | * The parameters for these mechanisms is the public key. | |||
4934 | */ | |||
4935 | CK_MECHANISM mech = { 0, NULL((void*)0), 0 }; | |||
4936 | ||||
4937 | CK_ULONG modulusLen = 0; | |||
4938 | CK_ULONG subPrimeLen = 0; | |||
4939 | PRBool isEncryptable = PR_FALSE0; | |||
4940 | PRBool canSignVerify = PR_FALSE0; | |||
4941 | PRBool isDerivable = PR_FALSE0; | |||
4942 | CK_RV crv; | |||
4943 | ||||
4944 | /* Variables used for Encrypt/Decrypt functions. */ | |||
4945 | unsigned char *known_message = (unsigned char *)"Known Crypto Message"; | |||
4946 | unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH20]; | |||
4947 | CK_ULONG bytes_decrypted; | |||
4948 | unsigned char *ciphertext; | |||
4949 | unsigned char *text_compared; | |||
4950 | CK_ULONG bytes_encrypted; | |||
4951 | CK_ULONG bytes_compared; | |||
4952 | CK_ULONG pairwise_digest_length = PAIRWISE_DIGEST_LENGTH20; | |||
4953 | ||||
4954 | /* Variables used for Signature/Verification functions. */ | |||
4955 | /* Must be at least 256 bits for DSA2 digest */ | |||
4956 | unsigned char *known_digest = (unsigned char *)"Mozilla Rules the World through NSS!"; | |||
4957 | unsigned char *signature; | |||
4958 | CK_ULONG signature_length; | |||
4959 | ||||
4960 | if (keyType == CKK_RSA0x00000000UL) { | |||
4961 | SFTKAttribute *attribute; | |||
4962 | ||||
4963 | /* Get modulus length of private key. */ | |||
4964 | attribute = sftk_FindAttribute(privateKey, CKA_MODULUS0x00000120UL); | |||
4965 | if (attribute == NULL((void*)0)) { | |||
4966 | return CKR_DEVICE_ERROR0x00000030UL; | |||
4967 | } | |||
4968 | modulusLen = attribute->attrib.ulValueLen; | |||
4969 | if (*(unsigned char *)attribute->attrib.pValue == 0) { | |||
4970 | modulusLen--; | |||
4971 | } | |||
4972 | sftk_FreeAttribute(attribute); | |||
4973 | } else if (keyType == CKK_DSA0x00000001UL) { | |||
4974 | SFTKAttribute *attribute; | |||
4975 | ||||
4976 | /* Get subprime length of private key. */ | |||
4977 | attribute = sftk_FindAttribute(privateKey, CKA_SUBPRIME0x00000131UL); | |||
4978 | if (attribute == NULL((void*)0)) { | |||
4979 | return CKR_DEVICE_ERROR0x00000030UL; | |||
4980 | } | |||
4981 | subPrimeLen = attribute->attrib.ulValueLen; | |||
4982 | if (subPrimeLen > 1 && *(unsigned char *)attribute->attrib.pValue == 0) { | |||
4983 | subPrimeLen--; | |||
4984 | } | |||
4985 | sftk_FreeAttribute(attribute); | |||
4986 | } | |||
4987 | ||||
4988 | /**************************************************/ | |||
4989 | /* Pairwise Consistency Check of Encrypt/Decrypt. */ | |||
4990 | /**************************************************/ | |||
4991 | ||||
4992 | isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT0x00000105UL); | |||
4993 | ||||
4994 | /* | |||
4995 | * If the decryption attribute is set, attempt to encrypt | |||
4996 | * with the public key and decrypt with the private key. | |||
4997 | */ | |||
4998 | if (isEncryptable) { | |||
4999 | if (keyType != CKK_RSA0x00000000UL) { | |||
5000 | return CKR_DEVICE_ERROR0x00000030UL; | |||
5001 | } | |||
5002 | bytes_encrypted = modulusLen; | |||
5003 | mech.mechanism = CKM_RSA_PKCS0x00000001UL; | |||
5004 | ||||
5005 | /* Allocate space for ciphertext. */ | |||
5006 | ciphertext = (unsigned char *)PORT_ZAllocPORT_ZAlloc_Util(bytes_encrypted); | |||
5007 | if (ciphertext == NULL((void*)0)) { | |||
5008 | return CKR_HOST_MEMORY0x00000002UL; | |||
5009 | } | |||
5010 | ||||
5011 | /* Prepare for encryption using the public key. */ | |||
5012 | crv = NSC_EncryptInit(hSession, &mech, publicKey->handle); | |||
5013 | if (crv != CKR_OK0x00000000UL) { | |||
5014 | PORT_FreePORT_Free_Util(ciphertext); | |||
5015 | return crv; | |||
5016 | } | |||
5017 | ||||
5018 | /* Encrypt using the public key. */ | |||
5019 | crv = NSC_Encrypt(hSession, | |||
5020 | known_message, | |||
5021 | PAIRWISE_MESSAGE_LENGTH20, | |||
5022 | ciphertext, | |||
5023 | &bytes_encrypted); | |||
5024 | if (crv != CKR_OK0x00000000UL) { | |||
5025 | PORT_FreePORT_Free_Util(ciphertext); | |||
5026 | return crv; | |||
5027 | } | |||
5028 | ||||
5029 | /* Always use the smaller of these two values . . . */ | |||
5030 | bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH)((bytes_encrypted)<(20)?(bytes_encrypted):(20)); | |||
5031 | ||||
5032 | /* | |||
5033 | * If there was a failure, the plaintext | |||
5034 | * goes at the end, therefore . . . | |||
5035 | */ | |||
5036 | text_compared = ciphertext + bytes_encrypted - bytes_compared; | |||
5037 | ||||
5038 | /* | |||
5039 | * Check to ensure that ciphertext does | |||
5040 | * NOT EQUAL known input message text | |||
5041 | * per FIPS PUB 140-2 directive. | |||
5042 | */ | |||
5043 | if (PORT_Memcmpmemcmp(text_compared, known_message, | |||
5044 | bytes_compared) == 0) { | |||
5045 | /* Set error to Invalid PRIVATE Key. */ | |||
5046 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY); | |||
5047 | PORT_FreePORT_Free_Util(ciphertext); | |||
5048 | return CKR_GENERAL_ERROR0x00000005UL; | |||
5049 | } | |||
5050 | ||||
5051 | /* Prepare for decryption using the private key. */ | |||
5052 | crv = NSC_DecryptInit(hSession, &mech, privateKey->handle); | |||
5053 | if (crv != CKR_OK0x00000000UL) { | |||
5054 | PORT_FreePORT_Free_Util(ciphertext); | |||
5055 | return crv; | |||
5056 | } | |||
5057 | ||||
5058 | memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH20); | |||
5059 | ||||
5060 | /* | |||
5061 | * Initialize bytes decrypted to be the | |||
5062 | * expected PAIRWISE_MESSAGE_LENGTH. | |||
5063 | */ | |||
5064 | bytes_decrypted = PAIRWISE_MESSAGE_LENGTH20; | |||
5065 | ||||
5066 | /* | |||
5067 | * Decrypt using the private key. | |||
5068 | * NOTE: No need to reset the | |||
5069 | * value of bytes_encrypted. | |||
5070 | */ | |||
5071 | crv = NSC_Decrypt(hSession, | |||
5072 | ciphertext, | |||
5073 | bytes_encrypted, | |||
5074 | plaintext, | |||
5075 | &bytes_decrypted); | |||
5076 | ||||
5077 | /* Finished with ciphertext; free it. */ | |||
5078 | PORT_FreePORT_Free_Util(ciphertext); | |||
5079 | ||||
5080 | if (crv != CKR_OK0x00000000UL) { | |||
5081 | return crv; | |||
5082 | } | |||
5083 | ||||
5084 | /* | |||
5085 | * Check to ensure that the output plaintext | |||
5086 | * does EQUAL known input message text. | |||
5087 | */ | |||
5088 | if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH20) || | |||
5089 | (PORT_Memcmpmemcmp(plaintext, known_message, | |||
5090 | PAIRWISE_MESSAGE_LENGTH20) != 0)) { | |||
5091 | /* Set error to Bad PUBLIC Key. */ | |||
5092 | PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY); | |||
5093 | return CKR_GENERAL_ERROR0x00000005UL; | |||
5094 | } | |||
5095 | } | |||
5096 | ||||
5097 | /**********************************************/ | |||
5098 | /* Pairwise Consistency Check of Sign/Verify. */ | |||
5099 | /**********************************************/ | |||
5100 | ||||
5101 | canSignVerify = sftk_isTrue(privateKey, CKA_SIGN0x00000108UL); | |||
5102 | /* Unfortunately CKA_SIGN is always true in lg dbs. We have to check the | |||
5103 | * actual curve to determine if we can do sign/verify. */ | |||
5104 | if (canSignVerify && keyType == CKK_EC0x00000003UL) { | |||
5105 | NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(privateKey, CKK_EC0x00000003UL, &crv); | |||
5106 | if (privKey && privKey->u.ec.ecParams.name == ECCurve25519) { | |||
5107 | canSignVerify = PR_FALSE0; | |||
5108 | } | |||
5109 | } | |||
5110 | ||||
5111 | if (canSignVerify) { | |||
5112 | /* Determine length of signature. */ | |||
5113 | switch (keyType) { | |||
5114 | case CKK_RSA0x00000000UL: | |||
5115 | signature_length = modulusLen; | |||
5116 | mech.mechanism = CKM_RSA_PKCS0x00000001UL; | |||
5117 | break; | |||
5118 | case CKK_DSA0x00000001UL: | |||
5119 | signature_length = DSA_MAX_SIGNATURE_LEN(32 * 2); | |||
5120 | pairwise_digest_length = subPrimeLen; | |||
5121 | mech.mechanism = CKM_DSA0x00000011UL; | |||
5122 | break; | |||
5123 | case CKK_EC0x00000003UL: | |||
5124 | signature_length = MAX_ECKEY_LEN72 * 2; | |||
5125 | mech.mechanism = CKM_ECDSA0x00001041UL; | |||
5126 | break; | |||
5127 | case CKK_EC_EDWARDS0x00000040UL: | |||
5128 | signature_length = ED25519_SIGN_LEN64U; | |||
5129 | mech.mechanism = CKM_EDDSA0x00001057UL; | |||
5130 | break; | |||
5131 | default: | |||
5132 | return CKR_DEVICE_ERROR0x00000030UL; | |||
5133 | } | |||
5134 | ||||
5135 | /* Allocate space for signature data. */ | |||
5136 | signature = (unsigned char *)PORT_ZAllocPORT_ZAlloc_Util(signature_length); | |||
5137 | if (signature == NULL((void*)0)) { | |||
5138 | return CKR_HOST_MEMORY0x00000002UL; | |||
5139 | } | |||
5140 | ||||
5141 | /* Sign the known hash using the private key. */ | |||
5142 | crv = NSC_SignInit(hSession, &mech, privateKey->handle); | |||
5143 | if (crv != CKR_OK0x00000000UL) { | |||
5144 | PORT_FreePORT_Free_Util(signature); | |||
5145 | return crv; | |||
5146 | } | |||
5147 | ||||
5148 | crv = NSC_Sign(hSession, | |||
5149 | known_digest, | |||
5150 | pairwise_digest_length, | |||
5151 | signature, | |||
5152 | &signature_length); | |||
5153 | if (crv != CKR_OK0x00000000UL) { | |||
5154 | PORT_FreePORT_Free_Util(signature); | |||
5155 | return crv; | |||
5156 | } | |||
5157 | ||||
5158 | /* detect trivial signing transforms */ | |||
5159 | if ((signature_length >= pairwise_digest_length) && | |||
5160 | (PORT_Memcmpmemcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) { | |||
5161 | PORT_FreePORT_Free_Util(signature); | |||
5162 | return CKR_DEVICE_ERROR0x00000030UL; | |||
5163 | } | |||
5164 | ||||
5165 | /* Verify the known hash using the public key. */ | |||
5166 | crv = NSC_VerifyInit(hSession, &mech, publicKey->handle); | |||
5167 | if (crv != CKR_OK0x00000000UL) { | |||
5168 | PORT_FreePORT_Free_Util(signature); | |||
5169 | return crv; | |||
5170 | } | |||
5171 | ||||
5172 | crv = NSC_Verify(hSession, | |||
5173 | known_digest, | |||
5174 | pairwise_digest_length, | |||
5175 | signature, | |||
5176 | signature_length); | |||
5177 | ||||
5178 | /* Free signature data. */ | |||
5179 | PORT_FreePORT_Free_Util(signature); | |||
5180 | ||||
5181 | if ((crv == CKR_SIGNATURE_LEN_RANGE0x000000C1UL) || | |||
5182 | (crv == CKR_SIGNATURE_INVALID0x000000C0UL)) { | |||
5183 | return CKR_GENERAL_ERROR0x00000005UL; | |||
5184 | } | |||
5185 | if (crv != CKR_OK0x00000000UL) { | |||
5186 | return crv; | |||
5187 | } | |||
5188 | } | |||
5189 | ||||
5190 | /**********************************************/ | |||
5191 | /* Pairwise Consistency Check for Derivation */ | |||
5192 | /**********************************************/ | |||
5193 | ||||
5194 | isDerivable = sftk_isTrue(privateKey, CKA_DERIVE0x0000010CUL); | |||
5195 | ||||
5196 | if (isDerivable) { | |||
5197 | SFTKAttribute *pubAttribute = NULL((void*)0); | |||
5198 | CK_OBJECT_HANDLE newKey; | |||
5199 | PRBool isFIPS = sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101)); | |||
5200 | CK_RV crv2; | |||
5201 | CK_OBJECT_CLASS secret = CKO_SECRET_KEY0x00000004UL; | |||
5202 | CK_KEY_TYPE generic = CKK_GENERIC_SECRET0x00000010UL; | |||
5203 | CK_ULONG keyLen = 128; | |||
5204 | CK_BBOOL ckTrue = CK_TRUE1; | |||
5205 | CK_ATTRIBUTE template[] = { | |||
5206 | { CKA_CLASS0x00000000UL, &secret, sizeof(secret) }, | |||
5207 | { CKA_KEY_TYPE0x00000100UL, &generic, sizeof(generic) }, | |||
5208 | { CKA_VALUE_LEN0x00000161UL, &keyLen, sizeof(keyLen) }, | |||
5209 | { CKA_DERIVE0x0000010CUL, &ckTrue, sizeof(ckTrue) } | |||
5210 | }; | |||
5211 | CK_ULONG templateCount = PR_ARRAY_SIZE(template)(sizeof(template)/sizeof((template)[0])); | |||
5212 | CK_ECDH1_DERIVE_PARAMS ecParams; | |||
5213 | ||||
5214 | crv = CKR_OK0x00000000UL; /*paranoia, already get's set before we drop to the end */ | |||
5215 | /* FIPS 140-2 requires we verify that the resulting key is a valid key. | |||
5216 | * The easiest way to do this is to do a derive operation, which checks | |||
5217 | * the validity of the key */ | |||
5218 | ||||
5219 | switch (keyType) { | |||
5220 | case CKK_DH0x00000002UL: | |||
5221 | mech.mechanism = CKM_DH_PKCS_DERIVE0x00000021UL; | |||
5222 | pubAttribute = sftk_FindAttribute(publicKey, CKA_VALUE0x00000011UL); | |||
5223 | if (pubAttribute == NULL((void*)0)) { | |||
5224 | return CKR_DEVICE_ERROR0x00000030UL; | |||
5225 | } | |||
5226 | mech.pParameter = pubAttribute->attrib.pValue; | |||
5227 | mech.ulParameterLen = pubAttribute->attrib.ulValueLen; | |||
5228 | break; | |||
5229 | case CKK_EC0x00000003UL: | |||
5230 | mech.mechanism = CKM_ECDH1_DERIVE0x00001050UL; | |||
5231 | pubAttribute = sftk_FindAttribute(publicKey, CKA_EC_POINT0x00000181UL); | |||
5232 | if (pubAttribute == NULL((void*)0)) { | |||
5233 | return CKR_DEVICE_ERROR0x00000030UL; | |||
5234 | } | |||
5235 | ecParams.kdf = CKD_NULL0x00000001UL; | |||
5236 | ecParams.ulSharedDataLen = 0; | |||
5237 | ecParams.pSharedData = NULL((void*)0); | |||
5238 | ecParams.ulPublicDataLen = pubAttribute->attrib.ulValueLen; | |||
5239 | ecParams.pPublicData = pubAttribute->attrib.pValue; | |||
5240 | mech.pParameter = &ecParams; | |||
5241 | mech.ulParameterLen = sizeof(ecParams); | |||
5242 | break; | |||
5243 | default: | |||
5244 | return CKR_DEVICE_ERROR0x00000030UL; | |||
5245 | } | |||
5246 | ||||
5247 | crv = NSC_DeriveKey(hSession, &mech, privateKey->handle, template, templateCount, &newKey); | |||
5248 | if (crv != CKR_OK0x00000000UL) { | |||
5249 | sftk_FreeAttribute(pubAttribute); | |||
5250 | return crv; | |||
5251 | } | |||
5252 | /* FIPS requires full validation, but in fipx mode NSC_Derive | |||
5253 | * only does partial validation with approved primes, now handle | |||
5254 | * full validation */ | |||
5255 | if (isFIPS && keyType == CKK_DH0x00000002UL) { | |||
5256 | SECItem pubKey; | |||
5257 | SECItem prime; | |||
5258 | SECItem subPrime; | |||
5259 | const SECItem *subPrimePtr = &subPrime; | |||
5260 | ||||
5261 | pubKey.data = pubAttribute->attrib.pValue; | |||
5262 | pubKey.len = pubAttribute->attrib.ulValueLen; | |||
5263 | prime.data = subPrime.data = NULL((void*)0); | |||
5264 | prime.len = subPrime.len = 0; | |||
5265 | crv = sftk_Attribute2SecItem(NULL((void*)0), &prime, privateKey, CKA_PRIME0x00000130UL); | |||
5266 | if (crv != CKR_OK0x00000000UL) { | |||
5267 | goto done; | |||
5268 | } | |||
5269 | crv = sftk_Attribute2SecItem(NULL((void*)0), &prime, privateKey, CKA_PRIME0x00000130UL); | |||
5270 | /* we ignore the return code an only look at the length */ | |||
5271 | if (subPrime.len == 0) { | |||
5272 | /* subprime not supplied, In this case look it up. | |||
5273 | * This only works with approved primes, but in FIPS mode | |||
5274 | * that's the only kine of prime that will get here */ | |||
5275 | subPrimePtr = sftk_VerifyDH_Prime(&prime, isFIPS); | |||
5276 | if (subPrimePtr == NULL((void*)0)) { | |||
5277 | crv = CKR_GENERAL_ERROR0x00000005UL; | |||
5278 | goto done; | |||
5279 | } | |||
5280 | } | |||
5281 | if (!KEA_Verify(&pubKey, &prime, (SECItem *)subPrimePtr)) { | |||
5282 | crv = CKR_GENERAL_ERROR0x00000005UL; | |||
5283 | } | |||
5284 | done: | |||
5285 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&subPrime, PR_FALSE0); | |||
5286 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&prime, PR_FALSE0); | |||
5287 | } | |||
5288 | /* clean up before we return */ | |||
5289 | sftk_FreeAttribute(pubAttribute); | |||
5290 | crv2 = NSC_DestroyObject(hSession, newKey); | |||
5291 | if (crv != CKR_OK0x00000000UL) { | |||
5292 | return crv; | |||
5293 | } | |||
5294 | if (crv2 != CKR_OK0x00000000UL) { | |||
5295 | return crv2; | |||
5296 | } | |||
5297 | } | |||
5298 | ||||
5299 | return CKR_OK0x00000000UL; | |||
5300 | } | |||
5301 | ||||
5302 | /* NSC_GenerateKeyPair generates a public-key/private-key pair, | |||
5303 | * creating new key objects. */ | |||
5304 | CK_RV | |||
5305 | NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, | |||
5306 | CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, | |||
5307 | CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, | |||
5308 | CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, | |||
5309 | CK_OBJECT_HANDLE_PTR phPrivateKey) | |||
5310 | { | |||
5311 | SFTKObject *publicKey, *privateKey; | |||
5312 | SFTKSession *session; | |||
5313 | CK_KEY_TYPE key_type; | |||
5314 | CK_RV crv = CKR_OK0x00000000UL; | |||
5315 | CK_BBOOL cktrue = CK_TRUE1; | |||
5316 | SECStatus rv; | |||
5317 | CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY0x00000002UL; | |||
5318 | CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY0x00000003UL; | |||
5319 | int i; | |||
5320 | SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); | |||
5321 | unsigned int bitSize; | |||
5322 | ||||
5323 | /* RSA */ | |||
5324 | int public_modulus_bits = 0; | |||
5325 | SECItem pubExp; | |||
5326 | RSAPrivateKey *rsaPriv; | |||
5327 | ||||
5328 | /* DSA */ | |||
5329 | PQGParams pqgParam; | |||
5330 | DHParams dhParam; | |||
5331 | DSAPrivateKey *dsaPriv; | |||
5332 | ||||
5333 | /* Diffie Hellman */ | |||
5334 | DHPrivateKey *dhPriv; | |||
5335 | ||||
5336 | /* Elliptic Curve Cryptography */ | |||
5337 | SECItem ecEncodedParams; /* DER Encoded parameters */ | |||
5338 | ECPrivateKey *ecPriv; | |||
5339 | ECParams *ecParams; | |||
5340 | ||||
5341 | /* Kyber */ | |||
5342 | CK_NSS_KEM_PARAMETER_SET_TYPE ckKyberParamSet; | |||
| ||||
5343 | ||||
5344 | CHECK_FORK(); | |||
5345 | ||||
5346 | if (!slot) { | |||
5347 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
5348 | } | |||
5349 | /* | |||
5350 | * now lets create an object to hang the attributes off of | |||
5351 | */ | |||
5352 | publicKey = sftk_NewObject(slot); /* fill in the handle later */ | |||
5353 | if (publicKey == NULL((void*)0)) { | |||
5354 | return CKR_HOST_MEMORY0x00000002UL; | |||
5355 | } | |||
5356 | ||||
5357 | /* | |||
5358 | * load the template values into the publicKey | |||
5359 | */ | |||
5360 | for (i = 0; i < (int)ulPublicKeyAttributeCount; i++) { | |||
5361 | if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS0x00000121UL) { | |||
5362 | public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue; | |||
5363 | continue; | |||
5364 | } | |||
5365 | ||||
5366 | if (pPublicKeyTemplate[i].type == CKA_NSS_PARAMETER_SET((0x80000000UL | 0x4E534350) + 40)) { | |||
5367 | ckKyberParamSet = *(CK_NSS_KEM_PARAMETER_SET_TYPE *)pPublicKeyTemplate[i].pValue; | |||
5368 | continue; | |||
5369 | } | |||
5370 | ||||
5371 | crv = sftk_AddAttributeType(publicKey, | |||
5372 | sftk_attr_expand(&pPublicKeyTemplate[i])(&pPublicKeyTemplate[i])->type, (&pPublicKeyTemplate [i])->pValue, (&pPublicKeyTemplate[i])->ulValueLen); | |||
5373 | if (crv != CKR_OK0x00000000UL) | |||
5374 | break; | |||
5375 | } | |||
5376 | ||||
5377 | if (crv
| |||
5378 | sftk_FreeObject(publicKey); | |||
5379 | return CKR_HOST_MEMORY0x00000002UL; | |||
5380 | } | |||
5381 | ||||
5382 | privateKey = sftk_NewObject(slot); /* fill in the handle later */ | |||
5383 | if (privateKey == NULL((void*)0)) { | |||
5384 | sftk_FreeObject(publicKey); | |||
5385 | return CKR_HOST_MEMORY0x00000002UL; | |||
5386 | } | |||
5387 | /* | |||
5388 | * now load the private key template | |||
5389 | */ | |||
5390 | for (i = 0; i < (int)ulPrivateKeyAttributeCount; i++) { | |||
5391 | if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS0x00000160UL) { | |||
5392 | continue; | |||
5393 | } | |||
5394 | ||||
5395 | crv = sftk_AddAttributeType(privateKey, | |||
5396 | sftk_attr_expand(&pPrivateKeyTemplate[i])(&pPrivateKeyTemplate[i])->type, (&pPrivateKeyTemplate [i])->pValue, (&pPrivateKeyTemplate[i])->ulValueLen); | |||
5397 | if (crv != CKR_OK0x00000000UL) | |||
5398 | break; | |||
5399 | } | |||
5400 | ||||
5401 | if (crv
| |||
5402 | sftk_FreeObject(publicKey); | |||
5403 | sftk_FreeObject(privateKey); | |||
5404 | return CKR_HOST_MEMORY0x00000002UL; | |||
5405 | } | |||
5406 | sftk_DeleteAttributeType(privateKey, CKA_CLASS0x00000000UL); | |||
5407 | sftk_DeleteAttributeType(privateKey, CKA_KEY_TYPE0x00000100UL); | |||
5408 | sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL); | |||
5409 | sftk_DeleteAttributeType(publicKey, CKA_CLASS0x00000000UL); | |||
5410 | sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE0x00000100UL); | |||
5411 | sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL); | |||
5412 | ||||
5413 | /* Now Set up the parameters to generate the key (based on mechanism) */ | |||
5414 | switch (pMechanism->mechanism) { | |||
5415 | case CKM_RSA_PKCS_KEY_PAIR_GEN0x00000000UL: | |||
5416 | /* format the keys */ | |||
5417 | sftk_DeleteAttributeType(publicKey, CKA_MODULUS0x00000120UL); | |||
5418 | sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L); | |||
5419 | sftk_DeleteAttributeType(privateKey, CKA_MODULUS0x00000120UL); | |||
5420 | sftk_DeleteAttributeType(privateKey, CKA_PRIVATE_EXPONENT0x00000123UL); | |||
5421 | sftk_DeleteAttributeType(privateKey, CKA_PUBLIC_EXPONENT0x00000122UL); | |||
5422 | sftk_DeleteAttributeType(privateKey, CKA_PRIME_10x00000124UL); | |||
5423 | sftk_DeleteAttributeType(privateKey, CKA_PRIME_20x00000125UL); | |||
5424 | sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_10x00000126UL); | |||
5425 | sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_20x00000127UL); | |||
5426 | sftk_DeleteAttributeType(privateKey, CKA_COEFFICIENT0x00000128UL); | |||
5427 | key_type = CKK_RSA0x00000000UL; | |||
5428 | if (public_modulus_bits == 0) { | |||
5429 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
5430 | break; | |||
5431 | } | |||
5432 | if (public_modulus_bits < RSA_MIN_MODULUS_BITS128) { | |||
5433 | crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL; | |||
5434 | break; | |||
5435 | } | |||
5436 | if (public_modulus_bits % 2 != 0) { | |||
5437 | crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL; | |||
5438 | break; | |||
5439 | } | |||
5440 | ||||
5441 | /* extract the exponent */ | |||
5442 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &pubExp, publicKey, CKA_PUBLIC_EXPONENT0x00000122UL); | |||
5443 | if (crv != CKR_OK0x00000000UL) | |||
5444 | break; | |||
5445 | bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len); | |||
5446 | if (bitSize < 2) { | |||
5447 | crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL; | |||
5448 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubExp, PR_FALSE0); | |||
5449 | break; | |||
5450 | } | |||
5451 | crv = sftk_AddAttributeType(privateKey, CKA_PUBLIC_EXPONENT0x00000122UL, | |||
5452 | sftk_item_expand(&pubExp)(&pubExp)->data, (&pubExp)->len); | |||
5453 | if (crv != CKR_OK0x00000000UL) { | |||
5454 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubExp, PR_FALSE0); | |||
5455 | break; | |||
5456 | } | |||
5457 | ||||
5458 | rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp); | |||
5459 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubExp, PR_FALSE0); | |||
5460 | if (rsaPriv == NULL((void*)0)) { | |||
5461 | if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
5462 | sftk_fatalError = PR_TRUE1; | |||
5463 | } | |||
5464 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5465 | break; | |||
5466 | } | |||
5467 | /* now fill in the RSA dependent paramenters in the public key */ | |||
5468 | crv = sftk_AddAttributeType(publicKey, CKA_MODULUS0x00000120UL, | |||
5469 | sftk_item_expand(&rsaPriv->modulus)(&rsaPriv->modulus)->data, (&rsaPriv->modulus )->len); | |||
5470 | if (crv != CKR_OK0x00000000UL) | |||
5471 | goto kpg_done; | |||
5472 | /* now fill in the RSA dependent paramenters in the private key */ | |||
5473 | crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L, | |||
5474 | sftk_item_expand(&rsaPriv->modulus)(&rsaPriv->modulus)->data, (&rsaPriv->modulus )->len); | |||
5475 | if (crv != CKR_OK0x00000000UL) | |||
5476 | goto kpg_done; | |||
5477 | crv = sftk_AddAttributeType(privateKey, CKA_MODULUS0x00000120UL, | |||
5478 | sftk_item_expand(&rsaPriv->modulus)(&rsaPriv->modulus)->data, (&rsaPriv->modulus )->len); | |||
5479 | if (crv != CKR_OK0x00000000UL) | |||
5480 | goto kpg_done; | |||
5481 | crv = sftk_AddAttributeType(privateKey, CKA_PRIVATE_EXPONENT0x00000123UL, | |||
5482 | sftk_item_expand(&rsaPriv->privateExponent)(&rsaPriv->privateExponent)->data, (&rsaPriv-> privateExponent)->len); | |||
5483 | if (crv != CKR_OK0x00000000UL) | |||
5484 | goto kpg_done; | |||
5485 | crv = sftk_AddAttributeType(privateKey, CKA_PRIME_10x00000124UL, | |||
5486 | sftk_item_expand(&rsaPriv->prime1)(&rsaPriv->prime1)->data, (&rsaPriv->prime1) ->len); | |||
5487 | if (crv != CKR_OK0x00000000UL) | |||
5488 | goto kpg_done; | |||
5489 | crv = sftk_AddAttributeType(privateKey, CKA_PRIME_20x00000125UL, | |||
5490 | sftk_item_expand(&rsaPriv->prime2)(&rsaPriv->prime2)->data, (&rsaPriv->prime2) ->len); | |||
5491 | if (crv != CKR_OK0x00000000UL) | |||
5492 | goto kpg_done; | |||
5493 | crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_10x00000126UL, | |||
5494 | sftk_item_expand(&rsaPriv->exponent1)(&rsaPriv->exponent1)->data, (&rsaPriv->exponent1 )->len); | |||
5495 | if (crv != CKR_OK0x00000000UL) | |||
5496 | goto kpg_done; | |||
5497 | crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_20x00000127UL, | |||
5498 | sftk_item_expand(&rsaPriv->exponent2)(&rsaPriv->exponent2)->data, (&rsaPriv->exponent2 )->len); | |||
5499 | if (crv != CKR_OK0x00000000UL) | |||
5500 | goto kpg_done; | |||
5501 | crv = sftk_AddAttributeType(privateKey, CKA_COEFFICIENT0x00000128UL, | |||
5502 | sftk_item_expand(&rsaPriv->coefficient)(&rsaPriv->coefficient)->data, (&rsaPriv->coefficient )->len); | |||
5503 | kpg_done: | |||
5504 | /* Should zeroize the contents first, since this func doesn't. */ | |||
5505 | PORT_FreeArenaPORT_FreeArena_Util(rsaPriv->arena, PR_TRUE1); | |||
5506 | break; | |||
5507 | case CKM_DSA_KEY_PAIR_GEN0x00000010UL: | |||
5508 | sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL); | |||
5509 | sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L); | |||
5510 | sftk_DeleteAttributeType(privateKey, CKA_PRIME0x00000130UL); | |||
5511 | sftk_DeleteAttributeType(privateKey, CKA_SUBPRIME0x00000131UL); | |||
5512 | sftk_DeleteAttributeType(privateKey, CKA_BASE0x00000132UL); | |||
5513 | key_type = CKK_DSA0x00000001UL; | |||
5514 | ||||
5515 | /* extract the necessary parameters and copy them to the private key */ | |||
5516 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &pqgParam.prime, publicKey, CKA_PRIME0x00000130UL); | |||
5517 | if (crv != CKR_OK0x00000000UL) | |||
5518 | break; | |||
5519 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &pqgParam.subPrime, publicKey, | |||
5520 | CKA_SUBPRIME0x00000131UL); | |||
5521 | if (crv != CKR_OK0x00000000UL) { | |||
5522 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5523 | break; | |||
5524 | } | |||
5525 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &pqgParam.base, publicKey, CKA_BASE0x00000132UL); | |||
5526 | if (crv != CKR_OK0x00000000UL) { | |||
5527 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5528 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5529 | break; | |||
5530 | } | |||
5531 | crv = sftk_AddAttributeType(privateKey, CKA_PRIME0x00000130UL, | |||
5532 | sftk_item_expand(&pqgParam.prime)(&pqgParam.prime)->data, (&pqgParam.prime)->len); | |||
5533 | if (crv != CKR_OK0x00000000UL) { | |||
5534 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5535 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5536 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0); | |||
5537 | break; | |||
5538 | } | |||
5539 | crv = sftk_AddAttributeType(privateKey, CKA_SUBPRIME0x00000131UL, | |||
5540 | sftk_item_expand(&pqgParam.subPrime)(&pqgParam.subPrime)->data, (&pqgParam.subPrime)-> len); | |||
5541 | if (crv != CKR_OK0x00000000UL) { | |||
5542 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5543 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5544 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0); | |||
5545 | break; | |||
5546 | } | |||
5547 | crv = sftk_AddAttributeType(privateKey, CKA_BASE0x00000132UL, | |||
5548 | sftk_item_expand(&pqgParam.base)(&pqgParam.base)->data, (&pqgParam.base)->len); | |||
5549 | if (crv != CKR_OK0x00000000UL) { | |||
5550 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5551 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5552 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0); | |||
5553 | break; | |||
5554 | } | |||
5555 | ||||
5556 | /* | |||
5557 | * these are checked by DSA_NewKey | |||
5558 | */ | |||
5559 | bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data, | |||
5560 | pqgParam.subPrime.len); | |||
5561 | if ((bitSize < DSA_MIN_Q_BITS160) || (bitSize > DSA_MAX_Q_BITS256)) { | |||
5562 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
5563 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5564 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5565 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0); | |||
5566 | break; | |||
5567 | } | |||
5568 | bitSize = sftk_GetLengthInBits(pqgParam.prime.data, pqgParam.prime.len); | |||
5569 | if ((bitSize < DSA_MIN_P_BITS512) || (bitSize > DSA_MAX_P_BITS3072)) { | |||
5570 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
5571 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5572 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5573 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0); | |||
5574 | break; | |||
5575 | } | |||
5576 | bitSize = sftk_GetLengthInBits(pqgParam.base.data, pqgParam.base.len); | |||
5577 | if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS3072)) { | |||
5578 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
5579 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5580 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5581 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0); | |||
5582 | break; | |||
5583 | } | |||
5584 | ||||
5585 | /* Generate the key */ | |||
5586 | rv = DSA_NewKey(&pqgParam, &dsaPriv); | |||
5587 | ||||
5588 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0); | |||
5589 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0); | |||
5590 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0); | |||
5591 | ||||
5592 | if (rv != SECSuccess) { | |||
5593 | if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
5594 | sftk_fatalError = PR_TRUE1; | |||
5595 | } | |||
5596 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5597 | break; | |||
5598 | } | |||
5599 | ||||
5600 | /* store the generated key into the attributes */ | |||
5601 | crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL, | |||
5602 | sftk_item_expand(&dsaPriv->publicValue)(&dsaPriv->publicValue)->data, (&dsaPriv->publicValue )->len); | |||
5603 | if (crv != CKR_OK0x00000000UL) | |||
5604 | goto dsagn_done; | |||
5605 | ||||
5606 | /* now fill in the RSA dependent paramenters in the private key */ | |||
5607 | crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L, | |||
5608 | sftk_item_expand(&dsaPriv->publicValue)(&dsaPriv->publicValue)->data, (&dsaPriv->publicValue )->len); | |||
5609 | if (crv != CKR_OK0x00000000UL) | |||
5610 | goto dsagn_done; | |||
5611 | crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL, | |||
5612 | sftk_item_expand(&dsaPriv->privateValue)(&dsaPriv->privateValue)->data, (&dsaPriv->privateValue )->len); | |||
5613 | ||||
5614 | dsagn_done: | |||
5615 | /* should zeroize, since this function doesn't. */ | |||
5616 | PORT_FreeArenaPORT_FreeArena_Util(dsaPriv->params.arena, PR_TRUE1); | |||
5617 | break; | |||
5618 | ||||
5619 | case CKM_DH_PKCS_KEY_PAIR_GEN0x00000020UL: | |||
5620 | sftk_DeleteAttributeType(privateKey, CKA_PRIME0x00000130UL); | |||
5621 | sftk_DeleteAttributeType(privateKey, CKA_BASE0x00000132UL); | |||
5622 | sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL); | |||
5623 | sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L); | |||
5624 | key_type = CKK_DH0x00000002UL; | |||
5625 | ||||
5626 | /* extract the necessary parameters and copy them to private keys */ | |||
5627 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &dhParam.prime, publicKey, | |||
5628 | CKA_PRIME0x00000130UL); | |||
5629 | if (crv != CKR_OK0x00000000UL) | |||
5630 | break; | |||
5631 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &dhParam.base, publicKey, CKA_BASE0x00000132UL); | |||
5632 | if (crv != CKR_OK0x00000000UL) { | |||
5633 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0); | |||
5634 | break; | |||
5635 | } | |||
5636 | crv = sftk_AddAttributeType(privateKey, CKA_PRIME0x00000130UL, | |||
5637 | sftk_item_expand(&dhParam.prime)(&dhParam.prime)->data, (&dhParam.prime)->len); | |||
5638 | if (crv != CKR_OK0x00000000UL) { | |||
5639 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0); | |||
5640 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0); | |||
5641 | break; | |||
5642 | } | |||
5643 | crv = sftk_AddAttributeType(privateKey, CKA_BASE0x00000132UL, | |||
5644 | sftk_item_expand(&dhParam.base)(&dhParam.base)->data, (&dhParam.base)->len); | |||
5645 | if (crv != CKR_OK0x00000000UL) { | |||
5646 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0); | |||
5647 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0); | |||
5648 | break; | |||
5649 | } | |||
5650 | bitSize = sftk_GetLengthInBits(dhParam.prime.data, dhParam.prime.len); | |||
5651 | if ((bitSize < DH_MIN_P_BITS128) || (bitSize > DH_MAX_P_BITS16384)) { | |||
5652 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
5653 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0); | |||
5654 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0); | |||
5655 | break; | |||
5656 | } | |||
5657 | bitSize = sftk_GetLengthInBits(dhParam.base.data, dhParam.base.len); | |||
5658 | if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS16384)) { | |||
5659 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
5660 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0); | |||
5661 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0); | |||
5662 | break; | |||
5663 | } | |||
5664 | ||||
5665 | rv = DH_NewKey(&dhParam, &dhPriv); | |||
5666 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0); | |||
5667 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0); | |||
5668 | if (rv != SECSuccess) { | |||
5669 | if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
5670 | sftk_fatalError = PR_TRUE1; | |||
5671 | } | |||
5672 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5673 | break; | |||
5674 | } | |||
5675 | ||||
5676 | crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL, | |||
5677 | sftk_item_expand(&dhPriv->publicValue)(&dhPriv->publicValue)->data, (&dhPriv->publicValue )->len); | |||
5678 | if (crv != CKR_OK0x00000000UL) | |||
5679 | goto dhgn_done; | |||
5680 | ||||
5681 | crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L, | |||
5682 | sftk_item_expand(&dhPriv->publicValue)(&dhPriv->publicValue)->data, (&dhPriv->publicValue )->len); | |||
5683 | if (crv != CKR_OK0x00000000UL) | |||
5684 | goto dhgn_done; | |||
5685 | ||||
5686 | crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL, | |||
5687 | sftk_item_expand(&dhPriv->privateValue)(&dhPriv->privateValue)->data, (&dhPriv->privateValue )->len); | |||
5688 | ||||
5689 | dhgn_done: | |||
5690 | /* should zeroize, since this function doesn't. */ | |||
5691 | PORT_FreeArenaPORT_FreeArena_Util(dhPriv->arena, PR_TRUE1); | |||
5692 | break; | |||
5693 | ||||
5694 | case CKM_EC_KEY_PAIR_GEN0x00001040UL: | |||
5695 | sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL); | |||
5696 | sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL); | |||
5697 | sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L); | |||
5698 | key_type = CKK_EC0x00000003UL; | |||
5699 | ||||
5700 | /* extract the necessary parameters and copy them to private keys */ | |||
5701 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &ecEncodedParams, publicKey, | |||
5702 | CKA_EC_PARAMS0x00000180UL); | |||
5703 | if (crv != CKR_OK0x00000000UL) | |||
5704 | break; | |||
5705 | ||||
5706 | crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL, | |||
5707 | sftk_item_expand(&ecEncodedParams)(&ecEncodedParams)->data, (&ecEncodedParams)->len); | |||
5708 | if (crv != CKR_OK0x00000000UL) { | |||
5709 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0); | |||
5710 | break; | |||
5711 | } | |||
5712 | ||||
5713 | /* Decode ec params before calling EC_NewKey */ | |||
5714 | rv = EC_DecodeParams(&ecEncodedParams, &ecParams); | |||
5715 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0); | |||
5716 | if (rv != SECSuccess) { | |||
5717 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5718 | break; | |||
5719 | } | |||
5720 | rv = EC_NewKey(ecParams, &ecPriv); | |||
5721 | if (rv != SECSuccess) { | |||
5722 | if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
5723 | sftk_fatalError = PR_TRUE1; | |||
5724 | } | |||
5725 | PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1); | |||
5726 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5727 | break; | |||
5728 | } | |||
5729 | ||||
5730 | if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") || | |||
5731 | ecParams->type != ec_params_named) { | |||
5732 | PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1); | |||
5733 | crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL, | |||
5734 | sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue )->len); | |||
5735 | } else { | |||
5736 | PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1); | |||
5737 | SECItem *pubValue = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), | |||
5738 | &ecPriv->publicValue, | |||
5739 | SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util); | |||
5740 | if (!pubValue) { | |||
5741 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
5742 | goto ecgn_done; | |||
5743 | } | |||
5744 | crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL, | |||
5745 | sftk_item_expand(pubValue)(pubValue)->data, (pubValue)->len); | |||
5746 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(pubValue, PR_TRUE1); | |||
5747 | } | |||
5748 | if (crv != CKR_OK0x00000000UL) | |||
5749 | goto ecgn_done; | |||
5750 | ||||
5751 | crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL, | |||
5752 | sftk_item_expand(&ecPriv->privateValue)(&ecPriv->privateValue)->data, (&ecPriv->privateValue )->len); | |||
5753 | if (crv != CKR_OK0x00000000UL) | |||
5754 | goto ecgn_done; | |||
5755 | ||||
5756 | crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L, | |||
5757 | sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue )->len); | |||
5758 | ecgn_done: | |||
5759 | /* should zeroize, since this function doesn't. */ | |||
5760 | PORT_FreeArenaPORT_FreeArena_Util(ecPriv->ecParams.arena, PR_TRUE1); | |||
5761 | break; | |||
5762 | ||||
5763 | case CKM_NSS_KYBER_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 45): | |||
5764 | sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L); | |||
5765 | key_type = CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5); | |||
5766 | ||||
5767 | SECItem privKey = { siBuffer, NULL((void*)0), 0 }; | |||
5768 | SECItem pubKey = { siBuffer, NULL((void*)0), 0 }; | |||
5769 | KyberParams kyberParams = sftk_kyber_PK11ParamToInternal(ckKyberParamSet); | |||
| ||||
5770 | if (!sftk_kyber_AllocPrivKeyItem(kyberParams, &privKey)) { | |||
5771 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
5772 | goto kyber_done; | |||
5773 | } | |||
5774 | if (!sftk_kyber_AllocPubKeyItem(kyberParams, &pubKey)) { | |||
5775 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
5776 | goto kyber_done; | |||
5777 | } | |||
5778 | rv = Kyber_NewKey(kyberParams, NULL((void*)0), &privKey, &pubKey); | |||
5779 | if (rv != SECSuccess) { | |||
5780 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5781 | goto kyber_done; | |||
5782 | } | |||
5783 | ||||
5784 | crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL, sftk_item_expand(&pubKey)(&pubKey)->data, (&pubKey)->len); | |||
5785 | if (crv != CKR_OK0x00000000UL) { | |||
5786 | goto kyber_done; | |||
5787 | } | |||
5788 | crv = sftk_AddAttributeType(publicKey, CKA_NSS_PARAMETER_SET((0x80000000UL | 0x4E534350) + 40), | |||
5789 | &ckKyberParamSet, sizeof(CK_NSS_KEM_PARAMETER_SET_TYPE)); | |||
5790 | if (crv != CKR_OK0x00000000UL) { | |||
5791 | goto kyber_done; | |||
5792 | } | |||
5793 | crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL, | |||
5794 | sftk_item_expand(&privKey)(&privKey)->data, (&privKey)->len); | |||
5795 | if (crv != CKR_OK0x00000000UL) { | |||
5796 | goto kyber_done; | |||
5797 | } | |||
5798 | crv = sftk_AddAttributeType(privateKey, CKA_NSS_PARAMETER_SET((0x80000000UL | 0x4E534350) + 40), | |||
5799 | &ckKyberParamSet, sizeof(CK_NSS_KEM_PARAMETER_SET_TYPE)); | |||
5800 | if (crv != CKR_OK0x00000000UL) { | |||
5801 | goto kyber_done; | |||
5802 | } | |||
5803 | crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L, | |||
5804 | sftk_item_expand(&pubKey)(&pubKey)->data, (&pubKey)->len); | |||
5805 | kyber_done: | |||
5806 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&privKey, PR_FALSE0); | |||
5807 | SECITEM_FreeItemSECITEM_FreeItem_Util(&pubKey, PR_FALSE0); | |||
5808 | break; | |||
5809 | ||||
5810 | case CKM_EC_EDWARDS_KEY_PAIR_GEN0x00001055UL: | |||
5811 | sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL); | |||
5812 | sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL); | |||
5813 | sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L); | |||
5814 | key_type = CKK_EC_EDWARDS0x00000040UL; | |||
5815 | ||||
5816 | /* extract the necessary parameters and copy them to private keys */ | |||
5817 | crv = sftk_Attribute2SSecItem(NULL((void*)0), &ecEncodedParams, publicKey, | |||
5818 | CKA_EC_PARAMS0x00000180UL); | |||
5819 | if (crv != CKR_OK0x00000000UL) { | |||
5820 | break; | |||
5821 | } | |||
5822 | ||||
5823 | crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL, | |||
5824 | sftk_item_expand(&ecEncodedParams)(&ecEncodedParams)->data, (&ecEncodedParams)->len); | |||
5825 | if (crv != CKR_OK0x00000000UL) { | |||
5826 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0); | |||
5827 | break; | |||
5828 | } | |||
5829 | ||||
5830 | /* Decode ec params before calling EC_NewKey */ | |||
5831 | rv = EC_DecodeParams(&ecEncodedParams, &ecParams); | |||
5832 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0); | |||
5833 | if (rv != SECSuccess) { | |||
5834 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5835 | break; | |||
5836 | } | |||
5837 | ||||
5838 | rv = EC_NewKey(ecParams, &ecPriv); | |||
5839 | if (rv != SECSuccess) { | |||
5840 | if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) { | |||
5841 | sftk_fatalError = PR_TRUE1; | |||
5842 | } | |||
5843 | PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1); | |||
5844 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
5845 | break; | |||
5846 | } | |||
5847 | PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1); | |||
5848 | crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL, | |||
5849 | sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue )->len); | |||
5850 | if (crv != CKR_OK0x00000000UL) | |||
5851 | goto edgn_done; | |||
5852 | ||||
5853 | crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL, | |||
5854 | sftk_item_expand(&ecPriv->privateValue)(&ecPriv->privateValue)->data, (&ecPriv->privateValue )->len); | |||
5855 | if (crv != CKR_OK0x00000000UL) | |||
5856 | goto edgn_done; | |||
5857 | ||||
5858 | crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L, | |||
5859 | sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue )->len); | |||
5860 | edgn_done: | |||
5861 | /* should zeroize, since this function doesn't. */ | |||
5862 | PORT_FreeArenaPORT_FreeArena_Util(ecPriv->ecParams.arena, PR_TRUE1); | |||
5863 | break; | |||
5864 | ||||
5865 | default: | |||
5866 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
5867 | } | |||
5868 | ||||
5869 | if (crv != CKR_OK0x00000000UL) { | |||
5870 | sftk_FreeObject(privateKey); | |||
5871 | sftk_FreeObject(publicKey); | |||
5872 | return crv; | |||
5873 | } | |||
5874 | ||||
5875 | /* Add the class, key_type The loop lets us check errors blow out | |||
5876 | * on errors and clean up at the bottom */ | |||
5877 | session = NULL((void*)0); /* make pedtantic happy... session cannot leave the*/ | |||
5878 | /* loop below NULL unless an error is set... */ | |||
5879 | do { | |||
5880 | crv = sftk_AddAttributeType(privateKey, CKA_CLASS0x00000000UL, &privClass, | |||
5881 | sizeof(CK_OBJECT_CLASS)); | |||
5882 | if (crv != CKR_OK0x00000000UL) | |||
5883 | break; | |||
5884 | crv = sftk_AddAttributeType(publicKey, CKA_CLASS0x00000000UL, &pubClass, | |||
5885 | sizeof(CK_OBJECT_CLASS)); | |||
5886 | if (crv != CKR_OK0x00000000UL) | |||
5887 | break; | |||
5888 | crv = sftk_AddAttributeType(privateKey, CKA_KEY_TYPE0x00000100UL, &key_type, | |||
5889 | sizeof(CK_KEY_TYPE)); | |||
5890 | if (crv != CKR_OK0x00000000UL) | |||
5891 | break; | |||
5892 | crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE0x00000100UL, &key_type, | |||
5893 | sizeof(CK_KEY_TYPE)); | |||
5894 | if (crv != CKR_OK0x00000000UL) | |||
5895 | break; | |||
5896 | session = sftk_SessionFromHandle(hSession); | |||
5897 | if (session == NULL((void*)0)) | |||
5898 | crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
5899 | } while (0); | |||
5900 | ||||
5901 | if (crv != CKR_OK0x00000000UL) { | |||
5902 | sftk_FreeObject(privateKey); | |||
5903 | sftk_FreeObject(publicKey); | |||
5904 | return crv; | |||
5905 | } | |||
5906 | ||||
5907 | /* | |||
5908 | * handle the base object cleanup for the public Key | |||
5909 | */ | |||
5910 | crv = sftk_handleObject(privateKey, session); | |||
5911 | if (crv != CKR_OK0x00000000UL) { | |||
5912 | sftk_FreeSession(session); | |||
5913 | sftk_FreeObject(privateKey); | |||
5914 | sftk_FreeObject(publicKey); | |||
5915 | return crv; | |||
5916 | } | |||
5917 | ||||
5918 | /* | |||
5919 | * handle the base object cleanup for the private Key | |||
5920 | * If we have any problems, we destroy the public Key we've | |||
5921 | * created and linked. | |||
5922 | */ | |||
5923 | crv = sftk_handleObject(publicKey, session); | |||
5924 | sftk_FreeSession(session); | |||
5925 | if (crv != CKR_OK0x00000000UL) { | |||
5926 | sftk_FreeObject(publicKey); | |||
5927 | NSC_DestroyObject(hSession, privateKey->handle); | |||
5928 | sftk_FreeObject(privateKey); | |||
5929 | return crv; | |||
5930 | } | |||
5931 | if (sftk_isTrue(privateKey, CKA_SENSITIVE0x00000103UL)) { | |||
5932 | crv = sftk_forceAttribute(privateKey, CKA_ALWAYS_SENSITIVE0x00000165UL, | |||
5933 | &cktrue, sizeof(CK_BBOOL)); | |||
5934 | } | |||
5935 | if (crv == CKR_OK0x00000000UL && sftk_isTrue(publicKey, CKA_SENSITIVE0x00000103UL)) { | |||
5936 | crv = sftk_forceAttribute(publicKey, CKA_ALWAYS_SENSITIVE0x00000165UL, | |||
5937 | &cktrue, sizeof(CK_BBOOL)); | |||
5938 | } | |||
5939 | if (crv == CKR_OK0x00000000UL && !sftk_isTrue(privateKey, CKA_EXTRACTABLE0x00000162UL)) { | |||
5940 | crv = sftk_forceAttribute(privateKey, CKA_NEVER_EXTRACTABLE0x00000164UL, | |||
5941 | &cktrue, sizeof(CK_BBOOL)); | |||
5942 | } | |||
5943 | if (crv == CKR_OK0x00000000UL && !sftk_isTrue(publicKey, CKA_EXTRACTABLE0x00000162UL)) { | |||
5944 | crv = sftk_forceAttribute(publicKey, CKA_NEVER_EXTRACTABLE0x00000164UL, | |||
5945 | &cktrue, sizeof(CK_BBOOL)); | |||
5946 | } | |||
5947 | ||||
5948 | if (crv == CKR_OK0x00000000UL && key_type != CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5)) { | |||
5949 | /* Perform FIPS 140-2 pairwise consistency check. */ | |||
5950 | crv = sftk_PairwiseConsistencyCheck(hSession, slot, | |||
5951 | publicKey, privateKey, key_type); | |||
5952 | if (crv != CKR_OK0x00000000UL) { | |||
5953 | if (sftk_audit_enabled) { | |||
5954 | char msg[128]; | |||
5955 | PR_snprintf(msg, sizeof msg, | |||
5956 | "C_GenerateKeyPair(hSession=0x%08lX, " | |||
5957 | "pMechanism->mechanism=0x%08lX)=0x%08lX " | |||
5958 | "self-test: pair-wise consistency test failed", | |||
5959 | (PRUint32)hSession, (PRUint32)pMechanism->mechanism, | |||
5960 | (PRUint32)crv); | |||
5961 | sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); | |||
5962 | } | |||
5963 | } | |||
5964 | } | |||
5965 | ||||
5966 | if (crv != CKR_OK0x00000000UL) { | |||
5967 | NSC_DestroyObject(hSession, publicKey->handle); | |||
5968 | sftk_FreeObject(publicKey); | |||
5969 | NSC_DestroyObject(hSession, privateKey->handle); | |||
5970 | sftk_FreeObject(privateKey); | |||
5971 | return crv; | |||
5972 | } | |||
5973 | ||||
5974 | *phPrivateKey = privateKey->handle; | |||
5975 | *phPublicKey = publicKey->handle; | |||
5976 | sftk_FreeObject(publicKey); | |||
5977 | sftk_FreeObject(privateKey); | |||
5978 | ||||
5979 | return CKR_OK0x00000000UL; | |||
5980 | } | |||
5981 | ||||
5982 | static SECItem * | |||
5983 | sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) | |||
5984 | { | |||
5985 | NSSLOWKEYPrivateKey *lk = NULL((void*)0); | |||
5986 | NSSLOWKEYPrivateKeyInfo *pki = NULL((void*)0); | |||
5987 | SFTKAttribute *attribute = NULL((void*)0); | |||
5988 | PLArenaPool *arena = NULL((void*)0); | |||
5989 | SECOidTag algorithm = SEC_OID_UNKNOWN; | |||
5990 | void *dummy, *param = NULL((void*)0); | |||
5991 | SECStatus rv = SECSuccess; | |||
5992 | SECItem *encodedKey = NULL((void*)0); | |||
5993 | #ifdef EC_DEBUG | |||
5994 | SECItem *fordebug; | |||
5995 | #endif | |||
5996 | int savelen; | |||
5997 | ||||
5998 | if (!key) { | |||
5999 | *crvp = CKR_KEY_HANDLE_INVALID0x00000060UL; /* really can't happen */ | |||
6000 | return NULL((void*)0); | |||
6001 | } | |||
6002 | ||||
6003 | attribute = sftk_FindAttribute(key, CKA_KEY_TYPE0x00000100UL); | |||
6004 | if (!attribute) { | |||
6005 | *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6006 | return NULL((void*)0); | |||
6007 | } | |||
6008 | ||||
6009 | lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp); | |||
6010 | sftk_FreeAttribute(attribute); | |||
6011 | if (!lk) { | |||
6012 | return NULL((void*)0); | |||
6013 | } | |||
6014 | ||||
6015 | arena = PORT_NewArenaPORT_NewArena_Util(2048); /* XXX different size? */ | |||
6016 | if (!arena) { | |||
6017 | *crvp = CKR_HOST_MEMORY0x00000002UL; | |||
6018 | rv = SECFailure; | |||
6019 | goto loser; | |||
6020 | } | |||
6021 | ||||
6022 | pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, | |||
6023 | sizeof(NSSLOWKEYPrivateKeyInfo)); | |||
6024 | if (!pki) { | |||
6025 | *crvp = CKR_HOST_MEMORY0x00000002UL; | |||
6026 | rv = SECFailure; | |||
6027 | goto loser; | |||
6028 | } | |||
6029 | pki->arena = arena; | |||
6030 | ||||
6031 | param = NULL((void*)0); | |||
6032 | switch (lk->keyType) { | |||
6033 | case NSSLOWKEYRSAKey: | |||
6034 | prepare_low_rsa_priv_key_for_asn1(lk); | |||
6035 | dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk, | |||
6036 | nsslowkey_RSAPrivateKeyTemplate); | |||
6037 | ||||
6038 | /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */ | |||
6039 | attribute = sftk_FindAttribute(key, CKA_PUBLIC_KEY_INFO0x00000129UL); | |||
6040 | if (attribute) { | |||
6041 | NSSLOWKEYSubjectPublicKeyInfo *publicKeyInfo; | |||
6042 | SECItem spki; | |||
6043 | ||||
6044 | spki.data = attribute->attrib.pValue; | |||
6045 | spki.len = attribute->attrib.ulValueLen; | |||
6046 | ||||
6047 | publicKeyInfo = PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, | |||
6048 | sizeof(NSSLOWKEYSubjectPublicKeyInfo)); | |||
6049 | if (!publicKeyInfo) { | |||
6050 | sftk_FreeAttribute(attribute); | |||
6051 | *crvp = CKR_HOST_MEMORY0x00000002UL; | |||
6052 | rv = SECFailure; | |||
6053 | goto loser; | |||
6054 | } | |||
6055 | rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, publicKeyInfo, | |||
6056 | nsslowkey_SubjectPublicKeyInfoTemplate, | |||
6057 | &spki); | |||
6058 | if (rv != SECSuccess) { | |||
6059 | sftk_FreeAttribute(attribute); | |||
6060 | *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6061 | goto loser; | |||
6062 | } | |||
6063 | algorithm = SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&publicKeyInfo->algorithm); | |||
6064 | if (algorithm != SEC_OID_PKCS1_RSA_ENCRYPTION && | |||
6065 | algorithm != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { | |||
6066 | sftk_FreeAttribute(attribute); | |||
6067 | rv = SECFailure; | |||
6068 | *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6069 | goto loser; | |||
6070 | } | |||
6071 | param = SECITEM_DupItemSECITEM_DupItem_Util(&publicKeyInfo->algorithm.parameters); | |||
6072 | if (!param) { | |||
6073 | sftk_FreeAttribute(attribute); | |||
6074 | rv = SECFailure; | |||
6075 | *crvp = CKR_HOST_MEMORY0x00000002UL; | |||
6076 | goto loser; | |||
6077 | } | |||
6078 | sftk_FreeAttribute(attribute); | |||
6079 | } else { | |||
6080 | /* default to PKCS #1 */ | |||
6081 | algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; | |||
6082 | } | |||
6083 | break; | |||
6084 | case NSSLOWKEYDSAKey: | |||
6085 | prepare_low_dsa_priv_key_export_for_asn1(lk); | |||
6086 | dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk, | |||
6087 | nsslowkey_DSAPrivateKeyExportTemplate); | |||
6088 | prepare_low_pqg_params_for_asn1(&lk->u.dsa.params); | |||
6089 | param = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), &(lk->u.dsa.params), | |||
6090 | nsslowkey_PQGParamsTemplate); | |||
6091 | algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE; | |||
6092 | break; | |||
6093 | case NSSLOWKEYECKey: | |||
6094 | prepare_low_ec_priv_key_for_asn1(lk); | |||
6095 | /* Public value is encoded as a bit string so adjust length | |||
6096 | * to be in bits before ASN encoding and readjust | |||
6097 | * immediately after. | |||
6098 | * | |||
6099 | * Since the SECG specification recommends not including the | |||
6100 | * parameters as part of ECPrivateKey, we zero out the curveOID | |||
6101 | * length before encoding and restore it later. | |||
6102 | */ | |||
6103 | lk->u.ec.publicValue.len <<= 3; | |||
6104 | savelen = lk->u.ec.ecParams.curveOID.len; | |||
6105 | lk->u.ec.ecParams.curveOID.len = 0; | |||
6106 | dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk, | |||
6107 | nsslowkey_ECPrivateKeyTemplate); | |||
6108 | lk->u.ec.ecParams.curveOID.len = savelen; | |||
6109 | lk->u.ec.publicValue.len >>= 3; | |||
6110 | ||||
6111 | #ifdef EC_DEBUG | |||
6112 | fordebug = &pki->privateKey; | |||
6113 | SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType, | |||
6114 | fordebug); | |||
6115 | #endif | |||
6116 | ||||
6117 | param = SECITEM_DupItemSECITEM_DupItem_Util(&lk->u.ec.ecParams.DEREncoding); | |||
6118 | ||||
6119 | algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY; | |||
6120 | break; | |||
6121 | case NSSLOWKEYDHKey: | |||
6122 | default: | |||
6123 | dummy = NULL((void*)0); | |||
6124 | break; | |||
6125 | } | |||
6126 | ||||
6127 | if (!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) { | |||
6128 | *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */ | |||
6129 | rv = SECFailure; | |||
6130 | goto loser; | |||
6131 | } | |||
6132 | ||||
6133 | rv = SECOID_SetAlgorithmIDSECOID_SetAlgorithmID_Util(arena, &pki->algorithm, algorithm, | |||
6134 | (SECItem *)param); | |||
6135 | if (rv != SECSuccess) { | |||
6136 | *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */ | |||
6137 | rv = SECFailure; | |||
6138 | goto loser; | |||
6139 | } | |||
6140 | ||||
6141 | dummy = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, &pki->version, | |||
6142 | NSSLOWKEY_PRIVATE_KEY_INFO_VERSION0); | |||
6143 | if (!dummy) { | |||
6144 | *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */ | |||
6145 | rv = SECFailure; | |||
6146 | goto loser; | |||
6147 | } | |||
6148 | ||||
6149 | encodedKey = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), pki, | |||
6150 | nsslowkey_PrivateKeyInfoTemplate); | |||
6151 | *crvp = encodedKey ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL; | |||
6152 | ||||
6153 | #ifdef EC_DEBUG | |||
6154 | fordebug = encodedKey; | |||
6155 | SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType, | |||
6156 | fordebug); | |||
6157 | #endif | |||
6158 | loser: | |||
6159 | if (arena) { | |||
6160 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
6161 | } | |||
6162 | ||||
6163 | if (lk && (lk != key->objectInfo)) { | |||
6164 | nsslowkey_DestroyPrivateKey(lk); | |||
6165 | } | |||
6166 | ||||
6167 | if (param) { | |||
6168 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util((SECItem *)param, PR_TRUE1); | |||
6169 | } | |||
6170 | ||||
6171 | if (rv != SECSuccess) { | |||
6172 | return NULL((void*)0); | |||
6173 | } | |||
6174 | ||||
6175 | return encodedKey; | |||
6176 | } | |||
6177 | ||||
6178 | /* it doesn't matter yet, since we colapse error conditions in the | |||
6179 | * level above, but we really should map those few key error differences */ | |||
6180 | static CK_RV | |||
6181 | sftk_mapWrap(CK_RV crv) | |||
6182 | { | |||
6183 | switch (crv) { | |||
6184 | case CKR_ENCRYPTED_DATA_INVALID0x00000040UL: | |||
6185 | crv = CKR_WRAPPED_KEY_INVALID0x00000110UL; | |||
6186 | break; | |||
6187 | } | |||
6188 | return crv; | |||
6189 | } | |||
6190 | ||||
6191 | /* NSC_WrapKey wraps (i.e., encrypts) a key. */ | |||
6192 | CK_RV | |||
6193 | NSC_WrapKey(CK_SESSION_HANDLE hSession, | |||
6194 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, | |||
6195 | CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, | |||
6196 | CK_ULONG_PTR pulWrappedKeyLen) | |||
6197 | { | |||
6198 | SFTKSession *session; | |||
6199 | SFTKAttribute *attribute; | |||
6200 | SFTKObject *key; | |||
6201 | CK_RV crv; | |||
6202 | ||||
6203 | CHECK_FORK(); | |||
6204 | ||||
6205 | session = sftk_SessionFromHandle(hSession); | |||
6206 | if (session == NULL((void*)0)) { | |||
6207 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
6208 | } | |||
6209 | ||||
6210 | key = sftk_ObjectFromHandle(hKey, session); | |||
6211 | if (key == NULL((void*)0)) { | |||
6212 | sftk_FreeSession(session); | |||
6213 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
6214 | } | |||
6215 | ||||
6216 | switch (key->objclass) { | |||
6217 | case CKO_SECRET_KEY0x00000004UL: { | |||
6218 | SFTKSessionContext *context = NULL((void*)0); | |||
6219 | SECItem pText; | |||
6220 | ||||
6221 | attribute = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
6222 | ||||
6223 | if (attribute == NULL((void*)0)) { | |||
6224 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6225 | break; | |||
6226 | } | |||
6227 | crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey, | |||
6228 | CKA_WRAP0x00000106UL, CKA_WRAP0x00000106UL, SFTK_ENCRYPT, PR_TRUE1); | |||
6229 | if (crv != CKR_OK0x00000000UL) { | |||
6230 | sftk_FreeAttribute(attribute); | |||
6231 | break; | |||
6232 | } | |||
6233 | ||||
6234 | pText.type = siBuffer; | |||
6235 | pText.data = (unsigned char *)attribute->attrib.pValue; | |||
6236 | pText.len = attribute->attrib.ulValueLen; | |||
6237 | ||||
6238 | /* Find out if this is a block cipher. */ | |||
6239 | crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_FALSE0, NULL((void*)0)); | |||
6240 | if (crv != CKR_OK0x00000000UL || !context) | |||
6241 | break; | |||
6242 | if (context->blockSize > 1) { | |||
6243 | unsigned int remainder = pText.len % context->blockSize; | |||
6244 | if (!context->doPad && remainder) { | |||
6245 | /* When wrapping secret keys with unpadded block ciphers, | |||
6246 | ** the keys are zero padded, if necessary, to fill out | |||
6247 | ** a full block. | |||
6248 | */ | |||
6249 | pText.len += context->blockSize - remainder; | |||
6250 | pText.data = PORT_ZAllocPORT_ZAlloc_Util(pText.len); | |||
6251 | if (pText.data) | |||
6252 | memcpy(pText.data, attribute->attrib.pValue, | |||
6253 | attribute->attrib.ulValueLen); | |||
6254 | else { | |||
6255 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
6256 | break; | |||
6257 | } | |||
6258 | } | |||
6259 | } | |||
6260 | ||||
6261 | crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data, | |||
6262 | pText.len, pWrappedKey, pulWrappedKeyLen); | |||
6263 | /* always force a finalize, both on errors and when | |||
6264 | * we are just getting the size */ | |||
6265 | if (crv != CKR_OK0x00000000UL || pWrappedKey == NULL((void*)0)) { | |||
6266 | CK_RV lcrv; | |||
6267 | lcrv = sftk_GetContext(hSession, &context, | |||
6268 | SFTK_ENCRYPT, PR_FALSE0, NULL((void*)0)); | |||
6269 | sftk_SetContextByType(session, SFTK_ENCRYPT, NULL((void*)0)); | |||
6270 | if (lcrv == CKR_OK0x00000000UL && context) { | |||
6271 | sftk_FreeContext(context); | |||
6272 | } | |||
6273 | } | |||
6274 | ||||
6275 | if (pText.data != (unsigned char *)attribute->attrib.pValue) | |||
6276 | PORT_ZFreePORT_ZFree_Util(pText.data, pText.len); | |||
6277 | sftk_FreeAttribute(attribute); | |||
6278 | break; | |||
6279 | } | |||
6280 | ||||
6281 | case CKO_PRIVATE_KEY0x00000003UL: { | |||
6282 | SECItem *bpki = sftk_PackagePrivateKey(key, &crv); | |||
6283 | SFTKSessionContext *context = NULL((void*)0); | |||
6284 | ||||
6285 | if (!bpki) { | |||
6286 | break; | |||
6287 | } | |||
6288 | ||||
6289 | crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey, | |||
6290 | CKA_WRAP0x00000106UL, CKA_WRAP0x00000106UL, SFTK_ENCRYPT, PR_TRUE1); | |||
6291 | if (crv != CKR_OK0x00000000UL) { | |||
6292 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(bpki, PR_TRUE1); | |||
6293 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6294 | break; | |||
6295 | } | |||
6296 | ||||
6297 | crv = NSC_Encrypt(hSession, bpki->data, bpki->len, | |||
6298 | pWrappedKey, pulWrappedKeyLen); | |||
6299 | /* always force a finalize */ | |||
6300 | if (crv != CKR_OK0x00000000UL || pWrappedKey == NULL((void*)0)) { | |||
6301 | CK_RV lcrv; | |||
6302 | lcrv = sftk_GetContext(hSession, &context, | |||
6303 | SFTK_ENCRYPT, PR_FALSE0, NULL((void*)0)); | |||
6304 | sftk_SetContextByType(session, SFTK_ENCRYPT, NULL((void*)0)); | |||
6305 | if (lcrv == CKR_OK0x00000000UL && context) { | |||
6306 | sftk_FreeContext(context); | |||
6307 | } | |||
6308 | } | |||
6309 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(bpki, PR_TRUE1); | |||
6310 | break; | |||
6311 | } | |||
6312 | ||||
6313 | default: | |||
6314 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6315 | break; | |||
6316 | } | |||
6317 | sftk_FreeObject(key); | |||
6318 | sftk_FreeSession(session); | |||
6319 | return sftk_mapWrap(crv); | |||
6320 | } | |||
6321 | ||||
6322 | /* | |||
6323 | * import a pprivate key info into the desired slot | |||
6324 | */ | |||
6325 | static SECStatus | |||
6326 | sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) | |||
6327 | { | |||
6328 | CK_BBOOL cktrue = CK_TRUE1; | |||
6329 | CK_KEY_TYPE keyType = CKK_RSA0x00000000UL; | |||
6330 | SECStatus rv = SECFailure; | |||
6331 | const SEC_ASN1Template *keyTemplate, *paramTemplate; | |||
6332 | void *paramDest = NULL((void*)0); | |||
6333 | PLArenaPool *arena; | |||
6334 | NSSLOWKEYPrivateKey *lpk = NULL((void*)0); | |||
6335 | NSSLOWKEYPrivateKeyInfo *pki = NULL((void*)0); | |||
6336 | CK_RV crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6337 | ||||
6338 | arena = PORT_NewArenaPORT_NewArena_Util(2048); | |||
6339 | if (!arena) { | |||
6340 | return SECFailure; | |||
6341 | } | |||
6342 | ||||
6343 | pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, | |||
6344 | sizeof(NSSLOWKEYPrivateKeyInfo)); | |||
6345 | if (!pki) { | |||
6346 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); | |||
6347 | return SECFailure; | |||
6348 | } | |||
6349 | ||||
6350 | if (SEC_ASN1DecodeItemSEC_ASN1DecodeItem_Util(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) != SECSuccess) { | |||
6351 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
6352 | return SECFailure; | |||
6353 | } | |||
6354 | ||||
6355 | lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena, | |||
6356 | sizeof(NSSLOWKEYPrivateKey)); | |||
6357 | if (lpk == NULL((void*)0)) { | |||
6358 | goto loser; | |||
6359 | } | |||
6360 | lpk->arena = arena; | |||
6361 | ||||
6362 | switch (SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&pki->algorithm)) { | |||
6363 | case SEC_OID_PKCS1_RSA_ENCRYPTION: | |||
6364 | case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: | |||
6365 | keyTemplate = nsslowkey_RSAPrivateKeyTemplate; | |||
6366 | paramTemplate = NULL((void*)0); | |||
6367 | paramDest = NULL((void*)0); | |||
6368 | lpk->keyType = NSSLOWKEYRSAKey; | |||
6369 | prepare_low_rsa_priv_key_for_asn1(lpk); | |||
6370 | break; | |||
6371 | case SEC_OID_ANSIX9_DSA_SIGNATURE: | |||
6372 | keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate; | |||
6373 | paramTemplate = nsslowkey_PQGParamsTemplate; | |||
6374 | paramDest = &(lpk->u.dsa.params); | |||
6375 | lpk->keyType = NSSLOWKEYDSAKey; | |||
6376 | prepare_low_dsa_priv_key_export_for_asn1(lpk); | |||
6377 | prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params); | |||
6378 | break; | |||
6379 | /* case NSSLOWKEYDHKey: */ | |||
6380 | case SEC_OID_ANSIX962_EC_PUBLIC_KEY: | |||
6381 | keyTemplate = nsslowkey_ECPrivateKeyTemplate; | |||
6382 | paramTemplate = NULL((void*)0); | |||
6383 | paramDest = &(lpk->u.ec.ecParams.DEREncoding); | |||
6384 | lpk->keyType = NSSLOWKEYECKey; | |||
6385 | prepare_low_ec_priv_key_for_asn1(lpk); | |||
6386 | prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams); | |||
6387 | break; | |||
6388 | default: | |||
6389 | keyTemplate = NULL((void*)0); | |||
6390 | paramTemplate = NULL((void*)0); | |||
6391 | paramDest = NULL((void*)0); | |||
6392 | break; | |||
6393 | } | |||
6394 | ||||
6395 | if (!keyTemplate) { | |||
6396 | goto loser; | |||
6397 | } | |||
6398 | ||||
6399 | /* decode the private key and any algorithm parameters */ | |||
6400 | rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, lpk, keyTemplate, &pki->privateKey); | |||
6401 | ||||
6402 | if (lpk->keyType == NSSLOWKEYECKey) { | |||
6403 | /* convert length in bits to length in bytes */ | |||
6404 | lpk->u.ec.publicValue.len >>= 3; | |||
6405 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, | |||
6406 | &(lpk->u.ec.ecParams.DEREncoding), | |||
6407 | &(pki->algorithm.parameters)); | |||
6408 | if (rv != SECSuccess) { | |||
6409 | goto loser; | |||
6410 | } | |||
6411 | } | |||
6412 | ||||
6413 | if (rv != SECSuccess) { | |||
6414 | goto loser; | |||
6415 | } | |||
6416 | if (paramDest && paramTemplate) { | |||
6417 | rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, paramDest, paramTemplate, | |||
6418 | &(pki->algorithm.parameters)); | |||
6419 | if (rv != SECSuccess) { | |||
6420 | goto loser; | |||
6421 | } | |||
6422 | } | |||
6423 | ||||
6424 | rv = SECFailure; | |||
6425 | ||||
6426 | switch (lpk->keyType) { | |||
6427 | case NSSLOWKEYRSAKey: | |||
6428 | keyType = CKK_RSA0x00000000UL; | |||
6429 | if (sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) { | |||
6430 | sftk_DeleteAttributeType(key, CKA_NSS_DB0xD5A0DB00L); | |||
6431 | } | |||
6432 | crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType, | |||
6433 | sizeof(keyType)); | |||
6434 | if (crv != CKR_OK0x00000000UL) | |||
6435 | break; | |||
6436 | crv = sftk_AddAttributeType(key, CKA_UNWRAP0x00000107UL, &cktrue, | |||
6437 | sizeof(CK_BBOOL)); | |||
6438 | if (crv != CKR_OK0x00000000UL) | |||
6439 | break; | |||
6440 | crv = sftk_AddAttributeType(key, CKA_DECRYPT0x00000105UL, &cktrue, | |||
6441 | sizeof(CK_BBOOL)); | |||
6442 | if (crv != CKR_OK0x00000000UL) | |||
6443 | break; | |||
6444 | crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue, | |||
6445 | sizeof(CK_BBOOL)); | |||
6446 | if (crv != CKR_OK0x00000000UL) | |||
6447 | break; | |||
6448 | crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &cktrue, | |||
6449 | sizeof(CK_BBOOL)); | |||
6450 | if (crv != CKR_OK0x00000000UL) | |||
6451 | break; | |||
6452 | crv = sftk_AddAttributeType(key, CKA_MODULUS0x00000120UL, | |||
6453 | sftk_item_expand(&lpk->u.rsa.modulus)(&lpk->u.rsa.modulus)->data, (&lpk->u.rsa.modulus )->len); | |||
6454 | if (crv != CKR_OK0x00000000UL) | |||
6455 | break; | |||
6456 | crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT0x00000122UL, | |||
6457 | sftk_item_expand(&lpk->u.rsa.publicExponent)(&lpk->u.rsa.publicExponent)->data, (&lpk->u .rsa.publicExponent)->len); | |||
6458 | if (crv != CKR_OK0x00000000UL) | |||
6459 | break; | |||
6460 | crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT0x00000123UL, | |||
6461 | sftk_item_expand(&lpk->u.rsa.privateExponent)(&lpk->u.rsa.privateExponent)->data, (&lpk-> u.rsa.privateExponent)->len); | |||
6462 | if (crv != CKR_OK0x00000000UL) | |||
6463 | break; | |||
6464 | crv = sftk_AddAttributeType(key, CKA_PRIME_10x00000124UL, | |||
6465 | sftk_item_expand(&lpk->u.rsa.prime1)(&lpk->u.rsa.prime1)->data, (&lpk->u.rsa.prime1 )->len); | |||
6466 | if (crv != CKR_OK0x00000000UL) | |||
6467 | break; | |||
6468 | crv = sftk_AddAttributeType(key, CKA_PRIME_20x00000125UL, | |||
6469 | sftk_item_expand(&lpk->u.rsa.prime2)(&lpk->u.rsa.prime2)->data, (&lpk->u.rsa.prime2 )->len); | |||
6470 | if (crv != CKR_OK0x00000000UL) | |||
6471 | break; | |||
6472 | crv = sftk_AddAttributeType(key, CKA_EXPONENT_10x00000126UL, | |||
6473 | sftk_item_expand(&lpk->u.rsa.exponent1)(&lpk->u.rsa.exponent1)->data, (&lpk->u.rsa. exponent1)->len); | |||
6474 | if (crv != CKR_OK0x00000000UL) | |||
6475 | break; | |||
6476 | crv = sftk_AddAttributeType(key, CKA_EXPONENT_20x00000127UL, | |||
6477 | sftk_item_expand(&lpk->u.rsa.exponent2)(&lpk->u.rsa.exponent2)->data, (&lpk->u.rsa. exponent2)->len); | |||
6478 | if (crv != CKR_OK0x00000000UL) | |||
6479 | break; | |||
6480 | crv = sftk_AddAttributeType(key, CKA_COEFFICIENT0x00000128UL, | |||
6481 | sftk_item_expand(&lpk->u.rsa.coefficient)(&lpk->u.rsa.coefficient)->data, (&lpk->u.rsa .coefficient)->len); | |||
6482 | break; | |||
6483 | case NSSLOWKEYDSAKey: | |||
6484 | keyType = CKK_DSA0x00000001UL; | |||
6485 | crv = (sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) ? CKR_OK0x00000000UL : CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6486 | if (crv != CKR_OK0x00000000UL) | |||
6487 | break; | |||
6488 | crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType, | |||
6489 | sizeof(keyType)); | |||
6490 | if (crv != CKR_OK0x00000000UL) | |||
6491 | break; | |||
6492 | crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue, | |||
6493 | sizeof(CK_BBOOL)); | |||
6494 | if (crv != CKR_OK0x00000000UL) | |||
6495 | break; | |||
6496 | crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &cktrue, | |||
6497 | sizeof(CK_BBOOL)); | |||
6498 | if (crv != CKR_OK0x00000000UL) | |||
6499 | break; | |||
6500 | crv = sftk_AddAttributeType(key, CKA_PRIME0x00000130UL, | |||
6501 | sftk_item_expand(&lpk->u.dsa.params.prime)(&lpk->u.dsa.params.prime)->data, (&lpk->u.dsa .params.prime)->len); | |||
6502 | if (crv != CKR_OK0x00000000UL) | |||
6503 | break; | |||
6504 | crv = sftk_AddAttributeType(key, CKA_SUBPRIME0x00000131UL, | |||
6505 | sftk_item_expand(&lpk->u.dsa.params.subPrime)(&lpk->u.dsa.params.subPrime)->data, (&lpk-> u.dsa.params.subPrime)->len); | |||
6506 | if (crv != CKR_OK0x00000000UL) | |||
6507 | break; | |||
6508 | crv = sftk_AddAttributeType(key, CKA_BASE0x00000132UL, | |||
6509 | sftk_item_expand(&lpk->u.dsa.params.base)(&lpk->u.dsa.params.base)->data, (&lpk->u.dsa .params.base)->len); | |||
6510 | if (crv != CKR_OK0x00000000UL) | |||
6511 | break; | |||
6512 | crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL, | |||
6513 | sftk_item_expand(&lpk->u.dsa.privateValue)(&lpk->u.dsa.privateValue)->data, (&lpk->u.dsa .privateValue)->len); | |||
6514 | if (crv != CKR_OK0x00000000UL) | |||
6515 | break; | |||
6516 | break; | |||
6517 | #ifdef notdef | |||
6518 | case NSSLOWKEYDHKey: | |||
6519 | template = dhTemplate; | |||
6520 | templateCount = sizeof(dhTemplate) / sizeof(CK_ATTRIBUTE); | |||
6521 | keyType = CKK_DH0x00000002UL; | |||
6522 | break; | |||
6523 | #endif | |||
6524 | /* what about fortezza??? */ | |||
6525 | case NSSLOWKEYECKey: | |||
6526 | keyType = CKK_EC0x00000003UL; | |||
6527 | crv = (sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) ? CKR_OK0x00000000UL : CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6528 | if (crv != CKR_OK0x00000000UL) | |||
6529 | break; | |||
6530 | crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType, | |||
6531 | sizeof(keyType)); | |||
6532 | if (crv != CKR_OK0x00000000UL) | |||
6533 | break; | |||
6534 | crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue, | |||
6535 | sizeof(CK_BBOOL)); | |||
6536 | if (crv != CKR_OK0x00000000UL) | |||
6537 | break; | |||
6538 | crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &cktrue, | |||
6539 | sizeof(CK_BBOOL)); | |||
6540 | if (crv != CKR_OK0x00000000UL) | |||
6541 | break; | |||
6542 | crv = sftk_AddAttributeType(key, CKA_DERIVE0x0000010CUL, &cktrue, | |||
6543 | sizeof(CK_BBOOL)); | |||
6544 | if (crv != CKR_OK0x00000000UL) | |||
6545 | break; | |||
6546 | crv = sftk_AddAttributeType(key, CKA_EC_PARAMS0x00000180UL, | |||
6547 | sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding)(&lpk->u.ec.ecParams.DEREncoding)->data, (&lpk-> u.ec.ecParams.DEREncoding)->len); | |||
6548 | if (crv != CKR_OK0x00000000UL) | |||
6549 | break; | |||
6550 | crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL, | |||
6551 | sftk_item_expand(&lpk->u.ec.privateValue)(&lpk->u.ec.privateValue)->data, (&lpk->u.ec .privateValue)->len); | |||
6552 | if (crv != CKR_OK0x00000000UL) | |||
6553 | break; | |||
6554 | /* XXX Do we need to decode the EC Params here ?? */ | |||
6555 | break; | |||
6556 | default: | |||
6557 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6558 | break; | |||
6559 | } | |||
6560 | ||||
6561 | if (crv != CKR_OK0x00000000UL) { | |||
6562 | goto loser; | |||
6563 | } | |||
6564 | ||||
6565 | /* For RSA-PSS, record the original algorithm parameters so | |||
6566 | * they can be encrypted altoghether when wrapping */ | |||
6567 | if (SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&pki->algorithm) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { | |||
6568 | NSSLOWKEYSubjectPublicKeyInfo spki; | |||
6569 | NSSLOWKEYPublicKey pubk; | |||
6570 | SECItem *publicKeyInfo; | |||
6571 | ||||
6572 | memset(&spki, 0, sizeof(NSSLOWKEYSubjectPublicKeyInfo)); | |||
6573 | rv = SECOID_CopyAlgorithmIDSECOID_CopyAlgorithmID_Util(arena, &spki.algorithm, &pki->algorithm); | |||
6574 | if (rv != SECSuccess) { | |||
6575 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
6576 | goto loser; | |||
6577 | } | |||
6578 | ||||
6579 | prepare_low_rsa_pub_key_for_asn1(&pubk); | |||
6580 | ||||
6581 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk.u.rsa.modulus, &lpk->u.rsa.modulus); | |||
6582 | if (rv != SECSuccess) { | |||
6583 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
6584 | goto loser; | |||
6585 | } | |||
6586 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk.u.rsa.publicExponent, &lpk->u.rsa.publicExponent); | |||
6587 | if (rv != SECSuccess) { | |||
6588 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
6589 | goto loser; | |||
6590 | } | |||
6591 | ||||
6592 | if (SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &spki.subjectPublicKey, | |||
6593 | &pubk, nsslowkey_RSAPublicKeyTemplate) == NULL((void*)0)) { | |||
6594 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
6595 | goto loser; | |||
6596 | } | |||
6597 | ||||
6598 | publicKeyInfo = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, NULL((void*)0), | |||
6599 | &spki, nsslowkey_SubjectPublicKeyInfoTemplate); | |||
6600 | if (!publicKeyInfo) { | |||
6601 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
6602 | goto loser; | |||
6603 | } | |||
6604 | crv = sftk_AddAttributeType(key, CKA_PUBLIC_KEY_INFO0x00000129UL, | |||
6605 | sftk_item_expand(publicKeyInfo)(publicKeyInfo)->data, (publicKeyInfo)->len); | |||
6606 | } | |||
6607 | ||||
6608 | loser: | |||
6609 | if (lpk) { | |||
6610 | nsslowkey_DestroyPrivateKey(lpk); | |||
6611 | } | |||
6612 | ||||
6613 | if (crv != CKR_OK0x00000000UL) { | |||
6614 | return SECFailure; | |||
6615 | } | |||
6616 | ||||
6617 | return SECSuccess; | |||
6618 | } | |||
6619 | ||||
6620 | /* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ | |||
6621 | CK_RV | |||
6622 | NSC_UnwrapKey(CK_SESSION_HANDLE hSession, | |||
6623 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, | |||
6624 | CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, | |||
6625 | CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, | |||
6626 | CK_OBJECT_HANDLE_PTR phKey) | |||
6627 | { | |||
6628 | SFTKObject *key = NULL((void*)0); | |||
6629 | SFTKSession *session; | |||
6630 | CK_ULONG key_length = 0; | |||
6631 | unsigned char *buf = NULL((void*)0); | |||
6632 | CK_RV crv = CKR_OK0x00000000UL; | |||
6633 | int i; | |||
6634 | CK_ULONG bsize = ulWrappedKeyLen; | |||
6635 | SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); | |||
6636 | SECItem bpki; | |||
6637 | CK_OBJECT_CLASS target_type = CKO_SECRET_KEY0x00000004UL; | |||
6638 | ||||
6639 | CHECK_FORK(); | |||
6640 | ||||
6641 | if (!slot) { | |||
6642 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
6643 | } | |||
6644 | /* | |||
6645 | * now lets create an object to hang the attributes off of | |||
6646 | */ | |||
6647 | key = sftk_NewObject(slot); /* fill in the handle later */ | |||
6648 | if (key == NULL((void*)0)) { | |||
6649 | return CKR_HOST_MEMORY0x00000002UL; | |||
6650 | } | |||
6651 | ||||
6652 | /* | |||
6653 | * load the template values into the object | |||
6654 | */ | |||
6655 | for (i = 0; i < (int)ulAttributeCount; i++) { | |||
6656 | if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) { | |||
6657 | key_length = *(CK_ULONG *)pTemplate[i].pValue; | |||
6658 | continue; | |||
6659 | } | |||
6660 | if (pTemplate[i].type == CKA_CLASS0x00000000UL) { | |||
6661 | target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; | |||
6662 | } | |||
6663 | crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue, (&pTemplate[i])->ulValueLen); | |||
6664 | if (crv != CKR_OK0x00000000UL) | |||
6665 | break; | |||
6666 | } | |||
6667 | if (crv != CKR_OK0x00000000UL) { | |||
6668 | sftk_FreeObject(key); | |||
6669 | return crv; | |||
6670 | } | |||
6671 | ||||
6672 | crv = sftk_CryptInit(hSession, pMechanism, hUnwrappingKey, CKA_UNWRAP0x00000107UL, | |||
6673 | CKA_UNWRAP0x00000107UL, SFTK_DECRYPT, PR_FALSE0); | |||
6674 | if (crv != CKR_OK0x00000000UL) { | |||
6675 | sftk_FreeObject(key); | |||
6676 | return sftk_mapWrap(crv); | |||
6677 | } | |||
6678 | ||||
6679 | /* allocate the buffer to decrypt into | |||
6680 | * this assumes the unwrapped key is never larger than the | |||
6681 | * wrapped key. For all the mechanisms we support this is true */ | |||
6682 | buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(ulWrappedKeyLen); | |||
6683 | bsize = ulWrappedKeyLen; | |||
6684 | ||||
6685 | crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize); | |||
6686 | if (crv != CKR_OK0x00000000UL) { | |||
6687 | sftk_FreeObject(key); | |||
6688 | PORT_FreePORT_Free_Util(buf); | |||
6689 | return sftk_mapWrap(crv); | |||
6690 | } | |||
6691 | ||||
6692 | switch (target_type) { | |||
6693 | case CKO_SECRET_KEY0x00000004UL: | |||
6694 | if (!sftk_hasAttribute(key, CKA_KEY_TYPE0x00000100UL)) { | |||
6695 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
6696 | break; | |||
6697 | } | |||
6698 | ||||
6699 | if (key_length == 0 || key_length > bsize) { | |||
6700 | key_length = bsize; | |||
6701 | } | |||
6702 | if (key_length > MAX_KEY_LEN256) { | |||
6703 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
6704 | break; | |||
6705 | } | |||
6706 | ||||
6707 | /* add the value */ | |||
6708 | crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL, buf, key_length); | |||
6709 | break; | |||
6710 | case CKO_PRIVATE_KEY0x00000003UL: | |||
6711 | bpki.data = (unsigned char *)buf; | |||
6712 | bpki.len = bsize; | |||
6713 | crv = CKR_OK0x00000000UL; | |||
6714 | if (sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) { | |||
6715 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
6716 | } | |||
6717 | break; | |||
6718 | default: | |||
6719 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
6720 | break; | |||
6721 | } | |||
6722 | ||||
6723 | PORT_ZFreePORT_ZFree_Util(buf, bsize); | |||
6724 | if (crv != CKR_OK0x00000000UL) { | |||
6725 | sftk_FreeObject(key); | |||
6726 | return crv; | |||
6727 | } | |||
6728 | ||||
6729 | /* get the session */ | |||
6730 | session = sftk_SessionFromHandle(hSession); | |||
6731 | if (session == NULL((void*)0)) { | |||
6732 | sftk_FreeObject(key); | |||
6733 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
6734 | } | |||
6735 | ||||
6736 | /* mark the key as FIPS if the previous operation was all FIPS */ | |||
6737 | key->isFIPS = session->lastOpWasFIPS; | |||
6738 | ||||
6739 | /* | |||
6740 | * handle the base object stuff | |||
6741 | */ | |||
6742 | crv = sftk_handleObject(key, session); | |||
6743 | *phKey = key->handle; | |||
6744 | sftk_FreeSession(session); | |||
6745 | sftk_FreeObject(key); | |||
6746 | ||||
6747 | return crv; | |||
6748 | } | |||
6749 | ||||
6750 | /* | |||
6751 | * The SSL key gen mechanism create's lots of keys. This function handles the | |||
6752 | * details of each of these key creation. | |||
6753 | */ | |||
6754 | static CK_RV | |||
6755 | sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey, | |||
6756 | PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize, | |||
6757 | CK_OBJECT_HANDLE *keyHandle) | |||
6758 | { | |||
6759 | SFTKObject *key; | |||
6760 | SFTKSession *session; | |||
6761 | CK_KEY_TYPE keyType = CKK_GENERIC_SECRET0x00000010UL; | |||
6762 | CK_BBOOL cktrue = CK_TRUE1; | |||
6763 | CK_BBOOL ckfalse = CK_FALSE0; | |||
6764 | CK_RV crv = CKR_HOST_MEMORY0x00000002UL; | |||
6765 | ||||
6766 | /* | |||
6767 | * now lets create an object to hang the attributes off of | |||
6768 | */ | |||
6769 | *keyHandle = CK_INVALID_HANDLE0; | |||
6770 | key = sftk_NewObject(baseKey->slot); | |||
6771 | if (key == NULL((void*)0)) | |||
6772 | return CKR_HOST_MEMORY0x00000002UL; | |||
6773 | sftk_narrowToSessionObject(key)->wasDerived = PR_TRUE1; | |||
6774 | ||||
6775 | crv = sftk_CopyObject(key, baseKey); | |||
6776 | if (crv != CKR_OK0x00000000UL) | |||
6777 | goto loser; | |||
6778 | if (isMacKey) { | |||
6779 | crv = sftk_forceAttribute(key, CKA_KEY_TYPE0x00000100UL, &keyType, sizeof(keyType)); | |||
6780 | if (crv != CKR_OK0x00000000UL) | |||
6781 | goto loser; | |||
6782 | crv = sftk_forceAttribute(key, CKA_DERIVE0x0000010CUL, &cktrue, sizeof(CK_BBOOL)); | |||
6783 | if (crv != CKR_OK0x00000000UL) | |||
6784 | goto loser; | |||
6785 | crv = sftk_forceAttribute(key, CKA_ENCRYPT0x00000104UL, &ckfalse, sizeof(CK_BBOOL)); | |||
6786 | if (crv != CKR_OK0x00000000UL) | |||
6787 | goto loser; | |||
6788 | crv = sftk_forceAttribute(key, CKA_DECRYPT0x00000105UL, &ckfalse, sizeof(CK_BBOOL)); | |||
6789 | if (crv != CKR_OK0x00000000UL) | |||
6790 | goto loser; | |||
6791 | crv = sftk_forceAttribute(key, CKA_SIGN0x00000108UL, &cktrue, sizeof(CK_BBOOL)); | |||
6792 | if (crv != CKR_OK0x00000000UL) | |||
6793 | goto loser; | |||
6794 | crv = sftk_forceAttribute(key, CKA_VERIFY0x0000010AUL, &cktrue, sizeof(CK_BBOOL)); | |||
6795 | if (crv != CKR_OK0x00000000UL) | |||
6796 | goto loser; | |||
6797 | crv = sftk_forceAttribute(key, CKA_WRAP0x00000106UL, &ckfalse, sizeof(CK_BBOOL)); | |||
6798 | if (crv != CKR_OK0x00000000UL) | |||
6799 | goto loser; | |||
6800 | crv = sftk_forceAttribute(key, CKA_UNWRAP0x00000107UL, &ckfalse, sizeof(CK_BBOOL)); | |||
6801 | if (crv != CKR_OK0x00000000UL) | |||
6802 | goto loser; | |||
6803 | } | |||
6804 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, keyBlock, keySize); | |||
6805 | if (crv != CKR_OK0x00000000UL) | |||
6806 | goto loser; | |||
6807 | ||||
6808 | /* get the session */ | |||
6809 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
6810 | session = sftk_SessionFromHandle(hSession); | |||
6811 | if (session == NULL((void*)0)) { | |||
6812 | goto loser; | |||
6813 | } | |||
6814 | ||||
6815 | crv = sftk_handleObject(key, session); | |||
6816 | sftk_FreeSession(session); | |||
6817 | *keyHandle = key->handle; | |||
6818 | loser: | |||
6819 | if (key) | |||
6820 | sftk_FreeObject(key); | |||
6821 | return crv; | |||
6822 | } | |||
6823 | ||||
6824 | /* | |||
6825 | * if there is an error, we need to free the keys we already created in SSL | |||
6826 | * This is the routine that will do it.. | |||
6827 | */ | |||
6828 | static void | |||
6829 | sftk_freeSSLKeys(CK_SESSION_HANDLE session, | |||
6830 | CK_SSL3_KEY_MAT_OUT *returnedMaterial) | |||
6831 | { | |||
6832 | if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE0) { | |||
6833 | NSC_DestroyObject(session, returnedMaterial->hClientMacSecret); | |||
6834 | } | |||
6835 | if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE0) { | |||
6836 | NSC_DestroyObject(session, returnedMaterial->hServerMacSecret); | |||
6837 | } | |||
6838 | if (returnedMaterial->hClientKey != CK_INVALID_HANDLE0) { | |||
6839 | NSC_DestroyObject(session, returnedMaterial->hClientKey); | |||
6840 | } | |||
6841 | if (returnedMaterial->hServerKey != CK_INVALID_HANDLE0) { | |||
6842 | NSC_DestroyObject(session, returnedMaterial->hServerKey); | |||
6843 | } | |||
6844 | } | |||
6845 | ||||
6846 | /* | |||
6847 | * when deriving from sensitive and extractable keys, we need to preserve some | |||
6848 | * of the semantics in the derived key. This helper routine maintains these | |||
6849 | * semantics. | |||
6850 | */ | |||
6851 | static CK_RV | |||
6852 | sftk_DeriveSensitiveCheck(SFTKObject *baseKey, SFTKObject *destKey, | |||
6853 | PRBool canBeData) | |||
6854 | { | |||
6855 | PRBool hasSensitive; | |||
6856 | PRBool sensitive = PR_FALSE0; | |||
6857 | CK_BBOOL bFalse = CK_FALSE0; | |||
6858 | PRBool hasExtractable; | |||
6859 | PRBool extractable = PR_TRUE1; | |||
6860 | CK_BBOOL bTrue = CK_TRUE1; | |||
6861 | CK_RV crv = CKR_OK0x00000000UL; | |||
6862 | SFTKAttribute *att; | |||
6863 | PRBool isData = PR_TRUE1; | |||
6864 | ||||
6865 | if (canBeData) { | |||
6866 | CK_OBJECT_CLASS objClass; | |||
6867 | ||||
6868 | /* if the target key is actually data, don't set the unexpected | |||
6869 | * attributes */ | |||
6870 | crv = sftk_GetULongAttribute(destKey, CKA_CLASS0x00000000UL, &objClass); | |||
6871 | if (crv != CKR_OK0x00000000UL) { | |||
6872 | return crv; | |||
6873 | } | |||
6874 | if (objClass == CKO_DATA0x00000000UL) { | |||
6875 | return CKR_OK0x00000000UL; | |||
6876 | } | |||
6877 | ||||
6878 | /* if the base key is data, it doesn't have sensitive attributes, | |||
6879 | * allow the destKey to get it's own */ | |||
6880 | crv = sftk_GetULongAttribute(baseKey, CKA_CLASS0x00000000UL, &objClass); | |||
6881 | if (crv != CKR_OK0x00000000UL) { | |||
6882 | return crv; | |||
6883 | } | |||
6884 | if (objClass == CKO_DATA0x00000000UL) { | |||
6885 | isData = PR_TRUE1; | |||
6886 | } | |||
6887 | } | |||
6888 | ||||
6889 | hasSensitive = PR_FALSE0; | |||
6890 | att = sftk_FindAttribute(destKey, CKA_SENSITIVE0x00000103UL); | |||
6891 | if (att) { | |||
6892 | hasSensitive = PR_TRUE1; | |||
6893 | sensitive = (PRBool) * (CK_BBOOL *)att->attrib.pValue; | |||
6894 | sftk_FreeAttribute(att); | |||
6895 | } | |||
6896 | ||||
6897 | hasExtractable = PR_FALSE0; | |||
6898 | att = sftk_FindAttribute(destKey, CKA_EXTRACTABLE0x00000162UL); | |||
6899 | if (att) { | |||
6900 | hasExtractable = PR_TRUE1; | |||
6901 | extractable = (PRBool) * (CK_BBOOL *)att->attrib.pValue; | |||
6902 | sftk_FreeAttribute(att); | |||
6903 | } | |||
6904 | ||||
6905 | /* don't make a key more accessible */ | |||
6906 | if (sftk_isTrue(baseKey, CKA_SENSITIVE0x00000103UL) && hasSensitive && | |||
6907 | (sensitive == PR_FALSE0)) { | |||
6908 | return CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
6909 | } | |||
6910 | if (!sftk_isTrue(baseKey, CKA_EXTRACTABLE0x00000162UL) && hasExtractable && | |||
6911 | (extractable == PR_TRUE1)) { | |||
6912 | return CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
6913 | } | |||
6914 | ||||
6915 | /* inherit parent's sensitivity */ | |||
6916 | if (!hasSensitive) { | |||
6917 | att = sftk_FindAttribute(baseKey, CKA_SENSITIVE0x00000103UL); | |||
6918 | if (att != NULL((void*)0)) { | |||
6919 | crv = sftk_defaultAttribute(destKey, | |||
6920 | sftk_attr_expand(&att->attrib)(&att->attrib)->type, (&att->attrib)->pValue , (&att->attrib)->ulValueLen); | |||
6921 | sftk_FreeAttribute(att); | |||
6922 | } else if (isData) { | |||
6923 | crv = sftk_defaultAttribute(destKey, CKA_SENSITIVE0x00000103UL, | |||
6924 | &bFalse, sizeof(bFalse)); | |||
6925 | } else { | |||
6926 | return CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6927 | } | |||
6928 | if (crv != CKR_OK0x00000000UL) | |||
6929 | return crv; | |||
6930 | } | |||
6931 | if (!hasExtractable) { | |||
6932 | att = sftk_FindAttribute(baseKey, CKA_EXTRACTABLE0x00000162UL); | |||
6933 | if (att != NULL((void*)0)) { | |||
6934 | crv = sftk_defaultAttribute(destKey, | |||
6935 | sftk_attr_expand(&att->attrib)(&att->attrib)->type, (&att->attrib)->pValue , (&att->attrib)->ulValueLen); | |||
6936 | sftk_FreeAttribute(att); | |||
6937 | } else if (isData) { | |||
6938 | crv = sftk_defaultAttribute(destKey, CKA_EXTRACTABLE0x00000162UL, | |||
6939 | &bTrue, sizeof(bTrue)); | |||
6940 | } else { | |||
6941 | return CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
6942 | } | |||
6943 | if (crv != CKR_OK0x00000000UL) | |||
6944 | return crv; | |||
6945 | } | |||
6946 | ||||
6947 | /* we should inherit the parent's always extractable/ never sensitive info, | |||
6948 | * but handleObject always forces this attributes, so we would need to do | |||
6949 | * something special. */ | |||
6950 | return CKR_OK0x00000000UL; | |||
6951 | } | |||
6952 | ||||
6953 | /* | |||
6954 | * make known fixed PKCS #11 key types to their sizes in bytes | |||
6955 | */ | |||
6956 | unsigned long | |||
6957 | sftk_MapKeySize(CK_KEY_TYPE keyType) | |||
6958 | { | |||
6959 | switch (keyType) { | |||
6960 | case CKK_CDMF0x0000001EUL: | |||
6961 | return 8; | |||
6962 | case CKK_DES0x00000013UL: | |||
6963 | return 8; | |||
6964 | case CKK_DES20x00000014UL: | |||
6965 | return 16; | |||
6966 | case CKK_DES30x00000015UL: | |||
6967 | return 24; | |||
6968 | /* IDEA and CAST need to be added */ | |||
6969 | default: | |||
6970 | break; | |||
6971 | } | |||
6972 | return 0; | |||
6973 | } | |||
6974 | ||||
6975 | /* Inputs: | |||
6976 | * key_len: Length of derived key to be generated. | |||
6977 | * SharedSecret: a shared secret that is the output of a key agreement primitive. | |||
6978 | * SharedInfo: (Optional) some data shared by the entities computing the secret key. | |||
6979 | * SharedInfoLen: the length in octets of SharedInfo | |||
6980 | * Hash: The hash function to be used in the KDF | |||
6981 | * HashLen: the length in octets of the output of Hash | |||
6982 | * Output: | |||
6983 | * key: Pointer to a buffer containing derived key, if return value is SECSuccess. | |||
6984 | */ | |||
6985 | static CK_RV | |||
6986 | sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECItem *SharedSecret, | |||
6987 | CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, | |||
6988 | SECStatus Hash(unsigned char *, const unsigned char *, PRUint32), | |||
6989 | CK_ULONG HashLen) | |||
6990 | { | |||
6991 | unsigned char *buffer = NULL((void*)0), *output_buffer = NULL((void*)0); | |||
6992 | PRUint32 buffer_len, max_counter, i; | |||
6993 | SECStatus rv; | |||
6994 | CK_RV crv; | |||
6995 | ||||
6996 | /* Check that key_len isn't too long. The maximum key length could be | |||
6997 | * greatly increased if the code below did not limit the 4-byte counter | |||
6998 | * to a maximum value of 255. */ | |||
6999 | if (key_len > 254 * HashLen) | |||
7000 | return CKR_ARGUMENTS_BAD0x00000007UL; | |||
7001 | ||||
7002 | if (SharedInfo == NULL((void*)0)) | |||
7003 | SharedInfoLen = 0; | |||
7004 | ||||
7005 | buffer_len = SharedSecret->len + 4 + SharedInfoLen; | |||
7006 | buffer = (CK_BYTE *)PORT_AllocPORT_Alloc_Util(buffer_len); | |||
7007 | if (buffer == NULL((void*)0)) { | |||
7008 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
7009 | goto loser; | |||
7010 | } | |||
7011 | ||||
7012 | max_counter = key_len / HashLen; | |||
7013 | if (key_len > max_counter * HashLen) | |||
7014 | max_counter++; | |||
7015 | ||||
7016 | output_buffer = (CK_BYTE *)PORT_AllocPORT_Alloc_Util(max_counter * HashLen); | |||
7017 | if (output_buffer == NULL((void*)0)) { | |||
7018 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
7019 | goto loser; | |||
7020 | } | |||
7021 | ||||
7022 | /* Populate buffer with SharedSecret || Counter || [SharedInfo] | |||
7023 | * where Counter is 0x00000001 */ | |||
7024 | PORT_Memcpymemcpy(buffer, SharedSecret->data, SharedSecret->len); | |||
7025 | buffer[SharedSecret->len] = 0; | |||
7026 | buffer[SharedSecret->len + 1] = 0; | |||
7027 | buffer[SharedSecret->len + 2] = 0; | |||
7028 | buffer[SharedSecret->len + 3] = 1; | |||
7029 | if (SharedInfo) { | |||
7030 | PORT_Memcpymemcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen); | |||
7031 | } | |||
7032 | ||||
7033 | for (i = 0; i < max_counter; i++) { | |||
7034 | rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len); | |||
7035 | if (rv != SECSuccess) { | |||
7036 | /* 'Hash' should not fail. */ | |||
7037 | crv = CKR_FUNCTION_FAILED0x00000006UL; | |||
7038 | goto loser; | |||
7039 | } | |||
7040 | ||||
7041 | /* Increment counter (assumes max_counter < 255) */ | |||
7042 | buffer[SharedSecret->len + 3]++; | |||
7043 | } | |||
7044 | ||||
7045 | PORT_ZFreePORT_ZFree_Util(buffer, buffer_len); | |||
7046 | if (key_len < max_counter * HashLen) { | |||
7047 | PORT_Memsetmemset(output_buffer + key_len, 0, max_counter * HashLen - key_len); | |||
7048 | } | |||
7049 | *key = output_buffer; | |||
7050 | ||||
7051 | return CKR_OK0x00000000UL; | |||
7052 | ||||
7053 | loser: | |||
7054 | if (buffer) { | |||
7055 | PORT_ZFreePORT_ZFree_Util(buffer, buffer_len); | |||
7056 | } | |||
7057 | if (output_buffer) { | |||
7058 | PORT_ZFreePORT_ZFree_Util(output_buffer, max_counter * HashLen); | |||
7059 | } | |||
7060 | return crv; | |||
7061 | } | |||
7062 | ||||
7063 | static CK_RV | |||
7064 | sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, | |||
7065 | SECItem *SharedSecret, | |||
7066 | CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, | |||
7067 | CK_EC_KDF_TYPE kdf) | |||
7068 | { | |||
7069 | if (kdf == CKD_SHA1_KDF0x00000002UL) | |||
7070 | return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, | |||
7071 | SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH20); | |||
7072 | else if (kdf == CKD_SHA224_KDF0x00000005UL) | |||
7073 | return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, | |||
7074 | SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH28); | |||
7075 | else if (kdf == CKD_SHA256_KDF0x00000006UL) | |||
7076 | return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, | |||
7077 | SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH32); | |||
7078 | else if (kdf == CKD_SHA384_KDF0x00000007UL) | |||
7079 | return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, | |||
7080 | SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH48); | |||
7081 | else if (kdf == CKD_SHA512_KDF0x00000008UL) | |||
7082 | return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, | |||
7083 | SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH64); | |||
7084 | else | |||
7085 | return CKR_MECHANISM_INVALID0x00000070UL; | |||
7086 | } | |||
7087 | ||||
7088 | /* | |||
7089 | * Handle the derive from a block encryption cipher | |||
7090 | */ | |||
7091 | CK_RV | |||
7092 | sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo, | |||
7093 | int blockSize, SFTKObject *key, CK_ULONG keySize, | |||
7094 | unsigned char *data, CK_ULONG len) | |||
7095 | { | |||
7096 | /* large enough for a 512-bit key */ | |||
7097 | unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE64]; | |||
7098 | SECStatus rv; | |||
7099 | unsigned int outLen; | |||
7100 | CK_RV crv; | |||
7101 | ||||
7102 | if ((len % blockSize) != 0) { | |||
7103 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7104 | } | |||
7105 | if (len > SFTK_MAX_DERIVE_KEY_SIZE64) { | |||
7106 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7107 | } | |||
7108 | if (keySize && (len < keySize)) { | |||
7109 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7110 | } | |||
7111 | if (keySize == 0) { | |||
7112 | keySize = len; | |||
7113 | } | |||
7114 | ||||
7115 | rv = (*encrypt)(cipherInfo, &tmpdata, &outLen, len, data, len); | |||
7116 | if (rv != SECSuccess) { | |||
7117 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
7118 | return crv; | |||
7119 | } | |||
7120 | ||||
7121 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, tmpdata, keySize); | |||
7122 | PORT_Memsetmemset(tmpdata, 0, sizeof tmpdata); | |||
7123 | return crv; | |||
7124 | } | |||
7125 | ||||
7126 | CK_RV | |||
7127 | sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_SESSION_HANDLE hSession, | |||
7128 | SFTKObject *sourceKey, const unsigned char *sourceKeyBytes, | |||
7129 | int sourceKeyLen, SFTKObject *key, unsigned char *outKeyBytes, | |||
7130 | int keySize, PRBool canBeData, PRBool isFIPS) | |||
7131 | { | |||
7132 | SFTKSession *session; | |||
7133 | SFTKAttribute *saltKey_att = NULL((void*)0); | |||
7134 | const SECHashObject *rawHash; | |||
7135 | unsigned hashLen; | |||
7136 | unsigned genLen = 0; | |||
7137 | unsigned char hashbuf[HASH_LENGTH_MAX64]; | |||
7138 | unsigned char keyBlock[9 * SFTK_MAX_MAC_LENGTH64]; | |||
7139 | unsigned char *keyBlockAlloc = NULL((void*)0); /* allocated keyBlock */ | |||
7140 | unsigned char *keyBlockData = keyBlock; /* pointer to current keyBlock */ | |||
7141 | const unsigned char *prk; /* psuedo-random key */ | |||
7142 | CK_ULONG prkLen; | |||
7143 | const unsigned char *okm; /* output keying material */ | |||
7144 | HASH_HashType hashType = sftk_GetHashTypeFromMechanism(params->prfHashMechanism); | |||
7145 | SFTKObject *saltKey = NULL((void*)0); | |||
7146 | CK_RV crv = CKR_OK0x00000000UL; | |||
7147 | ||||
7148 | /* Spec says it should be the base hash, but also accept the HMAC */ | |||
7149 | if (hashType == HASH_AlgNULL) { | |||
7150 | hashType = sftk_HMACMechanismToHash(params->prfHashMechanism); | |||
7151 | } | |||
7152 | rawHash = HASH_GetRawHashObject(hashType); | |||
7153 | if (rawHash == NULL((void*)0) || rawHash->length > sizeof(hashbuf)) { | |||
7154 | return CKR_MECHANISM_INVALID0x00000070UL; | |||
7155 | } | |||
7156 | hashLen = rawHash->length; | |||
7157 | ||||
7158 | if ((!params->bExpand && !params->bExtract) || | |||
7159 | (params->bExtract && params->ulSaltLen > 0 && !params->pSalt) || | |||
7160 | (params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) { | |||
7161 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7162 | } | |||
7163 | if ((params->bExpand && keySize == 0) || | |||
7164 | (!params->bExpand && keySize > hashLen) || | |||
7165 | (params->bExpand && keySize > 255 * hashLen)) { | |||
7166 | return CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
7167 | } | |||
7168 | ||||
7169 | /* sourceKey is NULL if we are called from the POST, skip the | |||
7170 | * sensitiveCheck */ | |||
7171 | if (sourceKey != NULL((void*)0)) { | |||
7172 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, canBeData); | |||
7173 | if (crv != CKR_OK0x00000000UL) | |||
7174 | return crv; | |||
7175 | } | |||
7176 | ||||
7177 | /* HKDF-Extract(salt, base key value) */ | |||
7178 | if (params->bExtract) { | |||
7179 | CK_BYTE *salt; | |||
7180 | CK_ULONG saltLen; | |||
7181 | HMACContext *hmac; | |||
7182 | unsigned int bufLen; | |||
7183 | ||||
7184 | switch (params->ulSaltType) { | |||
7185 | case CKF_HKDF_SALT_NULL0x00000001UL: | |||
7186 | saltLen = hashLen; | |||
7187 | salt = hashbuf; | |||
7188 | memset(salt, 0, saltLen); | |||
7189 | break; | |||
7190 | case CKF_HKDF_SALT_DATA0x00000002UL: | |||
7191 | salt = params->pSalt; | |||
7192 | saltLen = params->ulSaltLen; | |||
7193 | if ((salt == NULL((void*)0)) || (params->ulSaltLen == 0)) { | |||
7194 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7195 | } | |||
7196 | break; | |||
7197 | case CKF_HKDF_SALT_KEY0x00000004UL: | |||
7198 | /* lookup key */ | |||
7199 | session = sftk_SessionFromHandle(hSession); | |||
7200 | if (session == NULL((void*)0)) { | |||
7201 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
7202 | } | |||
7203 | ||||
7204 | saltKey = sftk_ObjectFromHandle(params->hSaltKey, session); | |||
7205 | sftk_FreeSession(session); | |||
7206 | if (saltKey == NULL((void*)0)) { | |||
7207 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
7208 | } | |||
7209 | /* if the base key is not fips, but the salt key is, the | |||
7210 | * resulting key can be fips */ | |||
7211 | if (isFIPS && (key->isFIPS == 0) && (saltKey->isFIPS == 1)) { | |||
7212 | CK_MECHANISM mech; | |||
7213 | mech.mechanism = CKM_HKDF_DERIVE0x0000402aUL; | |||
7214 | mech.pParameter = params; | |||
7215 | mech.ulParameterLen = sizeof(*params); | |||
7216 | key->isFIPS = sftk_operationIsFIPS(saltKey->slot, &mech, | |||
7217 | CKA_DERIVE0x0000010CUL, saltKey); | |||
7218 | } | |||
7219 | saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE0x00000011UL); | |||
7220 | if (saltKey_att == NULL((void*)0)) { | |||
7221 | sftk_FreeObject(saltKey); | |||
7222 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
7223 | } | |||
7224 | /* save the resulting salt */ | |||
7225 | salt = saltKey_att->attrib.pValue; | |||
7226 | saltLen = saltKey_att->attrib.ulValueLen; | |||
7227 | break; | |||
7228 | default: | |||
7229 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7230 | break; | |||
7231 | } | |||
7232 | ||||
7233 | hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS); | |||
7234 | if (saltKey_att) { | |||
7235 | sftk_FreeAttribute(saltKey_att); | |||
7236 | } | |||
7237 | if (saltKey) { | |||
7238 | sftk_FreeObject(saltKey); | |||
7239 | } | |||
7240 | if (!hmac) { | |||
7241 | return CKR_HOST_MEMORY0x00000002UL; | |||
7242 | } | |||
7243 | HMAC_Begin(hmac); | |||
7244 | HMAC_Update(hmac, sourceKeyBytes, sourceKeyLen); | |||
7245 | HMAC_Finish(hmac, hashbuf, &bufLen, sizeof(hashbuf)); | |||
7246 | HMAC_Destroy(hmac, PR_TRUE1); | |||
7247 | PORT_Assert(bufLen == rawHash->length)((bufLen == rawHash->length)?((void)0):PR_Assert("bufLen == rawHash->length" ,"pkcs11c.c",7247)); | |||
7248 | prk = hashbuf; | |||
7249 | prkLen = bufLen; | |||
7250 | } else { | |||
7251 | /* PRK = base key value */ | |||
7252 | prk = sourceKeyBytes; | |||
7253 | prkLen = sourceKeyLen; | |||
7254 | } | |||
7255 | ||||
7256 | /* HKDF-Expand */ | |||
7257 | if (!params->bExpand) { | |||
7258 | okm = prk; | |||
7259 | keySize = genLen = hashLen; | |||
7260 | } else { | |||
7261 | /* T(1) = HMAC-Hash(prk, "" | info | 0x01) | |||
7262 | * T(n) = HMAC-Hash(prk, T(n-1) | info | n | |||
7263 | * key material = T(1) | ... | T(n) | |||
7264 | */ | |||
7265 | HMACContext *hmac; | |||
7266 | CK_BYTE bi; | |||
7267 | unsigned iterations; | |||
7268 | ||||
7269 | genLen = PR_ROUNDUP(keySize, hashLen)((((keySize)+((hashLen)-1))/(hashLen))*(hashLen)); | |||
7270 | iterations = genLen / hashLen; | |||
7271 | ||||
7272 | if (genLen > sizeof(keyBlock)) { | |||
7273 | keyBlockAlloc = PORT_AllocPORT_Alloc_Util(genLen); | |||
7274 | if (keyBlockAlloc == NULL((void*)0)) { | |||
7275 | return CKR_HOST_MEMORY0x00000002UL; | |||
7276 | } | |||
7277 | keyBlockData = keyBlockAlloc; | |||
7278 | } | |||
7279 | hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS); | |||
7280 | if (hmac == NULL((void*)0)) { | |||
7281 | PORT_FreePORT_Free_Util(keyBlockAlloc); | |||
7282 | return CKR_HOST_MEMORY0x00000002UL; | |||
7283 | } | |||
7284 | for (bi = 1; bi <= iterations && bi > 0; ++bi) { | |||
7285 | unsigned len; | |||
7286 | HMAC_Begin(hmac); | |||
7287 | if (bi > 1) { | |||
7288 | HMAC_Update(hmac, &keyBlockData[(bi - 2) * hashLen], hashLen); | |||
7289 | } | |||
7290 | if (params->ulInfoLen != 0) { | |||
7291 | HMAC_Update(hmac, params->pInfo, params->ulInfoLen); | |||
7292 | } | |||
7293 | HMAC_Update(hmac, &bi, 1); | |||
7294 | HMAC_Finish(hmac, &keyBlockData[(bi - 1) * hashLen], &len, | |||
7295 | hashLen); | |||
7296 | PORT_Assert(len == hashLen)((len == hashLen)?((void)0):PR_Assert("len == hashLen","pkcs11c.c" ,7296)); | |||
7297 | } | |||
7298 | HMAC_Destroy(hmac, PR_TRUE1); | |||
7299 | okm = &keyBlockData[0]; | |||
7300 | } | |||
7301 | /* key material = okm */ | |||
7302 | crv = CKR_OK0x00000000UL; | |||
7303 | if (key) { | |||
7304 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, okm, keySize); | |||
7305 | } else { | |||
7306 | PORT_Assert(outKeyBytes != NULL)((outKeyBytes != ((void*)0))?((void)0):PR_Assert("outKeyBytes != NULL" ,"pkcs11c.c",7306)); | |||
7307 | PORT_Memcpymemcpy(outKeyBytes, okm, keySize); | |||
7308 | } | |||
7309 | PORT_Memsetmemset(keyBlockData, 0, genLen); | |||
7310 | PORT_Memsetmemset(hashbuf, 0, sizeof(hashbuf)); | |||
7311 | PORT_FreePORT_Free_Util(keyBlockAlloc); | |||
7312 | return crv; | |||
7313 | } | |||
7314 | ||||
7315 | /* | |||
7316 | * SSL Key generation given pre master secret | |||
7317 | */ | |||
7318 | #define NUM_MIXERS9 9 | |||
7319 | static const char *const mixers[NUM_MIXERS9] = { | |||
7320 | "A", | |||
7321 | "BB", | |||
7322 | "CCC", | |||
7323 | "DDDD", | |||
7324 | "EEEEE", | |||
7325 | "FFFFFF", | |||
7326 | "GGGGGGG", | |||
7327 | "HHHHHHHH", | |||
7328 | "IIIIIIIII" | |||
7329 | }; | |||
7330 | #define SSL3_PMS_LENGTH48 48 | |||
7331 | #define SSL3_MASTER_SECRET_LENGTH48 48 | |||
7332 | #define SSL3_RANDOM_LENGTH32 32 | |||
7333 | ||||
7334 | /* NSC_DeriveKey derives a key from a base key, creating a new key object. */ | |||
7335 | CK_RV | |||
7336 | NSC_DeriveKey(CK_SESSION_HANDLE hSession, | |||
7337 | CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, | |||
7338 | CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, | |||
7339 | CK_OBJECT_HANDLE_PTR phKey) | |||
7340 | { | |||
7341 | SFTKSession *session; | |||
7342 | SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); | |||
7343 | SFTKObject *key; | |||
7344 | SFTKObject *sourceKey; | |||
7345 | SFTKAttribute *att = NULL((void*)0); | |||
7346 | SFTKAttribute *att2 = NULL((void*)0); | |||
7347 | unsigned char *buf; | |||
7348 | SHA1Context *sha; | |||
7349 | MD5Context *md5; | |||
7350 | MD2Context *md2; | |||
7351 | CK_ULONG macSize; | |||
7352 | CK_ULONG tmpKeySize; | |||
7353 | CK_ULONG IVSize; | |||
7354 | CK_ULONG keySize = 0; | |||
7355 | CK_RV crv = CKR_OK0x00000000UL; | |||
7356 | CK_BBOOL cktrue = CK_TRUE1; | |||
7357 | CK_BBOOL ckfalse = CK_FALSE0; | |||
7358 | CK_KEY_TYPE keyType = CKK_GENERIC_SECRET0x00000010UL; | |||
7359 | CK_OBJECT_CLASS classType = CKO_SECRET_KEY0x00000004UL; | |||
7360 | CK_KEY_DERIVATION_STRING_DATA *stringPtr; | |||
7361 | PRBool isTLS = PR_FALSE0; | |||
7362 | PRBool isDH = PR_FALSE0; | |||
7363 | HASH_HashType tlsPrfHash = HASH_AlgNULL; | |||
7364 | SECStatus rv; | |||
7365 | int i; | |||
7366 | unsigned int outLen; | |||
7367 | unsigned char sha_out[SHA1_LENGTH20]; | |||
7368 | unsigned char key_block[NUM_MIXERS9 * SFTK_MAX_MAC_LENGTH64]; | |||
7369 | PRBool isFIPS; | |||
7370 | HASH_HashType hashType; | |||
7371 | CK_MECHANISM_TYPE hashMech; | |||
7372 | PRBool extractValue = PR_TRUE1; | |||
7373 | CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS ikeAppB; | |||
7374 | CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS *pIkeAppB; | |||
7375 | ||||
7376 | CHECK_FORK(); | |||
7377 | ||||
7378 | if (!slot) { | |||
7379 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
7380 | } | |||
7381 | if (!pMechanism) { | |||
7382 | return CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7383 | } | |||
7384 | CK_MECHANISM_TYPE mechanism = pMechanism->mechanism; | |||
7385 | ||||
7386 | /* | |||
7387 | * now lets create an object to hang the attributes off of | |||
7388 | */ | |||
7389 | if (phKey) | |||
7390 | *phKey = CK_INVALID_HANDLE0; | |||
7391 | ||||
7392 | key = sftk_NewObject(slot); /* fill in the handle later */ | |||
7393 | if (key == NULL((void*)0)) { | |||
7394 | return CKR_HOST_MEMORY0x00000002UL; | |||
7395 | } | |||
7396 | isFIPS = sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101)); | |||
7397 | ||||
7398 | /* | |||
7399 | * load the template values into the object | |||
7400 | */ | |||
7401 | for (i = 0; i < (int)ulAttributeCount; i++) { | |||
7402 | crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue, (&pTemplate[i])->ulValueLen); | |||
7403 | if (crv != CKR_OK0x00000000UL) | |||
7404 | break; | |||
7405 | ||||
7406 | if (pTemplate[i].type == CKA_KEY_TYPE0x00000100UL) { | |||
7407 | keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue; | |||
7408 | } | |||
7409 | if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) { | |||
7410 | keySize = *(CK_ULONG *)pTemplate[i].pValue; | |||
7411 | } | |||
7412 | } | |||
7413 | if (crv != CKR_OK0x00000000UL) { | |||
7414 | sftk_FreeObject(key); | |||
7415 | return crv; | |||
7416 | } | |||
7417 | ||||
7418 | if (keySize == 0) { | |||
7419 | keySize = sftk_MapKeySize(keyType); | |||
7420 | } | |||
7421 | ||||
7422 | switch (mechanism) { | |||
7423 | case CKM_NSS_JPAKE_ROUND2_SHA1((0x80000000UL | 0x4E534350) + 11): /* fall through */ | |||
7424 | case CKM_NSS_JPAKE_ROUND2_SHA256((0x80000000UL | 0x4E534350) + 12): /* fall through */ | |||
7425 | case CKM_NSS_JPAKE_ROUND2_SHA384((0x80000000UL | 0x4E534350) + 13): /* fall through */ | |||
7426 | case CKM_NSS_JPAKE_ROUND2_SHA512((0x80000000UL | 0x4E534350) + 14): | |||
7427 | extractValue = PR_FALSE0; | |||
7428 | classType = CKO_PRIVATE_KEY0x00000003UL; | |||
7429 | break; | |||
7430 | case CKM_NSS_PUB_FROM_PRIV((0x80000000UL | 0x4E534350) + 40): | |||
7431 | extractValue = PR_FALSE0; | |||
7432 | classType = CKO_PUBLIC_KEY0x00000002UL; | |||
7433 | break; | |||
7434 | case CKM_HKDF_DATA0x0000402bUL: /* fall through */ | |||
7435 | case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 42): /* fall through */ | |||
7436 | case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 43): /* fall through */ | |||
7437 | case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 44): | |||
7438 | classType = CKO_DATA0x00000000UL; | |||
7439 | break; | |||
7440 | case CKM_NSS_JPAKE_FINAL_SHA1((0x80000000UL | 0x4E534350) + 15): /* fall through */ | |||
7441 | case CKM_NSS_JPAKE_FINAL_SHA256((0x80000000UL | 0x4E534350) + 16): /* fall through */ | |||
7442 | case CKM_NSS_JPAKE_FINAL_SHA384((0x80000000UL | 0x4E534350) + 17): /* fall through */ | |||
7443 | case CKM_NSS_JPAKE_FINAL_SHA512((0x80000000UL | 0x4E534350) + 18): | |||
7444 | extractValue = PR_FALSE0; | |||
7445 | /* fall through */ | |||
7446 | default: | |||
7447 | classType = CKO_SECRET_KEY0x00000004UL; | |||
7448 | } | |||
7449 | ||||
7450 | crv = sftk_forceAttribute(key, CKA_CLASS0x00000000UL, &classType, sizeof(classType)); | |||
7451 | if (crv != CKR_OK0x00000000UL) { | |||
7452 | sftk_FreeObject(key); | |||
7453 | return crv; | |||
7454 | } | |||
7455 | ||||
7456 | /* look up the base key we're deriving with */ | |||
7457 | session = sftk_SessionFromHandle(hSession); | |||
7458 | if (session == NULL((void*)0)) { | |||
7459 | sftk_FreeObject(key); | |||
7460 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
7461 | } | |||
7462 | ||||
7463 | sourceKey = sftk_ObjectFromHandle(hBaseKey, session); | |||
7464 | sftk_FreeSession(session); | |||
7465 | /* is this eventually succeeds, lastOpWasFIPS will be set the resulting key's | |||
7466 | * FIPS state below. */ | |||
7467 | session->lastOpWasFIPS = PR_FALSE0; | |||
7468 | if (sourceKey == NULL((void*)0)) { | |||
7469 | sftk_FreeObject(key); | |||
7470 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
7471 | } | |||
7472 | ||||
7473 | if (extractValue) { | |||
7474 | /* get the value of the base key */ | |||
7475 | att = sftk_FindAttribute(sourceKey, CKA_VALUE0x00000011UL); | |||
7476 | if (att == NULL((void*)0)) { | |||
7477 | sftk_FreeObject(key); | |||
7478 | sftk_FreeObject(sourceKey); | |||
7479 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
7480 | } | |||
7481 | } | |||
7482 | key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_DERIVE0x0000010CUL, sourceKey); | |||
7483 | ||||
7484 | switch (mechanism) { | |||
7485 | /* get a public key from a private key. nsslowkey_ConvertToPublickey() | |||
7486 | * will generate the public portion if it doesn't already exist. */ | |||
7487 | case CKM_NSS_PUB_FROM_PRIV((0x80000000UL | 0x4E534350) + 40): { | |||
7488 | NSSLOWKEYPrivateKey *privKey; | |||
7489 | NSSLOWKEYPublicKey *pubKey; | |||
7490 | int error; | |||
7491 | ||||
7492 | crv = sftk_GetULongAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL, &keyType); | |||
7493 | if (crv != CKR_OK0x00000000UL) { | |||
7494 | break; | |||
7495 | } | |||
7496 | ||||
7497 | /* privKey is stored in sourceKey and will be destroyed when | |||
7498 | * the sourceKey is freed. */ | |||
7499 | privKey = sftk_GetPrivKey(sourceKey, keyType, &crv); | |||
7500 | if (privKey == NULL((void*)0)) { | |||
7501 | break; | |||
7502 | } | |||
7503 | pubKey = nsslowkey_ConvertToPublicKey(privKey); | |||
7504 | if (pubKey == NULL((void*)0)) { | |||
7505 | error = PORT_GetErrorPORT_GetError_Util(); | |||
7506 | crv = sftk_MapCryptError(error); | |||
7507 | break; | |||
7508 | } | |||
7509 | crv = sftk_PutPubKey(key, sourceKey, keyType, pubKey); | |||
7510 | nsslowkey_DestroyPublicKey(pubKey); | |||
7511 | break; | |||
7512 | } | |||
7513 | case CKM_NSS_IKE_PRF_DERIVE((0x80000000UL | 0x4E534350) + 35): | |||
7514 | if (pMechanism->ulParameterLen != | |||
7515 | sizeof(CK_NSS_IKE_PRF_DERIVE_PARAMS)) { | |||
7516 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7517 | break; | |||
7518 | } | |||
7519 | crv = sftk_ike_prf(hSession, att, | |||
7520 | (CK_NSS_IKE_PRF_DERIVE_PARAMS *)pMechanism->pParameter, key); | |||
7521 | break; | |||
7522 | case CKM_NSS_IKE1_PRF_DERIVE((0x80000000UL | 0x4E534350) + 36): | |||
7523 | if (pMechanism->ulParameterLen != | |||
7524 | sizeof(CK_NSS_IKE1_PRF_DERIVE_PARAMS)) { | |||
7525 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7526 | break; | |||
7527 | } | |||
7528 | crv = sftk_ike1_prf(hSession, att, | |||
7529 | (CK_NSS_IKE1_PRF_DERIVE_PARAMS *)pMechanism->pParameter, | |||
7530 | key, keySize); | |||
7531 | break; | |||
7532 | case CKM_NSS_IKE1_APP_B_PRF_DERIVE((0x80000000UL | 0x4E534350) + 37): | |||
7533 | pIkeAppB = (CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS *)pMechanism->pParameter; | |||
7534 | if (pMechanism->ulParameterLen == | |||
7535 | sizeof(CK_MECHANISM_TYPE)) { | |||
7536 | ikeAppB.prfMechanism = *(CK_MECHANISM_TYPE *)pMechanism->pParameter; | |||
7537 | ikeAppB.bHasKeygxy = PR_FALSE0; | |||
7538 | ikeAppB.hKeygxy = CK_INVALID_HANDLE0; | |||
7539 | ikeAppB.pExtraData = NULL((void*)0); | |||
7540 | ikeAppB.ulExtraDataLen = 0; | |||
7541 | pIkeAppB = &ikeAppB; | |||
7542 | } else if (pMechanism->ulParameterLen != | |||
7543 | sizeof(CK_NSS_IKE1_APP_B_PRF_DERIVE_PARAMS)) { | |||
7544 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7545 | break; | |||
7546 | } | |||
7547 | crv = sftk_ike1_appendix_b_prf(hSession, att, pIkeAppB, key, | |||
7548 | keySize); | |||
7549 | break; | |||
7550 | case CKM_NSS_IKE_PRF_PLUS_DERIVE((0x80000000UL | 0x4E534350) + 34): | |||
7551 | if (pMechanism->ulParameterLen != | |||
7552 | sizeof(CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS)) { | |||
7553 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7554 | break; | |||
7555 | } | |||
7556 | crv = sftk_ike_prf_plus(hSession, att, | |||
7557 | (CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *)pMechanism->pParameter, | |||
7558 | key, keySize); | |||
7559 | break; | |||
7560 | /* | |||
7561 | * generate the master secret | |||
7562 | */ | |||
7563 | case CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL: | |||
7564 | case CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL: | |||
7565 | case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 22): | |||
7566 | case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24): | |||
7567 | case CKM_TLS_MASTER_KEY_DERIVE0x00000375UL: | |||
7568 | case CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377UL: | |||
7569 | case CKM_SSL3_MASTER_KEY_DERIVE0x00000371UL: | |||
7570 | case CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL: { | |||
7571 | CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master; | |||
7572 | SSL3RSAPreMasterSecret *rsa_pms; | |||
7573 | unsigned char crsrdata[SSL3_RANDOM_LENGTH32 * 2]; | |||
7574 | ||||
7575 | if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL) || | |||
7576 | (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL)) { | |||
7577 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))) { | |||
7578 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7579 | break; | |||
7580 | } | |||
7581 | CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master = | |||
7582 | (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter; | |||
7583 | tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_master->prfHashMechanism); | |||
7584 | if (tlsPrfHash == HASH_AlgNULL) { | |||
7585 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7586 | break; | |||
7587 | } | |||
7588 | } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 22)) || | |||
7589 | (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24))) { | |||
7590 | tlsPrfHash = HASH_AlgSHA256; | |||
7591 | } | |||
7592 | ||||
7593 | if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE0x00000371UL) && | |||
7594 | (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL)) { | |||
7595 | isTLS = PR_TRUE1; | |||
7596 | } | |||
7597 | if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL) || | |||
7598 | (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377UL) || | |||
7599 | (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24)) || | |||
7600 | (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL)) { | |||
7601 | isDH = PR_TRUE1; | |||
7602 | } | |||
7603 | ||||
7604 | /* first do the consistency checks */ | |||
7605 | if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH48)) { | |||
7606 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
7607 | break; | |||
7608 | } | |||
7609 | att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL); | |||
7610 | if ((att2 == NULL((void*)0)) || (*(CK_KEY_TYPE *)att2->attrib.pValue != | |||
7611 | CKK_GENERIC_SECRET0x00000010UL)) { | |||
7612 | if (att2) | |||
7613 | sftk_FreeAttribute(att2); | |||
7614 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7615 | break; | |||
7616 | } | |||
7617 | sftk_FreeAttribute(att2); | |||
7618 | if (keyType != CKK_GENERIC_SECRET0x00000010UL) { | |||
7619 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7620 | break; | |||
7621 | } | |||
7622 | if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH48)) { | |||
7623 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7624 | break; | |||
7625 | } | |||
7626 | ||||
7627 | /* finally do the key gen */ | |||
7628 | ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) | |||
7629 | pMechanism->pParameter; | |||
7630 | ||||
7631 | if (ssl3_master->pVersion) { | |||
7632 | SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); | |||
7633 | rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue; | |||
7634 | /* don't leak more key material then necessary for SSL to work */ | |||
7635 | if ((sessKey == NULL((void*)0)) || sessKey->wasDerived) { | |||
7636 | ssl3_master->pVersion->major = 0xff; | |||
7637 | ssl3_master->pVersion->minor = 0xff; | |||
7638 | } else { | |||
7639 | ssl3_master->pVersion->major = rsa_pms->client_version[0]; | |||
7640 | ssl3_master->pVersion->minor = rsa_pms->client_version[1]; | |||
7641 | } | |||
7642 | } | |||
7643 | if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH32) { | |||
7644 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7645 | break; | |||
7646 | } | |||
7647 | if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH32) { | |||
7648 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7649 | break; | |||
7650 | } | |||
7651 | PORT_Memcpymemcpy(crsrdata, | |||
7652 | ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH32); | |||
7653 | PORT_Memcpymemcpy(crsrdata + SSL3_RANDOM_LENGTH32, | |||
7654 | ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH32); | |||
7655 | ||||
7656 | if (isTLS) { | |||
7657 | SECStatus status; | |||
7658 | SECItem crsr = { siBuffer, NULL((void*)0), 0 }; | |||
7659 | SECItem master = { siBuffer, NULL((void*)0), 0 }; | |||
7660 | SECItem pms = { siBuffer, NULL((void*)0), 0 }; | |||
7661 | ||||
7662 | crsr.data = crsrdata; | |||
7663 | crsr.len = sizeof crsrdata; | |||
7664 | master.data = key_block; | |||
7665 | master.len = SSL3_MASTER_SECRET_LENGTH48; | |||
7666 | pms.data = (unsigned char *)att->attrib.pValue; | |||
7667 | pms.len = att->attrib.ulValueLen; | |||
7668 | ||||
7669 | if (tlsPrfHash != HASH_AlgNULL) { | |||
7670 | status = TLS_P_hash(tlsPrfHash, &pms, "master secret", | |||
7671 | &crsr, &master, isFIPS); | |||
7672 | } else { | |||
7673 | status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); | |||
7674 | } | |||
7675 | if (status != SECSuccess) { | |||
7676 | PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata); | |||
7677 | crv = CKR_FUNCTION_FAILED0x00000006UL; | |||
7678 | break; | |||
7679 | } | |||
7680 | } else { | |||
7681 | /* now allocate the hash contexts */ | |||
7682 | md5 = MD5_NewContext(); | |||
7683 | if (md5 == NULL((void*)0)) { | |||
7684 | PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata); | |||
7685 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
7686 | break; | |||
7687 | } | |||
7688 | sha = SHA1_NewContext(); | |||
7689 | if (sha == NULL((void*)0)) { | |||
7690 | PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata); | |||
7691 | PORT_FreePORT_Free_Util(md5); | |||
7692 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
7693 | break; | |||
7694 | } | |||
7695 | for (i = 0; i < 3; i++) { | |||
7696 | SHA1_Begin(sha); | |||
7697 | SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i])); | |||
7698 | SHA1_Update(sha, (const unsigned char *)att->attrib.pValue, | |||
7699 | att->attrib.ulValueLen); | |||
7700 | SHA1_Update(sha, crsrdata, sizeof crsrdata); | |||
7701 | SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH20); | |||
7702 | PORT_Assert(outLen == SHA1_LENGTH)((outLen == 20)?((void)0):PR_Assert("outLen == SHA1_LENGTH","pkcs11c.c" ,7702)); | |||
7703 | ||||
7704 | MD5_Begin(md5); | |||
7705 | MD5_Update(md5, (const unsigned char *)att->attrib.pValue, | |||
7706 | att->attrib.ulValueLen); | |||
7707 | MD5_Update(md5, sha_out, outLen); | |||
7708 | MD5_End(md5, &key_block[i * MD5_LENGTH16], &outLen, MD5_LENGTH16); | |||
7709 | PORT_Assert(outLen == MD5_LENGTH)((outLen == 16)?((void)0):PR_Assert("outLen == MD5_LENGTH","pkcs11c.c" ,7709)); | |||
7710 | } | |||
7711 | PORT_FreePORT_Free_Util(md5); | |||
7712 | PORT_FreePORT_Free_Util(sha); | |||
7713 | PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata); | |||
7714 | PORT_Memsetmemset(sha_out, 0, sizeof sha_out); | |||
7715 | } | |||
7716 | ||||
7717 | /* store the results */ | |||
7718 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, SSL3_MASTER_SECRET_LENGTH48); | |||
7719 | PORT_Memsetmemset(key_block, 0, sizeof key_block); | |||
7720 | if (crv != CKR_OK0x00000000UL) | |||
7721 | break; | |||
7722 | keyType = CKK_GENERIC_SECRET0x00000010UL; | |||
7723 | crv = sftk_forceAttribute(key, CKA_KEY_TYPE0x00000100UL, &keyType, sizeof(keyType)); | |||
7724 | if (isTLS) { | |||
7725 | /* TLS's master secret is used to "sign" finished msgs with PRF. */ | |||
7726 | /* XXX This seems like a hack. But SFTK_Derive only accepts | |||
7727 | * one "operation" argument. */ | |||
7728 | crv = sftk_forceAttribute(key, CKA_SIGN0x00000108UL, &cktrue, sizeof(CK_BBOOL)); | |||
7729 | if (crv != CKR_OK0x00000000UL) | |||
7730 | break; | |||
7731 | crv = sftk_forceAttribute(key, CKA_VERIFY0x0000010AUL, &cktrue, sizeof(CK_BBOOL)); | |||
7732 | if (crv != CKR_OK0x00000000UL) | |||
7733 | break; | |||
7734 | /* While we're here, we might as well force this, too. */ | |||
7735 | crv = sftk_forceAttribute(key, CKA_DERIVE0x0000010CUL, &cktrue, sizeof(CK_BBOOL)); | |||
7736 | if (crv != CKR_OK0x00000000UL) | |||
7737 | break; | |||
7738 | } | |||
7739 | break; | |||
7740 | } | |||
7741 | ||||
7742 | /* Extended master key derivation [draft-ietf-tls-session-hash] */ | |||
7743 | case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE((0x80000000UL | 0x4E534350) + 25): | |||
7744 | case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH((0x80000000UL | 0x4E534350) + 26): { | |||
7745 | CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params; | |||
7746 | SSL3RSAPreMasterSecret *rsa_pms; | |||
7747 | SECStatus status; | |||
7748 | SECItem pms = { siBuffer, NULL((void*)0), 0 }; | |||
7749 | SECItem seed = { siBuffer, NULL((void*)0), 0 }; | |||
7750 | SECItem master = { siBuffer, NULL((void*)0), 0 }; | |||
7751 | ||||
7752 | ems_params = (CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *) | |||
7753 | pMechanism->pParameter; | |||
7754 | ||||
7755 | /* First do the consistency checks */ | |||
7756 | if ((mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE((0x80000000UL | 0x4E534350) + 25)) && | |||
7757 | (att->attrib.ulValueLen != SSL3_PMS_LENGTH48)) { | |||
7758 | crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
7759 | break; | |||
7760 | } | |||
7761 | att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL); | |||
7762 | if ((att2 == NULL((void*)0)) || | |||
7763 | (*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET0x00000010UL)) { | |||
7764 | if (att2) | |||
7765 | sftk_FreeAttribute(att2); | |||
7766 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7767 | break; | |||
7768 | } | |||
7769 | sftk_FreeAttribute(att2); | |||
7770 | if (keyType != CKK_GENERIC_SECRET0x00000010UL) { | |||
7771 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7772 | break; | |||
7773 | } | |||
7774 | if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH48)) { | |||
7775 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7776 | break; | |||
7777 | } | |||
7778 | ||||
7779 | /* Do the key derivation */ | |||
7780 | pms.data = (unsigned char *)att->attrib.pValue; | |||
7781 | pms.len = att->attrib.ulValueLen; | |||
7782 | seed.data = ems_params->pSessionHash; | |||
7783 | seed.len = ems_params->ulSessionHashLen; | |||
7784 | master.data = key_block; | |||
7785 | master.len = SSL3_MASTER_SECRET_LENGTH48; | |||
7786 | if (ems_params->prfHashMechanism == CKM_TLS_PRF0x00000378UL) { | |||
7787 | /* | |||
7788 | * In this case, the session hash is the concatenation of SHA-1 | |||
7789 | * and MD5, so it should be 36 bytes long. | |||
7790 | */ | |||
7791 | if (seed.len != MD5_LENGTH16 + SHA1_LENGTH20) { | |||
7792 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
7793 | break; | |||
7794 | } | |||
7795 | ||||
7796 | status = TLS_PRF(&pms, "extended master secret", | |||
7797 | &seed, &master, isFIPS); | |||
7798 | } else { | |||
7799 | const SECHashObject *hashObj; | |||
7800 | ||||
7801 | tlsPrfHash = sftk_GetHashTypeFromMechanism(ems_params->prfHashMechanism); | |||
7802 | if (tlsPrfHash == HASH_AlgNULL) { | |||
7803 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7804 | break; | |||
7805 | } | |||
7806 | ||||
7807 | hashObj = HASH_GetRawHashObject(tlsPrfHash); | |||
7808 | if (seed.len != hashObj->length) { | |||
7809 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
7810 | break; | |||
7811 | } | |||
7812 | ||||
7813 | status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret", | |||
7814 | &seed, &master, isFIPS); | |||
7815 | } | |||
7816 | if (status != SECSuccess) { | |||
7817 | crv = CKR_FUNCTION_FAILED0x00000006UL; | |||
7818 | break; | |||
7819 | } | |||
7820 | ||||
7821 | /* Reflect the version if required */ | |||
7822 | if (ems_params->pVersion) { | |||
7823 | SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); | |||
7824 | rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue; | |||
7825 | /* don't leak more key material than necessary for SSL to work */ | |||
7826 | if ((sessKey == NULL((void*)0)) || sessKey->wasDerived) { | |||
7827 | ems_params->pVersion->major = 0xff; | |||
7828 | ems_params->pVersion->minor = 0xff; | |||
7829 | } else { | |||
7830 | ems_params->pVersion->major = rsa_pms->client_version[0]; | |||
7831 | ems_params->pVersion->minor = rsa_pms->client_version[1]; | |||
7832 | } | |||
7833 | } | |||
7834 | ||||
7835 | /* Store the results */ | |||
7836 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, | |||
7837 | SSL3_MASTER_SECRET_LENGTH48); | |||
7838 | PORT_Memsetmemset(key_block, 0, sizeof key_block); | |||
7839 | break; | |||
7840 | } | |||
7841 | ||||
7842 | case CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL: | |||
7843 | case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 23): | |||
7844 | case CKM_TLS_KEY_AND_MAC_DERIVE0x00000376UL: | |||
7845 | case CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372UL: { | |||
7846 | CK_SSL3_KEY_MAT_PARAMS *ssl3_keys; | |||
7847 | CK_SSL3_KEY_MAT_OUT *ssl3_keys_out; | |||
7848 | CK_ULONG effKeySize; | |||
7849 | unsigned int block_needed; | |||
7850 | unsigned char srcrdata[SSL3_RANDOM_LENGTH32 * 2]; | |||
7851 | ||||
7852 | if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL) { | |||
7853 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_KEY_MAT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_TLS12_KEY_MAT_PARAMS))) { | |||
7854 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7855 | break; | |||
7856 | } | |||
7857 | CK_TLS12_KEY_MAT_PARAMS *tls12_keys = | |||
7858 | (CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter; | |||
7859 | tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_keys->prfHashMechanism); | |||
7860 | if (tlsPrfHash == HASH_AlgNULL) { | |||
7861 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7862 | break; | |||
7863 | } | |||
7864 | } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 23)) { | |||
7865 | tlsPrfHash = HASH_AlgSHA256; | |||
7866 | } | |||
7867 | ||||
7868 | if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372UL) { | |||
7869 | isTLS = PR_TRUE1; | |||
7870 | } | |||
7871 | ||||
7872 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
7873 | if (crv != CKR_OK0x00000000UL) | |||
7874 | break; | |||
7875 | ||||
7876 | if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH48) { | |||
7877 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7878 | break; | |||
7879 | } | |||
7880 | att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL); | |||
7881 | if ((att2 == NULL((void*)0)) || (*(CK_KEY_TYPE *)att2->attrib.pValue != | |||
7882 | CKK_GENERIC_SECRET0x00000010UL)) { | |||
7883 | if (att2) | |||
7884 | sftk_FreeAttribute(att2); | |||
7885 | crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL; | |||
7886 | break; | |||
7887 | } | |||
7888 | sftk_FreeAttribute(att2); | |||
7889 | md5 = MD5_NewContext(); | |||
7890 | if (md5 == NULL((void*)0)) { | |||
7891 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
7892 | break; | |||
7893 | } | |||
7894 | sha = SHA1_NewContext(); | |||
7895 | if (sha == NULL((void*)0)) { | |||
7896 | MD5_DestroyContext(md5, PR_TRUE1); | |||
7897 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
7898 | break; | |||
7899 | } | |||
7900 | ||||
7901 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_SSL3_KEY_MAT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_SSL3_KEY_MAT_PARAMS))) { | |||
7902 | MD5_DestroyContext(md5, PR_TRUE1); | |||
7903 | SHA1_DestroyContext(sha, PR_TRUE1); | |||
7904 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7905 | break; | |||
7906 | } | |||
7907 | ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; | |||
7908 | ||||
7909 | PORT_Memcpymemcpy(srcrdata, | |||
7910 | ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH32); | |||
7911 | PORT_Memcpymemcpy(srcrdata + SSL3_RANDOM_LENGTH32, | |||
7912 | ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH32); | |||
7913 | ||||
7914 | /* | |||
7915 | * clear out our returned keys so we can recover on failure | |||
7916 | */ | |||
7917 | ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial; | |||
7918 | ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE0; | |||
7919 | ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE0; | |||
7920 | ssl3_keys_out->hClientKey = CK_INVALID_HANDLE0; | |||
7921 | ssl3_keys_out->hServerKey = CK_INVALID_HANDLE0; | |||
7922 | ||||
7923 | /* | |||
7924 | * How much key material do we need? | |||
7925 | */ | |||
7926 | macSize = ssl3_keys->ulMacSizeInBits / 8; | |||
7927 | effKeySize = ssl3_keys->ulKeySizeInBits / 8; | |||
7928 | IVSize = ssl3_keys->ulIVSizeInBits / 8; | |||
7929 | if (keySize == 0) { | |||
7930 | effKeySize = keySize; | |||
7931 | } | |||
7932 | ||||
7933 | /* bIsExport must be false. */ | |||
7934 | if (ssl3_keys->bIsExport) { | |||
7935 | MD5_DestroyContext(md5, PR_TRUE1); | |||
7936 | SHA1_DestroyContext(sha, PR_TRUE1); | |||
7937 | PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata); | |||
7938 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
7939 | break; | |||
7940 | } | |||
7941 | ||||
7942 | block_needed = 2 * (macSize + effKeySize + IVSize); | |||
7943 | PORT_Assert(block_needed <= sizeof key_block)((block_needed <= sizeof key_block)?((void)0):PR_Assert("block_needed <= sizeof key_block" ,"pkcs11c.c",7943)); | |||
7944 | if (block_needed > sizeof key_block) | |||
7945 | block_needed = sizeof key_block; | |||
7946 | ||||
7947 | /* | |||
7948 | * generate the key material: This looks amazingly similar to the | |||
7949 | * PMS code, and is clearly crying out for a function to provide it. | |||
7950 | */ | |||
7951 | if (isTLS) { | |||
7952 | SECStatus status; | |||
7953 | SECItem srcr = { siBuffer, NULL((void*)0), 0 }; | |||
7954 | SECItem keyblk = { siBuffer, NULL((void*)0), 0 }; | |||
7955 | SECItem master = { siBuffer, NULL((void*)0), 0 }; | |||
7956 | ||||
7957 | srcr.data = srcrdata; | |||
7958 | srcr.len = sizeof srcrdata; | |||
7959 | keyblk.data = key_block; | |||
7960 | keyblk.len = block_needed; | |||
7961 | master.data = (unsigned char *)att->attrib.pValue; | |||
7962 | master.len = att->attrib.ulValueLen; | |||
7963 | ||||
7964 | if (tlsPrfHash != HASH_AlgNULL) { | |||
7965 | status = TLS_P_hash(tlsPrfHash, &master, "key expansion", | |||
7966 | &srcr, &keyblk, isFIPS); | |||
7967 | } else { | |||
7968 | status = TLS_PRF(&master, "key expansion", &srcr, &keyblk, | |||
7969 | isFIPS); | |||
7970 | } | |||
7971 | if (status != SECSuccess) { | |||
7972 | goto key_and_mac_derive_fail; | |||
7973 | } | |||
7974 | } else { | |||
7975 | unsigned int block_bytes = 0; | |||
7976 | /* key_block = | |||
7977 | * MD5(master_secret + SHA('A' + master_secret + | |||
7978 | * ServerHello.random + ClientHello.random)) + | |||
7979 | * MD5(master_secret + SHA('BB' + master_secret + | |||
7980 | * ServerHello.random + ClientHello.random)) + | |||
7981 | * MD5(master_secret + SHA('CCC' + master_secret + | |||
7982 | * ServerHello.random + ClientHello.random)) + | |||
7983 | * [...]; | |||
7984 | */ | |||
7985 | for (i = 0; i < NUM_MIXERS9 && block_bytes < block_needed; i++) { | |||
7986 | SHA1_Begin(sha); | |||
7987 | SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i])); | |||
7988 | SHA1_Update(sha, (const unsigned char *)att->attrib.pValue, | |||
7989 | att->attrib.ulValueLen); | |||
7990 | SHA1_Update(sha, srcrdata, sizeof srcrdata); | |||
7991 | SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH20); | |||
7992 | PORT_Assert(outLen == SHA1_LENGTH)((outLen == 20)?((void)0):PR_Assert("outLen == SHA1_LENGTH","pkcs11c.c" ,7992)); | |||
7993 | MD5_Begin(md5); | |||
7994 | MD5_Update(md5, (const unsigned char *)att->attrib.pValue, | |||
7995 | att->attrib.ulValueLen); | |||
7996 | MD5_Update(md5, sha_out, outLen); | |||
7997 | MD5_End(md5, &key_block[i * MD5_LENGTH16], &outLen, MD5_LENGTH16); | |||
7998 | PORT_Assert(outLen == MD5_LENGTH)((outLen == 16)?((void)0):PR_Assert("outLen == MD5_LENGTH","pkcs11c.c" ,7998)); | |||
7999 | block_bytes += outLen; | |||
8000 | } | |||
8001 | PORT_Memsetmemset(sha_out, 0, sizeof sha_out); | |||
8002 | } | |||
8003 | ||||
8004 | /* | |||
8005 | * Put the key material where it goes. | |||
8006 | */ | |||
8007 | i = 0; /* now shows how much consumed */ | |||
8008 | ||||
8009 | /* | |||
8010 | * The key_block is partitioned as follows: | |||
8011 | * client_write_MAC_secret[CipherSpec.hash_size] | |||
8012 | */ | |||
8013 | crv = sftk_buildSSLKey(hSession, key, PR_TRUE1, &key_block[i], macSize, | |||
8014 | &ssl3_keys_out->hClientMacSecret); | |||
8015 | if (crv != CKR_OK0x00000000UL) | |||
8016 | goto key_and_mac_derive_fail; | |||
8017 | ||||
8018 | i += macSize; | |||
8019 | ||||
8020 | /* | |||
8021 | * server_write_MAC_secret[CipherSpec.hash_size] | |||
8022 | */ | |||
8023 | crv = sftk_buildSSLKey(hSession, key, PR_TRUE1, &key_block[i], macSize, | |||
8024 | &ssl3_keys_out->hServerMacSecret); | |||
8025 | if (crv != CKR_OK0x00000000UL) { | |||
8026 | goto key_and_mac_derive_fail; | |||
8027 | } | |||
8028 | i += macSize; | |||
8029 | ||||
8030 | if (keySize) { | |||
8031 | /* | |||
8032 | ** Generate Domestic write keys and IVs. | |||
8033 | ** client_write_key[CipherSpec.key_material] | |||
8034 | */ | |||
8035 | crv = sftk_buildSSLKey(hSession, key, PR_FALSE0, &key_block[i], | |||
8036 | keySize, &ssl3_keys_out->hClientKey); | |||
8037 | if (crv != CKR_OK0x00000000UL) { | |||
8038 | goto key_and_mac_derive_fail; | |||
8039 | } | |||
8040 | i += keySize; | |||
8041 | ||||
8042 | /* | |||
8043 | ** server_write_key[CipherSpec.key_material] | |||
8044 | */ | |||
8045 | crv = sftk_buildSSLKey(hSession, key, PR_FALSE0, &key_block[i], | |||
8046 | keySize, &ssl3_keys_out->hServerKey); | |||
8047 | if (crv != CKR_OK0x00000000UL) { | |||
8048 | goto key_and_mac_derive_fail; | |||
8049 | } | |||
8050 | i += keySize; | |||
8051 | ||||
8052 | /* | |||
8053 | ** client_write_IV[CipherSpec.IV_size] | |||
8054 | */ | |||
8055 | if (IVSize > 0) { | |||
8056 | PORT_Memcpymemcpy(ssl3_keys_out->pIVClient, | |||
8057 | &key_block[i], IVSize); | |||
8058 | i += IVSize; | |||
8059 | } | |||
8060 | ||||
8061 | /* | |||
8062 | ** server_write_IV[CipherSpec.IV_size] | |||
8063 | */ | |||
8064 | if (IVSize > 0) { | |||
8065 | PORT_Memcpymemcpy(ssl3_keys_out->pIVServer, | |||
8066 | &key_block[i], IVSize); | |||
8067 | i += IVSize; | |||
8068 | } | |||
8069 | PORT_Assert(i <= sizeof key_block)((i <= sizeof key_block)?((void)0):PR_Assert("i <= sizeof key_block" ,"pkcs11c.c",8069)); | |||
8070 | } | |||
8071 | ||||
8072 | crv = CKR_OK0x00000000UL; | |||
8073 | ||||
8074 | if (0) { | |||
8075 | key_and_mac_derive_fail: | |||
8076 | if (crv == CKR_OK0x00000000UL) | |||
8077 | crv = CKR_FUNCTION_FAILED0x00000006UL; | |||
8078 | sftk_freeSSLKeys(hSession, ssl3_keys_out); | |||
8079 | } | |||
8080 | PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata); | |||
8081 | PORT_Memsetmemset(key_block, 0, sizeof key_block); | |||
8082 | MD5_DestroyContext(md5, PR_TRUE1); | |||
8083 | SHA1_DestroyContext(sha, PR_TRUE1); | |||
8084 | sftk_FreeObject(key); | |||
8085 | key = NULL((void*)0); | |||
8086 | break; | |||
8087 | } | |||
8088 | ||||
8089 | case CKM_DES3_ECB_ENCRYPT_DATA0x00001102UL: | |||
8090 | case CKM_DES3_CBC_ENCRYPT_DATA0x00001103UL: { | |||
8091 | void *cipherInfo; | |||
8092 | unsigned char des3key[MAX_DES3_KEY_SIZE24]; | |||
8093 | CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr; | |||
8094 | int mode; | |||
8095 | unsigned char *iv; | |||
8096 | unsigned char *data; | |||
8097 | CK_ULONG len; | |||
8098 | ||||
8099 | if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA0x00001102UL) { | |||
8100 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_KEY_DERIVATION_STRING_DATA))) { | |||
8101 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8102 | break; | |||
8103 | } | |||
8104 | stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) | |||
8105 | pMechanism->pParameter; | |||
8106 | mode = NSS_DES_EDE32; | |||
8107 | iv = NULL((void*)0); | |||
8108 | data = stringPtr->pData; | |||
8109 | len = stringPtr->ulLen; | |||
8110 | } else { | |||
8111 | mode = NSS_DES_EDE3_CBC3; | |||
8112 | desEncryptPtr = | |||
8113 | (CK_DES_CBC_ENCRYPT_DATA_PARAMS *) | |||
8114 | pMechanism->pParameter; | |||
8115 | iv = desEncryptPtr->iv; | |||
8116 | data = desEncryptPtr->pData; | |||
8117 | len = desEncryptPtr->length; | |||
8118 | } | |||
8119 | if (att->attrib.ulValueLen == 16) { | |||
8120 | PORT_Memcpymemcpy(des3key, att->attrib.pValue, 16); | |||
8121 | PORT_Memcpymemcpy(des3key + 16, des3key, 8); | |||
8122 | } else if (att->attrib.ulValueLen == 24) { | |||
8123 | PORT_Memcpymemcpy(des3key, att->attrib.pValue, 24); | |||
8124 | } else { | |||
8125 | crv = CKR_KEY_SIZE_RANGE0x00000062UL; | |||
8126 | break; | |||
8127 | } | |||
8128 | cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE1); | |||
8129 | PORT_Memsetmemset(des3key, 0, 24); | |||
8130 | if (cipherInfo == NULL((void*)0)) { | |||
8131 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8132 | break; | |||
8133 | } | |||
8134 | crv = sftk_DeriveEncrypt((SFTKCipher)DES_Encrypt, | |||
8135 | cipherInfo, 8, key, keySize, | |||
8136 | data, len); | |||
8137 | DES_DestroyContext(cipherInfo, PR_TRUE1); | |||
8138 | break; | |||
8139 | } | |||
8140 | ||||
8141 | case CKM_AES_ECB_ENCRYPT_DATA0x00001104UL: | |||
8142 | case CKM_AES_CBC_ENCRYPT_DATA0x00001105UL: { | |||
8143 | void *cipherInfo; | |||
8144 | CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; | |||
8145 | int mode; | |||
8146 | unsigned char *iv; | |||
8147 | unsigned char *data; | |||
8148 | CK_ULONG len; | |||
8149 | ||||
8150 | if (mechanism == CKM_AES_ECB_ENCRYPT_DATA0x00001104UL) { | |||
8151 | mode = NSS_AES0; | |||
8152 | iv = NULL((void*)0); | |||
8153 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_KEY_DERIVATION_STRING_DATA))) { | |||
8154 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8155 | break; | |||
8156 | } | |||
8157 | stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; | |||
8158 | data = stringPtr->pData; | |||
8159 | len = stringPtr->ulLen; | |||
8160 | } else { | |||
8161 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) { | |||
8162 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8163 | break; | |||
8164 | } | |||
8165 | aesEncryptPtr = | |||
8166 | (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter; | |||
8167 | mode = NSS_AES_CBC1; | |||
8168 | iv = aesEncryptPtr->iv; | |||
8169 | data = aesEncryptPtr->pData; | |||
8170 | len = aesEncryptPtr->length; | |||
8171 | } | |||
8172 | ||||
8173 | cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue, | |||
8174 | iv, mode, PR_TRUE1, | |||
8175 | att->attrib.ulValueLen, 16); | |||
8176 | if (cipherInfo == NULL((void*)0)) { | |||
8177 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8178 | break; | |||
8179 | } | |||
8180 | crv = sftk_DeriveEncrypt((SFTKCipher)AES_Encrypt, | |||
8181 | cipherInfo, 16, key, keySize, | |||
8182 | data, len); | |||
8183 | AES_DestroyContext(cipherInfo, PR_TRUE1); | |||
8184 | break; | |||
8185 | } | |||
8186 | ||||
8187 | case CKM_CAMELLIA_ECB_ENCRYPT_DATA0x00000556UL: | |||
8188 | case CKM_CAMELLIA_CBC_ENCRYPT_DATA0x00000557UL: { | |||
8189 | void *cipherInfo; | |||
8190 | CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; | |||
8191 | int mode; | |||
8192 | unsigned char *iv; | |||
8193 | unsigned char *data; | |||
8194 | CK_ULONG len; | |||
8195 | ||||
8196 | if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA0x00000556UL) { | |||
8197 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_KEY_DERIVATION_STRING_DATA))) { | |||
8198 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8199 | break; | |||
8200 | } | |||
8201 | stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) | |||
8202 | pMechanism->pParameter; | |||
8203 | aesEncryptPtr = NULL((void*)0); | |||
8204 | mode = NSS_CAMELLIA0; | |||
8205 | data = stringPtr->pData; | |||
8206 | len = stringPtr->ulLen; | |||
8207 | iv = NULL((void*)0); | |||
8208 | } else { | |||
8209 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) { | |||
8210 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8211 | break; | |||
8212 | } | |||
8213 | stringPtr = NULL((void*)0); | |||
8214 | aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) | |||
8215 | pMechanism->pParameter; | |||
8216 | mode = NSS_CAMELLIA_CBC1; | |||
8217 | iv = aesEncryptPtr->iv; | |||
8218 | data = aesEncryptPtr->pData; | |||
8219 | len = aesEncryptPtr->length; | |||
8220 | } | |||
8221 | ||||
8222 | cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue, | |||
8223 | iv, mode, PR_TRUE1, | |||
8224 | att->attrib.ulValueLen); | |||
8225 | if (cipherInfo == NULL((void*)0)) { | |||
8226 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8227 | break; | |||
8228 | } | |||
8229 | crv = sftk_DeriveEncrypt((SFTKCipher)Camellia_Encrypt, | |||
8230 | cipherInfo, 16, key, keySize, | |||
8231 | data, len); | |||
8232 | Camellia_DestroyContext(cipherInfo, PR_TRUE1); | |||
8233 | break; | |||
8234 | } | |||
8235 | ||||
8236 | #ifndef NSS_DISABLE_DEPRECATED_SEED | |||
8237 | case CKM_SEED_ECB_ENCRYPT_DATA0x00000656UL: | |||
8238 | case CKM_SEED_CBC_ENCRYPT_DATA0x00000657UL: { | |||
8239 | void *cipherInfo; | |||
8240 | CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; | |||
8241 | int mode; | |||
8242 | unsigned char *iv; | |||
8243 | unsigned char *data; | |||
8244 | CK_ULONG len; | |||
8245 | ||||
8246 | if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA0x00000656UL) { | |||
8247 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_KEY_DERIVATION_STRING_DATA))) { | |||
8248 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8249 | break; | |||
8250 | } | |||
8251 | mode = NSS_SEED0; | |||
8252 | stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) | |||
8253 | pMechanism->pParameter; | |||
8254 | aesEncryptPtr = NULL((void*)0); | |||
8255 | data = stringPtr->pData; | |||
8256 | len = stringPtr->ulLen; | |||
8257 | iv = NULL((void*)0); | |||
8258 | } else { | |||
8259 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) { | |||
8260 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8261 | break; | |||
8262 | } | |||
8263 | mode = NSS_SEED_CBC1; | |||
8264 | aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) | |||
8265 | pMechanism->pParameter; | |||
8266 | iv = aesEncryptPtr->iv; | |||
8267 | data = aesEncryptPtr->pData; | |||
8268 | len = aesEncryptPtr->length; | |||
8269 | } | |||
8270 | ||||
8271 | cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue, | |||
8272 | iv, mode, PR_TRUE1); | |||
8273 | if (cipherInfo == NULL((void*)0)) { | |||
8274 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8275 | break; | |||
8276 | } | |||
8277 | crv = sftk_DeriveEncrypt((SFTKCipher)SEED_Encrypt, | |||
8278 | cipherInfo, 16, key, keySize, | |||
8279 | data, len); | |||
8280 | SEED_DestroyContext(cipherInfo, PR_TRUE1); | |||
8281 | break; | |||
8282 | } | |||
8283 | #endif /* NSS_DISABLE_DEPRECATED_SEED */ | |||
8284 | ||||
8285 | case CKM_CONCATENATE_BASE_AND_KEY0x00000360UL: { | |||
8286 | SFTKObject *paramKey; | |||
8287 | ||||
8288 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
8289 | if (crv != CKR_OK0x00000000UL) | |||
8290 | break; | |||
8291 | ||||
8292 | session = sftk_SessionFromHandle(hSession); | |||
8293 | if (session == NULL((void*)0)) { | |||
8294 | crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
8295 | break; | |||
8296 | } | |||
8297 | ||||
8298 | paramKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *) | |||
8299 | pMechanism->pParameter, | |||
8300 | session); | |||
8301 | sftk_FreeSession(session); | |||
8302 | if (paramKey == NULL((void*)0)) { | |||
8303 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
8304 | break; | |||
8305 | } | |||
8306 | ||||
8307 | if (sftk_isTrue(paramKey, CKA_SENSITIVE0x00000103UL)) { | |||
8308 | crv = sftk_forceAttribute(key, CKA_SENSITIVE0x00000103UL, &cktrue, | |||
8309 | sizeof(CK_BBOOL)); | |||
8310 | if (crv != CKR_OK0x00000000UL) { | |||
8311 | sftk_FreeObject(paramKey); | |||
8312 | break; | |||
8313 | } | |||
8314 | } | |||
8315 | ||||
8316 | if (sftk_hasAttribute(paramKey, CKA_EXTRACTABLE0x00000162UL) && !sftk_isTrue(paramKey, CKA_EXTRACTABLE0x00000162UL)) { | |||
8317 | crv = sftk_forceAttribute(key, CKA_EXTRACTABLE0x00000162UL, &ckfalse, sizeof(CK_BBOOL)); | |||
8318 | if (crv != CKR_OK0x00000000UL) { | |||
8319 | sftk_FreeObject(paramKey); | |||
8320 | break; | |||
8321 | } | |||
8322 | } | |||
8323 | ||||
8324 | att2 = sftk_FindAttribute(paramKey, CKA_VALUE0x00000011UL); | |||
8325 | if (att2 == NULL((void*)0)) { | |||
8326 | sftk_FreeObject(paramKey); | |||
8327 | crv = CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
8328 | break; | |||
8329 | } | |||
8330 | tmpKeySize = att->attrib.ulValueLen + att2->attrib.ulValueLen; | |||
8331 | if (keySize == 0) | |||
8332 | keySize = tmpKeySize; | |||
8333 | if (keySize > tmpKeySize) { | |||
8334 | sftk_FreeObject(paramKey); | |||
8335 | sftk_FreeAttribute(att2); | |||
8336 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
8337 | break; | |||
8338 | } | |||
8339 | buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize); | |||
8340 | if (buf == NULL((void*)0)) { | |||
8341 | sftk_FreeAttribute(att2); | |||
8342 | sftk_FreeObject(paramKey); | |||
8343 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8344 | break; | |||
8345 | } | |||
8346 | ||||
8347 | PORT_Memcpymemcpy(buf, att->attrib.pValue, att->attrib.ulValueLen); | |||
8348 | PORT_Memcpymemcpy(buf + att->attrib.ulValueLen, | |||
8349 | att2->attrib.pValue, att2->attrib.ulValueLen); | |||
8350 | ||||
8351 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize); | |||
8352 | PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize); | |||
8353 | sftk_FreeAttribute(att2); | |||
8354 | sftk_FreeObject(paramKey); | |||
8355 | break; | |||
8356 | } | |||
8357 | ||||
8358 | case CKM_CONCATENATE_BASE_AND_DATA0x00000362UL: | |||
8359 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
8360 | if (crv != CKR_OK0x00000000UL) | |||
8361 | break; | |||
8362 | ||||
8363 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_KEY_DERIVATION_STRING_DATA))) { | |||
8364 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8365 | break; | |||
8366 | } | |||
8367 | stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; | |||
8368 | tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen; | |||
8369 | if (keySize == 0) | |||
8370 | keySize = tmpKeySize; | |||
8371 | if (keySize > tmpKeySize) { | |||
8372 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
8373 | break; | |||
8374 | } | |||
8375 | buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize); | |||
8376 | if (buf == NULL((void*)0)) { | |||
8377 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8378 | break; | |||
8379 | } | |||
8380 | ||||
8381 | PORT_Memcpymemcpy(buf, att->attrib.pValue, att->attrib.ulValueLen); | |||
8382 | PORT_Memcpymemcpy(buf + att->attrib.ulValueLen, stringPtr->pData, | |||
8383 | stringPtr->ulLen); | |||
8384 | ||||
8385 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize); | |||
8386 | PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize); | |||
8387 | break; | |||
8388 | case CKM_CONCATENATE_DATA_AND_BASE0x00000363UL: | |||
8389 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
8390 | if (crv != CKR_OK0x00000000UL) | |||
8391 | break; | |||
8392 | ||||
8393 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_KEY_DERIVATION_STRING_DATA))) { | |||
8394 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8395 | break; | |||
8396 | } | |||
8397 | stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; | |||
8398 | tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen; | |||
8399 | if (keySize == 0) | |||
8400 | keySize = tmpKeySize; | |||
8401 | if (keySize > tmpKeySize) { | |||
8402 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
8403 | break; | |||
8404 | } | |||
8405 | buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize); | |||
8406 | if (buf == NULL((void*)0)) { | |||
8407 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8408 | break; | |||
8409 | } | |||
8410 | ||||
8411 | PORT_Memcpymemcpy(buf, stringPtr->pData, stringPtr->ulLen); | |||
8412 | PORT_Memcpymemcpy(buf + stringPtr->ulLen, att->attrib.pValue, | |||
8413 | att->attrib.ulValueLen); | |||
8414 | ||||
8415 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize); | |||
8416 | PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize); | |||
8417 | break; | |||
8418 | case CKM_XOR_BASE_AND_DATA0x00000364UL: | |||
8419 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
8420 | if (crv != CKR_OK0x00000000UL) | |||
8421 | break; | |||
8422 | ||||
8423 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_KEY_DERIVATION_STRING_DATA))) { | |||
8424 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8425 | break; | |||
8426 | } | |||
8427 | stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; | |||
8428 | tmpKeySize = PR_MIN(att->attrib.ulValueLen, stringPtr->ulLen)((att->attrib.ulValueLen)<(stringPtr->ulLen)?(att-> attrib.ulValueLen):(stringPtr->ulLen)); | |||
8429 | if (keySize == 0) | |||
8430 | keySize = tmpKeySize; | |||
8431 | if (keySize > tmpKeySize) { | |||
8432 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
8433 | break; | |||
8434 | } | |||
8435 | buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(keySize); | |||
8436 | if (buf == NULL((void*)0)) { | |||
8437 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8438 | break; | |||
8439 | } | |||
8440 | ||||
8441 | PORT_Memcpymemcpy(buf, att->attrib.pValue, keySize); | |||
8442 | for (i = 0; i < (int)keySize; i++) { | |||
8443 | buf[i] ^= stringPtr->pData[i]; | |||
8444 | } | |||
8445 | ||||
8446 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize); | |||
8447 | PORT_ZFreePORT_ZFree_Util(buf, keySize); | |||
8448 | break; | |||
8449 | ||||
8450 | case CKM_EXTRACT_KEY_FROM_KEY0x00000365UL: { | |||
8451 | if (BAD_PARAM_CAST(pMechanism, sizeof(CK_EXTRACT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen < sizeof(CK_EXTRACT_PARAMS))) { | |||
8452 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8453 | break; | |||
8454 | } | |||
8455 | /* the following assumes 8 bits per byte */ | |||
8456 | CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter; | |||
8457 | CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */ | |||
8458 | CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */ | |||
8459 | ||||
8460 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
8461 | if (crv != CKR_OK0x00000000UL) | |||
8462 | break; | |||
8463 | ||||
8464 | if (keySize == 0) { | |||
8465 | crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL; | |||
8466 | break; | |||
8467 | } | |||
8468 | /* make sure we have enough bits in the original key */ | |||
8469 | if (att->attrib.ulValueLen < | |||
8470 | (offset + keySize + ((shift != 0) ? 1 : 0))) { | |||
8471 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8472 | break; | |||
8473 | } | |||
8474 | buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(keySize); | |||
8475 | if (buf == NULL((void*)0)) { | |||
8476 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8477 | break; | |||
8478 | } | |||
8479 | ||||
8480 | /* copy the bits we need into the new key */ | |||
8481 | for (i = 0; i < (int)keySize; i++) { | |||
8482 | unsigned char *value = | |||
8483 | ((unsigned char *)att->attrib.pValue) + offset + i; | |||
8484 | if (shift) { | |||
8485 | buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift)); | |||
8486 | } else { | |||
8487 | buf[i] = value[0]; | |||
8488 | } | |||
8489 | } | |||
8490 | ||||
8491 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize); | |||
8492 | PORT_ZFreePORT_ZFree_Util(buf, keySize); | |||
8493 | break; | |||
8494 | } | |||
8495 | case CKM_MD2_KEY_DERIVATION0x00000391UL: | |||
8496 | if (keySize == 0) | |||
8497 | keySize = MD2_LENGTH16; | |||
8498 | if (keySize > MD2_LENGTH16) { | |||
8499 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
8500 | break; | |||
8501 | } | |||
8502 | /* now allocate the hash contexts */ | |||
8503 | md2 = MD2_NewContext(); | |||
8504 | if (md2 == NULL((void*)0)) { | |||
8505 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8506 | break; | |||
8507 | } | |||
8508 | MD2_Begin(md2); | |||
8509 | MD2_Update(md2, (const unsigned char *)att->attrib.pValue, | |||
8510 | att->attrib.ulValueLen); | |||
8511 | MD2_End(md2, key_block, &outLen, MD2_LENGTH16); | |||
8512 | MD2_DestroyContext(md2, PR_TRUE1); | |||
8513 | ||||
8514 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, keySize); | |||
8515 | PORT_Memsetmemset(key_block, 0, MD2_LENGTH16); | |||
8516 | break; | |||
8517 | #define DERIVE_KEY_HASH(hash)case CKM_hash_KEY_DERIVATION: if (keySize == 0) keySize = hash_LENGTH ; if (keySize > hash_LENGTH) { crv = 0x000000D1UL; break; } hash_HashBuf(key_block, (const unsigned char *)att->attrib .pValue, att->attrib.ulValueLen); crv = sftk_forceAttribute (key, 0x00000011UL, key_block, keySize); memset(key_block, 0, hash_LENGTH); break; \ | |||
8518 | case CKM_##hash##_KEY_DERIVATION: \ | |||
8519 | if (keySize == 0) \ | |||
8520 | keySize = hash##_LENGTH; \ | |||
8521 | if (keySize > hash##_LENGTH) { \ | |||
8522 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; \ | |||
8523 | break; \ | |||
8524 | } \ | |||
8525 | hash##_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, \ | |||
8526 | att->attrib.ulValueLen); \ | |||
8527 | crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, keySize); \ | |||
8528 | PORT_Memsetmemset(key_block, 0, hash##_LENGTH); \ | |||
8529 | break; | |||
8530 | DERIVE_KEY_HASH(MD5)case 0x00000390UL: if (keySize == 0) keySize = 16; if (keySize > 16) { crv = 0x000000D1UL; break; } MD5_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 16); break; | |||
8531 | DERIVE_KEY_HASH(SHA1)case 0x00000392UL: if (keySize == 0) keySize = 20; if (keySize > 20) { crv = 0x000000D1UL; break; } SHA1_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 20); break; | |||
8532 | DERIVE_KEY_HASH(SHA224)case 0x00000396UL: if (keySize == 0) keySize = 28; if (keySize > 28) { crv = 0x000000D1UL; break; } SHA224_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 28); break; | |||
8533 | DERIVE_KEY_HASH(SHA256)case 0x00000393UL: if (keySize == 0) keySize = 32; if (keySize > 32) { crv = 0x000000D1UL; break; } SHA256_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 32); break; | |||
8534 | DERIVE_KEY_HASH(SHA384)case 0x00000394UL: if (keySize == 0) keySize = 48; if (keySize > 48) { crv = 0x000000D1UL; break; } SHA384_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 48); break; | |||
8535 | DERIVE_KEY_HASH(SHA512)case 0x00000395UL: if (keySize == 0) keySize = 64; if (keySize > 64) { crv = 0x000000D1UL; break; } SHA512_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 64); break; | |||
8536 | DERIVE_KEY_HASH(SHA3_224)case 0x00000398UL: if (keySize == 0) keySize = 28; if (keySize > 28) { crv = 0x000000D1UL; break; } SHA3_224_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 28); break; | |||
8537 | DERIVE_KEY_HASH(SHA3_256)case 0x00000397UL: if (keySize == 0) keySize = 32; if (keySize > 32) { crv = 0x000000D1UL; break; } SHA3_256_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 32); break; | |||
8538 | DERIVE_KEY_HASH(SHA3_384)case 0x00000399UL: if (keySize == 0) keySize = 48; if (keySize > 48) { crv = 0x000000D1UL; break; } SHA3_384_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 48); break; | |||
8539 | DERIVE_KEY_HASH(SHA3_512)case 0x0000039AUL: if (keySize == 0) keySize = 64; if (keySize > 64) { crv = 0x000000D1UL; break; } SHA3_512_HashBuf(key_block , (const unsigned char *)att->attrib.pValue, att->attrib .ulValueLen); crv = sftk_forceAttribute(key, 0x00000011UL, key_block , keySize); memset(key_block, 0, 64); break; | |||
8540 | ||||
8541 | case CKM_DH_PKCS_DERIVE0x00000021UL: { | |||
8542 | SECItem derived, dhPublic; | |||
8543 | SECItem dhPrime, dhValue; | |||
8544 | const SECItem *subPrime; | |||
8545 | /* sourceKey - values for the local existing low key */ | |||
8546 | /* get prime and value attributes */ | |||
8547 | crv = sftk_Attribute2SecItem(NULL((void*)0), &dhPrime, sourceKey, CKA_PRIME0x00000130UL); | |||
8548 | if (crv != CKR_OK0x00000000UL) | |||
8549 | break; | |||
8550 | ||||
8551 | dhPublic.data = pMechanism->pParameter; | |||
8552 | dhPublic.len = pMechanism->ulParameterLen; | |||
8553 | ||||
8554 | /* if the prime is an approved prime, we can skip all the other | |||
8555 | * checks. */ | |||
8556 | subPrime = sftk_VerifyDH_Prime(&dhPrime, isFIPS); | |||
8557 | if (subPrime == NULL((void*)0)) { | |||
8558 | SECItem dhSubPrime; | |||
8559 | /* If the caller set the subprime value, it means that | |||
8560 | * either the caller knows the subprime value and wants us | |||
8561 | * to validate the key against the subprime, or that the | |||
8562 | * caller wants us to verify that the prime is a safe prime | |||
8563 | * by passing in subprime = (prime-1)/2 */ | |||
8564 | dhSubPrime.data = NULL((void*)0); | |||
8565 | dhSubPrime.len = 0; | |||
8566 | crv = sftk_Attribute2SecItem(NULL((void*)0), &dhSubPrime, | |||
8567 | sourceKey, CKA_SUBPRIME0x00000131UL); | |||
8568 | /* we ignore the value of crv here, We treat a valid | |||
8569 | * return of len = 0 and a failure to find a subrime the same | |||
8570 | * NOTE: we free the subprime in both cases depending on | |||
8571 | * PORT_Free of NULL to be a noop */ | |||
8572 | if (dhSubPrime.len != 0) { | |||
8573 | PRBool isSafe = PR_FALSE0; | |||
8574 | ||||
8575 | /* Callers can set dhSubPrime to q=(p-1)/2 to force | |||
8576 | * checks for safe primes. If so we only need to check | |||
8577 | * q and p for primality and skip the group test. */ | |||
8578 | rv = sftk_IsSafePrime(&dhPrime, &dhSubPrime, &isSafe); | |||
8579 | if (rv != SECSuccess) { | |||
8580 | /* either p or q was even and therefore not prime, | |||
8581 | * we can stop processing here and fail now */ | |||
8582 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
8583 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0); | |||
8584 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0); | |||
8585 | break; | |||
8586 | } | |||
8587 | ||||
8588 | /* first make sure the primes are really prime */ | |||
8589 | if (!KEA_PrimeCheck(&dhPrime)) { | |||
8590 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
8591 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0); | |||
8592 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0); | |||
8593 | break; | |||
8594 | } | |||
8595 | if (!KEA_PrimeCheck(&dhSubPrime)) { | |||
8596 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
8597 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0); | |||
8598 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0); | |||
8599 | break; | |||
8600 | } | |||
8601 | if (isFIPS || !isSafe) { | |||
8602 | /* With safe primes, there is only one other small | |||
8603 | * subgroup. As long as y isn't 0, 1, or -1 mod p, | |||
8604 | * any other y is safe. Only do the full check for | |||
8605 | * non-safe primes, except in FIPS mode we need | |||
8606 | * to do this check on all primes in which | |||
8607 | * we receive the subprime value */ | |||
8608 | if (!KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime)) { | |||
8609 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
8610 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0); | |||
8611 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0); | |||
8612 | break; | |||
8613 | } | |||
8614 | } | |||
8615 | } else if (isFIPS) { | |||
8616 | /* In FIPS mode we only accept approved primes, or | |||
8617 | * primes with the full subprime value */ | |||
8618 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
8619 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0); | |||
8620 | break; | |||
8621 | } | |||
8622 | /* checks are complete, no need for the subPrime any longer */ | |||
8623 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0); | |||
8624 | } | |||
8625 | ||||
8626 | /* now that the prime is validated, get the private value */ | |||
8627 | crv = sftk_Attribute2SecItem(NULL((void*)0), &dhValue, sourceKey, CKA_VALUE0x00000011UL); | |||
8628 | if (crv != CKR_OK0x00000000UL) { | |||
8629 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0); | |||
8630 | break; | |||
8631 | } | |||
8632 | ||||
8633 | /* calculate private value - oct */ | |||
8634 | rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize); | |||
8635 | ||||
8636 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0); | |||
8637 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhValue, PR_FALSE0); | |||
8638 | ||||
8639 | if (rv == SECSuccess) { | |||
8640 | sftk_forceAttribute(key, CKA_VALUE0x00000011UL, derived.data, derived.len); | |||
8641 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&derived, PR_FALSE0); | |||
8642 | crv = CKR_OK0x00000000UL; | |||
8643 | } else | |||
8644 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8645 | ||||
8646 | break; | |||
8647 | } | |||
8648 | ||||
8649 | case CKM_ECDH1_DERIVE0x00001050UL: | |||
8650 | case CKM_ECDH1_COFACTOR_DERIVE0x00001051UL: { | |||
8651 | SECItem ecScalar, ecPoint; | |||
8652 | SECItem tmp; | |||
8653 | PRBool withCofactor = PR_FALSE0; | |||
8654 | unsigned char *secret; | |||
8655 | unsigned char *keyData = NULL((void*)0); | |||
8656 | unsigned int secretlen, pubKeyLen; | |||
8657 | CK_ECDH1_DERIVE_PARAMS *mechParams; | |||
8658 | NSSLOWKEYPrivateKey *privKey; | |||
8659 | PLArenaPool *arena = NULL((void*)0); | |||
8660 | ||||
8661 | /* Check mechanism parameters */ | |||
8662 | mechParams = (CK_ECDH1_DERIVE_PARAMS *)pMechanism->pParameter; | |||
8663 | if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) || | |||
8664 | ((mechParams->kdf == CKD_NULL0x00000001UL) && | |||
8665 | ((mechParams->ulSharedDataLen != 0) || | |||
8666 | (mechParams->pSharedData != NULL((void*)0))))) { | |||
8667 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8668 | break; | |||
8669 | } | |||
8670 | ||||
8671 | privKey = sftk_GetPrivKey(sourceKey, CKK_EC0x00000003UL, &crv); | |||
8672 | if (privKey == NULL((void*)0)) { | |||
8673 | break; | |||
8674 | } | |||
8675 | ||||
8676 | /* Now we are working with a non-NULL private key */ | |||
8677 | SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &ecScalar, &privKey->u.ec.privateValue); | |||
8678 | ||||
8679 | ecPoint.data = mechParams->pPublicData; | |||
8680 | ecPoint.len = mechParams->ulPublicDataLen; | |||
8681 | ||||
8682 | pubKeyLen = EC_GetPointSize(&privKey->u.ec.ecParams); | |||
8683 | ||||
8684 | /* if the len is too large, might be an encoded point */ | |||
8685 | if (ecPoint.len > pubKeyLen) { | |||
8686 | SECItem newPoint; | |||
8687 | ||||
8688 | arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048)); | |||
8689 | if (arena == NULL((void*)0)) { | |||
8690 | goto ec_loser; | |||
8691 | } | |||
8692 | ||||
8693 | rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, &newPoint, | |||
8694 | SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util, | |||
8695 | &ecPoint); | |||
8696 | if (rv != SECSuccess) { | |||
8697 | goto ec_loser; | |||
8698 | } | |||
8699 | ecPoint = newPoint; | |||
8700 | } | |||
8701 | ||||
8702 | if (mechanism == CKM_ECDH1_COFACTOR_DERIVE0x00001051UL) { | |||
8703 | withCofactor = PR_TRUE1; | |||
8704 | } | |||
8705 | ||||
8706 | rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar, | |||
8707 | withCofactor, &tmp); | |||
8708 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecScalar, PR_FALSE0); | |||
8709 | ecScalar.data = NULL((void*)0); | |||
8710 | if (privKey != sourceKey->objectInfo) { | |||
8711 | nsslowkey_DestroyPrivateKey(privKey); | |||
8712 | privKey = NULL((void*)0); | |||
8713 | } | |||
8714 | if (arena) { | |||
8715 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0); | |||
8716 | arena = NULL((void*)0); | |||
8717 | } | |||
8718 | ||||
8719 | if (rv != SECSuccess) { | |||
8720 | crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util()); | |||
8721 | break; | |||
8722 | } | |||
8723 | ||||
8724 | /* | |||
8725 | * apply the kdf function. | |||
8726 | */ | |||
8727 | if (mechParams->kdf == CKD_NULL0x00000001UL) { | |||
8728 | /* | |||
8729 | * tmp is the raw data created by ECDH_Derive, | |||
8730 | * secret and secretlen are the values we will | |||
8731 | * eventually pass as our generated key. | |||
8732 | */ | |||
8733 | secret = tmp.data; | |||
8734 | secretlen = tmp.len; | |||
8735 | } else { | |||
8736 | secretlen = keySize; | |||
8737 | crv = sftk_ANSI_X9_63_kdf(&secret, keySize, | |||
8738 | &tmp, mechParams->pSharedData, | |||
8739 | mechParams->ulSharedDataLen, mechParams->kdf); | |||
8740 | PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len); | |||
8741 | if (crv != CKR_OK0x00000000UL) { | |||
8742 | break; | |||
8743 | } | |||
8744 | tmp.data = secret; | |||
8745 | tmp.len = secretlen; | |||
8746 | } | |||
8747 | ||||
8748 | /* | |||
8749 | * if keySize is supplied, then we are generating a key of a specific | |||
8750 | * length. This is done by taking the least significant 'keySize' | |||
8751 | * bytes from the unsigned value calculated by ECDH. Note: this may | |||
8752 | * mean padding temp with extra leading zeros from what ECDH_Derive | |||
8753 | * already returned (which itself may contain leading zeros). | |||
8754 | */ | |||
8755 | if (keySize) { | |||
8756 | if (secretlen < keySize) { | |||
8757 | keyData = PORT_ZAllocPORT_ZAlloc_Util(keySize); | |||
8758 | if (!keyData) { | |||
8759 | PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len); | |||
8760 | crv = CKR_HOST_MEMORY0x00000002UL; | |||
8761 | break; | |||
8762 | } | |||
8763 | PORT_Memcpymemcpy(&keyData[keySize - secretlen], secret, secretlen); | |||
8764 | secret = keyData; | |||
8765 | } else { | |||
8766 | secret += (secretlen - keySize); | |||
8767 | } | |||
8768 | secretlen = keySize; | |||
8769 | } | |||
8770 | ||||
8771 | sftk_forceAttribute(key, CKA_VALUE0x00000011UL, secret, secretlen); | |||
8772 | PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len); | |||
8773 | if (keyData) { | |||
8774 | PORT_ZFreePORT_ZFree_Util(keyData, keySize); | |||
8775 | } | |||
8776 | break; | |||
8777 | ||||
8778 | ec_loser: | |||
8779 | crv = CKR_ARGUMENTS_BAD0x00000007UL; | |||
8780 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecScalar, PR_FALSE0); | |||
8781 | if (privKey != sourceKey->objectInfo) | |||
8782 | nsslowkey_DestroyPrivateKey(privKey); | |||
8783 | if (arena) { | |||
8784 | PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1); | |||
8785 | } | |||
8786 | break; | |||
8787 | } | |||
8788 | /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */ | |||
8789 | case CKM_NSS_HKDF_SHA1((0x80000000UL | 0x4E534350) + 3): | |||
8790 | hashMech = CKM_SHA_10x00000220UL; | |||
8791 | goto hkdf; | |||
8792 | case CKM_NSS_HKDF_SHA256((0x80000000UL | 0x4E534350) + 4): | |||
8793 | hashMech = CKM_SHA2560x00000250UL; | |||
8794 | goto hkdf; | |||
8795 | case CKM_NSS_HKDF_SHA384((0x80000000UL | 0x4E534350) + 5): | |||
8796 | hashMech = CKM_SHA3840x00000260UL; | |||
8797 | goto hkdf; | |||
8798 | case CKM_NSS_HKDF_SHA512((0x80000000UL | 0x4E534350) + 6): | |||
8799 | hashMech = CKM_SHA5120x00000270UL; | |||
8800 | goto hkdf; | |||
8801 | hkdf : { | |||
8802 | const CK_NSS_HKDFParams *params = | |||
8803 | (const CK_NSS_HKDFParams *)pMechanism->pParameter; | |||
8804 | CK_HKDF_PARAMS hkdfParams; | |||
8805 | ||||
8806 | if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams)) { | |||
8807 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8808 | break; | |||
8809 | } | |||
8810 | hkdfParams.bExtract = params->bExtract; | |||
8811 | hkdfParams.bExpand = params->bExpand; | |||
8812 | if (params->pSalt) { | |||
8813 | hkdfParams.ulSaltType = CKF_HKDF_SALT_DATA0x00000002UL; | |||
8814 | } else { | |||
8815 | hkdfParams.ulSaltType = CKF_HKDF_SALT_NULL0x00000001UL; | |||
8816 | } | |||
8817 | hkdfParams.pSalt = params->pSalt; | |||
8818 | hkdfParams.ulSaltLen = params->ulSaltLen; | |||
8819 | hkdfParams.hSaltKey = CK_INVALID_HANDLE0; | |||
8820 | hkdfParams.pInfo = params->pInfo; | |||
8821 | hkdfParams.ulInfoLen = params->ulInfoLen; | |||
8822 | hkdfParams.prfHashMechanism = hashMech; | |||
8823 | ||||
8824 | crv = sftk_HKDF(&hkdfParams, hSession, sourceKey, | |||
8825 | att->attrib.pValue, att->attrib.ulValueLen, | |||
8826 | key, NULL((void*)0), keySize, PR_FALSE0, isFIPS); | |||
8827 | } break; | |||
8828 | case CKM_HKDF_DERIVE0x0000402aUL: | |||
8829 | case CKM_HKDF_DATA0x0000402bUL: /* only difference is the class of key */ | |||
8830 | if ((pMechanism->pParameter == NULL((void*)0)) || | |||
8831 | (pMechanism->ulParameterLen != sizeof(CK_HKDF_PARAMS))) { | |||
8832 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8833 | break; | |||
8834 | } | |||
8835 | crv = sftk_HKDF((CK_HKDF_PARAMS_PTR)pMechanism->pParameter, | |||
8836 | hSession, sourceKey, att->attrib.pValue, | |||
8837 | att->attrib.ulValueLen, key, NULL((void*)0), keySize, PR_TRUE1, | |||
8838 | isFIPS); | |||
8839 | break; | |||
8840 | case CKM_NSS_JPAKE_ROUND2_SHA1((0x80000000UL | 0x4E534350) + 11): | |||
8841 | hashType = HASH_AlgSHA1; | |||
8842 | goto jpake2; | |||
8843 | case CKM_NSS_JPAKE_ROUND2_SHA256((0x80000000UL | 0x4E534350) + 12): | |||
8844 | hashType = HASH_AlgSHA256; | |||
8845 | goto jpake2; | |||
8846 | case CKM_NSS_JPAKE_ROUND2_SHA384((0x80000000UL | 0x4E534350) + 13): | |||
8847 | hashType = HASH_AlgSHA384; | |||
8848 | goto jpake2; | |||
8849 | case CKM_NSS_JPAKE_ROUND2_SHA512((0x80000000UL | 0x4E534350) + 14): | |||
8850 | hashType = HASH_AlgSHA512; | |||
8851 | goto jpake2; | |||
8852 | jpake2: | |||
8853 | if (pMechanism->pParameter == NULL((void*)0) || | |||
8854 | pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params)) | |||
8855 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8856 | if (crv == CKR_OK0x00000000UL && sftk_isTrue(key, CKA_TOKEN0x00000001UL)) | |||
8857 | crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; | |||
8858 | if (crv == CKR_OK0x00000000UL) | |||
8859 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
8860 | if (crv == CKR_OK0x00000000UL) | |||
8861 | crv = jpake_Round2(hashType, | |||
8862 | (CK_NSS_JPAKERound2Params *)pMechanism->pParameter, | |||
8863 | sourceKey, key); | |||
8864 | break; | |||
8865 | ||||
8866 | case CKM_NSS_JPAKE_FINAL_SHA1((0x80000000UL | 0x4E534350) + 15): | |||
8867 | hashType = HASH_AlgSHA1; | |||
8868 | goto jpakeFinal; | |||
8869 | case CKM_NSS_JPAKE_FINAL_SHA256((0x80000000UL | 0x4E534350) + 16): | |||
8870 | hashType = HASH_AlgSHA256; | |||
8871 | goto jpakeFinal; | |||
8872 | case CKM_NSS_JPAKE_FINAL_SHA384((0x80000000UL | 0x4E534350) + 17): | |||
8873 | hashType = HASH_AlgSHA384; | |||
8874 | goto jpakeFinal; | |||
8875 | case CKM_NSS_JPAKE_FINAL_SHA512((0x80000000UL | 0x4E534350) + 18): | |||
8876 | hashType = HASH_AlgSHA512; | |||
8877 | goto jpakeFinal; | |||
8878 | jpakeFinal: | |||
8879 | if (pMechanism->pParameter == NULL((void*)0) || | |||
8880 | pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams)) | |||
8881 | crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; | |||
8882 | /* We purposely do not do the derive sensitivity check; we want to be | |||
8883 | able to derive non-sensitive keys while allowing the ROUND1 and | |||
8884 | ROUND2 keys to be sensitive (which they always are, since they are | |||
8885 | in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE | |||
8886 | in the template in order for the resultant keyblock key to be | |||
8887 | sensitive. | |||
8888 | */ | |||
8889 | if (crv == CKR_OK0x00000000UL) | |||
8890 | crv = jpake_Final(hashType, | |||
8891 | (CK_NSS_JPAKEFinalParams *)pMechanism->pParameter, | |||
8892 | sourceKey, key); | |||
8893 | break; | |||
8894 | ||||
8895 | case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 42): /* fall through */ | |||
8896 | case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 43): /* fall through */ | |||
8897 | case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 44): /* fall through */ | |||
8898 | case CKM_SP800_108_COUNTER_KDF0x000003acUL: /* fall through */ | |||
8899 | case CKM_SP800_108_FEEDBACK_KDF0x000003adUL: /* fall through */ | |||
8900 | case CKM_SP800_108_DOUBLE_PIPELINE_KDF0x000003aeUL: | |||
8901 | crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0); | |||
8902 | if (crv != CKR_OK0x00000000UL) { | |||
8903 | break; | |||
8904 | } | |||
8905 | ||||
8906 | crv = kbkdf_Dispatch(mechanism, hSession, pMechanism, sourceKey, key, keySize); | |||
8907 | break; | |||
8908 | default: | |||
8909 | crv = CKR_MECHANISM_INVALID0x00000070UL; | |||
8910 | } | |||
8911 | if (att) { | |||
8912 | sftk_FreeAttribute(att); | |||
8913 | } | |||
8914 | sftk_FreeObject(sourceKey); | |||
8915 | if (crv != CKR_OK0x00000000UL) { | |||
8916 | if (key) | |||
8917 | sftk_FreeObject(key); | |||
8918 | return crv; | |||
8919 | } | |||
8920 | ||||
8921 | /* link the key object into the list */ | |||
8922 | if (key) { | |||
8923 | SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); | |||
8924 | PORT_Assert(sessKey)((sessKey)?((void)0):PR_Assert("sessKey","pkcs11c.c",8924)); | |||
8925 | /* get the session */ | |||
8926 | sessKey->wasDerived = PR_TRUE1; | |||
8927 | session = sftk_SessionFromHandle(hSession); | |||
8928 | if (session == NULL((void*)0)) { | |||
8929 | sftk_FreeObject(key); | |||
8930 | return CKR_HOST_MEMORY0x00000002UL; | |||
8931 | } | |||
8932 | ||||
8933 | crv = sftk_handleObject(key, session); | |||
8934 | session->lastOpWasFIPS = key->isFIPS; | |||
8935 | sftk_FreeSession(session); | |||
8936 | *phKey = key->handle; | |||
8937 | sftk_FreeObject(key); | |||
8938 | } | |||
8939 | return crv; | |||
8940 | } | |||
8941 | ||||
8942 | /* NSC_GetFunctionStatus obtains an updated status of a function running | |||
8943 | * in parallel with an application. */ | |||
8944 | CK_RV | |||
8945 | NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession) | |||
8946 | { | |||
8947 | CHECK_FORK(); | |||
8948 | ||||
8949 | return CKR_FUNCTION_NOT_PARALLEL0x00000051UL; | |||
8950 | } | |||
8951 | ||||
8952 | /* NSC_CancelFunction cancels a function running in parallel */ | |||
8953 | CK_RV | |||
8954 | NSC_CancelFunction(CK_SESSION_HANDLE hSession) | |||
8955 | { | |||
8956 | CHECK_FORK(); | |||
8957 | ||||
8958 | return CKR_FUNCTION_NOT_PARALLEL0x00000051UL; | |||
8959 | } | |||
8960 | ||||
8961 | /* NSC_GetOperationState saves the state of the cryptographic | |||
8962 | * operation in a session. | |||
8963 | * NOTE: This code only works for digest functions for now. eventually need | |||
8964 | * to add full flatten/resurect to our state stuff so that all types of state | |||
8965 | * can be saved */ | |||
8966 | CK_RV | |||
8967 | NSC_GetOperationState(CK_SESSION_HANDLE hSession, | |||
8968 | CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) | |||
8969 | { | |||
8970 | SFTKSessionContext *context; | |||
8971 | SFTKSession *session; | |||
8972 | CK_RV crv; | |||
8973 | CK_ULONG pOSLen = *pulOperationStateLen; | |||
8974 | ||||
8975 | CHECK_FORK(); | |||
8976 | ||||
8977 | /* make sure we're legal */ | |||
8978 | crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, &session); | |||
8979 | if (crv != CKR_OK0x00000000UL) | |||
8980 | return crv; | |||
8981 | ||||
8982 | /* a zero cipherInfoLen signals that this context cannot be serialized */ | |||
8983 | if (context->cipherInfoLen == 0) { | |||
8984 | return CKR_STATE_UNSAVEABLE0x00000180UL; | |||
8985 | } | |||
8986 | ||||
8987 | *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE) + sizeof(SFTKContextType); | |||
8988 | if (pOperationState == NULL((void*)0)) { | |||
8989 | sftk_FreeSession(session); | |||
8990 | return CKR_OK0x00000000UL; | |||
8991 | } else { | |||
8992 | if (pOSLen < *pulOperationStateLen) { | |||
8993 | return CKR_BUFFER_TOO_SMALL0x00000150UL; | |||
8994 | } | |||
8995 | } | |||
8996 | PORT_Memcpymemcpy(pOperationState, &context->type, sizeof(SFTKContextType)); | |||
8997 | pOperationState += sizeof(SFTKContextType); | |||
8998 | PORT_Memcpymemcpy(pOperationState, &context->currentMech, | |||
8999 | sizeof(CK_MECHANISM_TYPE)); | |||
9000 | pOperationState += sizeof(CK_MECHANISM_TYPE); | |||
9001 | PORT_Memcpymemcpy(pOperationState, context->cipherInfo, context->cipherInfoLen); | |||
9002 | sftk_FreeSession(session); | |||
9003 | return CKR_OK0x00000000UL; | |||
9004 | } | |||
9005 | ||||
9006 | #define sftk_Decrement(stateSize, len)stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize) - (CK_ULONG)(len)) : 0; \ | |||
9007 | stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize) - (CK_ULONG)(len)) : 0; | |||
9008 | ||||
9009 | /* NSC_SetOperationState restores the state of the cryptographic | |||
9010 | * operation in a session. This is coded like it can restore lots of | |||
9011 | * states, but it only works for truly flat cipher structures. */ | |||
9012 | CK_RV | |||
9013 | NSC_SetOperationState(CK_SESSION_HANDLE hSession, | |||
9014 | CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, | |||
9015 | CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) | |||
9016 | { | |||
9017 | SFTKSessionContext *context; | |||
9018 | SFTKSession *session; | |||
9019 | SFTKContextType type; | |||
9020 | CK_MECHANISM mech; | |||
9021 | CK_RV crv = CKR_OK0x00000000UL; | |||
9022 | ||||
9023 | CHECK_FORK(); | |||
9024 | ||||
9025 | while (ulOperationStateLen != 0) { | |||
9026 | /* get what type of state we're dealing with... */ | |||
9027 | PORT_Memcpymemcpy(&type, pOperationState, sizeof(SFTKContextType)); | |||
9028 | ||||
9029 | /* fix up session contexts based on type */ | |||
9030 | session = sftk_SessionFromHandle(hSession); | |||
9031 | if (session == NULL((void*)0)) | |||
9032 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
9033 | context = sftk_ReturnContextByType(session, type); | |||
9034 | sftk_SetContextByType(session, type, NULL((void*)0)); | |||
9035 | if (context) { | |||
9036 | sftk_FreeContext(context); | |||
9037 | } | |||
9038 | pOperationState += sizeof(SFTKContextType); | |||
9039 | sftk_Decrement(ulOperationStateLen, sizeof(SFTKContextType))ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)( sizeof(SFTKContextType))) ? ((ulOperationStateLen) - (CK_ULONG )(sizeof(SFTKContextType))) : 0;; | |||
9040 | ||||
9041 | /* get the mechanism structure */ | |||
9042 | PORT_Memcpymemcpy(&mech.mechanism, pOperationState, sizeof(CK_MECHANISM_TYPE)); | |||
9043 | pOperationState += sizeof(CK_MECHANISM_TYPE); | |||
9044 | sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE))ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)( sizeof(CK_MECHANISM_TYPE))) ? ((ulOperationStateLen) - (CK_ULONG )(sizeof(CK_MECHANISM_TYPE))) : 0;; | |||
9045 | /* should be filled in... but not necessary for hash */ | |||
9046 | mech.pParameter = NULL((void*)0); | |||
9047 | mech.ulParameterLen = 0; | |||
9048 | switch (type) { | |||
9049 | case SFTK_HASH: | |||
9050 | crv = NSC_DigestInit(hSession, &mech); | |||
9051 | if (crv != CKR_OK0x00000000UL) | |||
9052 | break; | |||
9053 | crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, | |||
9054 | NULL((void*)0)); | |||
9055 | if (crv != CKR_OK0x00000000UL) | |||
9056 | break; | |||
9057 | if (context->cipherInfoLen == 0) { | |||
9058 | crv = CKR_SAVED_STATE_INVALID0x00000160UL; | |||
9059 | break; | |||
9060 | } | |||
9061 | PORT_Memcpymemcpy(context->cipherInfo, pOperationState, | |||
9062 | context->cipherInfoLen); | |||
9063 | pOperationState += context->cipherInfoLen; | |||
9064 | sftk_Decrement(ulOperationStateLen, context->cipherInfoLen)ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)( context->cipherInfoLen)) ? ((ulOperationStateLen) - (CK_ULONG )(context->cipherInfoLen)) : 0;; | |||
9065 | break; | |||
9066 | default: | |||
9067 | /* do sign/encrypt/decrypt later */ | |||
9068 | crv = CKR_SAVED_STATE_INVALID0x00000160UL; | |||
9069 | } | |||
9070 | sftk_FreeSession(session); | |||
9071 | if (crv != CKR_OK0x00000000UL) | |||
9072 | break; | |||
9073 | } | |||
9074 | return crv; | |||
9075 | } | |||
9076 | ||||
9077 | /* Dual-function cryptographic operations */ | |||
9078 | ||||
9079 | /* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption | |||
9080 | * operation. */ | |||
9081 | CK_RV | |||
9082 | NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, | |||
9083 | CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, | |||
9084 | CK_ULONG_PTR pulEncryptedPartLen) | |||
9085 | { | |||
9086 | CK_RV crv; | |||
9087 | ||||
9088 | CHECK_FORK(); | |||
9089 | ||||
9090 | crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, | |||
9091 | pulEncryptedPartLen); | |||
9092 | if (crv != CKR_OK0x00000000UL) | |||
9093 | return crv; | |||
9094 | crv = NSC_DigestUpdate(hSession, pPart, ulPartLen); | |||
9095 | ||||
9096 | return crv; | |||
9097 | } | |||
9098 | ||||
9099 | /* NSC_DecryptDigestUpdate continues a multiple-part decryption and | |||
9100 | * digesting operation. */ | |||
9101 | CK_RV | |||
9102 | NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, | |||
9103 | CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, | |||
9104 | CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) | |||
9105 | { | |||
9106 | CK_RV crv; | |||
9107 | ||||
9108 | CHECK_FORK(); | |||
9109 | ||||
9110 | crv = NSC_DecryptUpdate(hSession, pEncryptedPart, ulEncryptedPartLen, | |||
9111 | pPart, pulPartLen); | |||
9112 | if (crv != CKR_OK0x00000000UL) | |||
9113 | return crv; | |||
9114 | crv = NSC_DigestUpdate(hSession, pPart, *pulPartLen); | |||
9115 | ||||
9116 | return crv; | |||
9117 | } | |||
9118 | ||||
9119 | /* NSC_SignEncryptUpdate continues a multiple-part signing and | |||
9120 | * encryption operation. */ | |||
9121 | CK_RV | |||
9122 | NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, | |||
9123 | CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, | |||
9124 | CK_ULONG_PTR pulEncryptedPartLen) | |||
9125 | { | |||
9126 | CK_RV crv; | |||
9127 | ||||
9128 | CHECK_FORK(); | |||
9129 | ||||
9130 | crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, | |||
9131 | pulEncryptedPartLen); | |||
9132 | if (crv != CKR_OK0x00000000UL) | |||
9133 | return crv; | |||
9134 | crv = NSC_SignUpdate(hSession, pPart, ulPartLen); | |||
9135 | ||||
9136 | return crv; | |||
9137 | } | |||
9138 | ||||
9139 | /* NSC_DecryptVerifyUpdate continues a multiple-part decryption | |||
9140 | * and verify operation. */ | |||
9141 | CK_RV | |||
9142 | NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, | |||
9143 | CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, | |||
9144 | CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) | |||
9145 | { | |||
9146 | CK_RV crv; | |||
9147 | ||||
9148 | CHECK_FORK(); | |||
9149 | ||||
9150 | crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen, | |||
9151 | pData, pulDataLen); | |||
9152 | if (crv != CKR_OK0x00000000UL) | |||
9153 | return crv; | |||
9154 | crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen); | |||
9155 | ||||
9156 | return crv; | |||
9157 | } | |||
9158 | ||||
9159 | /* NSC_DigestKey continues a multi-part message-digesting operation, | |||
9160 | * by digesting the value of a secret key as part of the data already digested. | |||
9161 | */ | |||
9162 | CK_RV | |||
9163 | NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) | |||
9164 | { | |||
9165 | SFTKSession *session = NULL((void*)0); | |||
9166 | SFTKObject *key = NULL((void*)0); | |||
9167 | SFTKAttribute *att; | |||
9168 | CK_RV crv; | |||
9169 | ||||
9170 | CHECK_FORK(); | |||
9171 | ||||
9172 | session = sftk_SessionFromHandle(hSession); | |||
9173 | if (session == NULL((void*)0)) | |||
9174 | return CKR_SESSION_HANDLE_INVALID0x000000B3UL; | |||
9175 | ||||
9176 | key = sftk_ObjectFromHandle(hKey, session); | |||
9177 | sftk_FreeSession(session); | |||
9178 | if (key == NULL((void*)0)) | |||
9179 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
9180 | ||||
9181 | /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */ | |||
9182 | ||||
9183 | /* make sure it's a valid key for this operation */ | |||
9184 | if (key->objclass != CKO_SECRET_KEY0x00000004UL) { | |||
9185 | sftk_FreeObject(key); | |||
9186 | return CKR_KEY_TYPE_INCONSISTENT0x00000063UL; | |||
9187 | } | |||
9188 | /* get the key value */ | |||
9189 | att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL); | |||
9190 | sftk_FreeObject(key); | |||
9191 | if (!att) { | |||
9192 | return CKR_KEY_HANDLE_INVALID0x00000060UL; | |||
9193 | } | |||
9194 | crv = NSC_DigestUpdate(hSession, (CK_BYTE_PTR)att->attrib.pValue, | |||
9195 | att->attrib.ulValueLen); | |||
9196 | sftk_FreeAttribute(att); | |||
9197 | return crv; | |||
9198 | } |