Bug Summary

File:s/lib/softoken/pkcs11c.c
Warning:line 3268, column 13
Null pointer passed to 2nd parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pkcs11c.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D SOFTOKEN_LIB_NAME="libsoftokn3.so" -D SHLIB_VERSION="3" -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c pkcs11c.c
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
71typedef struct {
72 PRUint8 client_version[2];
73 PRUint8 random[46];
74} SSL3RSAPreMasterSecret;
75
76static void
77sftk_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 */
99static void
100sftk_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit)
101{
102 nsslowkey_DestroyPrivateKey(key);
103}
104
105static void
106sftk_Space(void *data, PRBool freeit)
107{
108 PORT_FreePORT_Free_Util(data);
109}
110
111static void
112sftk_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 */
122static CK_RV
123sftk_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);
176done:
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. */
183CK_RV
184NSC_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 */
247static PRBool
248sftk_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 */
263static PRBool
264sftk_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 */
287SFTKSessionContext *
288sftk_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 */
312void
313sftk_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 */
345CK_RV
346sftk_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 */
373void
374sftk_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 */
390CK_RV
391sftk_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
460static int
461sftk_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
479static SECStatus
480sftk_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
501static SECStatus
502sftk_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
523static SECStatus
524sftk_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
545static SECStatus
546sftk_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
567static void
568sftk_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
574static SECStatus
575sftk_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
597static SECStatus
598sftk_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
625static SFTKChaCha20Poly1305Info *
626sftk_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
672static void
673sftk_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
689static SECStatus
690sftk_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
706static SECStatus
707sftk_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
723static SECStatus
724sftk_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
739static void
740sftk_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 */
755CK_RV
756sftk_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. */
1426CK_RV
1427NSC_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. */
1436CK_RV
1437NSC_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. */
1520CK_RV
1521NSC_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
1562finish:
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. */
1570CK_RV
1571NSC_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);
1646fail:
1647 sftk_TerminateOp(session, SFTK_ENCRYPT, context);
1648done:
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. */
1661CK_RV
1662NSC_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. */
1671CK_RV
1672NSC_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. */
1749CK_RV
1750NSC_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);
1796finish:
1797 sftk_FreeSession(session);
1798 return crv;
1799}
1800
1801/* NSC_Decrypt decrypts encrypted data in a single part. */
1802CK_RV
1803NSC_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);
1865done:
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. */
1875CK_RV
1876NSC_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. */
1941CK_RV
1942NSC_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);
1980finish:
1981 sftk_FreeSession(session);
1982 return CKR_OK0x00000000UL;
1983}
1984
1985/* NSC_DigestUpdate continues a multiple-part message-digesting operation. */
1986CK_RV
1987NSC_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. */
2015CK_RV
2016NSC_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
2064DOSUB(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; }
2065DOSUB(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; }
2066DOSUB(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; }
2067DOSUB(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
; }
2068DOSUB(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
; }
2069DOSUB(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
; }
2070DOSUB(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
2072static SECStatus
2073sftk_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 */
2095static SECStatus
2096sftk_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 */
2110static CK_RV
2111sftk_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 */
2171static 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};
2181static 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
2192static SECStatus
2193sftk_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
2210static SECStatus
2211sftk_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 */
2231static CK_RV
2232sftk_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 */
2296static CK_RV
2297sftk_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;
2495fail:
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 */
2507static SECStatus
2508sftk_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. */
2523static 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 */
2537static 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 */
2551SECStatus
2552RSA_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
2590loser:
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
2598static SECStatus
2599sftk_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
2619static SECStatus
2620sftk_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
2640static SECStatus
2641sftk_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
2667static SECStatus
2668nsc_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
2677static SECStatus
2678nsc_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
2693static SECStatus
2694nsc_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
2703static SECStatus
2704nsc_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
2720static SECStatus
2721nsc_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
2730static SECStatus
2731nsc_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 */
2769CK_RV
2770NSC_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 */
3175static CK_RV
3176sftk_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 */
3189static CK_RV
3190sftk_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 */
3214static CK_RV
3215sftk_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
3.1
'crv' is equal to CKR_OK
!= CKR_OK0x00000000UL)
4
Taking false branch
3225 return crv;
3226
3227 if (context->hashInfo) {
5
Assuming field 'hashInfo' is null
6
Taking false branch
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;
7
'blkSize' initialized here
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) {
8
Assuming 'ulPartLen' is > 'minInput'
9
Taking false branch
3247 PORT_Memcpymemcpy(residual, pPart, ulPartLen);
3248 context->padDataLength += ulPartLen;
3249 goto cleanup;
3250 }
3251 /* MACing residual */
3252 if (context->padDataLength) {
10
Assuming field 'padDataLength' is 0
11
Taking false branch
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) {
12
Assuming 'ulPartLen' is > 'blkSize'
13
Loop condition is true. Entering loop body
16
Assuming 'ulPartLen' is <= 'blkSize'
17
Loop condition is false. Execution continues on line 3267
3261 if (CKR_OK0x00000000UL != (crv = sftk_MACBlock(context, pPart)))
14
Taking false branch
3262 goto terminate;
3263 ulPartLen -= blkSize;
3264 pPart += blkSize;
15
Null pointer value stored to 'pPart'
3265 }
3266 /* save the residual */
3267 if ((context->padDataLength = ulPartLen))
18
Assuming field 'padDataLength' is not equal to 0
19
Taking true branch
3268 PORT_Memcpymemcpy(context->padBuf, pPart, ulPartLen);
20
Null pointer passed to 2nd parameter expecting 'nonnull'
3269 } /* blk cipher MACing */
3270
3271 goto cleanup;
3272
3273terminate:
3274 sftk_TerminateOp(session, type, context);
3275cleanup:
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 */
3286CK_RV
3287NSC_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
3294struct SFTK_SESSION_FLAGS {
3295 CK_FLAGS flag;
3296 SFTKContextType type;
3297};
3298
3299const 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};
3312const 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 */
3317CK_RV
3318NSC_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. */
3352CK_RV
3353NSC_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);
3399finish:
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 */
3408CK_RV
3409NSC_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
3451finish:
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 */
3462CK_RV
3463NSC_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 */
3481CK_RV
3482NSC_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 */
3495static SECStatus
3496sftk_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
3510SECStatus
3511RSA_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
3550static SECStatus
3551sftk_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
3564static SECStatus
3565sftk_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
3578static SECStatus
3579sftk_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) */
3603CK_RV
3604NSC_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 */
3840CK_RV
3841NSC_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 */
3878CK_RV
3879NSC_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);
3
Calling 'sftk_MACUpdate'
3884}
3885
3886/* NSC_VerifyFinal finishes a multiple-part verification operation,
3887 * checking the signature. */
3888CK_RV
3889NSC_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 */
3931static SECStatus
3932sftk_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
3946static SECStatus
3947sftk_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 */
3964CK_RV
3965NSC_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 */
4026CK_RV
4027NSC_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);
4058finish:
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. */
4069CK_RV
4070NSC_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. */
4082CK_RV
4083NSC_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 */
4106static CK_RV
4107nsc_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 */
4158static unsigned int
4159sftk_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
4174static CK_RV
4175nsc_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, &params->prime, key, CKA_PRIME0x00000130UL);
4238 if (crv != CKR_OK0x00000000UL) {
4239 goto loser;
4240 }
4241 crv = sftk_Attribute2SSecItem(arena, &params->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, &params, &vfy);
4280 } else {
4281 rv = PQG_ParamGenSeedLen(j, seedBits / 8, &params, &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, &params, &vfy);
4291 }
4292
4293 if (rv != SECSuccess) {
4294 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
4295 sftk_fatalError = PR_TRUE1;
4296 }
4297 return sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
4298 }
4299 crv = sftk_AddAttributeType(key, CKA_PRIME0x00000130UL,
4300 params->prime.data, params->prime.len);
4301 if (crv != CKR_OK0x00000000UL)
4302 goto loser;
4303 crv = sftk_AddAttributeType(key, CKA_SUBPRIME0x00000131UL,
4304 params->subPrime.data, params->subPrime.len);
4305 if (crv != CKR_OK0x00000000UL)
4306 goto loser;
4307 crv = sftk_AddAttributeType(key, CKA_BASE0x00000132UL,
4308 params->base.data, params->base.len);
4309 if (crv != CKR_OK0x00000000UL)
4310 goto loser;
4311 counter = vfy->counter;
4312 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_COUNTER((0x80000000UL | 0x4E534350) + 20),
4313 &counter, sizeof(counter));
4314 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21),
4315 vfy->seed.data, vfy->seed.len);
4316 if (crv != CKR_OK0x00000000UL)
4317 goto loser;
4318 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22),
4319 vfy->h.data, vfy->h.len);
4320 if (crv != CKR_OK0x00000000UL)
4321 goto loser;
4322
4323loser:
4324 if (params) {
4325 PQG_DestroyParams(params);
4326 }
4327
4328 if (vfy) {
4329 PQG_DestroyVerify(vfy);
4330 }
4331 return crv;
4332}
4333
4334static CK_RV
4335nsc_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
4419CK_RV
4420nsc_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, &params->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? */
4503static CK_RV
4504nsc_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. */
4616CK_RV
4617NSC_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 }
4894loser:
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 */
4912static CK_RV
4913sftk_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. */
5304CK_RV
5305NSC_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
5982static SECItem *
5983sftk_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
6158loser:
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 */
6180static CK_RV
6181sftk_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. */
6192CK_RV
6193NSC_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 */
6325static SECStatus
6326sftk_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
6608loser:
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. */
6621CK_RV
6622NSC_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 */
6754static CK_RV
6755sftk_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;
6818loser:
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 */
6828static void
6829sftk_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 */
6851static CK_RV
6852sftk_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 */
6956unsigned long
6957sftk_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 */
6985static CK_RV
6986sftk_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
7053loser:
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
7063static CK_RV
7064sftk_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 */
7091CK_RV
7092sftk_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
7126CK_RV
7127sftk_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
7319static 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. */
7335CK_RV
7336NSC_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. */
8944CK_RV
8945NSC_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 */
8953CK_RV
8954NSC_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 */
8966CK_RV
8967NSC_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. */
9012CK_RV
9013NSC_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. */
9081CK_RV
9082NSC_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. */
9101CK_RV
9102NSC_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. */
9121CK_RV
9122NSC_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. */
9141CK_RV
9142NSC_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
0.1
'crv' is equal to CKR_OK
!= CKR_OK0x00000000UL)
1
Taking false branch
9153 return crv;
9154 crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);
2
Calling 'NSC_VerifyUpdate'
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 */
9162CK_RV
9163NSC_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}