File: | s/lib/softoken/pkcs11c.c |
Warning: | line 4312, column 5 Value stored to 'crv' is never read |
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), |
Value stored to 'crv' is never read | |
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 != CKR_OK0x00000000UL) { |
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 != CKR_OK0x00000000UL) { |
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 | } |