Bug Summary

File:root/firefox-clang/security/nss/lib/softoken/pkcs11c.c
Warning:line 3713, 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 -O2 -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 -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/softoken/softoken_softokn -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/softoken/softoken_softokn -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D SOFTOKEN_LIB_NAME="libsoftokn3.so" -D SHLIB_VERSION="3" -D NSS_FIPS_DISABLED -D NSS_NO_INIT_SUPPORT -D NSS_X86_OR_X64 -D NSS_X64 -D NSS_USE_64 -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -D LINUX2_1 -D LINUX -D linux -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D HAVE_STRERROR -D XP_UNIX -D _REENTRANT -D NSS_DISABLE_DBM -D NSS_DISABLE_LIBPKIX -D NSS_USE_PKCS5_PBKD2_PARAMS2_ONLY -D SOFTOKEN_USE_PKCS5_PBKD2_PARAMS2_ONLY -I /root/firefox-clang/security/nss/lib/softoken -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/security/nss/lib/softoken/softoken_softokn -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/private/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c /root/firefox-clang/security/nss/lib/softoken/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 "lowkeyti.h"
24#include "seccomon.h"
25#include "secitem.h"
26#include "secport.h"
27#include "blapi.h"
28/* we need to use the deprecated mechanisms values for backward compatibility */
29#include "pkcs11.h"
30#include "pkcs11i.h"
31#include "pkcs1sig.h"
32#include "lowkeyi.h"
33#include "secder.h"
34#include "secdig.h"
35#include "lowpbe.h" /* We do PBE below */
36#include "pkcs11t.h"
37#include "secoid.h"
38#include "cmac.h"
39#include "alghmac.h"
40#include "softoken.h"
41#include "secasn1.h"
42#include "secerr.h"
43#include "kem.h"
44#include "kyber.h"
45
46#include "prprf.h"
47#include "prenv.h"
48#include "prerror.h"
49
50#define __PASTE(x, y)xy x##y
51#define BAD_PARAM_CAST(pMech, typeSize)(!pMech->pParameter || pMech->ulParameterLen < typeSize
)
(!pMech->pParameter || pMech->ulParameterLen < typeSize)
52/*
53 * we renamed all our internal functions, get the correct
54 * definitions for them...
55 */
56#undef CK_PKCS11_FUNCTION_INFO
57#undef CK_NEED_ARG_LIST1
58
59#define CK_PKCS11_3_01 1
60
61#define CK_EXTERNextern extern
62#define CK_PKCS11_FUNCTION_INFO(func)CK_RV NSfunc \
63 CK_RV __PASTE(NS, func)NSfunc
64#define CK_NEED_ARG_LIST1 1
65
66#include "pkcs11f.h"
67
68/* create a definition of SHA1 that's consistent
69 * with the rest of the CKM_SHAxxx hashes*/
70#define CKM_SHA10x00000220UL CKM_SHA_10x00000220UL
71#define CKM_SHA1_HMAC0x00000221UL CKM_SHA_1_HMAC0x00000221UL
72#define CKM_SHA1_HMAC_GENERAL0x00000222UL CKM_SHA_1_HMAC_GENERAL0x00000222UL
73
74typedef struct {
75 PRUint8 client_version[2];
76 PRUint8 random[46];
77} SSL3RSAPreMasterSecret;
78
79static void
80sftk_Null(void *data, PRBool freeit)
81{
82 return;
83}
84
85/* fake hash end, the hashed data is already in the signature context,
86 * return a NULL hash, which will be passed to the sign final and ignored */
87void
88sftk_NullHashEnd(void *info, unsigned char *data, unsigned int *lenp,
89 unsigned int maxlen)
90{
91 *lenp = 0;
92}
93
94#ifdef EC_DEBUG
95#define SEC_PRINT(str1, str2, num, sitem) \
96 printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \
97 str1, str2, num, sitem->len); \
98 for (i = 0; i < sitem->len; i++) { \
99 printf("%02x:", sitem->data[i]); \
100 } \
101 printf("\n")
102#else
103#undef EC_DEBUG
104#define SEC_PRINT(a, b, c, d)
105#endif
106
107/* Wrappers to avoid undefined behavior calling functions through a pointer of incorrect type. */
108#define SFTKHashWrap(ctxtype, mmm)static void SFTKHash_mmm_Update(void *vctx, const unsigned char
*input, unsigned int len) { ctxtype *ctx = vctx; mmm_Update(
ctx, input, len); } static void SFTKHash_mmm_End(void *vctx, unsigned
char *digest, unsigned int *len, unsigned int maxLen) { ctxtype
*ctx = vctx; mmm_End(ctx, digest, len, maxLen); } static void
SFTKHash_mmm_DestroyContext(void *vctx, PRBool freeit) { ctxtype
*ctx = vctx; mmm_DestroyContext(ctx, freeit); }
\
109 static void \
110 SFTKHash_##mmm##_Update(void *vctx, const unsigned char *input, unsigned int len) \
111 { \
112 ctxtype *ctx = vctx; \
113 mmm##_Update(ctx, input, len); \
114 } \
115 static void \
116 SFTKHash_##mmm##_End(void *vctx, unsigned char *digest, \
117 unsigned int *len, unsigned int maxLen) \
118 { \
119 ctxtype *ctx = vctx; \
120 mmm##_End(ctx, digest, len, maxLen); \
121 } \
122 static void \
123 SFTKHash_##mmm##_DestroyContext(void *vctx, PRBool freeit) \
124 { \
125 ctxtype *ctx = vctx; \
126 mmm##_DestroyContext(ctx, freeit); \
127 }
128
129SFTKHashWrap(MD2Context, MD2)static void SFTKHash_MD2_Update(void *vctx, const unsigned char
*input, unsigned int len) { MD2Context *ctx = vctx; MD2_Update
(ctx, input, len); } static void SFTKHash_MD2_End(void *vctx,
unsigned char *digest, unsigned int *len, unsigned int maxLen
) { MD2Context *ctx = vctx; MD2_End(ctx, digest, len, maxLen)
; } static void SFTKHash_MD2_DestroyContext(void *vctx, PRBool
freeit) { MD2Context *ctx = vctx; MD2_DestroyContext(ctx, freeit
); }
;
130SFTKHashWrap(MD5Context, MD5)static void SFTKHash_MD5_Update(void *vctx, const unsigned char
*input, unsigned int len) { MD5Context *ctx = vctx; MD5_Update
(ctx, input, len); } static void SFTKHash_MD5_End(void *vctx,
unsigned char *digest, unsigned int *len, unsigned int maxLen
) { MD5Context *ctx = vctx; MD5_End(ctx, digest, len, maxLen)
; } static void SFTKHash_MD5_DestroyContext(void *vctx, PRBool
freeit) { MD5Context *ctx = vctx; MD5_DestroyContext(ctx, freeit
); }
;
131SFTKHashWrap(SHA1Context, SHA1)static void SFTKHash_SHA1_Update(void *vctx, const unsigned char
*input, unsigned int len) { SHA1Context *ctx = vctx; SHA1_Update
(ctx, input, len); } static void SFTKHash_SHA1_End(void *vctx
, unsigned char *digest, unsigned int *len, unsigned int maxLen
) { SHA1Context *ctx = vctx; SHA1_End(ctx, digest, len, maxLen
); } static void SFTKHash_SHA1_DestroyContext(void *vctx, PRBool
freeit) { SHA1Context *ctx = vctx; SHA1_DestroyContext(ctx, freeit
); }
;
132SFTKHashWrap(SHA224Context, SHA224)static void SFTKHash_SHA224_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA224Context *ctx = vctx; SHA224_Update
(ctx, input, len); } static void SFTKHash_SHA224_End(void *vctx
, unsigned char *digest, unsigned int *len, unsigned int maxLen
) { SHA224Context *ctx = vctx; SHA224_End(ctx, digest, len, maxLen
); } static void SFTKHash_SHA224_DestroyContext(void *vctx, PRBool
freeit) { SHA224Context *ctx = vctx; SHA224_DestroyContext(ctx
, freeit); }
;
133SFTKHashWrap(SHA256Context, SHA256)static void SFTKHash_SHA256_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA256Context *ctx = vctx; SHA256_Update
(ctx, input, len); } static void SFTKHash_SHA256_End(void *vctx
, unsigned char *digest, unsigned int *len, unsigned int maxLen
) { SHA256Context *ctx = vctx; SHA256_End(ctx, digest, len, maxLen
); } static void SFTKHash_SHA256_DestroyContext(void *vctx, PRBool
freeit) { SHA256Context *ctx = vctx; SHA256_DestroyContext(ctx
, freeit); }
;
134SFTKHashWrap(SHA384Context, SHA384)static void SFTKHash_SHA384_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA384Context *ctx = vctx; SHA384_Update
(ctx, input, len); } static void SFTKHash_SHA384_End(void *vctx
, unsigned char *digest, unsigned int *len, unsigned int maxLen
) { SHA384Context *ctx = vctx; SHA384_End(ctx, digest, len, maxLen
); } static void SFTKHash_SHA384_DestroyContext(void *vctx, PRBool
freeit) { SHA384Context *ctx = vctx; SHA384_DestroyContext(ctx
, freeit); }
;
135SFTKHashWrap(SHA512Context, SHA512)static void SFTKHash_SHA512_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA512Context *ctx = vctx; SHA512_Update
(ctx, input, len); } static void SFTKHash_SHA512_End(void *vctx
, unsigned char *digest, unsigned int *len, unsigned int maxLen
) { SHA512Context *ctx = vctx; SHA512_End(ctx, digest, len, maxLen
); } static void SFTKHash_SHA512_DestroyContext(void *vctx, PRBool
freeit) { SHA512Context *ctx = vctx; SHA512_DestroyContext(ctx
, freeit); }
;
136SFTKHashWrap(SHA3_224Context, SHA3_224)static void SFTKHash_SHA3_224_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA3_224Context *ctx = vctx
; SHA3_224_Update(ctx, input, len); } static void SFTKHash_SHA3_224_End
(void *vctx, unsigned char *digest, unsigned int *len, unsigned
int maxLen) { SHA3_224Context *ctx = vctx; SHA3_224_End(ctx,
digest, len, maxLen); } static void SFTKHash_SHA3_224_DestroyContext
(void *vctx, PRBool freeit) { SHA3_224Context *ctx = vctx; SHA3_224_DestroyContext
(ctx, freeit); }
;
137SFTKHashWrap(SHA3_256Context, SHA3_256)static void SFTKHash_SHA3_256_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA3_256Context *ctx = vctx
; SHA3_256_Update(ctx, input, len); } static void SFTKHash_SHA3_256_End
(void *vctx, unsigned char *digest, unsigned int *len, unsigned
int maxLen) { SHA3_256Context *ctx = vctx; SHA3_256_End(ctx,
digest, len, maxLen); } static void SFTKHash_SHA3_256_DestroyContext
(void *vctx, PRBool freeit) { SHA3_256Context *ctx = vctx; SHA3_256_DestroyContext
(ctx, freeit); }
;
138SFTKHashWrap(SHA3_384Context, SHA3_384)static void SFTKHash_SHA3_384_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA3_384Context *ctx = vctx
; SHA3_384_Update(ctx, input, len); } static void SFTKHash_SHA3_384_End
(void *vctx, unsigned char *digest, unsigned int *len, unsigned
int maxLen) { SHA3_384Context *ctx = vctx; SHA3_384_End(ctx,
digest, len, maxLen); } static void SFTKHash_SHA3_384_DestroyContext
(void *vctx, PRBool freeit) { SHA3_384Context *ctx = vctx; SHA3_384_DestroyContext
(ctx, freeit); }
;
139SFTKHashWrap(SHA3_512Context, SHA3_512)static void SFTKHash_SHA3_512_Update(void *vctx, const unsigned
char *input, unsigned int len) { SHA3_512Context *ctx = vctx
; SHA3_512_Update(ctx, input, len); } static void SFTKHash_SHA3_512_End
(void *vctx, unsigned char *digest, unsigned int *len, unsigned
int maxLen) { SHA3_512Context *ctx = vctx; SHA3_512_End(ctx,
digest, len, maxLen); } static void SFTKHash_SHA3_512_DestroyContext
(void *vctx, PRBool freeit) { SHA3_512Context *ctx = vctx; SHA3_512_DestroyContext
(ctx, freeit); }
;
140SFTKHashWrap(sftk_MACCtx, sftk_MAC)static void SFTKHash_sftk_MAC_Update(void *vctx, const unsigned
char *input, unsigned int len) { sftk_MACCtx *ctx = vctx; sftk_MAC_Update
(ctx, input, len); } static void SFTKHash_sftk_MAC_End(void *
vctx, unsigned char *digest, unsigned int *len, unsigned int maxLen
) { sftk_MACCtx *ctx = vctx; sftk_MAC_End(ctx, digest, len, maxLen
); } static void SFTKHash_sftk_MAC_DestroyContext(void *vctx,
PRBool freeit) { sftk_MACCtx *ctx = vctx; sftk_MAC_DestroyContext
(ctx, freeit); }
;
141
142static void
143SFTKHash_SHA1_Begin(void *vctx)
144{
145 SHA1Context *ctx = vctx;
146 SHA1_Begin(ctx);
147}
148
149static void
150SFTKHash_MD5_Begin(void *vctx)
151{
152 MD5Context *ctx = vctx;
153 MD5_Begin(ctx);
154}
155
156#define SFTKCipherWrap(ctxtype, mmm)static SECStatus SFTKCipher_mmm(void *vctx, unsigned char *output
, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned
char *input, unsigned int inputLen) { ctxtype *ctx = vctx; return
mmm(ctx, output, outputLen, maxOutputLen, input, inputLen); }
\
157 static SECStatus \
158 SFTKCipher_##mmm(void *vctx, unsigned char *output, \
159 unsigned int *outputLen, unsigned int maxOutputLen, \
160 const unsigned char *input, unsigned int inputLen) \
161 { \
162 ctxtype *ctx = vctx; \
163 return mmm(ctx, output, outputLen, maxOutputLen, \
164 input, inputLen); \
165 }
166
167SFTKCipherWrap(AESKeyWrapContext, AESKeyWrap_EncryptKWP)static SECStatus SFTKCipher_AESKeyWrap_EncryptKWP(void *vctx,
unsigned char *output, unsigned int *outputLen, unsigned int
maxOutputLen, const unsigned char *input, unsigned int inputLen
) { AESKeyWrapContext *ctx = vctx; return AESKeyWrap_EncryptKWP
(ctx, output, outputLen, maxOutputLen, input, inputLen); }
;
168SFTKCipherWrap(AESKeyWrapContext, AESKeyWrap_DecryptKWP)static SECStatus SFTKCipher_AESKeyWrap_DecryptKWP(void *vctx,
unsigned char *output, unsigned int *outputLen, unsigned int
maxOutputLen, const unsigned char *input, unsigned int inputLen
) { AESKeyWrapContext *ctx = vctx; return AESKeyWrap_DecryptKWP
(ctx, output, outputLen, maxOutputLen, input, inputLen); }
;
169
170#define SFTKCipherWrap2(ctxtype, mmm)static SECStatus SFTKCipher_mmm_Encrypt(void *vctx, unsigned char
*output, unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen) { ctxtype
*ctx = vctx; return mmm_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }; static SECStatus SFTKCipher_mmm_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { ctxtype *ctx = vctx; return mmm_Decrypt(ctx, output, outputLen
, maxOutputLen, input, inputLen); }; static void SFTKCipher_mmm_DestroyContext
(void *vctx, PRBool freeit) { ctxtype *ctx = vctx; mmm_DestroyContext
(ctx, freeit); }
\
171 SFTKCipherWrap(ctxtype, mmm##_Encrypt)static SECStatus SFTKCipher_mmm##_Encrypt(void *vctx, unsigned
char *output, unsigned int *outputLen, unsigned int maxOutputLen
, const unsigned char *input, unsigned int inputLen) { ctxtype
*ctx = vctx; return mmm##_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }
; \
172 SFTKCipherWrap(ctxtype, mmm##_Decrypt)static SECStatus SFTKCipher_mmm##_Decrypt(void *vctx, unsigned
char *output, unsigned int *outputLen, unsigned int maxOutputLen
, const unsigned char *input, unsigned int inputLen) { ctxtype
*ctx = vctx; return mmm##_Decrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }
; \
173 static void SFTKCipher_##mmm##_DestroyContext(void *vctx, PRBool freeit) \
174 { \
175 ctxtype *ctx = vctx; \
176 mmm##_DestroyContext(ctx, freeit); \
177 }
178
179#ifndef NSS_DISABLE_DEPRECATED_RC2
180SFTKCipherWrap2(RC2Context, RC2)static SECStatus SFTKCipher_RC2_Encrypt(void *vctx, unsigned char
*output, unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen) { RC2Context
*ctx = vctx; return RC2_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }; static SECStatus SFTKCipher_RC2_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { RC2Context *ctx = vctx; return RC2_Decrypt(ctx, output, outputLen
, maxOutputLen, input, inputLen); }; static void SFTKCipher_RC2_DestroyContext
(void *vctx, PRBool freeit) { RC2Context *ctx = vctx; RC2_DestroyContext
(ctx, freeit); }
;
181#endif
182SFTKCipherWrap2(RC4Context, RC4)static SECStatus SFTKCipher_RC4_Encrypt(void *vctx, unsigned char
*output, unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen) { RC4Context
*ctx = vctx; return RC4_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }; static SECStatus SFTKCipher_RC4_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { RC4Context *ctx = vctx; return RC4_Decrypt(ctx, output, outputLen
, maxOutputLen, input, inputLen); }; static void SFTKCipher_RC4_DestroyContext
(void *vctx, PRBool freeit) { RC4Context *ctx = vctx; RC4_DestroyContext
(ctx, freeit); }
;
183SFTKCipherWrap2(DESContext, DES)static SECStatus SFTKCipher_DES_Encrypt(void *vctx, unsigned char
*output, unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen) { DESContext
*ctx = vctx; return DES_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }; static SECStatus SFTKCipher_DES_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { DESContext *ctx = vctx; return DES_Decrypt(ctx, output, outputLen
, maxOutputLen, input, inputLen); }; static void SFTKCipher_DES_DestroyContext
(void *vctx, PRBool freeit) { DESContext *ctx = vctx; DES_DestroyContext
(ctx, freeit); }
;
184#ifndef NSS_DISABLE_DEPRECATED_SEED
185SFTKCipherWrap2(SEEDContext, SEED)static SECStatus SFTKCipher_SEED_Encrypt(void *vctx, unsigned
char *output, unsigned int *outputLen, unsigned int maxOutputLen
, const unsigned char *input, unsigned int inputLen) { SEEDContext
*ctx = vctx; return SEED_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }; static SECStatus SFTKCipher_SEED_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { SEEDContext *ctx = vctx; return SEED_Decrypt(ctx, output,
outputLen, maxOutputLen, input, inputLen); }; static void SFTKCipher_SEED_DestroyContext
(void *vctx, PRBool freeit) { SEEDContext *ctx = vctx; SEED_DestroyContext
(ctx, freeit); }
;
186#endif
187SFTKCipherWrap2(CamelliaContext, Camellia)static SECStatus SFTKCipher_Camellia_Encrypt(void *vctx, unsigned
char *output, unsigned int *outputLen, unsigned int maxOutputLen
, const unsigned char *input, unsigned int inputLen) { CamelliaContext
*ctx = vctx; return Camellia_Encrypt(ctx, output, outputLen,
maxOutputLen, input, inputLen); }; static SECStatus SFTKCipher_Camellia_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { CamelliaContext *ctx = vctx; return Camellia_Decrypt(ctx,
output, outputLen, maxOutputLen, input, inputLen); }; static
void SFTKCipher_Camellia_DestroyContext(void *vctx, PRBool freeit
) { CamelliaContext *ctx = vctx; Camellia_DestroyContext(ctx,
freeit); }
;
188SFTKCipherWrap2(AESContext, AES)static SECStatus SFTKCipher_AES_Encrypt(void *vctx, unsigned char
*output, unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen) { AESContext
*ctx = vctx; return AES_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }; static SECStatus SFTKCipher_AES_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { AESContext *ctx = vctx; return AES_Decrypt(ctx, output, outputLen
, maxOutputLen, input, inputLen); }; static void SFTKCipher_AES_DestroyContext
(void *vctx, PRBool freeit) { AESContext *ctx = vctx; AES_DestroyContext
(ctx, freeit); }
;
189SFTKCipherWrap2(AESKeyWrapContext, AESKeyWrap)static SECStatus SFTKCipher_AESKeyWrap_Encrypt(void *vctx, unsigned
char *output, unsigned int *outputLen, unsigned int maxOutputLen
, const unsigned char *input, unsigned int inputLen) { AESKeyWrapContext
*ctx = vctx; return AESKeyWrap_Encrypt(ctx, output, outputLen
, maxOutputLen, input, inputLen); }; static SECStatus SFTKCipher_AESKeyWrap_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { AESKeyWrapContext *ctx = vctx; return AESKeyWrap_Decrypt(
ctx, output, outputLen, maxOutputLen, input, inputLen); }; static
void SFTKCipher_AESKeyWrap_DestroyContext(void *vctx, PRBool
freeit) { AESKeyWrapContext *ctx = vctx; AESKeyWrap_DestroyContext
(ctx, freeit); }
;
190
191#if NSS_SOFTOKEN_DOES_RC5
192SFTKCipherWrap2(RC5Context, RC5)static SECStatus SFTKCipher_RC5_Encrypt(void *vctx, unsigned char
*output, unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen) { RC5Context
*ctx = vctx; return RC5_Encrypt(ctx, output, outputLen, maxOutputLen
, input, inputLen); }; static SECStatus SFTKCipher_RC5_Decrypt
(void *vctx, unsigned char *output, unsigned int *outputLen, unsigned
int maxOutputLen, const unsigned char *input, unsigned int inputLen
) { RC5Context *ctx = vctx; return RC5_Decrypt(ctx, output, outputLen
, maxOutputLen, input, inputLen); }; static void SFTKCipher_RC5_DestroyContext
(void *vctx, PRBool freeit) { RC5Context *ctx = vctx; RC5_DestroyContext
(ctx, freeit); }
;
193#endif
194
195/*
196 * free routines.... Free local type allocated data, and convert
197 * other free routines to the destroy signature.
198 */
199static void
200sftk_FreePrivKey(void *vkey, PRBool freeit)
201{
202 NSSLOWKEYPrivateKey *key = vkey;
203 nsslowkey_DestroyPrivateKey(key);
204}
205
206static void
207sftk_Space(void *data, PRBool freeit)
208{
209 PORT_FreePORT_Free_Util(data);
210}
211
212static void
213sftk_ZSpace(void *data, PRBool freeit)
214{
215 size_t len = *(size_t *)data;
216 PORT_ZFreePORT_ZFree_Util(data, len);
217}
218
219/*
220 * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
221 * Deprecating a full des key to 40 bit key strenth.
222 */
223static CK_RV
224sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
225{
226 unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae };
227 unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 };
228 unsigned char enc_src[8];
229 unsigned char enc_dest[8];
230 unsigned int leng, i;
231 DESContext *descx;
232 SECStatus rv;
233 CK_RV crv = CKR_OK0x00000000UL;
234
235 /* zero the parity bits */
236 for (i = 0; i < 8; i++) {
237 enc_src[i] = cdmfkey[i] & 0xfe;
238 }
239
240 /* encrypt with key 1 */
241 descx = DES_CreateContext(key1, NULL((void*)0), NSS_DES0, PR_TRUE1);
242 if (descx == NULL((void*)0)) {
243 crv = CKR_HOST_MEMORY0x00000002UL;
244 goto done;
245 }
246 rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8);
247 DES_DestroyContext(descx, PR_TRUE1);
248 if (rv != SECSuccess) {
249 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
250 goto done;
251 }
252
253 /* xor source with des, zero the parity bits and deprecate the key*/
254 for (i = 0; i < 8; i++) {
255 if (i & 1) {
256 enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe;
257 } else {
258 enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e;
259 }
260 }
261
262 /* encrypt with key 2 */
263 descx = DES_CreateContext(key2, NULL((void*)0), NSS_DES0, PR_TRUE1);
264 if (descx == NULL((void*)0)) {
265 crv = CKR_HOST_MEMORY0x00000002UL;
266 goto done;
267 }
268 rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8);
269 DES_DestroyContext(descx, PR_TRUE1);
270 if (rv != SECSuccess) {
271 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
272 goto done;
273 }
274
275 /* set the corret parity on our new des key */
276 sftk_FormatDESKey(deskey, 8);
277done:
278 PORT_Memsetmemset(enc_src, 0, sizeof enc_src);
279 PORT_Memsetmemset(enc_dest, 0, sizeof enc_dest);
280 return crv;
281}
282
283/* NSC_DestroyObject destroys an object. */
284CK_RV
285NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
286{
287 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
288 SFTKSession *session;
289 SFTKObject *object;
290 SFTKFreeStatus status;
291
292 CHECK_FORK();
293
294 if (slot == NULL((void*)0)) {
295 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
296 }
297 /*
298 * This whole block just makes sure we really can destroy the
299 * requested object.
300 */
301 session = sftk_SessionFromHandle(hSession);
302 if (session == NULL((void*)0)) {
303 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
304 }
305
306 object = sftk_ObjectFromHandle(hObject, session);
307 if (object == NULL((void*)0)) {
308 sftk_FreeSession(session);
309 return CKR_OBJECT_HANDLE_INVALID0x00000082UL;
310 }
311
312 /* don't destroy a private object if we aren't logged in */
313 PR_Lock(slot->slotLock);
314 PRBool wouldNeedToLogIn = !slot->isLoggedIn && slot->needLogin;
315 PR_Unlock(slot->slotLock);
316 if (wouldNeedToLogIn && sftk_isTrue(object, CKA_PRIVATE0x00000002UL)) {
317 sftk_FreeSession(session);
318 sftk_FreeObject(object);
319 return CKR_USER_NOT_LOGGED_IN0x00000101UL;
320 }
321
322 /* don't destroy a token object if we aren't in a rw session */
323
324 if (((session->info.flags & CKF_RW_SESSION0x00000002UL) == 0) &&
325 (sftk_isTrue(object, CKA_TOKEN0x00000001UL))) {
326 sftk_FreeSession(session);
327 sftk_FreeObject(object);
328 return CKR_SESSION_READ_ONLY0x000000B5UL;
329 }
330
331 sftk_DeleteObject(session, object);
332
333 sftk_FreeSession(session);
334
335 /*
336 * get some indication if the object is destroyed. Note: this is not
337 * 100%. Someone may have an object reference outstanding (though that
338 * should not be the case by here. Also note that the object is "half"
339 * destroyed. Our internal representation is destroyed, but it may still
340 * be in the data base.
341 */
342 status = sftk_FreeObject(object);
343
344 return (status != SFTK_DestroyFailure) ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL;
345}
346
347/*
348 * Returns true if "params" contains a valid set of PSS parameters
349 */
350static PRBool
351sftk_ValidatePssParams(const CK_RSA_PKCS_PSS_PARAMS *params)
352{
353 if (!params) {
354 return PR_FALSE0;
355 }
356 if (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL ||
357 sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) {
358 return PR_FALSE0;
359 }
360 return PR_TRUE1;
361}
362
363/*
364 * Returns true if "params" contains a valid set of OAEP parameters
365 */
366static PRBool
367sftk_ValidateOaepParams(const CK_RSA_PKCS_OAEP_PARAMS *params)
368{
369 if (!params) {
370 return PR_FALSE0;
371 }
372 /* The requirements of ulSourceLen/pSourceData come from PKCS #11, which
373 * state:
374 * If the parameter is empty, pSourceData must be NULL and
375 * ulSourceDataLen must be zero.
376 */
377 if (params->source != CKZ_DATA_SPECIFIED0x00000001UL ||
378 (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) ||
379 (sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) ||
380 (params->ulSourceDataLen == 0 && params->pSourceData != NULL((void*)0)) ||
381 (params->ulSourceDataLen != 0 && params->pSourceData == NULL((void*)0))) {
382 return PR_FALSE0;
383 }
384 return PR_TRUE1;
385}
386
387/*
388 * return a context based on the SFTKContext type.
389 */
390SFTKSessionContext *
391sftk_ReturnContextByType(SFTKSession *session, SFTKContextType type)
392{
393 switch (type) {
394 case SFTK_ENCRYPT:
395 case SFTK_DECRYPT:
396 case SFTK_MESSAGE_ENCRYPT:
397 case SFTK_MESSAGE_DECRYPT:
398 return session->enc_context;
399 case SFTK_HASH:
400 return session->hash_context;
401 case SFTK_SIGN:
402 case SFTK_SIGN_RECOVER:
403 case SFTK_VERIFY:
404 case SFTK_VERIFY_RECOVER:
405 case SFTK_MESSAGE_SIGN:
406 case SFTK_MESSAGE_VERIFY:
407 return session->hash_context;
408 }
409 return NULL((void*)0);
410}
411
412/*
413 * change a context based on the SFTKContext type.
414 */
415void
416sftk_SetContextByType(SFTKSession *session, SFTKContextType type,
417 SFTKSessionContext *context)
418{
419 switch (type) {
420 case SFTK_ENCRYPT:
421 case SFTK_DECRYPT:
422 case SFTK_MESSAGE_ENCRYPT:
423 case SFTK_MESSAGE_DECRYPT:
424 session->enc_context = context;
425 break;
426 case SFTK_HASH:
427 session->hash_context = context;
428 break;
429 case SFTK_SIGN:
430 case SFTK_SIGN_RECOVER:
431 case SFTK_VERIFY:
432 case SFTK_VERIFY_RECOVER:
433 case SFTK_MESSAGE_SIGN:
434 case SFTK_MESSAGE_VERIFY:
435 session->hash_context = context;
436 break;
437 }
438 return;
439}
440
441/*
442 * Atomically install a freshly-initialized context onto a session, used
443 * by every C_...Init function. The bucket lock makes the "is the slot
444 * empty?" check and the assignment a single critical section, closing
445 * the race where two threads concurrently entering an Init each pass
446 * the unlocked check in sftk_InitGeneric, allocate a context, and then
447 * one overwrites the other's pointer (leaking the loser's context).
448 *
449 * On CKR_OPERATION_ACTIVE the caller retains ownership of `context` and
450 * must free it (typically via sftk_FreeContext).
451 */
452CK_RV
453sftk_InstallContext(SFTKSession *session, SFTKContextType type,
454 SFTKSessionContext *context)
455{
456 SFTKSlot *slot = sftk_SlotFromSession(session)((session)->slot);
457 PRLock *lock = SFTK_SESSION_LOCK(slot, session->handle)((slot)->sessionLock[((((PRUint32)(((session->handle)) *
1791398085) & ((slot)->sessHashSize - 1))) >> 0
) & (slot)->sessionLockMask])
;
458 CK_RV crv;
459
460 PR_Lock(lock);
461 if (sftk_ReturnContextByType(session, type) != NULL((void*)0)) {
462 crv = CKR_OPERATION_ACTIVE0x00000090UL;
463 } else {
464 sftk_SetContextByType(session, type, context);
465 crv = CKR_OK0x00000000UL;
466 }
467 PR_Unlock(lock);
468 return crv;
469}
470
471/* Pair to sftk_InstallContext. Atomically detach whatever context is
472 * stored on the session for `type` and free it. Holding the session
473 * bucket lock for the detach ensures that a concurrent
474 * sftk_InstallContext sees either the old context still in place
475 * (yielding CKR_OPERATION_ACTIVE) or the slot already NULL (allowing
476 * its install to succeed), never a transient stale pointer. */
477void
478sftk_UninstallContext(SFTKSession *session, SFTKContextType type)
479{
480 SFTKSlot *slot = sftk_SlotFromSession(session)((session)->slot);
481 PRLock *lock = SFTK_SESSION_LOCK(slot, session->handle)((slot)->sessionLock[((((PRUint32)(((session->handle)) *
1791398085) & ((slot)->sessHashSize - 1))) >> 0
) & (slot)->sessionLockMask])
;
482 SFTKSessionContext *context;
483
484 PR_Lock(lock);
485 context = sftk_ReturnContextByType(session, type);
486 sftk_SetContextByType(session, type, NULL((void*)0));
487 /* Read isFIPS while still under the lock so the write to
488 * session->lastOpWasFIPS reflects the context being torn down,
489 * not one a concurrent installer might race in afterwards. */
490 if (context) {
491 session->lastOpWasFIPS = context->isFIPS;
492 }
493 PR_Unlock(lock);
494 if (context) {
495 sftk_FreeContext(context);
496 }
497}
498
499/*
500 * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal,
501 * and C_XXX function. The function takes a session handle, the context
502 * type, and whether or not the session needs to be multipart. It
503 * returns the context and the session pointer; the caller is
504 * responsible for freeing the session. If the caller doesn't need
505 * a context lookup (e.g. it already holds a session reference), it
506 * should call sftk_ReturnContextByType directly.
507 */
508CK_RV
509sftk_GetContext(CK_SESSION_HANDLE handle, SFTKSessionContext **contextPtr,
510 SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr)
511{
512 SFTKSession *session;
513 SFTKSessionContext *context;
514
515 PORT_Assert(sessionPtr != NULL)((sessionPtr != ((void*)0)) ? ((void)0) : PR_Assert("sessionPtr != NULL"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 515
))
;
516 session = sftk_SessionFromHandle(handle);
517 if (session == NULL((void*)0))
518 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
519 context = sftk_ReturnContextByType(session, type);
520 /* make sure the context is valid */
521 if ((context == NULL((void*)0)) || (context->type != type) || (needMulti && !(context->multi))) {
522 sftk_FreeSession(session);
523 return CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
524 }
525 *contextPtr = context;
526 *sessionPtr = session;
527 return CKR_OK0x00000000UL;
528}
529
530/* Terminate operation (in the PKCS#11 spec sense). Thin wrapper over
531 * sftk_UninstallContext: the install/uninstall pair takes the slot
532 * lock, frees whatever is currently installed for `ctype`, and reads
533 * context->isFIPS into session->lastOpWasFIPS under the lock. */
534void
535sftk_TerminateOp(SFTKSession *session, SFTKContextType ctype)
536{
537 sftk_UninstallContext(session, ctype);
538}
539
540/*
541 ************** Crypto Functions: Encrypt ************************
542 */
543
544/*
545 * All the NSC_InitXXX functions have a set of common checks and processing they
546 * all need to do at the beginning. This is done here.
547 */
548CK_RV
549sftk_InitGeneric(SFTKSession *session, CK_MECHANISM *pMechanism,
550 SFTKSessionContext **contextPtr,
551 SFTKContextType ctype, SFTKObject **keyPtr,
552 CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr,
553 CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation)
554{
555 SFTKObject *key = NULL((void*)0);
556 SFTKAttribute *att;
557 SFTKSessionContext *context;
558
559 /* We can only init if there is not current context active */
560 if (sftk_ReturnContextByType(session, ctype) != NULL((void*)0)) {
561 return CKR_OPERATION_ACTIVE0x00000090UL;
562 }
563
564 /* find the key */
565 if (keyPtr) {
566 key = sftk_ObjectFromHandle(hKey, session);
567 if (key == NULL((void*)0)) {
568 return CKR_KEY_HANDLE_INVALID0x00000060UL;
569 }
570
571 /* make sure it's a valid key for this operation */
572 if (((key->objclass != CKO_SECRET_KEY0x00000004UL) &&
573 (key->objclass != pubKeyType)) ||
574 !sftk_isTrue(key, operation)) {
575 sftk_FreeObject(key);
576 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
577 }
578 /* get the key type */
579 att = sftk_FindAttribute(key, CKA_KEY_TYPE0x00000100UL);
580 if (att == NULL((void*)0)) {
581 sftk_FreeObject(key);
582 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
583 }
584 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)"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 584
))
;
585 if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) {
586 sftk_FreeAttribute(att);
587 sftk_FreeObject(key);
588 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
589 }
590 PORT_Memcpymemcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE));
591 sftk_FreeAttribute(att);
592 *keyPtr = key;
593 }
594
595 /* allocate the context structure */
596 context = (SFTKSessionContext *)PORT_AllocPORT_Alloc_Util(sizeof(SFTKSessionContext));
597 if (context == NULL((void*)0)) {
598 if (key)
599 sftk_FreeObject(key);
600 return CKR_HOST_MEMORY0x00000002UL;
601 }
602 context->type = ctype;
603 context->multi = PR_TRUE1;
604 context->rsa = PR_FALSE0;
605 context->cipherInfo = NULL((void*)0);
606 context->hashInfo = NULL((void*)0);
607 context->doPad = PR_FALSE0;
608 context->padDataLength = 0;
609 context->key = key;
610 context->blockSize = 0;
611 context->maxLen = 0;
612 context->signature = NULL((void*)0);
613 context->isFIPS = sftk_operationIsFIPS(session->slot, pMechanism,
614 operation, key, 0);
615 *contextPtr = context;
616 return CKR_OK0x00000000UL;
617}
618
619static int
620sftk_aes_mode(CK_MECHANISM_TYPE mechanism)
621{
622 switch (mechanism) {
623 case CKM_AES_CBC_PAD0x00001085UL:
624 case CKM_AES_CBC0x00001082UL:
625 return NSS_AES_CBC1;
626 case CKM_AES_ECB0x00001081UL:
627 return NSS_AES0;
628 case CKM_AES_CTS0x00001089UL:
629 return NSS_AES_CTS2;
630 case CKM_AES_CTR0x00001086UL:
631 return NSS_AES_CTR3;
632 case CKM_AES_GCM0x00001087UL:
633 return NSS_AES_GCM4;
634 }
635 return -1;
636}
637
638static SECStatus
639sftk_RSAEncryptRaw(void *ctx, unsigned char *output,
640 unsigned int *outputLen, unsigned int maxLen,
641 const unsigned char *input, unsigned int inputLen)
642{
643 NSSLOWKEYPublicKey *key = ctx;
644 SECStatus rv = SECFailure;
645
646 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 646))
;
647 if (key->keyType != NSSLOWKEYRSAKey) {
648 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
649 return SECFailure;
650 }
651
652 rv = RSA_EncryptRaw(&key->u.rsa, output, outputLen, maxLen, input,
653 inputLen);
654 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
655 sftk_fatalError = PR_TRUE1;
656 }
657
658 return rv;
659}
660
661static SECStatus
662sftk_RSADecryptRaw(void *ctx, unsigned char *output,
663 unsigned int *outputLen, unsigned int maxLen,
664 const unsigned char *input, unsigned int inputLen)
665{
666 NSSLOWKEYPrivateKey *key = ctx;
667 SECStatus rv = SECFailure;
668
669 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 669))
;
670 if (key->keyType != NSSLOWKEYRSAKey) {
671 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
672 return SECFailure;
673 }
674
675 rv = RSA_DecryptRaw(&key->u.rsa, output, outputLen, maxLen, input,
676 inputLen);
677 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
678 sftk_fatalError = PR_TRUE1;
679 }
680
681 return rv;
682}
683
684static SECStatus
685sftk_RSAEncrypt(void *ctx, unsigned char *output,
686 unsigned int *outputLen, unsigned int maxLen,
687 const unsigned char *input, unsigned int inputLen)
688{
689 NSSLOWKEYPublicKey *key = ctx;
690 SECStatus rv = SECFailure;
691
692 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 692))
;
693 if (key->keyType != NSSLOWKEYRSAKey) {
694 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
695 return SECFailure;
696 }
697
698 rv = RSA_EncryptBlock(&key->u.rsa, output, outputLen, maxLen, input,
699 inputLen);
700 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
701 sftk_fatalError = PR_TRUE1;
702 }
703
704 return rv;
705}
706
707static SECStatus
708sftk_RSADecrypt(void *ctx, unsigned char *output,
709 unsigned int *outputLen, unsigned int maxLen,
710 const unsigned char *input, unsigned int inputLen)
711{
712 NSSLOWKEYPrivateKey *key = ctx;
713 SECStatus rv = SECFailure;
714
715 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 715))
;
716 if (key->keyType != NSSLOWKEYRSAKey) {
717 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
718 return SECFailure;
719 }
720
721 rv = RSA_DecryptBlock(&key->u.rsa, output, outputLen, maxLen, input,
722 inputLen);
723 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
724 sftk_fatalError = PR_TRUE1;
725 }
726
727 return rv;
728}
729
730static void
731sftk_freeRSAOAEPInfo(void *ctx, PRBool freeit)
732{
733 SFTKOAEPInfo *info = ctx;
734 PORT_ZFreePORT_ZFree_Util(info->params.pSourceData, info->params.ulSourceDataLen);
735 PORT_ZFreePORT_ZFree_Util(info, sizeof(SFTKOAEPInfo));
736}
737
738static SECStatus
739sftk_RSAEncryptOAEP(void *ctx, unsigned char *output,
740 unsigned int *outputLen, unsigned int maxLen,
741 const unsigned char *input, unsigned int inputLen)
742{
743 SFTKOAEPInfo *info = ctx;
744 HASH_HashType hashAlg;
745 HASH_HashType maskHashAlg;
746
747 PORT_Assert(info->key.pub->keyType == NSSLOWKEYRSAKey)((info->key.pub->keyType == NSSLOWKEYRSAKey) ? ((void)0
) : PR_Assert("info->key.pub->keyType == NSSLOWKEYRSAKey"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 747
))
;
748 if (info->key.pub->keyType != NSSLOWKEYRSAKey) {
749 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
750 return SECFailure;
751 }
752
753 hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg);
754 maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf);
755
756 return RSA_EncryptOAEP(&info->key.pub->u.rsa, hashAlg, maskHashAlg,
757 (const unsigned char *)info->params.pSourceData,
758 info->params.ulSourceDataLen, NULL((void*)0), 0,
759 output, outputLen, maxLen, input, inputLen);
760}
761
762static SECStatus
763sftk_RSADecryptOAEP(void *ctx, unsigned char *output,
764 unsigned int *outputLen, unsigned int maxLen,
765 const unsigned char *input, unsigned int inputLen)
766{
767 SFTKOAEPInfo *info = ctx;
768 SECStatus rv = SECFailure;
769 HASH_HashType hashAlg;
770 HASH_HashType maskHashAlg;
771
772 PORT_Assert(info->key.priv->keyType == NSSLOWKEYRSAKey)((info->key.priv->keyType == NSSLOWKEYRSAKey) ? ((void)
0) : PR_Assert("info->key.priv->keyType == NSSLOWKEYRSAKey"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 772
))
;
773 if (info->key.priv->keyType != NSSLOWKEYRSAKey) {
774 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
775 return SECFailure;
776 }
777
778 hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg);
779 maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf);
780
781 rv = RSA_DecryptOAEP(&info->key.priv->u.rsa, hashAlg, maskHashAlg,
782 (const unsigned char *)info->params.pSourceData,
783 info->params.ulSourceDataLen,
784 output, outputLen, maxLen, input, inputLen);
785 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
786 sftk_fatalError = PR_TRUE1;
787 }
788 return rv;
789}
790
791static SFTKChaCha20Poly1305Info *
792sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
793 unsigned int keyLen,
794 const CK_NSS_AEAD_PARAMS *params)
795{
796 SFTKChaCha20Poly1305Info *ctx;
797
798 if (params->ulNonceLen != sizeof(ctx->nonce)) {
799 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INPUT_LEN);
800 return NULL((void*)0);
801 }
802
803 ctx = PORT_New(SFTKChaCha20Poly1305Info)(SFTKChaCha20Poly1305Info *)PORT_Alloc_Util(sizeof(SFTKChaCha20Poly1305Info
))
;
804 if (ctx == NULL((void*)0)) {
805 return NULL((void*)0);
806 }
807
808 if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
809 params->ulTagLen) != SECSuccess) {
810 PORT_FreePORT_Free_Util(ctx);
811 return NULL((void*)0);
812 }
813
814 PORT_Memcpymemcpy(ctx->nonce, params->pNonce, sizeof(ctx->nonce));
815
816 /* AAD data and length must both be null, or both non-null. */
817 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)"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 817
))
;
818
819 if (params->ulAADLen > sizeof(ctx->ad)) {
820 /* Need to allocate an overflow buffer for the additional data. */
821 ctx->adOverflow = (unsigned char *)PORT_AllocPORT_Alloc_Util(params->ulAADLen);
822 if (!ctx->adOverflow) {
823 PORT_FreePORT_Free_Util(ctx);
824 return NULL((void*)0);
825 }
826 PORT_Memcpymemcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
827 } else {
828 ctx->adOverflow = NULL((void*)0);
829 if (params->pAAD) {
830 PORT_Memcpymemcpy(ctx->ad, params->pAAD, params->ulAADLen);
831 }
832 }
833 ctx->adLen = params->ulAADLen;
834
835 return ctx;
836}
837
838static void
839sftk_ChaCha20Poly1305_DestroyContext(void *vctx,
840 PRBool freeit)
841{
842 SFTKChaCha20Poly1305Info *ctx = vctx;
843 ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE0);
844 if (ctx->adOverflow != NULL((void*)0)) {
845 PORT_ZFreePORT_ZFree_Util(ctx->adOverflow, ctx->adLen);
846 ctx->adOverflow = NULL((void*)0);
847 } else {
848 PORT_Memsetmemset(ctx->ad, 0, ctx->adLen);
849 }
850 ctx->adLen = 0;
851 if (freeit) {
852 PORT_FreePORT_Free_Util(ctx);
853 }
854}
855
856static SECStatus
857sftk_ChaCha20Poly1305_Encrypt(void *vctx,
858 unsigned char *output, unsigned int *outputLen,
859 unsigned int maxOutputLen,
860 const unsigned char *input, unsigned int inputLen)
861{
862 const SFTKChaCha20Poly1305Info *ctx = vctx;
863 const unsigned char *ad = ctx->adOverflow;
864
865 if (ad == NULL((void*)0)) {
866 ad = ctx->ad;
867 }
868
869 return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
870 maxOutputLen, input, inputLen, ctx->nonce,
871 sizeof(ctx->nonce), ad, ctx->adLen);
872}
873
874static SECStatus
875sftk_ChaCha20Poly1305_Decrypt(void *vctx,
876 unsigned char *output, unsigned int *outputLen,
877 unsigned int maxOutputLen,
878 const unsigned char *input, unsigned int inputLen)
879{
880 const SFTKChaCha20Poly1305Info *ctx = vctx;
881 const unsigned char *ad = ctx->adOverflow;
882
883 if (ad == NULL((void*)0)) {
884 ad = ctx->ad;
885 }
886
887 return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
888 maxOutputLen, input, inputLen, ctx->nonce,
889 sizeof(ctx->nonce), ad, ctx->adLen);
890}
891
892static SECStatus
893sftk_ChaCha20Ctr(void *vctx,
894 unsigned char *output, unsigned int *outputLen,
895 unsigned int maxOutputLen,
896 const unsigned char *input, unsigned int inputLen)
897{
898 if (maxOutputLen < inputLen) {
899 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OUTPUT_LEN);
900 return SECFailure;
901 }
902 SFTKChaCha20CtrInfo *ctx = vctx;
903 ChaCha20_Xor(output, input, inputLen, ctx->key,
904 ctx->nonce, ctx->counter);
905 *outputLen = inputLen;
906 return SECSuccess;
907}
908
909static void
910sftk_ChaCha20Ctr_DestroyContext(void *vctx,
911 PRBool freeit)
912{
913 SFTKChaCha20CtrInfo *ctx = vctx;
914 memset(ctx, 0, sizeof(SFTKChaCha20CtrInfo));
915 if (freeit) {
916 PORT_FreePORT_Free_Util(ctx);
917 }
918}
919
920/** NSC_CryptInit initializes an encryption/Decryption operation.
921 *
922 * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
923 * Called by NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac) only for block
924 * ciphers MAC'ing.
925 */
926CK_RV
927sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
928 CK_OBJECT_HANDLE hKey,
929 CK_ATTRIBUTE_TYPE mechUsage, CK_ATTRIBUTE_TYPE keyUsage,
930 SFTKContextType contextType, PRBool isEncrypt)
931{
932 SFTKSession *session;
933 SFTKObject *key;
934 SFTKSessionContext *context;
935 SFTKAttribute *att;
936#ifndef NSS_DISABLE_DEPRECATED_RC2
937 CK_RC2_CBC_PARAMS *rc2_param;
938 unsigned effectiveKeyLength;
939#endif
940#if NSS_SOFTOKEN_DOES_RC5
941 CK_RC5_CBC_PARAMS *rc5_param;
942 SECItem rc5Key;
943#endif
944 CK_NSS_GCM_PARAMS nss_gcm_param;
945 void *aes_param;
946 CK_NSS_AEAD_PARAMS nss_aead_params;
947 CK_NSS_AEAD_PARAMS *nss_aead_params_ptr = NULL((void*)0);
948 CK_KEY_TYPE key_type;
949 CK_RV crv = CKR_OK0x00000000UL;
950 unsigned char newdeskey[24];
951 PRBool useNewKey = PR_FALSE0;
952 int t;
953
954 if (!pMechanism) {
955 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
956 }
957
958 crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage);
959 if (crv != CKR_OK0x00000000UL)
960 return crv;
961
962 session = sftk_SessionFromHandle(hSession);
963 if (session == NULL((void*)0))
964 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
965
966 crv = sftk_InitGeneric(session, pMechanism, &context, contextType, &key,
967 hKey, &key_type,
968 isEncrypt ? CKO_PUBLIC_KEY0x00000002UL : CKO_PRIVATE_KEY0x00000003UL,
969 keyUsage);
970
971 if (crv != CKR_OK0x00000000UL) {
972 sftk_FreeSession(session);
973 return crv;
974 }
975
976 context->doPad = PR_FALSE0;
977 switch (pMechanism->mechanism) {
978 case CKM_RSA_PKCS0x00000001UL:
979 case CKM_RSA_X_5090x00000003UL:
980 if (key_type != CKK_RSA0x00000000UL) {
981 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
982 break;
983 }
984 context->multi = PR_FALSE0;
985 context->rsa = PR_TRUE1;
986 if (isEncrypt) {
987 NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv);
988 if (pubKey == NULL((void*)0)) {
989 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
990 break;
991 }
992 context->maxLen = nsslowkey_PublicModulusLen(pubKey);
993 context->cipherInfo = (void *)pubKey;
994 context->update = pMechanism->mechanism == CKM_RSA_X_5090x00000003UL
995 ? sftk_RSAEncryptRaw
996 : sftk_RSAEncrypt;
997 } else {
998 NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv);
999 if (privKey == NULL((void*)0)) {
1000 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1001 break;
1002 }
1003 context->maxLen = nsslowkey_PrivateModulusLen(privKey);
1004 context->cipherInfo = (void *)privKey;
1005 context->update = pMechanism->mechanism == CKM_RSA_X_5090x00000003UL
1006 ? sftk_RSADecryptRaw
1007 : sftk_RSADecrypt;
1008 }
1009 context->destroy = sftk_Null;
1010 break;
1011 case CKM_RSA_PKCS_OAEP0x00000009UL:
1012 if (key_type != CKK_RSA0x00000000UL) {
1013 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1014 break;
1015 }
1016 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS) ||
1017 !sftk_ValidateOaepParams((CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter)) {
1018 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1019 break;
1020 }
1021 context->multi = PR_FALSE0;
1022 context->rsa = PR_TRUE1;
1023 {
1024 SFTKOAEPInfo *info;
1025 CK_RSA_PKCS_OAEP_PARAMS *params =
1026 (CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter;
1027 /* make a copy of the source data value for future
1028 * use (once the user has reclaimed his data in pParameter)*/
1029 void *newSource = NULL((void*)0);
1030 if (params->pSourceData) {
1031 newSource = PORT_AllocPORT_Alloc_Util(params->ulSourceDataLen);
1032 if (newSource == NULL((void*)0)) {
1033 crv = CKR_HOST_MEMORY0x00000002UL;
1034 break;
1035 }
1036 PORT_Memcpymemcpy(newSource, params->pSourceData, params->ulSourceDataLen);
1037 }
1038 info = PORT_New(SFTKOAEPInfo)(SFTKOAEPInfo *)PORT_Alloc_Util(sizeof(SFTKOAEPInfo));
1039 if (info == NULL((void*)0)) {
1040 PORT_ZFreePORT_ZFree_Util(newSource, params->ulSourceDataLen);
1041 crv = CKR_HOST_MEMORY0x00000002UL;
1042 break;
1043 }
1044 info->params = *params;
1045 info->params.pSourceData = newSource;
1046 info->isEncrypt = isEncrypt;
1047
1048 /* now setup encryption and decryption contexts */
1049 if (isEncrypt) {
1050 info->key.pub = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv);
1051 if (info->key.pub == NULL((void*)0)) {
1052 sftk_freeRSAOAEPInfo(info, PR_TRUE1);
1053 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1054 break;
1055 }
1056 context->update = sftk_RSAEncryptOAEP;
1057 context->maxLen = nsslowkey_PublicModulusLen(info->key.pub);
1058 } else {
1059 info->key.priv = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv);
1060 if (info->key.priv == NULL((void*)0)) {
1061 sftk_freeRSAOAEPInfo(info, PR_TRUE1);
1062 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1063 break;
1064 }
1065 context->update = sftk_RSADecryptOAEP;
1066 context->maxLen = nsslowkey_PrivateModulusLen(info->key.priv);
1067 }
1068 context->cipherInfo = info;
1069 }
1070 context->destroy = sftk_freeRSAOAEPInfo;
1071 break;
1072#ifndef NSS_DISABLE_DEPRECATED_RC2
1073 case CKM_RC2_CBC_PAD0x00000105UL:
1074 context->doPad = PR_TRUE1;
1075 /* fall thru */
1076 case CKM_RC2_ECB0x00000101UL:
1077 case CKM_RC2_CBC0x00000102UL:
1078 context->blockSize = 8;
1079 if (key_type != CKK_RC20x00000011UL) {
1080 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1081 break;
1082 }
1083 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1084 if (att == NULL((void*)0)) {
1085 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1086 break;
1087 }
1088
1089 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_CBC_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_RC2_CBC_PARAMS))
) {
1090 sftk_FreeAttribute(att);
1091 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1092 break;
1093 }
1094 rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
1095 effectiveKeyLength = (rc2_param->ulEffectiveBits + 7) / 8;
1096 context->cipherInfo =
1097 RC2_CreateContext((unsigned char *)att->attrib.pValue,
1098 att->attrib.ulValueLen, rc2_param->iv,
1099 pMechanism->mechanism == CKM_RC2_ECB0x00000101UL ? NSS_RC20 : NSS_RC2_CBC1, effectiveKeyLength);
1100 sftk_FreeAttribute(att);
1101 if (context->cipherInfo == NULL((void*)0)) {
1102 crv = CKR_HOST_MEMORY0x00000002UL;
1103 break;
1104 }
1105 context->update = isEncrypt ? SFTKCipher_RC2_Encrypt : SFTKCipher_RC2_Decrypt;
1106 context->destroy = SFTKCipher_RC2_DestroyContext;
1107 break;
1108#endif /* NSS_DISABLE_DEPRECATED_RC2 */
1109
1110#if NSS_SOFTOKEN_DOES_RC5
1111 case CKM_RC5_CBC_PAD0x00000335UL:
1112 context->doPad = PR_TRUE1;
1113 /* fall thru */
1114 case CKM_RC5_ECB0x00000331UL:
1115 case CKM_RC5_CBC0x00000332UL:
1116 if (key_type != CKK_RC50x00000019UL) {
1117 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1118 break;
1119 }
1120 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1121 if (att == NULL((void*)0)) {
1122 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1123 break;
1124 }
1125
1126 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_CBC_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_RC5_CBC_PARAMS))
) {
1127 sftk_FreeAttribute(att);
1128 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1129 break;
1130 }
1131 rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
1132 context->blockSize = rc5_param->ulWordsize * 2;
1133 rc5Key.data = (unsigned char *)att->attrib.pValue;
1134 rc5Key.len = att->attrib.ulValueLen;
1135 context->cipherInfo = RC5_CreateContext(&rc5Key, rc5_param->ulRounds,
1136 rc5_param->ulWordsize, rc5_param->pIv,
1137 pMechanism->mechanism == CKM_RC5_ECB0x00000331UL ? NSS_RC50 : NSS_RC5_CBC1);
1138 sftk_FreeAttribute(att);
1139 if (context->cipherInfo == NULL((void*)0)) {
1140 crv = CKR_HOST_MEMORY0x00000002UL;
1141 break;
1142 }
1143 context->update = isEncrypt ? SFTKCipher_RC5_Encrypt : SFTKCipher_RC5_Decrypt;
1144 context->destroy = SFTKCipher_RC5_DestroyContext;
1145 break;
1146#endif
1147 case CKM_RC40x00000111UL:
1148 if (key_type != CKK_RC40x00000012UL) {
1149 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1150 break;
1151 }
1152 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1153 if (att == NULL((void*)0)) {
1154 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1155 break;
1156 }
1157 context->cipherInfo =
1158 RC4_CreateContext((unsigned char *)att->attrib.pValue,
1159 att->attrib.ulValueLen);
1160 sftk_FreeAttribute(att);
1161 if (context->cipherInfo == NULL((void*)0)) {
1162 crv = CKR_HOST_MEMORY0x00000002UL; /* WRONG !!! */
1163 break;
1164 }
1165 context->update = isEncrypt ? SFTKCipher_RC4_Encrypt : SFTKCipher_RC4_Decrypt;
1166 context->destroy = SFTKCipher_RC4_DestroyContext;
1167 break;
1168 case CKM_CDMF_CBC_PAD0x00000145UL:
1169 context->doPad = PR_TRUE1;
1170 /* fall thru */
1171 case CKM_CDMF_ECB0x00000141UL:
1172 case CKM_CDMF_CBC0x00000142UL:
1173 if (key_type != CKK_CDMF0x0000001EUL) {
1174 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1175 break;
1176 }
1177 t = (pMechanism->mechanism == CKM_CDMF_ECB0x00000141UL) ? NSS_DES0 : NSS_DES_CBC1;
1178 goto finish_des;
1179 case CKM_DES_ECB0x00000121UL:
1180 if (key_type != CKK_DES0x00000013UL) {
1181 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1182 break;
1183 }
1184 t = NSS_DES0;
1185 goto finish_des;
1186 case CKM_DES_CBC_PAD0x00000125UL:
1187 context->doPad = PR_TRUE1;
1188 /* fall thru */
1189 case CKM_DES_CBC0x00000122UL:
1190 if (key_type != CKK_DES0x00000013UL) {
1191 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1192 break;
1193 }
1194 t = NSS_DES_CBC1;
1195 goto finish_des;
1196 case CKM_DES3_ECB0x00000132UL:
1197 if ((key_type != CKK_DES20x00000014UL) && (key_type != CKK_DES30x00000015UL)) {
1198 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1199 break;
1200 }
1201 t = NSS_DES_EDE32;
1202 goto finish_des;
1203 case CKM_DES3_CBC_PAD0x00000136UL:
1204 context->doPad = PR_TRUE1;
1205 /* fall thru */
1206 case CKM_DES3_CBC0x00000133UL:
1207 if ((key_type != CKK_DES20x00000014UL) && (key_type != CKK_DES30x00000015UL)) {
1208 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1209 break;
1210 }
1211 t = NSS_DES_EDE3_CBC3;
1212 finish_des:
1213 if ((t != NSS_DES0 && t != NSS_DES_EDE32) && (pMechanism->pParameter == NULL((void*)0) ||
1214 pMechanism->ulParameterLen < 8)) {
1215 crv = CKR_DOMAIN_PARAMS_INVALID0x00000130UL;
1216 break;
1217 }
1218 context->blockSize = 8;
1219 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1220 if (att == NULL((void*)0)) {
1221 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1222 break;
1223 }
1224 if (key_type == CKK_DES20x00000014UL &&
1225 (t == NSS_DES_EDE3_CBC3 || t == NSS_DES_EDE32)) {
1226 /* extend DES2 key to DES3 key. */
1227 memcpy(newdeskey, att->attrib.pValue, 16);
1228 memcpy(newdeskey + 16, newdeskey, 8);
1229 useNewKey = PR_TRUE1;
1230 } else if (key_type == CKK_CDMF0x0000001EUL) {
1231 crv = sftk_cdmf2des((unsigned char *)att->attrib.pValue, newdeskey);
1232 if (crv != CKR_OK0x00000000UL) {
1233 sftk_FreeAttribute(att);
1234 break;
1235 }
1236 useNewKey = PR_TRUE1;
1237 }
1238 context->cipherInfo = DES_CreateContext(
1239 useNewKey ? newdeskey : (unsigned char *)att->attrib.pValue,
1240 (unsigned char *)pMechanism->pParameter, t, isEncrypt);
1241 if (useNewKey)
1242 memset(newdeskey, 0, sizeof newdeskey);
1243 sftk_FreeAttribute(att);
1244 if (context->cipherInfo == NULL((void*)0)) {
1245 crv = CKR_HOST_MEMORY0x00000002UL;
1246 break;
1247 }
1248 context->update = isEncrypt ? SFTKCipher_DES_Encrypt : SFTKCipher_DES_Decrypt;
1249 context->destroy = SFTKCipher_DES_DestroyContext;
1250 break;
1251#ifndef NSS_DISABLE_DEPRECATED_SEED
1252 case CKM_SEED_CBC_PAD0x00000655UL:
1253 context->doPad = PR_TRUE1;
1254 /* fall thru */
1255 case CKM_SEED_CBC0x00000652UL:
1256 if (!pMechanism->pParameter ||
1257 pMechanism->ulParameterLen != 16) {
1258 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1259 break;
1260 }
1261 /* fall thru */
1262 case CKM_SEED_ECB0x00000651UL:
1263 context->blockSize = 16;
1264 if (key_type != CKK_SEED0x0000002FUL) {
1265 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1266 break;
1267 }
1268 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1269 if (att == NULL((void*)0)) {
1270 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1271 break;
1272 }
1273 context->cipherInfo = SEED_CreateContext(
1274 (unsigned char *)att->attrib.pValue,
1275 (unsigned char *)pMechanism->pParameter,
1276 pMechanism->mechanism == CKM_SEED_ECB0x00000651UL ? NSS_SEED0 : NSS_SEED_CBC1,
1277 isEncrypt);
1278 sftk_FreeAttribute(att);
1279 if (context->cipherInfo == NULL((void*)0)) {
1280 crv = CKR_HOST_MEMORY0x00000002UL;
1281 break;
1282 }
1283 context->update = isEncrypt ? SFTKCipher_SEED_Encrypt : SFTKCipher_SEED_Decrypt;
1284 context->destroy = SFTKCipher_SEED_DestroyContext;
1285 break;
1286#endif /* NSS_DISABLE_DEPRECATED_SEED */
1287 case CKM_CAMELLIA_CBC_PAD0x00000555UL:
1288 context->doPad = PR_TRUE1;
1289 /* fall thru */
1290 case CKM_CAMELLIA_CBC0x00000552UL:
1291 if (!pMechanism->pParameter ||
1292 pMechanism->ulParameterLen != 16) {
1293 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1294 break;
1295 }
1296 /* fall thru */
1297 case CKM_CAMELLIA_ECB0x00000551UL:
1298 context->blockSize = 16;
1299 if (key_type != CKK_CAMELLIA0x00000025UL) {
1300 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1301 break;
1302 }
1303 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1304 if (att == NULL((void*)0)) {
1305 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1306 break;
1307 }
1308 context->cipherInfo = Camellia_CreateContext(
1309 (unsigned char *)att->attrib.pValue,
1310 (unsigned char *)pMechanism->pParameter,
1311 pMechanism->mechanism ==
1312 CKM_CAMELLIA_ECB0x00000551UL
1313 ? NSS_CAMELLIA0
1314 : NSS_CAMELLIA_CBC1,
1315 isEncrypt, att->attrib.ulValueLen);
1316 sftk_FreeAttribute(att);
1317 if (context->cipherInfo == NULL((void*)0)) {
1318 crv = CKR_HOST_MEMORY0x00000002UL;
1319 break;
1320 }
1321 context->update = isEncrypt ? SFTKCipher_Camellia_Encrypt : SFTKCipher_Camellia_Decrypt;
1322 context->destroy = SFTKCipher_Camellia_DestroyContext;
1323 break;
1324
1325 case CKM_AES_CBC_PAD0x00001085UL:
1326 context->doPad = PR_TRUE1;
1327 /* fall thru */
1328 case CKM_AES_ECB0x00001081UL:
1329 case CKM_AES_CBC0x00001082UL:
1330 context->blockSize = 16;
1331 case CKM_AES_CTS0x00001089UL:
1332 case CKM_AES_CTR0x00001086UL:
1333 case CKM_AES_GCM0x00001087UL:
1334 aes_param = pMechanism->pParameter;
1335 /*
1336 * Due to a mismatch between the documentation and the header
1337 * file, two different definitions for CK_GCM_PARAMS exist.
1338 * The header file is normative according to Oasis, but NSS used
1339 * the documentation. In PKCS #11 v3.0, this was reconciled in
1340 * favor of the header file definition. To maintain binary
1341 * compatibility, NSS now defines CK_GCM_PARAMS_V3 as the official
1342 * version v3 (V2.4 header file) and CK_NSS_GCM_PARAMS as the
1343 * legacy (V2.4 documentation, NSS version). CK_GCM_PARAMS
1344 * is defined as CK_GCM_PARAMS_V3 if NSS_PKCS11_2_0_COMPAT is not
1345 * defined and CK_NSS_GCM_PARAMS if it is. Internally
1346 * softoken continues to use the legacy version. The code below
1347 * automatically detects which parameter was passed in and
1348 * converts CK_GCM_PARAMS_V3 to the CK_NSS_GCM_PARAMS (legacy
1349 * version) on the fly. NSS proper will eventually start
1350 * using the CK_GCM_PARAMS_V3 version and fall back to the
1351 * CK_NSS_GCM_PARAMS if the CK_GCM_PARAMS_V3 version fails with
1352 * CKR_MECHANISM_PARAM_INVALID.
1353 */
1354 if (pMechanism->mechanism == CKM_AES_GCM0x00001087UL) {
1355 if (!aes_param) {
1356 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1357 break;
1358 }
1359 if (pMechanism->ulParameterLen == sizeof(CK_GCM_PARAMS_V3)) {
1360 /* convert the true V3 parameters into the old NSS parameters */
1361 CK_GCM_PARAMS_V3 *gcm_params = (CK_GCM_PARAMS_V3 *)aes_param;
1362 if (gcm_params->ulIvLen * 8 != gcm_params->ulIvBits) {
1363 /* only support byte aligned IV lengths */
1364 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1365 break;
1366 }
1367 aes_param = (void *)&nss_gcm_param;
1368 nss_gcm_param.pIv = gcm_params->pIv;
1369 nss_gcm_param.ulIvLen = gcm_params->ulIvLen;
1370 nss_gcm_param.pAAD = gcm_params->pAAD;
1371 nss_gcm_param.ulAADLen = gcm_params->ulAADLen;
1372 nss_gcm_param.ulTagBits = gcm_params->ulTagBits;
1373 } else if (pMechanism->ulParameterLen != sizeof(CK_NSS_GCM_PARAMS)) {
1374 /* neither old nor new style params, must be invalid */
1375 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1376 break;
1377 }
1378 } 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))
) ||
1379 ((pMechanism->mechanism == CKM_AES_CBC0x00001082UL ||
1380 pMechanism->mechanism == CKM_AES_CBC_PAD0x00001085UL ||
1381 pMechanism->mechanism == CKM_AES_CTS0x00001089UL) &&
1382 BAD_PARAM_CAST(pMechanism, AES_BLOCK_SIZE)(!pMechanism->pParameter || pMechanism->ulParameterLen <
16)
)) {
1383 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1384 break;
1385 }
1386
1387 if (pMechanism->mechanism == CKM_AES_GCM0x00001087UL) {
1388 context->multi = PR_FALSE0;
1389 }
1390 if (key_type != CKK_AES0x0000001FUL) {
1391 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1392 break;
1393 }
1394 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1395 if (att == NULL((void*)0)) {
1396 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1397 break;
1398 }
1399 context->cipherInfo = AES_CreateContext(
1400 (unsigned char *)att->attrib.pValue,
1401 (unsigned char *)aes_param,
1402 sftk_aes_mode(pMechanism->mechanism),
1403 isEncrypt, att->attrib.ulValueLen, 16);
1404 sftk_FreeAttribute(att);
1405 if (context->cipherInfo == NULL((void*)0)) {
1406 crv = CKR_HOST_MEMORY0x00000002UL;
1407 break;
1408 }
1409 context->update = isEncrypt ? SFTKCipher_AES_Encrypt : SFTKCipher_AES_Decrypt;
1410 context->destroy = SFTKCipher_AES_DestroyContext;
1411 break;
1412
1413 case CKM_NSS_CHACHA20_POLY1305((0x80000000UL | 0x4E534350) + 28):
1414 case CKM_CHACHA20_POLY13050x00004021UL:
1415 if (pMechanism->mechanism == CKM_NSS_CHACHA20_POLY1305((0x80000000UL | 0x4E534350) + 28)) {
1416 if (key_type != CKK_NSS_CHACHA20((0x80000000UL | 0x4E534350) + 4)) {
1417 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1418 break;
1419 }
1420 if ((pMechanism->pParameter == NULL((void*)0)) ||
1421 (pMechanism->ulParameterLen != sizeof(CK_NSS_AEAD_PARAMS))) {
1422 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1423 break;
1424 }
1425 nss_aead_params_ptr = (CK_NSS_AEAD_PARAMS *)pMechanism->pParameter;
1426 } else {
1427 CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR chacha_poly_params;
1428 if (key_type != CKK_CHACHA200x00000033UL) {
1429 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1430 break;
1431 }
1432 if ((pMechanism->pParameter == NULL((void*)0)) ||
1433 (pMechanism->ulParameterLen !=
1434 sizeof(CK_SALSA20_CHACHA20_POLY1305_PARAMS))) {
1435 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1436 break;
1437 }
1438 chacha_poly_params = (CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR)
1439 pMechanism->pParameter;
1440 nss_aead_params_ptr = &nss_aead_params;
1441 nss_aead_params.pNonce = chacha_poly_params->pNonce;
1442 nss_aead_params.ulNonceLen = chacha_poly_params->ulNonceLen;
1443 nss_aead_params.pAAD = chacha_poly_params->pAAD;
1444 nss_aead_params.ulAADLen = chacha_poly_params->ulAADLen;
1445 nss_aead_params.ulTagLen = 16; /* Poly1305 is always 16 */
1446 }
1447
1448 context->multi = PR_FALSE0;
1449 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1450 if (att == NULL((void*)0)) {
1451 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1452 break;
1453 }
1454 context->cipherInfo = sftk_ChaCha20Poly1305_CreateContext(
1455 (unsigned char *)att->attrib.pValue, att->attrib.ulValueLen,
1456 nss_aead_params_ptr);
1457 sftk_FreeAttribute(att);
1458 if (context->cipherInfo == NULL((void*)0)) {
1459 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
1460 break;
1461 }
1462 context->update = isEncrypt ? sftk_ChaCha20Poly1305_Encrypt : sftk_ChaCha20Poly1305_Decrypt;
1463 context->destroy = sftk_ChaCha20Poly1305_DestroyContext;
1464 break;
1465
1466 case CKM_NSS_CHACHA20_CTR((0x80000000UL | 0x4E534350) + 33): /* old NSS private version */
1467 case CKM_CHACHA200x00001226UL: /* PKCS #11 v3 version */
1468 {
1469 unsigned char *counter;
1470 unsigned char *nonce;
1471 unsigned long counter_len;
1472 unsigned long nonce_len;
1473 context->multi = PR_FALSE0;
1474 if (pMechanism->mechanism == CKM_NSS_CHACHA20_CTR((0x80000000UL | 0x4E534350) + 33)) {
1475 if (key_type != CKK_NSS_CHACHA20((0x80000000UL | 0x4E534350) + 4)) {
1476 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1477 break;
1478 }
1479 if (pMechanism->pParameter == NULL((void*)0) || pMechanism->ulParameterLen != 16) {
1480 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1481 break;
1482 }
1483 counter_len = 4;
1484 counter = pMechanism->pParameter;
1485 nonce = counter + 4;
1486 nonce_len = 12;
1487 } else {
1488 CK_CHACHA20_PARAMS_PTR chacha20_param_ptr;
1489 if (key_type != CKK_CHACHA200x00000033UL) {
1490 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1491 break;
1492 }
1493 if (pMechanism->pParameter == NULL((void*)0) || pMechanism->ulParameterLen != sizeof(CK_CHACHA20_PARAMS)) {
1494 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1495 break;
1496 }
1497 chacha20_param_ptr = (CK_CHACHA20_PARAMS_PTR)pMechanism->pParameter;
1498 if ((chacha20_param_ptr->blockCounterBits != 32) &&
1499 (chacha20_param_ptr->blockCounterBits != 64)) {
1500 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1501 break;
1502 }
1503 counter_len = chacha20_param_ptr->blockCounterBits / PR_BITS_PER_BYTE8;
1504 counter = chacha20_param_ptr->pBlockCounter;
1505 nonce = chacha20_param_ptr->pNonce;
1506 nonce_len = chacha20_param_ptr->ulNonceBits / PR_BITS_PER_BYTE8;
1507 }
1508
1509 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1510 if (att == NULL((void*)0)) {
1511 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1512 break;
1513 }
1514 SFTKChaCha20CtrInfo *ctx = PORT_ZNew(SFTKChaCha20CtrInfo)(SFTKChaCha20CtrInfo *)PORT_ZAlloc_Util(sizeof(SFTKChaCha20CtrInfo
))
;
1515 if (!ctx) {
1516 sftk_FreeAttribute(att);
1517 crv = CKR_HOST_MEMORY0x00000002UL;
1518 break;
1519 }
1520 if (att->attrib.ulValueLen != sizeof(ctx->key)) {
1521 sftk_FreeAttribute(att);
1522 PORT_FreePORT_Free_Util(ctx);
1523 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1524 break;
1525 }
1526 memcpy(ctx->key, att->attrib.pValue, att->attrib.ulValueLen);
1527 sftk_FreeAttribute(att);
1528
1529 /* make sure we don't overflow our parameters */
1530 if ((sizeof(ctx->counter) < counter_len) ||
1531 (sizeof(ctx->nonce) < nonce_len)) {
1532 PORT_FreePORT_Free_Util(ctx);
1533 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1534 break;
1535 }
1536
1537 /* The counter is little endian. */
1538 int i = 0;
1539 for (; i < counter_len; ++i) {
1540 ctx->counter |= (PRUint32)counter[i] << (i * 8);
1541 }
1542 memcpy(ctx->nonce, nonce, nonce_len);
1543 context->cipherInfo = ctx;
1544 context->update = sftk_ChaCha20Ctr;
1545 context->destroy = sftk_ChaCha20Ctr_DestroyContext;
1546 break;
1547 }
1548
1549 case CKM_NSS_AES_KEY_WRAP_PAD((0x80000000UL | 0x4E534350) + 2):
1550 case CKM_AES_KEY_WRAP_PAD0x0000210AUL:
1551 context->doPad = PR_TRUE1;
1552 /* fall thru */
1553 case CKM_NSS_AES_KEY_WRAP((0x80000000UL | 0x4E534350) + 1):
1554 case CKM_AES_KEY_WRAP0x00002109UL:
1555 context->blockSize = 8;
1556 context->multi = PR_FALSE0;
1557 if (key_type != CKK_AES0x0000001FUL) {
1558 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1559 break;
1560 }
1561 /* pParameter is an optional custom IV; if provided it must be
1562 * exactly AES_KEY_WRAP_IV_BYTES long to avoid an over-read in
1563 * AESKeyWrap_InitContext. */
1564 if (pMechanism->pParameter != NULL((void*)0) &&
1565 pMechanism->ulParameterLen != AES_KEY_WRAP_IV_BYTES(16 / 2)) {
1566 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1567 break;
1568 }
1569 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1570 if (att == NULL((void*)0)) {
1571 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1572 break;
1573 }
1574 context->cipherInfo = AESKeyWrap_CreateContext(
1575 (unsigned char *)att->attrib.pValue,
1576 (unsigned char *)pMechanism->pParameter,
1577 isEncrypt, att->attrib.ulValueLen);
1578 sftk_FreeAttribute(att);
1579 if (context->cipherInfo == NULL((void*)0)) {
1580 crv = CKR_HOST_MEMORY0x00000002UL;
1581 break;
1582 }
1583 context->update = isEncrypt ? SFTKCipher_AESKeyWrap_Encrypt
1584 : SFTKCipher_AESKeyWrap_Decrypt;
1585 context->destroy = SFTKCipher_AESKeyWrap_DestroyContext;
1586 break;
1587
1588 case CKM_AES_KEY_WRAP_KWP0x0000210BUL:
1589 /* KWP (RFC 5649) uses a fixed built-in AIV; no user-supplied IV
1590 * is accepted. */
1591 if (pMechanism->pParameter != NULL((void*)0) || pMechanism->ulParameterLen != 0) {
1592 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
1593 break;
1594 }
1595 context->multi = PR_FALSE0;
1596 if (key_type != CKK_AES0x0000001FUL) {
1597 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
1598 break;
1599 }
1600 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
1601 if (att == NULL((void*)0)) {
1602 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
1603 break;
1604 }
1605 context->cipherInfo = AESKeyWrap_CreateContext(
1606 (unsigned char *)att->attrib.pValue,
1607 NULL((void*)0), /* always use built-in AIV for KWP */
1608 isEncrypt, (unsigned int)att->attrib.ulValueLen);
1609 sftk_FreeAttribute(att);
1610 if (context->cipherInfo == NULL((void*)0)) {
1611 crv = CKR_HOST_MEMORY0x00000002UL;
1612 break;
1613 }
1614 context->update = isEncrypt ? SFTKCipher_AESKeyWrap_EncryptKWP
1615 : SFTKCipher_AESKeyWrap_DecryptKWP;
1616 context->destroy = SFTKCipher_AESKeyWrap_DestroyContext;
1617 break;
1618
1619 default:
1620 crv = CKR_MECHANISM_INVALID0x00000070UL;
1621 break;
1622 }
1623
1624 if (crv != CKR_OK0x00000000UL) {
1625 sftk_FreeContext(context);
1626 sftk_FreeSession(session);
1627 return crv;
1628 }
1629 crv = sftk_InstallContext(session, contextType, context);
1630 if (crv != CKR_OK0x00000000UL) {
1631 sftk_FreeContext(context);
1632 }
1633 sftk_FreeSession(session);
1634 return crv;
1635}
1636
1637/* NSC_EncryptInit initializes an encryption operation. */
1638CK_RV
1639NSC_EncryptInit(CK_SESSION_HANDLE hSession,
1640 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
1641{
1642 CHECK_FORK();
1643 return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT0x00000104UL, CKA_ENCRYPT0x00000104UL,
1644 SFTK_ENCRYPT, PR_TRUE1);
1645}
1646
1647/* NSC_EncryptUpdate continues a multiple-part encryption operation. */
1648CK_RV
1649NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
1650 CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
1651 CK_ULONG_PTR pulEncryptedPartLen)
1652{
1653 SFTKSession *session;
1654 SFTKSessionContext *context;
1655 unsigned int outlen, i;
1656 unsigned int padoutlen = 0;
1657 unsigned int maxout = *pulEncryptedPartLen;
1658 CK_RV crv;
1659 SECStatus rv;
1660
1661 CHECK_FORK();
1662
1663 /* Hold the session reference for the duration of the context deref;
1664 * see comment on NSC_DigestUpdate. */
1665 crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE1, &session);
1666 if (crv != CKR_OK0x00000000UL)
1667 return crv;
1668
1669 if (!pEncryptedPart) {
1670 if (context->doPad) {
1671 CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength;
1672 CK_ULONG blocksToSend = totalDataAvailable / context->blockSize;
1673
1674 *pulEncryptedPartLen = blocksToSend * context->blockSize;
1675 goto finish;
1676 }
1677 *pulEncryptedPartLen = ulPartLen;
1678 goto finish;
1679 }
1680
1681 /* do padding */
1682 if (context->doPad) {
1683 /* deal with previous buffered data */
1684 if (context->padDataLength != 0) {
1685 /* fill in the padded to a full block size */
1686 for (i = context->padDataLength;
1687 (ulPartLen != 0) && i < context->blockSize; i++) {
1688 context->padBuf[i] = *pPart++;
1689 ulPartLen--;
1690 context->padDataLength++;
1691 }
1692
1693 /* not enough data to encrypt yet? then return */
1694 if (context->padDataLength != context->blockSize) {
1695 *pulEncryptedPartLen = 0;
1696 goto finish;
1697 }
1698 /* encrypt the current padded data */
1699 rv = (*context->update)(context->cipherInfo, pEncryptedPart,
1700 &padoutlen, maxout, context->padBuf,
1701 context->blockSize);
1702 if (rv != SECSuccess) {
1703 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
1704 goto finish;
1705 }
1706 pEncryptedPart += padoutlen;
1707 maxout -= padoutlen;
1708 }
1709 /* save the residual */
1710 context->padDataLength = ulPartLen % context->blockSize;
1711 if (context->padDataLength) {
1712 PORT_Memcpymemcpy(context->padBuf,
1713 &pPart[ulPartLen - context->padDataLength],
1714 context->padDataLength);
1715 ulPartLen -= context->padDataLength;
1716 }
1717 /* if we've exhausted our new buffer, we're done */
1718 if (ulPartLen == 0) {
1719 *pulEncryptedPartLen = padoutlen;
1720 goto finish;
1721 }
1722 }
1723
1724 /* do it: NOTE: this assumes buf size in is >= buf size out! */
1725 rv = (*context->update)(context->cipherInfo, pEncryptedPart,
1726 &outlen, maxout, pPart, ulPartLen);
1727 if (rv != SECSuccess) {
1728 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
1729 goto finish;
1730 }
1731 *pulEncryptedPartLen = (CK_ULONG)(outlen + padoutlen);
1732finish:
1733 sftk_FreeSession(session);
1734 return crv;
1735}
1736
1737/* NSC_EncryptFinal finishes a multiple-part encryption operation. */
1738CK_RV
1739NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
1740 CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
1741{
1742 SFTKSession *session;
1743 SFTKSessionContext *context;
1744 unsigned int outlen, i;
1745 unsigned int maxout = *pulLastEncryptedPartLen;
1746 CK_RV crv;
1747 SECStatus rv = SECSuccess;
1748 PRBool contextFinished = PR_TRUE1;
1749
1750 CHECK_FORK();
1751
1752 /* make sure we're legal */
1753 crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE1, &session);
1754 if (crv != CKR_OK0x00000000UL)
1755 return crv;
1756
1757 *pulLastEncryptedPartLen = 0;
1758 if (!pLastEncryptedPart) {
1759 /* caller is checking the amount of remaining data */
1760 if (context->blockSize > 0 && context->doPad) {
1761 *pulLastEncryptedPartLen = context->blockSize;
1762 contextFinished = PR_FALSE0; /* still have padding to go */
1763 }
1764 goto finish;
1765 }
1766
1767 /* do padding */
1768 if (context->doPad) {
1769 unsigned char padbyte = (unsigned char)(context->blockSize - context->padDataLength);
1770 /* fill out rest of pad buffer with pad magic*/
1771 for (i = context->padDataLength; i < context->blockSize; i++) {
1772 context->padBuf[i] = padbyte;
1773 }
1774 rv = (*context->update)(context->cipherInfo, pLastEncryptedPart,
1775 &outlen, maxout, context->padBuf, context->blockSize);
1776 if (rv == SECSuccess)
1777 *pulLastEncryptedPartLen = (CK_ULONG)outlen;
1778 }
1779
1780finish:
1781 if (contextFinished)
1782 sftk_TerminateOp(session, SFTK_ENCRYPT);
1783 sftk_FreeSession(session);
1784 return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
1785}
1786
1787/* NSC_Encrypt encrypts single-part data. */
1788CK_RV
1789NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
1790 CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
1791 CK_ULONG_PTR pulEncryptedDataLen)
1792{
1793 SFTKSession *session;
1794 SFTKSessionContext *context;
1795 unsigned int outlen;
1796 unsigned int maxoutlen = *pulEncryptedDataLen;
1797 CK_RV crv;
1798 CK_RV crv2;
1799 SECStatus rv = SECSuccess;
1800 SECItem pText;
1801
1802 pText.type = siBuffer;
1803 pText.data = pData;
1804 pText.len = ulDataLen;
1805
1806 CHECK_FORK();
1807
1808 /* make sure we're legal */
1809 crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_FALSE0, &session);
1810 if (crv != CKR_OK0x00000000UL)
1811 return crv;
1812
1813 if (!pEncryptedData) {
1814 outlen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize;
1815 goto done;
1816 }
1817
1818 if (context->doPad) {
1819 if (context->multi) {
1820 CK_ULONG updateLen = maxoutlen;
1821 CK_ULONG finalLen;
1822 /* padding is fairly complicated, have the update and final
1823 * code deal with it */
1824 sftk_FreeSession(session);
1825 crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData,
1826 &updateLen);
1827 if (crv != CKR_OK0x00000000UL) {
1828 updateLen = 0;
1829 }
1830 maxoutlen -= updateLen;
1831 pEncryptedData += updateLen;
1832 finalLen = maxoutlen;
1833 crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
1834 if (crv == CKR_OK0x00000000UL && crv2 == CKR_OK0x00000000UL) {
1835 *pulEncryptedDataLen = updateLen + finalLen;
1836 }
1837 return crv == CKR_OK0x00000000UL ? crv2 : crv;
1838 }
1839 /* doPad without multi means that padding must be done on the first
1840 ** and only update. There will be no final.
1841 */
1842 PORT_Assert(context->blockSize > 1)((context->blockSize > 1) ? ((void)0) : PR_Assert("context->blockSize > 1"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 1842
))
;
1843 if (context->blockSize > 1) {
1844 CK_ULONG remainder = ulDataLen % context->blockSize;
1845 CK_ULONG padding = context->blockSize - remainder;
1846 pText.len += padding;
1847 pText.data = PORT_ZAllocPORT_ZAlloc_Util(pText.len);
1848 if (pText.data) {
1849 memcpy(pText.data, pData, ulDataLen);
1850 memset(pText.data + ulDataLen, padding, padding);
1851 } else {
1852 crv = CKR_HOST_MEMORY0x00000002UL;
1853 goto fail;
1854 }
1855 }
1856 }
1857
1858 /* do it: NOTE: this assumes buf size is big enough. */
1859 rv = (*context->update)(context->cipherInfo, pEncryptedData,
1860 &outlen, maxoutlen, pText.data, pText.len);
1861 crv = (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
1862 if (pText.data != pData)
1863 PORT_ZFreePORT_ZFree_Util(pText.data, pText.len);
1864fail:
1865 sftk_TerminateOp(session, SFTK_ENCRYPT);
1866done:
1867 sftk_FreeSession(session);
1868 if (crv == CKR_OK0x00000000UL) {
1869 *pulEncryptedDataLen = (CK_ULONG)outlen;
1870 }
1871 return crv;
1872}
1873
1874/*
1875 ************** Crypto Functions: Decrypt ************************
1876 */
1877
1878/* NSC_DecryptInit initializes a decryption operation. */
1879CK_RV
1880NSC_DecryptInit(CK_SESSION_HANDLE hSession,
1881 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
1882{
1883 CHECK_FORK();
1884 return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT0x00000105UL, CKA_DECRYPT0x00000105UL,
1885 SFTK_DECRYPT, PR_FALSE0);
1886}
1887
1888/* NSC_DecryptUpdate continues a multiple-part decryption operation. */
1889CK_RV
1890NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
1891 CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
1892 CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
1893{
1894 SFTKSession *session;
1895 SFTKSessionContext *context;
1896 unsigned int padoutlen = 0;
1897 unsigned int outlen;
1898 unsigned int maxout = *pulPartLen;
1899 CK_RV crv;
1900 SECStatus rv;
1901
1902 CHECK_FORK();
1903
1904 /* Hold the session reference for the duration of the context deref;
1905 * see comment on NSC_DigestUpdate. */
1906 crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE1, &session);
1907 if (crv != CKR_OK0x00000000UL)
1908 return crv;
1909
1910 /* this can only happen on an NSS programming error */
1911 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"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 1911
))
;
1912
1913 if (context->doPad) {
1914 /* Check the data length for block ciphers. If we are padding,
1915 * then we must be using a block cipher. In the non-padding case
1916 * the error will be returned by the underlying decryption
1917 * function when we do the actual decrypt. We need to do the
1918 * check here to avoid returning a negative length to the caller
1919 * or reading before the beginning of the pEncryptedPart buffer.
1920 */
1921 if ((ulEncryptedPartLen == 0) ||
1922 (ulEncryptedPartLen % context->blockSize) != 0) {
1923 crv = CKR_ENCRYPTED_DATA_LEN_RANGE0x00000041UL;
1924 goto finish;
1925 }
1926 }
1927
1928 if (!pPart) {
1929 if (context->doPad) {
1930 *pulPartLen =
1931 ulEncryptedPartLen + context->padDataLength - context->blockSize;
1932 goto finish;
1933 }
1934 /* for stream ciphers there is are no constraints on ulEncryptedPartLen.
1935 * for block ciphers, it must be a multiple of blockSize. The error is
1936 * detected when this function is called again do decrypt the output.
1937 */
1938 *pulPartLen = ulEncryptedPartLen;
1939 goto finish;
1940 }
1941
1942 if (context->doPad) {
1943 /* first decrypt our saved buffer */
1944 if (context->padDataLength != 0) {
1945 rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
1946 maxout, context->padBuf, context->blockSize);
1947 if (rv != SECSuccess) {
1948 crv = sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util());
1949 goto finish;
1950 }
1951 pPart += padoutlen;
1952 maxout -= padoutlen;
1953 }
1954 /* now save the final block for the next decrypt or the final */
1955 PORT_Memcpymemcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize],
1956 context->blockSize);
1957 context->padDataLength = context->blockSize;
1958 ulEncryptedPartLen -= context->padDataLength;
1959 }
1960
1961 /* do it: NOTE: this assumes buf size in is >= buf size out! */
1962 rv = (*context->update)(context->cipherInfo, pPart, &outlen,
1963 maxout, pEncryptedPart, ulEncryptedPartLen);
1964 if (rv != SECSuccess) {
1965 crv = sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util());
1966 goto finish;
1967 }
1968 *pulPartLen = (CK_ULONG)(outlen + padoutlen);
1969finish:
1970 sftk_FreeSession(session);
1971 return crv;
1972}
1973
1974/* NSC_DecryptFinal finishes a multiple-part decryption operation. */
1975CK_RV
1976NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
1977 CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
1978{
1979 SFTKSession *session;
1980 SFTKSessionContext *context;
1981 unsigned int outlen;
1982 unsigned int maxout = *pulLastPartLen;
1983 CK_RV crv;
1984 SECStatus rv = SECSuccess;
1985
1986 CHECK_FORK();
1987
1988 /* make sure we're legal */
1989 crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE1, &session);
1990 if (crv != CKR_OK0x00000000UL)
1991 return crv;
1992
1993 *pulLastPartLen = 0;
1994 if (!pLastPart) {
1995 /* caller is checking the amount of remaining data */
1996 if (context->padDataLength > 0) {
1997 *pulLastPartLen = context->padDataLength;
1998 }
1999 goto finish;
2000 }
2001
2002 if (context->doPad) {
2003 /* decrypt our saved buffer */
2004 if (context->padDataLength != 0) {
2005 /* this assumes that pLastPart is big enough to hold the *whole*
2006 * buffer!!! */
2007 rv = (*context->update)(context->cipherInfo, pLastPart, &outlen,
2008 maxout, context->padBuf, context->blockSize);
2009 if (rv != SECSuccess) {
2010 crv = sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util());
2011 } else {
2012 unsigned int padSize = 0;
2013 crv = sftk_CheckCBCPadding(pLastPart, outlen,
2014 context->blockSize, &padSize);
2015 /* Update pulLastPartLen, in constant time, if crv is OK */
2016 *pulLastPartLen = PORT_CT_SEL(sftk_CKRVToMask(crv), outlen - padSize, *pulLastPartLen)(((sftk_CKRVToMask(crv)) & (outlen - padSize)) | (~(sftk_CKRVToMask
(crv)) & (*pulLastPartLen)))
;
2017 }
2018 }
2019 }
2020
2021 sftk_TerminateOp(session, SFTK_DECRYPT);
2022finish:
2023 sftk_FreeSession(session);
2024 return crv;
2025}
2026
2027/* NSC_Decrypt decrypts encrypted data in a single part. */
2028CK_RV
2029NSC_Decrypt(CK_SESSION_HANDLE hSession,
2030 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,
2031 CK_ULONG_PTR pulDataLen)
2032{
2033 SFTKSession *session;
2034 SFTKSessionContext *context;
2035 unsigned int outlen;
2036 unsigned int maxoutlen = *pulDataLen;
2037 CK_RV crv;
2038 CK_RV crv2;
2039 SECStatus rv = SECSuccess;
2040
2041 CHECK_FORK();
2042
2043 /* make sure we're legal */
2044 crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_FALSE0, &session);
2045 if (crv != CKR_OK0x00000000UL)
2046 return crv;
2047
2048 if (!pData) {
2049 *pulDataLen = (CK_ULONG)(ulEncryptedDataLen + context->blockSize);
2050 goto done;
2051 }
2052
2053 if (context->doPad && context->multi) {
2054 CK_ULONG updateLen = maxoutlen;
2055 CK_ULONG finalLen;
2056 /* padding is fairly complicated, have the update and final
2057 * code deal with it */
2058 sftk_FreeSession(session);
2059 crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
2060 pData, &updateLen);
2061 if (crv == CKR_OK0x00000000UL) {
2062 maxoutlen -= updateLen;
2063 pData += updateLen;
2064 }
2065 finalLen = maxoutlen;
2066 crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
2067 if (crv == CKR_OK0x00000000UL) {
2068 *pulDataLen = PORT_CT_SEL(sftk_CKRVToMask(crv2), updateLen + finalLen, *pulDataLen)(((sftk_CKRVToMask(crv2)) & (updateLen + finalLen)) | (~(
sftk_CKRVToMask(crv2)) & (*pulDataLen)))
;
2069 return crv2;
2070 } else {
2071 return crv;
2072 }
2073 }
2074
2075 rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
2076 pEncryptedData, ulEncryptedDataLen);
2077 /* XXX need to do MUCH better error mapping than this. */
2078 crv = (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapDecryptError(PORT_GetErrorPORT_GetError_Util());
2079 if (rv == SECSuccess) {
2080 if (context->doPad) {
2081 unsigned int padSize = 0;
2082 crv = sftk_CheckCBCPadding(pData, outlen, context->blockSize,
2083 &padSize);
2084 /* Update pulDataLen, in constant time, if crv is OK */
2085 *pulDataLen = PORT_CT_SEL(sftk_CKRVToMask(crv), outlen - padSize, *pulDataLen)(((sftk_CKRVToMask(crv)) & (outlen - padSize)) | (~(sftk_CKRVToMask
(crv)) & (*pulDataLen)))
;
2086 } else {
2087 *pulDataLen = (CK_ULONG)outlen;
2088 }
2089 }
2090 sftk_TerminateOp(session, SFTK_DECRYPT);
2091done:
2092 sftk_FreeSession(session);
2093 return crv;
2094}
2095
2096/*
2097 ************** Crypto Functions: Digest (HASH) ************************
2098 */
2099
2100/* NSC_DigestInit initializes a message-digesting operation. */
2101CK_RV
2102NSC_DigestInit(CK_SESSION_HANDLE hSession,
2103 CK_MECHANISM_PTR pMechanism)
2104{
2105 SFTKSession *session;
2106 SFTKSessionContext *context;
2107 CK_RV crv = CKR_OK0x00000000UL;
2108
2109 CHECK_FORK();
2110
2111 session = sftk_SessionFromHandle(hSession);
2112 if (session == NULL((void*)0))
2113 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
2114 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_HASH,
2115 NULL((void*)0), 0, NULL((void*)0), 0, CKA_DIGEST0x81000000L);
2116 if (crv != CKR_OK0x00000000UL) {
2117 sftk_FreeSession(session);
2118 return crv;
2119 }
2120
2121#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
= SFTKHash_mmm_End; context->destroy = SFTKHash_mmm_DestroyContext
; context->maxLen = mmm_LENGTH; if (mmm_ctx) mmm_Begin(mmm_ctx
); else crv = 0x00000002UL; break; }
\
2122 case CKM_##mmm: { \
2123 mmm##Context *mmm##_ctx = mmm##_NewContext(); \
2124 context->cipherInfo = (void *)mmm##_ctx; \
2125 context->cipherInfoLen = mmm##_FlattenSize(mmm##_ctx); \
2126 context->currentMech = CKM_##mmm; \
2127 context->hashUpdate = SFTKHash_##mmm##_Update; \
2128 context->end = SFTKHash_##mmm##_End; \
2129 context->destroy = SFTKHash_##mmm##_DestroyContext; \
2130 context->maxLen = mmm##_LENGTH; \
2131 if (mmm##_ctx) \
2132 mmm##_Begin(mmm##_ctx); \
2133 else \
2134 crv = CKR_HOST_MEMORY0x00000002UL; \
2135 break; \
2136 }
2137
2138 switch (pMechanism->mechanism) {
2139 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
= SFTKHash_MD2_End; context->destroy = SFTKHash_MD2_DestroyContext
; context->maxLen = 16; if (MD2_ctx) MD2_Begin(MD2_ctx); else
crv = 0x00000002UL; break; }
2140 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
= SFTKHash_MD5_End; context->destroy = SFTKHash_MD5_DestroyContext
; context->maxLen = 16; if (MD5_ctx) MD5_Begin(MD5_ctx); else
crv = 0x00000002UL; break; }
2141 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 = SFTKHash_SHA1_End; context->destroy = SFTKHash_SHA1_DestroyContext
; context->maxLen = 20; if (SHA1_ctx) SHA1_Begin(SHA1_ctx)
; else crv = 0x00000002UL; break; }
2142 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 = SFTKHash_SHA224_End; context->destroy =
SFTKHash_SHA224_DestroyContext; context->maxLen = 28; if (
SHA224_ctx) SHA224_Begin(SHA224_ctx); else crv = 0x00000002UL
; break; }
2143 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 = SFTKHash_SHA256_End; context->destroy =
SFTKHash_SHA256_DestroyContext; context->maxLen = 32; if (
SHA256_ctx) SHA256_Begin(SHA256_ctx); else crv = 0x00000002UL
; break; }
2144 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 = SFTKHash_SHA384_End; context->destroy =
SFTKHash_SHA384_DestroyContext; context->maxLen = 48; if (
SHA384_ctx) SHA384_Begin(SHA384_ctx); else crv = 0x00000002UL
; break; }
2145 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 = SFTKHash_SHA512_End; context->destroy =
SFTKHash_SHA512_DestroyContext; context->maxLen = 64; if (
SHA512_ctx) SHA512_Begin(SHA512_ctx); else crv = 0x00000002UL
; break; }
2146 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 = SFTKHash_SHA3_224_End; context->destroy
= SFTKHash_SHA3_224_DestroyContext; context->maxLen = 28;
if (SHA3_224_ctx) SHA3_224_Begin(SHA3_224_ctx); else crv = 0x00000002UL
; break; }
2147 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 = SFTKHash_SHA3_256_End; context->destroy
= SFTKHash_SHA3_256_DestroyContext; context->maxLen = 32;
if (SHA3_256_ctx) SHA3_256_Begin(SHA3_256_ctx); else crv = 0x00000002UL
; break; }
2148 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 = SFTKHash_SHA3_384_End; context->destroy
= SFTKHash_SHA3_384_DestroyContext; context->maxLen = 48;
if (SHA3_384_ctx) SHA3_384_Begin(SHA3_384_ctx); else crv = 0x00000002UL
; break; }
2149 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 = SFTKHash_SHA3_512_End; context->destroy
= SFTKHash_SHA3_512_DestroyContext; context->maxLen = 64;
if (SHA3_512_ctx) SHA3_512_Begin(SHA3_512_ctx); else crv = 0x00000002UL
; break; }
2150
2151 default:
2152 crv = CKR_MECHANISM_INVALID0x00000070UL;
2153 break;
2154 }
2155
2156 if (crv != CKR_OK0x00000000UL) {
2157 sftk_FreeContext(context);
2158 sftk_FreeSession(session);
2159 return crv;
2160 }
2161 crv = sftk_InstallContext(session, SFTK_HASH, context);
2162 if (crv != CKR_OK0x00000000UL) {
2163 sftk_FreeContext(context);
2164 }
2165 sftk_FreeSession(session);
2166 return crv;
2167}
2168
2169/* NSC_Digest digests data in a single part. */
2170CK_RV
2171NSC_Digest(CK_SESSION_HANDLE hSession,
2172 CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest,
2173 CK_ULONG_PTR pulDigestLen)
2174{
2175 SFTKSession *session;
2176 SFTKSessionContext *context;
2177 unsigned int digestLen;
2178 unsigned int maxout = *pulDigestLen;
2179 CK_RV crv;
2180
2181 CHECK_FORK();
2182
2183 /* make sure we're legal */
2184 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_FALSE0, &session);
2185 if (crv != CKR_OK0x00000000UL)
2186 return crv;
2187
2188 if (pDigest == NULL((void*)0)) {
2189 *pulDigestLen = context->maxLen;
2190 goto finish;
2191 }
2192
2193#if (ULONG_MAX(9223372036854775807L *2UL+1UL) > UINT_MAX(2147483647 *2U +1U))
2194 /* The context->hashUpdate function takes an unsigned int for its data
2195 * length argument, but NSC_Digest takes an unsigned long. */
2196 while (ulDataLen > UINT_MAX(2147483647 *2U +1U)) {
2197 (*context->hashUpdate)(context->cipherInfo, pData, UINT_MAX(2147483647 *2U +1U));
2198 pData += UINT_MAX(2147483647 *2U +1U);
2199 ulDataLen -= UINT_MAX(2147483647 *2U +1U);
2200 }
2201#endif
2202 (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen);
2203
2204 /* NOTE: this assumes buf size is bigenough for the algorithm */
2205 (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
2206 *pulDigestLen = digestLen;
2207
2208 sftk_TerminateOp(session, SFTK_HASH);
2209finish:
2210 sftk_FreeSession(session);
2211 return CKR_OK0x00000000UL;
2212}
2213
2214/* NSC_DigestUpdate continues a multiple-part message-digesting operation. */
2215CK_RV
2216NSC_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
2217 CK_ULONG ulPartLen)
2218{
2219 SFTKSession *session;
2220 SFTKSessionContext *context;
2221 CK_RV crv;
2222
2223 CHECK_FORK();
2224
2225 /* Hold the session reference for the duration of the context deref:
2226 * without it, a concurrent NSC_CloseSession could drive refCount to 0
2227 * inside sftk_GetContext, destroying the session (and freeing the
2228 * context) before we touch context->hashUpdate. */
2229 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, &session);
2230 if (crv != CKR_OK0x00000000UL)
2231 return crv;
2232
2233#if (ULONG_MAX(9223372036854775807L *2UL+1UL) > UINT_MAX(2147483647 *2U +1U))
2234 /* The context->hashUpdate function takes an unsigned int for its data
2235 * length argument, but NSC_DigestUpdate takes an unsigned long. */
2236 while (ulPartLen > UINT_MAX(2147483647 *2U +1U)) {
2237 (*context->hashUpdate)(context->cipherInfo, pPart, UINT_MAX(2147483647 *2U +1U));
2238 pPart += UINT_MAX(2147483647 *2U +1U);
2239 ulPartLen -= UINT_MAX(2147483647 *2U +1U);
2240 }
2241#endif
2242 (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen);
2243
2244 sftk_FreeSession(session);
2245 return CKR_OK0x00000000UL;
2246}
2247
2248/* NSC_DigestFinal finishes a multiple-part message-digesting operation. */
2249CK_RV
2250NSC_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
2251 CK_ULONG_PTR pulDigestLen)
2252{
2253 SFTKSession *session;
2254 SFTKSessionContext *context;
2255 unsigned int maxout = *pulDigestLen;
2256 unsigned int digestLen;
2257 CK_RV crv;
2258
2259 CHECK_FORK();
2260
2261 /* make sure we're legal */
2262 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, &session);
2263 if (crv != CKR_OK0x00000000UL)
2264 return crv;
2265
2266 if (pDigest != NULL((void*)0)) {
2267 (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
2268 *pulDigestLen = digestLen;
2269 sftk_TerminateOp(session, SFTK_HASH);
2270 } else {
2271 *pulDigestLen = context->maxLen;
2272 }
2273
2274 sftk_FreeSession(session);
2275 return CKR_OK0x00000000UL;
2276}
2277
2278/*
2279 * these helper functions are used by Generic Macing and Signing functions
2280 * that use hashes as part of their operations.
2281 */
2282#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 = SFTKHash_mmm_End; context->hashdestroy = SFTKHash_mmm_DestroyContext
; if (!context->hashInfo) { return 0x00000002UL; } mmm_Begin
(mmm_ctx); return 0x00000000UL; }
\
2283 static CK_RV \
2284 sftk_doSub##mmm(SFTKSessionContext *context) \
2285 { \
2286 mmm##Context *mmm##_ctx = mmm##_NewContext(); \
2287 context->hashInfo = (void *)mmm##_ctx; \
2288 context->hashUpdate = SFTKHash_##mmm##_Update; \
2289 context->end = SFTKHash_##mmm##_End; \
2290 context->hashdestroy = SFTKHash_##mmm##_DestroyContext; \
2291 if (!context->hashInfo) { \
2292 return CKR_HOST_MEMORY0x00000002UL; \
2293 } \
2294 mmm##_Begin(mmm##_ctx); \
2295 return CKR_OK0x00000000UL; \
2296 }
2297
2298DOSUB(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 = SFTKHash_MD2_End; context->hashdestroy = SFTKHash_MD2_DestroyContext
; if (!context->hashInfo) { return 0x00000002UL; } MD2_Begin
(MD2_ctx); return 0x00000000UL; }
2299DOSUB(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 = SFTKHash_MD5_End; context->hashdestroy = SFTKHash_MD5_DestroyContext
; if (!context->hashInfo) { return 0x00000002UL; } MD5_Begin
(MD5_ctx); return 0x00000000UL; }
2300DOSUB(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 = SFTKHash_SHA1_End; context->hashdestroy = SFTKHash_SHA1_DestroyContext
; if (!context->hashInfo) { return 0x00000002UL; } SHA1_Begin
(SHA1_ctx); return 0x00000000UL; }
2301DOSUB(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 = SFTKHash_SHA224_End; context->hashdestroy
= SFTKHash_SHA224_DestroyContext; if (!context->hashInfo)
{ return 0x00000002UL; } SHA224_Begin(SHA224_ctx); return 0x00000000UL
; }
2302DOSUB(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 = SFTKHash_SHA256_End; context->hashdestroy
= SFTKHash_SHA256_DestroyContext; if (!context->hashInfo)
{ return 0x00000002UL; } SHA256_Begin(SHA256_ctx); return 0x00000000UL
; }
2303DOSUB(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 = SFTKHash_SHA384_End; context->hashdestroy
= SFTKHash_SHA384_DestroyContext; if (!context->hashInfo)
{ return 0x00000002UL; } SHA384_Begin(SHA384_ctx); return 0x00000000UL
; }
2304DOSUB(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 = SFTKHash_SHA512_End; context->hashdestroy
= SFTKHash_SHA512_DestroyContext; if (!context->hashInfo)
{ return 0x00000002UL; } SHA512_Begin(SHA512_ctx); return 0x00000000UL
; }
2305
2306static SECStatus
2307sftk_SignCopy(
2308 void *copyLen,
2309 unsigned char *out, unsigned int *outLength,
2310 unsigned int maxLength,
2311 const unsigned char *hashResult,
2312 unsigned int hashResultLength)
2313{
2314 unsigned int toCopy = *(CK_ULONG *)copyLen;
2315 if (toCopy > maxLength) {
2316 toCopy = maxLength;
2317 }
2318 if (toCopy > hashResultLength) {
2319 toCopy = hashResultLength;
2320 }
2321 memcpy(out, hashResult, toCopy);
2322 if (outLength) {
2323 *outLength = toCopy;
2324 }
2325 return SECSuccess;
2326}
2327
2328/* Verify is just a compare for HMAC */
2329static SECStatus
2330sftk_HMACCmp(void *ctx, const unsigned char *sig, unsigned int sigLen,
2331 const unsigned char *hash, unsigned int hashLen)
2332{
2333 CK_ULONG compareLen = *(CK_ULONG *)ctx;
2334 PORT_Assert(compareLen == hashLen)((compareLen == hashLen) ? ((void)0) : PR_Assert("compareLen == hashLen"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 2334
))
;
2335 if (compareLen != hashLen) {
2336 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE);
2337 return SECFailure;
2338 }
2339
2340 // Handle MAC truncation. NB: should the caller not wish to support
2341 // truncation, it is their responsibility to ensure that the MAC has not
2342 // been truncated.
2343 if (compareLen > sigLen) {
2344 compareLen = sigLen;
2345 }
2346 if (NSS_SecureMemcmp(sig, hash, compareLen) == 0) {
2347 return SECSuccess;
2348 }
2349
2350 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_SIGNATURE);
2351 return SECFailure;
2352}
2353
2354/*
2355 * common HMAC + CMAC initialization routine
2356 */
2357static CK_RV
2358sftk_doMACInit(CK_MECHANISM_TYPE mech, SFTKSessionContext *session,
2359 SFTKObject *key, CK_ULONG mac_size)
2360{
2361 CK_RV crv;
2362 sftk_MACCtx *context;
2363 CK_ULONG *intpointer;
2364 PRBool isFIPS = sftk_isFIPS(key->slot->slotID)(((key->slot->slotID) == 3) || ((key->slot->slotID
) >= 101))
;
2365
2366 /* Set up the initial context. */
2367 crv = sftk_MAC_Create(mech, key, &context);
2368 if (crv != CKR_OK0x00000000UL) {
2369 return crv;
2370 }
2371
2372 session->hashInfo = context;
2373 session->multi = PR_TRUE1;
2374
2375 /* Required by FIPS 198 Section 4. Delay this check until after the MAC
2376 * has been initialized to steal the output size of the MAC. */
2377 if (isFIPS && (mac_size < 4 || mac_size < context->mac_size / 2)) {
2378 sftk_MAC_DestroyContext(context, PR_TRUE1);
2379 return CKR_BUFFER_TOO_SMALL0x00000150UL;
2380 }
2381
2382 /* Configure our helper functions appropriately. Note that these casts
2383 * ignore the return values. */
2384 session->hashUpdate = SFTKHash_sftk_MAC_Update;
2385 session->end = SFTKHash_sftk_MAC_End;
2386 session->hashdestroy = SFTKHash_sftk_MAC_DestroyContext;
2387
2388 intpointer = PORT_New(CK_ULONG)(CK_ULONG *)PORT_Alloc_Util(sizeof(CK_ULONG));
2389 if (intpointer == NULL((void*)0)) {
2390 sftk_MAC_DestroyContext(context, PR_TRUE1);
2391 return CKR_HOST_MEMORY0x00000002UL;
2392 }
2393 *intpointer = mac_size;
2394 session->cipherInfo = intpointer;
2395
2396 /* Since we're only "hashing", copy the result from session->end to the
2397 * caller using sftk_SignCopy. */
2398 session->update = sftk_SignCopy;
2399 session->verify = sftk_HMACCmp;
2400 session->destroy = sftk_Space;
2401
2402 session->maxLen = context->mac_size;
2403
2404 return CKR_OK0x00000000UL;
2405}
2406
2407/*
2408 * SSL Macing support. SSL Macs are inited, then update with the base
2409 * hashing algorithm, then finalized in sign and verify
2410 */
2411
2412/*
2413 * FROM SSL:
2414 * 60 bytes is 3 times the maximum length MAC size that is supported.
2415 * We probably should have one copy of this table. We still need this table
2416 * in ssl to 'sign' the handshake hashes.
2417 */
2418static unsigned char ssl_pad_1[60] = {
2419 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
2420 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
2421 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
2422 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
2423 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
2424 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
2425 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
2426 0x36, 0x36, 0x36, 0x36
2427};
2428static unsigned char ssl_pad_2[60] = {
2429 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
2430 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
2431 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
2432 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
2433 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
2434 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
2435 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
2436 0x5c, 0x5c, 0x5c, 0x5c
2437};
2438
2439static SECStatus
2440sftk_SSLMACSign(void *ctx, unsigned char *sig, unsigned int *sigLen,
2441 unsigned int maxLen, const unsigned char *hash, unsigned int hashLen)
2442{
2443 SFTKSSLMACInfo *info = ctx;
2444 unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH64];
2445 unsigned int out;
2446
2447 PORT_Assert(info->macSize <= SFTK_MAX_MAC_LENGTH)((info->macSize <= 64) ? ((void)0) : PR_Assert("info->macSize <= SFTK_MAX_MAC_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 2447
))
;
2448 if (info->macSize > SFTK_MAX_MAC_LENGTH64) {
2449 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE);
2450 return SECFailure;
2451 }
2452
2453 if (info->macSize > maxLen) {
2454 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_ARGS);
2455 return SECFailure;
2456 }
2457
2458 info->begin(info->hashContext);
2459 info->update(info->hashContext, info->key, info->keySize);
2460 info->update(info->hashContext, ssl_pad_2, info->padSize);
2461 info->update(info->hashContext, hash, hashLen);
2462 info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH64);
2463 PORT_Memcpymemcpy(sig, tmpBuf, info->macSize);
2464 PORT_Memsetmemset(tmpBuf, 0, info->macSize);
2465 *sigLen = info->macSize;
2466 return SECSuccess;
2467}
2468
2469static SECStatus
2470sftk_SSLMACVerify(void *ctx, const unsigned char *sig, unsigned int sigLen,
2471 const unsigned char *hash, unsigned int hashLen)
2472{
2473 SFTKSSLMACInfo *info = ctx;
2474 unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH64];
2475 unsigned int out;
2476 int cmp;
2477
2478 PORT_Assert(info->macSize <= SFTK_MAX_MAC_LENGTH)((info->macSize <= 64) ? ((void)0) : PR_Assert("info->macSize <= SFTK_MAX_MAC_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 2478
))
;
2479 if (info->macSize > SFTK_MAX_MAC_LENGTH64) {
2480 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE);
2481 return SECFailure;
2482 }
2483
2484 if (info->macSize > sigLen) {
2485 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_SIGNATURE);
2486 return SECFailure;
2487 }
2488
2489 info->begin(info->hashContext);
2490 info->update(info->hashContext, info->key, info->keySize);
2491 info->update(info->hashContext, ssl_pad_2, info->padSize);
2492 info->update(info->hashContext, hash, hashLen);
2493 info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH64);
2494 cmp = NSS_SecureMemcmp(sig, tmpBuf, info->macSize);
2495 PORT_Memsetmemset(tmpBuf, 0, info->macSize);
2496 if (cmp == 0) {
2497 return SECSuccess;
2498 }
2499
2500 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_SIGNATURE);
2501 return SECFailure;
2502}
2503
2504/*
2505 * common HMAC initalization routine
2506 */
2507static CK_RV
2508sftk_doSSLMACInit(SFTKSessionContext *context, SECOidTag oid,
2509 SFTKObject *key, CK_ULONG mac_size)
2510{
2511 SFTKAttribute *keyval;
2512 SFTKBegin begin;
2513 int padSize;
2514 SFTKSSLMACInfo *sslmacinfo;
2515 CK_RV crv = CKR_MECHANISM_INVALID0x00000070UL;
2516
2517 if (oid == SEC_OID_SHA1) {
2518 crv = sftk_doSubSHA1(context);
2519 if (crv != CKR_OK0x00000000UL)
2520 return crv;
2521 begin = SFTKHash_SHA1_Begin;
2522 padSize = 40;
2523 } else {
2524 crv = sftk_doSubMD5(context);
2525 if (crv != CKR_OK0x00000000UL)
2526 return crv;
2527 begin = SFTKHash_MD5_Begin;
2528 padSize = 48;
2529 }
2530 context->multi = PR_TRUE1;
2531
2532 keyval = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
2533 if (keyval == NULL((void*)0))
2534 return CKR_KEY_SIZE_RANGE0x00000062UL;
2535
2536 context->hashUpdate(context->hashInfo, keyval->attrib.pValue,
2537 keyval->attrib.ulValueLen);
2538 context->hashUpdate(context->hashInfo, ssl_pad_1, padSize);
2539 sslmacinfo = (SFTKSSLMACInfo *)PORT_AllocPORT_Alloc_Util(sizeof(SFTKSSLMACInfo));
2540 if (sslmacinfo == NULL((void*)0)) {
2541 sftk_FreeAttribute(keyval);
2542 return CKR_HOST_MEMORY0x00000002UL;
2543 }
2544 sslmacinfo->size = sizeof(SFTKSSLMACInfo);
2545 sslmacinfo->macSize = mac_size;
2546 sslmacinfo->hashContext = context->hashInfo;
2547 PORT_Memcpymemcpy(sslmacinfo->key, keyval->attrib.pValue,
2548 keyval->attrib.ulValueLen);
2549 sslmacinfo->keySize = keyval->attrib.ulValueLen;
2550 sslmacinfo->begin = begin;
2551 sslmacinfo->end = context->end;
2552 sslmacinfo->update = context->hashUpdate;
2553 sslmacinfo->padSize = padSize;
2554 sftk_FreeAttribute(keyval);
2555 context->cipherInfo = (void *)sslmacinfo;
2556 context->destroy = sftk_ZSpace;
2557 context->update = sftk_SSLMACSign;
2558 context->verify = sftk_SSLMACVerify;
2559 context->maxLen = mac_size;
2560 return CKR_OK0x00000000UL;
2561}
2562
2563/*
2564 ************** Crypto Functions: Sign ************************
2565 */
2566
2567/**
2568 * Check if We're using CBCMacing and initialize the session context if we are.
2569 * @param contextType SFTK_SIGN or SFTK_VERIFY
2570 * @param keyUsage check whether key allows this usage
2571 */
2572static CK_RV
2573sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
2574 CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage,
2575 SFTKContextType contextType)
2576
2577{
2578 CK_MECHANISM cbc_mechanism;
2579 CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE0xffffffff;
2580#ifndef NSS_DISABLE_DEPRECATED_RC2
2581 CK_RC2_CBC_PARAMS rc2_params;
2582#endif
2583#if NSS_SOFTOKEN_DOES_RC5
2584 CK_RC5_CBC_PARAMS rc5_params;
2585 CK_RC5_MAC_GENERAL_PARAMS *rc5_mac;
2586#endif
2587 unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE16];
2588 unsigned char k2[SFTK_MAX_BLOCK_SIZE16];
2589 unsigned char k3[SFTK_MAX_BLOCK_SIZE16];
2590 SFTKSession *session;
2591 SFTKSessionContext *context;
2592 CK_RV crv;
2593 unsigned int blockSize;
2594 PRBool isXCBC = PR_FALSE0;
2595
2596 if (!pMechanism) {
2597 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2598 }
2599
2600 switch (pMechanism->mechanism) {
2601#ifndef NSS_DISABLE_DEPRECATED_RC2
2602 case CKM_RC2_MAC_GENERAL0x00000104UL:
2603 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_MAC_GENERAL_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_RC2_MAC_GENERAL_PARAMS))
) {
2604 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2605 }
2606 mac_bytes =
2607 ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
2608 /* fall through */
2609 case CKM_RC2_MAC0x00000103UL:
2610 if (pMechanism->mechanism == CKM_RC2_MAC0x00000103UL &&
2611 BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_CBC_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_RC2_CBC_PARAMS))
) {
2612 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2613 }
2614 /* this works because ulEffectiveBits is in the same place in both the
2615 * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */
2616 rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *)
2617 pMechanism->pParameter)
2618 ->ulEffectiveBits;
2619 PORT_Memsetmemset(rc2_params.iv, 0, sizeof(rc2_params.iv));
2620 cbc_mechanism.mechanism = CKM_RC2_CBC0x00000102UL;
2621 cbc_mechanism.pParameter = &rc2_params;
2622 cbc_mechanism.ulParameterLen = sizeof(rc2_params);
2623 blockSize = 8;
2624 break;
2625#endif /* NSS_DISABLE_DEPRECATED_RC2 */
2626
2627#if NSS_SOFTOKEN_DOES_RC5
2628 case CKM_RC5_MAC_GENERAL0x00000334UL:
2629 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_RC5_MAC_GENERAL_PARAMS))
) {
2630 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2631 }
2632 mac_bytes =
2633 ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
2634 /* fall through */
2635 case CKM_RC5_MAC0x00000333UL:
2636 /* this works because ulEffectiveBits is in the same place in both the
2637 * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */
2638 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_RC5_MAC_GENERAL_PARAMS))
) {
2639 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2640 }
2641 rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter;
2642 rc5_params.ulWordsize = rc5_mac->ulWordsize;
2643 rc5_params.ulRounds = rc5_mac->ulRounds;
2644 rc5_params.pIv = ivBlock;
2645 if ((blockSize = rc5_mac->ulWordsize * 2) > SFTK_MAX_BLOCK_SIZE16)
2646 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2647 rc5_params.ulIvLen = blockSize;
2648 PORT_Memsetmemset(ivBlock, 0, blockSize);
2649 cbc_mechanism.mechanism = CKM_RC5_CBC0x00000332UL;
2650 cbc_mechanism.pParameter = &rc5_params;
2651 cbc_mechanism.ulParameterLen = sizeof(rc5_params);
2652 break;
2653#endif
2654 /* add cast and idea later */
2655 case CKM_DES_MAC_GENERAL0x00000124UL:
2656 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
2657 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2658 }
2659 mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
2660 /* fall through */
2661 case CKM_DES_MAC0x00000123UL:
2662 blockSize = 8;
2663 PORT_Memsetmemset(ivBlock, 0, blockSize);
2664 cbc_mechanism.mechanism = CKM_DES_CBC0x00000122UL;
2665 cbc_mechanism.pParameter = &ivBlock;
2666 cbc_mechanism.ulParameterLen = blockSize;
2667 break;
2668 case CKM_DES3_MAC_GENERAL0x00000135UL:
2669 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
2670 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2671 }
2672 mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
2673 /* fall through */
2674 case CKM_DES3_MAC0x00000134UL:
2675 blockSize = 8;
2676 PORT_Memsetmemset(ivBlock, 0, blockSize);
2677 cbc_mechanism.mechanism = CKM_DES3_CBC0x00000133UL;
2678 cbc_mechanism.pParameter = &ivBlock;
2679 cbc_mechanism.ulParameterLen = blockSize;
2680 break;
2681 case CKM_CDMF_MAC_GENERAL0x00000144UL:
2682 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
2683 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2684 }
2685 mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
2686 /* fall through */
2687 case CKM_CDMF_MAC0x00000143UL:
2688 blockSize = 8;
2689 PORT_Memsetmemset(ivBlock, 0, blockSize);
2690 cbc_mechanism.mechanism = CKM_CDMF_CBC0x00000142UL;
2691 cbc_mechanism.pParameter = &ivBlock;
2692 cbc_mechanism.ulParameterLen = blockSize;
2693 break;
2694#ifndef NSS_DISABLE_DEPRECATED_SEED
2695 case CKM_SEED_MAC_GENERAL0x00000654UL:
2696 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
2697 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2698 }
2699 mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
2700 /* fall through */
2701 case CKM_SEED_MAC0x00000653UL:
2702 blockSize = 16;
2703 PORT_Memsetmemset(ivBlock, 0, blockSize);
2704 cbc_mechanism.mechanism = CKM_SEED_CBC0x00000652UL;
2705 cbc_mechanism.pParameter = &ivBlock;
2706 cbc_mechanism.ulParameterLen = blockSize;
2707 break;
2708#endif /* NSS_DISABLE_DEPRECATED_SEED */
2709 case CKM_CAMELLIA_MAC_GENERAL0x00000554UL:
2710 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
2711 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2712 }
2713 mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
2714 /* fall through */
2715 case CKM_CAMELLIA_MAC0x00000553UL:
2716 blockSize = 16;
2717 PORT_Memsetmemset(ivBlock, 0, blockSize);
2718 cbc_mechanism.mechanism = CKM_CAMELLIA_CBC0x00000552UL;
2719 cbc_mechanism.pParameter = &ivBlock;
2720 cbc_mechanism.ulParameterLen = blockSize;
2721 break;
2722 case CKM_AES_MAC_GENERAL0x00001084UL:
2723 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
2724 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2725 }
2726 mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
2727 /* fall through */
2728 case CKM_AES_MAC0x00001083UL:
2729 blockSize = 16;
2730 PORT_Memsetmemset(ivBlock, 0, blockSize);
2731 cbc_mechanism.mechanism = CKM_AES_CBC0x00001082UL;
2732 cbc_mechanism.pParameter = &ivBlock;
2733 cbc_mechanism.ulParameterLen = blockSize;
2734 break;
2735 case CKM_AES_XCBC_MAC_960x0000108DUL:
2736 case CKM_AES_XCBC_MAC0x0000108CUL:
2737 /* The only difference between CKM_AES_XCBC_MAC
2738 * and CKM_AES_XCBC_MAC_96 is the size of the returned mac. */
2739 mac_bytes = pMechanism->mechanism == CKM_AES_XCBC_MAC_960x0000108DUL ? 12 : 16;
2740 blockSize = 16;
2741 PORT_Memsetmemset(ivBlock, 0, blockSize);
2742 cbc_mechanism.mechanism = CKM_AES_CBC0x00001082UL;
2743 cbc_mechanism.pParameter = &ivBlock;
2744 cbc_mechanism.ulParameterLen = blockSize;
2745 /* is XCBC requires extra processing at the end of the operation */
2746 isXCBC = PR_TRUE1;
2747 /* The input key is used to generate k1, k2, and k3. k2 and k3
2748 * are used at the end in the pad step. k1 replaces the input
2749 * key in the aes cbc mac */
2750 crv = sftk_aes_xcbc_new_keys(hSession, hKey, &hKey, k2, k3);
2751 if (crv != CKR_OK0x00000000UL) {
2752 return crv;
2753 }
2754 break;
2755 default:
2756 return CKR_FUNCTION_NOT_SUPPORTED0x00000054UL;
2757 }
2758
2759 /* if MAC size is externally supplied, it should be checked.
2760 */
2761 if (mac_bytes == SFTK_INVALID_MAC_SIZE0xffffffff)
2762 mac_bytes = blockSize >> 1;
2763 else {
2764 if (mac_bytes > blockSize) {
2765 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
2766 goto fail;
2767 }
2768 }
2769
2770 crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey,
2771 CKA_ENCRYPT0x00000104UL, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */
2772 keyUsage, contextType, PR_TRUE1);
2773 if (crv != CKR_OK0x00000000UL)
2774 goto fail;
2775 /* Hold the session reference for the duration of the context writes;
2776 * see comment on NSC_DigestUpdate. */
2777 crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE1, &session);
2778
2779 /* this shouldn't happen! */
2780 PORT_Assert(crv == CKR_OK)((crv == 0x00000000UL) ? ((void)0) : PR_Assert("crv == CKR_OK"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 2780
))
;
2781 if (crv != CKR_OK0x00000000UL)
2782 goto fail;
2783 context->blockSize = blockSize;
2784 context->macSize = mac_bytes;
2785 context->isXCBC = isXCBC;
2786 if (isXCBC) {
2787 /* save the xcbc specific parameters */
2788 PORT_Memcpymemcpy(context->k2, k2, blockSize);
2789 PORT_Memcpymemcpy(context->k3, k3, blockSize);
2790 PORT_Memsetmemset(k2, 0, blockSize);
2791 PORT_Memsetmemset(k3, 0, blockSize);
2792 /* get rid of the temp key now that the context has been created */
2793 NSC_DestroyObject(hSession, hKey);
2794 }
2795 sftk_FreeSession(session);
2796 return CKR_OK0x00000000UL;
2797fail:
2798 if (isXCBC) {
2799 PORT_Memsetmemset(k2, 0, blockSize);
2800 PORT_Memsetmemset(k3, 0, blockSize);
2801 NSC_DestroyObject(hSession, hKey); /* get rid of our temp key */
2802 }
2803 return crv;
2804}
2805
2806/*
2807 * encode RSA PKCS #1 Signature data before signing...
2808 */
2809static SECStatus
2810sftk_RSAHashSign(void *ctx, unsigned char *sig,
2811 unsigned int *sigLen, unsigned int maxLen,
2812 const unsigned char *hash, unsigned int hashLen)
2813{
2814 SFTKHashSignInfo *info = ctx;
2815 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("info->key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 2815))
;
2816 if (info->key->keyType != NSSLOWKEYRSAKey) {
2817 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
2818 return SECFailure;
2819 }
2820
2821 return RSA_HashSign(info->hashOid, info->key, sig, sigLen, maxLen,
2822 hash, hashLen);
2823}
2824
2825/* XXX Old template; want to expunge it eventually. */
2826static DERTemplate SECAlgorithmIDTemplate[] = {
2827 { DER_SEQUENCE0x10,
2828 0, NULL((void*)0), sizeof(SECAlgorithmID) },
2829 { DER_OBJECT_ID0x06,
2830 offsetof(SECAlgorithmID, algorithm)__builtin_offsetof(SECAlgorithmID, algorithm) },
2831 { DER_OPTIONAL0x00100 | DER_ANY0x00400,
2832 offsetof(SECAlgorithmID, parameters)__builtin_offsetof(SECAlgorithmID, parameters) },
2833 { 0 }
2834};
2835
2836/*
2837 * XXX OLD Template. Once all uses have been switched over to new one,
2838 * remove this.
2839 */
2840static DERTemplate SGNDigestInfoTemplate[] = {
2841 { DER_SEQUENCE0x10,
2842 0, NULL((void*)0), sizeof(SGNDigestInfo) },
2843 { DER_INLINE0x00800,
2844 offsetof(SGNDigestInfo, digestAlgorithm)__builtin_offsetof(SGNDigestInfo, digestAlgorithm),
2845 SECAlgorithmIDTemplate },
2846 { DER_OCTET_STRING0x04,
2847 offsetof(SGNDigestInfo, digest)__builtin_offsetof(SGNDigestInfo, digest) },
2848 { 0 }
2849};
2850
2851/*
2852 * encode RSA PKCS #1 Signature data before signing...
2853 */
2854SECStatus
2855RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
2856 unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
2857 const unsigned char *hash, unsigned int hashLen)
2858{
2859 SECStatus rv = SECFailure;
2860 SECItem digder;
2861 PLArenaPool *arena = NULL((void*)0);
2862 SGNDigestInfo *di = NULL((void*)0);
2863
2864 digder.data = NULL((void*)0);
2865
2866 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
2867 if (!arena) {
2868 goto loser;
2869 }
2870
2871 /* Construct digest info */
2872 di = SGN_CreateDigestInfoSGN_CreateDigestInfo_Util(hashOid, hash, hashLen);
2873 if (!di) {
2874 goto loser;
2875 }
2876
2877 /* Der encode the digest as a DigestInfo */
2878 rv = DER_EncodeDER_Encode_Util(arena, &digder, SGNDigestInfoTemplate, di);
2879 if (rv != SECSuccess) {
2880 goto loser;
2881 }
2882
2883 /*
2884 ** Encrypt signature after constructing appropriate PKCS#1 signature
2885 ** block
2886 */
2887 rv = RSA_Sign(&key->u.rsa, sig, sigLen, maxLen, digder.data,
2888 digder.len);
2889 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
2890 sftk_fatalError = PR_TRUE1;
2891 }
2892
2893loser:
2894 SGN_DestroyDigestInfoSGN_DestroyDigestInfo_Util(di);
2895 if (arena != NULL((void*)0)) {
2896 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
2897 }
2898 return rv;
2899}
2900
2901static SECStatus
2902sftk_RSASign(void *ctx, unsigned char *output,
2903 unsigned int *outputLen, unsigned int maxOutputLen,
2904 const unsigned char *input, unsigned int inputLen)
2905{
2906 NSSLOWKEYPrivateKey *key = ctx;
2907 SECStatus rv = SECFailure;
2908
2909 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 2909))
;
2910 if (key->keyType != NSSLOWKEYRSAKey) {
2911 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
2912 return SECFailure;
2913 }
2914
2915 rv = RSA_Sign(&key->u.rsa, output, outputLen, maxOutputLen, input,
2916 inputLen);
2917 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
2918 sftk_fatalError = PR_TRUE1;
2919 }
2920 return rv;
2921}
2922
2923static SECStatus
2924sftk_RSASignRaw(void *ctx, unsigned char *output,
2925 unsigned int *outputLen, unsigned int maxOutputLen,
2926 const unsigned char *input, unsigned int inputLen)
2927{
2928 NSSLOWKEYPrivateKey *key = ctx;
2929 SECStatus rv = SECFailure;
2930
2931 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 2931))
;
2932 if (key->keyType != NSSLOWKEYRSAKey) {
2933 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
2934 return SECFailure;
2935 }
2936
2937 rv = RSA_SignRaw(&key->u.rsa, output, outputLen, maxOutputLen, input,
2938 inputLen);
2939 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
2940 sftk_fatalError = PR_TRUE1;
2941 }
2942 return rv;
2943}
2944
2945static SECStatus
2946sftk_RSASignPSS(void *ctx, unsigned char *sig,
2947 unsigned int *sigLen, unsigned int maxLen,
2948 const unsigned char *hash, unsigned int hashLen)
2949{
2950 SFTKPSSSignInfo *info = ctx;
2951 SECStatus rv = SECFailure;
2952 HASH_HashType hashAlg;
2953 HASH_HashType maskHashAlg;
2954 CK_RSA_PKCS_PSS_PARAMS *params = &info->params;
2955
2956 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("info->key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 2956))
;
2957 if (info->key->keyType != NSSLOWKEYRSAKey) {
2958 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
2959 return SECFailure;
2960 }
2961
2962 hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg);
2963 maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf);
2964
2965 rv = RSA_SignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, NULL((void*)0),
2966 params->sLen, sig, sigLen, maxLen, hash, hashLen);
2967 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
2968 sftk_fatalError = PR_TRUE1;
2969 }
2970 return rv;
2971}
2972
2973#ifndef NSS_DISABLE_DSA
2974static SECStatus
2975nsc_DSA_Verify_Stub(void *ctx, const unsigned char *sigBuf, unsigned int sigLen,
2976 const unsigned char *dataBuf, unsigned int dataLen)
2977{
2978 NSSLOWKEYPublicKey *key = ctx;
2979 SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen };
2980 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
2981 return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest);
2982}
2983
2984static SECStatus
2985nsc_DSA_Sign_Stub(void *ctx, unsigned char *sigBuf,
2986 unsigned int *sigLen, unsigned int maxSigLen,
2987 const unsigned char *dataBuf, unsigned int dataLen)
2988{
2989 NSSLOWKEYPrivateKey *key = ctx;
2990 SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen };
2991 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
2992 SECStatus rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
2993 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
2994 sftk_fatalError = PR_TRUE1;
2995 }
2996 *sigLen = signature.len;
2997 return rv;
2998}
2999#endif
3000
3001static SECStatus
3002nsc_ECDSAVerifyStub(void *ctx, const unsigned char *sigBuf, unsigned int sigLen,
3003 const unsigned char *dataBuf, unsigned int dataLen)
3004{
3005 NSSLOWKEYPublicKey *key = ctx;
3006 SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen };
3007 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
3008 return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest);
3009}
3010
3011static SECStatus
3012nsc_ECDSASignStub(void *ctx, unsigned char *sigBuf,
3013 unsigned int *sigLen, unsigned int maxSigLen,
3014 const unsigned char *dataBuf, unsigned int dataLen)
3015{
3016 NSSLOWKEYPrivateKey *key = ctx;
3017 SECItem signature = { siBuffer, sigBuf, maxSigLen };
3018 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
3019
3020 SECStatus rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
3021 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
3022 sftk_fatalError = PR_TRUE1;
3023 }
3024 *sigLen = signature.len;
3025 return rv;
3026}
3027
3028static SECStatus
3029nsc_EDDSAVerifyStub(void *ctx, const unsigned char *sigBuf, unsigned int sigLen,
3030 const unsigned char *dataBuf, unsigned int dataLen)
3031{
3032 NSSLOWKEYPublicKey *key = ctx;
3033 SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen };
3034 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
3035 return ED_VerifyMessage(&(key->u.ec), &signature, &digest);
3036}
3037
3038static SECStatus
3039nsc_EDDSASignStub(void *ctx, unsigned char *sigBuf,
3040 unsigned int *sigLen, unsigned int maxSigLen,
3041 const unsigned char *dataBuf, unsigned int dataLen)
3042{
3043 NSSLOWKEYPrivateKey *key = ctx;
3044 SECItem signature = { siBuffer, sigBuf, maxSigLen };
3045 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen };
3046
3047 SECStatus rv = ED_SignMessage(&(key->u.ec), &signature, &digest);
3048 if (rv != SECSuccess && PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
3049 sftk_fatalError = PR_TRUE1;
3050 }
3051 *sigLen = signature.len;
3052 return rv;
3053}
3054
3055static void
3056sftk_MLDSADestroyContext(void *info, PRBool freeit)
3057{
3058 MLDSA_DestroyContext((MLDSAContext *)info);
3059}
3060
3061void
3062sftk_MLDSASignUpdate(void *info, const unsigned char *data, unsigned int len)
3063{
3064 MLDSAContext *ctptr = (MLDSAContext *)info;
3065 const SECItem inData = { siBuffer, (unsigned char *)data, len };
3066 (void)MLDSA_SignUpdate(ctptr, &inData);
3067}
3068
3069void
3070sftk_MLDSAVerifyUpdate(void *info, const unsigned char *data, unsigned int len)
3071{
3072 MLDSAContext *ctptr = (MLDSAContext *)info;
3073 const SECItem inData = { siBuffer, (unsigned char *)data, len };
3074 (void)MLDSA_VerifyUpdate(ctptr, &inData);
3075}
3076
3077SECStatus
3078sftk_MLDSASignFinal(void *info, unsigned char *sig, unsigned int *sigLen,
3079 unsigned int maxLen, const unsigned char *data,
3080 unsigned int len)
3081{
3082 MLDSAContext *ctptr = (MLDSAContext *)info;
3083 SECItem sigOut = { siBuffer, sig, maxLen };
3084 SECStatus rv;
3085
3086 if (len != 0) {
3087 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE);
3088 return SECFailure;
3089 }
3090
3091 rv = MLDSA_SignFinal(ctptr, &sigOut);
3092 *sigLen = sigOut.len;
3093 return rv;
3094}
3095
3096SECStatus
3097sftk_MLDSAVerifyFinal(void *info, const unsigned char *sig, unsigned int sigLen,
3098 const unsigned char *data, unsigned int len)
3099{
3100 MLDSAContext *ctptr = (MLDSAContext *)info;
3101 const SECItem sigIn = { siBuffer, (unsigned char *)sig, sigLen };
3102
3103 if (len != 0) {
3104 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_LIBRARY_FAILURE);
3105 return SECFailure;
3106 }
3107
3108 return MLDSA_VerifyFinal(ctptr, &sigIn);
3109}
3110
3111unsigned int
3112sftk_MLDSAGetSigLen(CK_ML_DSA_PARAMETER_SET_TYPE paramSet)
3113{
3114 switch (paramSet) {
3115 case CKP_ML_DSA_440x00000001UL:
3116 return ML_DSA_44_SIGNATURE_LEN2420;
3117 case CKP_ML_DSA_650x00000002UL:
3118 return ML_DSA_65_SIGNATURE_LEN3309;
3119 case CKP_ML_DSA_870x00000003UL:
3120 return ML_DSA_87_SIGNATURE_LEN4627;
3121 }
3122 /* this is a programming error if we get a valid DSA key with an unknown
3123 * parmaSet */
3124 PORT_Assert(/* unknown param set */ 0)((0) ? ((void)0) : PR_Assert("0", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3124))
;
3125 return 0;
3126}
3127
3128/* NSC_SignInit setups up the signing operations. There are three basic
3129 * types of signing:
3130 * (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
3131 * to data in a single Sign operation (which often looks a lot like an
3132 * encrypt, with data coming in and data going out).
3133 * (2) Hash based signing, where we continually hash the data, then apply
3134 * some sort of signature to the end.
3135 * (3) Block Encryption CBC MAC's, where the Data is encrypted with a key,
3136 * and only the final block is part of the mac.
3137 *
3138 * For case number 3, we initialize a context much like the Encryption Context
3139 * (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and
3140 * C_Final by the following method... if it's not multi-part, and it's doesn't
3141 * have a hash context, it must be a block Encryption CBC MAC.
3142 *
3143 * For case number 2, we initialize a hash structure, as well as make it
3144 * multi-part. Updates are simple calls to the hash update function. Final
3145 * calls the hashend, then passes the result to the 'update' function (which
3146 * operates as a final signature function). In some hash based MAC'ing (as
3147 * opposed to hash base signatures), the update function is can be simply a
3148 * copy (as is the case with HMAC).
3149 */
3150CK_RV
3151NSC_SignInit(CK_SESSION_HANDLE hSession,
3152 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
3153{
3154 SFTKSession *session;
3155 SFTKObject *key;
3156 SFTKSessionContext *context;
3157 CK_KEY_TYPE key_type;
3158 CK_RV crv = CKR_OK0x00000000UL;
3159 NSSLOWKEYPrivateKey *privKey;
3160 SFTKHashSignInfo *info = NULL((void*)0);
3161 SFTKPSSSignInfo *pinfo = NULL((void*)0);
3162
3163 CHECK_FORK();
3164
3165 /* Block Cipher MACing Algorithms use a different Context init method..*/
3166 crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN0x00000108UL, SFTK_SIGN);
3167 if (crv != CKR_FUNCTION_NOT_SUPPORTED0x00000054UL)
3168 return crv;
3169
3170 /* we're not using a block cipher mac */
3171 session = sftk_SessionFromHandle(hSession);
3172 if (session == NULL((void*)0))
3173 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
3174 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_SIGN, &key,
3175 hKey, &key_type, CKO_PRIVATE_KEY0x00000003UL, CKA_SIGN0x00000108UL);
3176 if (crv != CKR_OK0x00000000UL) {
3177 sftk_FreeSession(session);
3178 return crv;
3179 }
3180
3181 context->multi = PR_FALSE0;
3182
3183#define INIT_RSA_SIGN_MECH(mmm)case CKM_mmm_RSA_PKCS: context->multi = 1; crv = sftk_doSubmmm
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_mmm; goto finish_rsa;
\
3184 case CKM_##mmm##_RSA_PKCS: \
3185 context->multi = PR_TRUE1; \
3186 crv = sftk_doSub##mmm(context); \
3187 if (crv != CKR_OK0x00000000UL) \
3188 break; \
3189 context->update = sftk_RSAHashSign; \
3190 info = PORT_New(SFTKHashSignInfo)(SFTKHashSignInfo *)PORT_Alloc_Util(sizeof(SFTKHashSignInfo)); \
3191 if (info == NULL((void*)0)) { \
3192 crv = CKR_HOST_MEMORY0x00000002UL; \
3193 break; \
3194 } \
3195 info->hashOid = SEC_OID_##mmm; \
3196 goto finish_rsa;
3197
3198 switch (pMechanism->mechanism) {
3199 INIT_RSA_SIGN_MECH(MD5)case 0x00000005UL: context->multi = 1; crv = sftk_doSubMD5
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_MD5; goto finish_rsa;
3200 INIT_RSA_SIGN_MECH(MD2)case 0x00000004UL: context->multi = 1; crv = sftk_doSubMD2
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_MD2; goto finish_rsa;
3201 INIT_RSA_SIGN_MECH(SHA1)case 0x00000006UL: context->multi = 1; crv = sftk_doSubSHA1
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_SHA1; goto finish_rsa;
3202 INIT_RSA_SIGN_MECH(SHA224)case 0x00000046UL: context->multi = 1; crv = sftk_doSubSHA224
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_SHA224; goto finish_rsa
;
3203 INIT_RSA_SIGN_MECH(SHA256)case 0x00000040UL: context->multi = 1; crv = sftk_doSubSHA256
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_SHA256; goto finish_rsa
;
3204 INIT_RSA_SIGN_MECH(SHA384)case 0x00000041UL: context->multi = 1; crv = sftk_doSubSHA384
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_SHA384; goto finish_rsa
;
3205 INIT_RSA_SIGN_MECH(SHA512)case 0x00000042UL: context->multi = 1; crv = sftk_doSubSHA512
(context); if (crv != 0x00000000UL) break; context->update
= sftk_RSAHashSign; info = (SFTKHashSignInfo *)PORT_Alloc_Util
(sizeof(SFTKHashSignInfo)); if (info == ((void*)0)) { crv = 0x00000002UL
; break; } info->hashOid = SEC_OID_SHA512; goto finish_rsa
;
3206
3207 case CKM_RSA_PKCS0x00000001UL:
3208 context->update = sftk_RSASign;
3209 goto finish_rsa;
3210 case CKM_RSA_X_5090x00000003UL:
3211 context->update = sftk_RSASignRaw;
3212 finish_rsa:
3213 if (key_type != CKK_RSA0x00000000UL) {
3214 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3215 break;
3216 }
3217 context->rsa = PR_TRUE1;
3218 privKey = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv);
3219 if (privKey == NULL((void*)0)) {
3220 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3221 break;
3222 }
3223 /* OK, info is allocated only if we're doing hash and sign mechanism.
3224 * It's necessary to be able to set the correct OID in the final
3225 * signature.
3226 */
3227 if (info) {
3228 info->key = privKey;
3229 context->cipherInfo = info;
3230 context->destroy = sftk_Space;
3231 } else {
3232 context->cipherInfo = privKey;
3233 context->destroy = sftk_Null;
3234 }
3235 context->maxLen = nsslowkey_PrivateModulusLen(privKey);
3236 break;
3237
3238#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;
\
3239 case CKM_##mmm##_RSA_PKCS_PSS: \
3240 context->multi = PR_TRUE1; \
3241 crv = sftk_doSub##mmm(context); \
3242 if (crv != CKR_OK0x00000000UL) \
3243 break; \
3244 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { \
3245 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; \
3246 break; \
3247 } \
3248 if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)->hashAlg != CKM_##mmm) { \
3249 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; \
3250 break; \
3251 } \
3252 goto finish_rsa_pss;
3253 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;
3254 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;
3255 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;
3256 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;
3257 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;
3258 case CKM_RSA_PKCS_PSS0x0000000DUL:
3259 finish_rsa_pss:
3260 if (key_type != CKK_RSA0x00000000UL) {
3261 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3262 break;
3263 }
3264 context->rsa = PR_TRUE1;
3265 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
3266 !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) {
3267 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3268 break;
3269 }
3270 pinfo = PORT_New(SFTKPSSSignInfo)(SFTKPSSSignInfo *)PORT_Alloc_Util(sizeof(SFTKPSSSignInfo));
3271 if (pinfo == NULL((void*)0)) {
3272 crv = CKR_HOST_MEMORY0x00000002UL;
3273 break;
3274 }
3275 pinfo->size = sizeof(SFTKPSSSignInfo);
3276 pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter;
3277 pinfo->key = sftk_GetPrivKey(key, CKK_RSA0x00000000UL, &crv);
3278 if (pinfo->key == NULL((void*)0)) {
3279 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3280 break;
3281 }
3282 context->cipherInfo = pinfo;
3283 context->destroy = sftk_ZSpace;
3284 context->update = sftk_RSASignPSS;
3285 context->maxLen = nsslowkey_PrivateModulusLen(pinfo->key);
3286 break;
3287
3288#ifndef NSS_DISABLE_DSA
3289#define INIT_DSA_SIG_MECH(mmm)case CKM_DSA_mmm: context->multi = 1; crv = sftk_doSubmmm(
context); if (crv != 0x00000000UL) break; goto finish_dsa;
\
3290 case CKM_DSA_##mmm: \
3291 context->multi = PR_TRUE1; \
3292 crv = sftk_doSub##mmm(context); \
3293 if (crv != CKR_OK0x00000000UL) \
3294 break; \
3295 goto finish_dsa;
3296 INIT_DSA_SIG_MECH(SHA1)case 0x00000012UL: context->multi = 1; crv = sftk_doSubSHA1
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
3297 INIT_DSA_SIG_MECH(SHA224)case 0x00000013UL: context->multi = 1; crv = sftk_doSubSHA224
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
3298 INIT_DSA_SIG_MECH(SHA256)case 0x00000014UL: context->multi = 1; crv = sftk_doSubSHA256
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
3299 INIT_DSA_SIG_MECH(SHA384)case 0x00000015UL: context->multi = 1; crv = sftk_doSubSHA384
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
3300 INIT_DSA_SIG_MECH(SHA512)case 0x00000016UL: context->multi = 1; crv = sftk_doSubSHA512
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
3301 case CKM_DSA0x00000011UL:
3302 finish_dsa:
3303 if (key_type != CKK_DSA0x00000001UL) {
3304 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3305 break;
3306 }
3307 privKey = sftk_GetPrivKey(key, CKK_DSA0x00000001UL, &crv);
3308 if (privKey == NULL((void*)0)) {
3309 break;
3310 }
3311 context->cipherInfo = privKey;
3312 context->update = nsc_DSA_Sign_Stub;
3313 context->destroy = (privKey == key->objectInfo) ? sftk_Null : sftk_FreePrivKey;
3314 context->maxLen = DSA_MAX_SIGNATURE_LEN(32 * 2);
3315
3316 break;
3317#endif
3318 case CKM_ML_DSA0x0000001dUL: {
3319 /* set our defaults */
3320 CK_HEDGE_TYPE hedgeType = CKH_HEDGE_PREFERRED0x00000000UL;
3321 SECItem signCtx = { siBuffer, NULL((void*)0), 0 };
3322 MLDSAContext *ctptr = NULL((void*)0);
3323 SECStatus rv;
3324
3325 /* make sure we have the right key type */
3326 if (key_type != CKK_ML_DSA0x0000004aUL) {
3327 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3328 break;
3329 }
3330 /* fill in our parameters from the mechanism parameters if
3331 * supplied */
3332 if (pMechanism->ulParameterLen != 0) {
3333 CK_SIGN_ADDITIONAL_CONTEXT *param;
3334 if (pMechanism->ulParameterLen !=
3335 sizeof(CK_SIGN_ADDITIONAL_CONTEXT)) {
3336 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3337 break;
3338 }
3339 param = (CK_SIGN_ADDITIONAL_CONTEXT *)pMechanism->pParameter;
3340 hedgeType = param->hedgeVariant;
3341 signCtx.data = param->pContext;
3342 signCtx.len = param->ulContextLen;
3343 }
3344 /* fetch the key */
3345 privKey = sftk_GetPrivKey(key, key_type, &crv);
3346 if (privKey == NULL((void*)0)) {
3347 crv = CKR_HOST_MEMORY0x00000002UL;
3348 break;
3349 }
3350 /* now initialize it the signature */
3351 rv = MLDSA_SignInit(&privKey->u.mldsa, hedgeType, &signCtx, &ctptr);
3352 if (rv != SECSuccess) {
3353 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
3354 break;
3355 }
3356 /* set up our cipher info. MLDSA is only a combined hash/sign
3357 * so the hash update is our sign update, the hash end is a null
3358 * function returning a zero length value, and the final gets our
3359 * signature based on the context. cipherInfo and hashInfo are the
3360 * same pointer, so only one of them may free it: destroy does,
3361 * hashdestroy doesn't. Freeing from here rather than from
3362 * MLDSA_SignFinal is what releases the context when the operation
3363 * is abandoned instead of finished. */
3364 context->multi = PR_TRUE1;
3365 context->cipherInfo = ctptr;
3366 context->hashInfo = ctptr;
3367 context->hashUpdate = sftk_MLDSASignUpdate;
3368 context->end = sftk_NullHashEnd;
3369 context->hashdestroy = sftk_Null;
3370 context->destroy = sftk_MLDSADestroyContext;
3371 context->update = sftk_MLDSASignFinal;
3372 context->maxLen = sftk_MLDSAGetSigLen(privKey->u.mldsa.paramSet);
3373 break;
3374 }
3375
3376#define INIT_ECDSA_SIG_MECH(mmm)case CKM_ECDSA_mmm: context->multi = 1; crv = sftk_doSubmmm
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
\
3377 case CKM_ECDSA_##mmm: \
3378 context->multi = PR_TRUE1; \
3379 crv = sftk_doSub##mmm(context); \
3380 if (crv != CKR_OK0x00000000UL) \
3381 break; \
3382 goto finish_ecdsa;
3383 INIT_ECDSA_SIG_MECH(SHA1)case 0x00001042UL: context->multi = 1; crv = sftk_doSubSHA1
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
3384 INIT_ECDSA_SIG_MECH(SHA224)case 0x00001043UL: context->multi = 1; crv = sftk_doSubSHA224
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
3385 INIT_ECDSA_SIG_MECH(SHA256)case 0x00001044UL: context->multi = 1; crv = sftk_doSubSHA256
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
3386 INIT_ECDSA_SIG_MECH(SHA384)case 0x00001045UL: context->multi = 1; crv = sftk_doSubSHA384
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
3387 INIT_ECDSA_SIG_MECH(SHA512)case 0x00001046UL: context->multi = 1; crv = sftk_doSubSHA512
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
3388 case CKM_ECDSA0x00001041UL:
3389 finish_ecdsa:
3390 if (key_type != CKK_EC0x00000003UL) {
3391 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3392 break;
3393 }
3394 privKey = sftk_GetPrivKey(key, CKK_EC0x00000003UL, &crv);
3395 if (privKey == NULL((void*)0)) {
3396 crv = CKR_HOST_MEMORY0x00000002UL;
3397 break;
3398 }
3399 context->cipherInfo = privKey;
3400 context->update = nsc_ECDSASignStub;
3401 context->destroy = (privKey == key->objectInfo) ? sftk_Null : sftk_FreePrivKey;
3402 context->maxLen = MAX_ECKEY_LEN72 * 2;
3403
3404 break;
3405
3406 case CKM_EDDSA0x00001057UL:
3407 if (key_type != CKK_EC_EDWARDS0x00000040UL) {
3408 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
3409 break;
3410 }
3411
3412 if (pMechanism->pParameter) {
3413 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3414 break;
3415 }
3416
3417 privKey = sftk_GetPrivKey(key, CKK_EC_EDWARDS0x00000040UL, &crv);
3418 if (privKey == NULL((void*)0)) {
3419 crv = CKR_HOST_MEMORY0x00000002UL;
3420 break;
3421 }
3422 context->cipherInfo = privKey;
3423 context->update = nsc_EDDSASignStub;
3424 context->destroy = (privKey == key->objectInfo) ? sftk_Null : sftk_FreePrivKey;
3425 context->maxLen = MAX_ECKEY_LEN72 * 2;
3426
3427 break;
3428
3429#define INIT_HMAC_MECH(mmm)case CKM_mmm_HMAC_GENERAL: ((pMechanism->pParameter) ? ((void
)0) : PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3429)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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;
\
3430 case CKM_##mmm##_HMAC_GENERAL: \
3431 PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter) ? ((void)0) : PR_Assert("pMechanism->pParameter"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 3431
))
; \
3432 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) { \
3433 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL; \
3434 break; \
3435 } \
3436 crv = sftk_doMACInit(pMechanism->mechanism, context, key, \
3437 *(CK_ULONG *)pMechanism->pParameter); \
3438 break; \
3439 case CKM_##mmm##_HMAC: \
3440 crv = sftk_doMACInit(pMechanism->mechanism, context, key, \
3441 mmm##_LENGTH); \
3442 break;
3443
3444 INIT_HMAC_MECH(MD2)case 0x00000202UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3444)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3445 INIT_HMAC_MECH(MD5)case 0x00000212UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3445)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3446 INIT_HMAC_MECH(SHA1)case 0x00000222UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3446)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3447 INIT_HMAC_MECH(SHA224)case 0x00000257UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3447)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3448 INIT_HMAC_MECH(SHA256)case 0x00000252UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3448)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3449 INIT_HMAC_MECH(SHA384)case 0x00000262UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3449)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3450 INIT_HMAC_MECH(SHA512)case 0x00000272UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3450)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3451 INIT_HMAC_MECH(SHA3_224)case 0x000002B7UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3451)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3452 INIT_HMAC_MECH(SHA3_256)case 0x000002B2UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3452)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3453 INIT_HMAC_MECH(SHA3_384)case 0x000002C2UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3453)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3454 INIT_HMAC_MECH(SHA3_512)case 0x000002D2UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3454)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
3455
3456 case CKM_AES_CMAC_GENERAL0x0000108BUL:
3457 PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter) ? ((void)0) : PR_Assert("pMechanism->pParameter"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 3457
))
;
3458 if (!pMechanism->pParameter || pMechanism->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)) {
3459 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3460 break;
3461 }
3462 crv = sftk_doMACInit(pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism->pParameter);
3463 break;
3464 case CKM_AES_CMAC0x0000108AUL:
3465 crv = sftk_doMACInit(pMechanism->mechanism, context, key, AES_BLOCK_SIZE16);
3466 break;
3467 case CKM_SSL3_MD5_MAC0x00000380UL:
3468 PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter) ? ((void)0) : PR_Assert("pMechanism->pParameter"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 3468
))
;
3469 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
3470 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3471 break;
3472 }
3473 crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key,
3474 *(CK_ULONG *)pMechanism->pParameter);
3475 break;
3476 case CKM_SSL3_SHA1_MAC0x00000381UL:
3477 PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter) ? ((void)0) : PR_Assert("pMechanism->pParameter"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 3477
))
;
3478 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
3479 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3480 break;
3481 }
3482 crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key,
3483 *(CK_ULONG *)pMechanism->pParameter);
3484 break;
3485 case CKM_TLS_PRF_GENERAL0x80000373UL:
3486 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0);
3487 break;
3488 case CKM_TLS_MAC0x000003E4UL: {
3489 CK_TLS_MAC_PARAMS *tls12_mac_params;
3490 HASH_HashType tlsPrfHash;
3491 const char *label;
3492
3493 if (pMechanism->ulParameterLen != sizeof(CK_TLS_MAC_PARAMS)) {
3494 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3495 break;
3496 }
3497 tls12_mac_params = (CK_TLS_MAC_PARAMS *)pMechanism->pParameter;
3498 if (tls12_mac_params->prfHashMechanism == CKM_TLS_PRF0x00000378UL) {
3499 /* The TLS 1.0 and 1.1 PRF */
3500 tlsPrfHash = HASH_AlgNULL;
3501 if (tls12_mac_params->ulMacLength != 12) {
3502 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3503 break;
3504 }
3505 } else {
3506 /* The hash function for the TLS 1.2 PRF */
3507 tlsPrfHash =
3508 sftk_GetHashTypeFromMechanism(tls12_mac_params->prfHashMechanism);
3509 if (tlsPrfHash == HASH_AlgNULL ||
3510 tls12_mac_params->ulMacLength < 12) {
3511 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3512 break;
3513 }
3514 }
3515 if (tls12_mac_params->ulServerOrClient == 1) {
3516 label = "server finished";
3517 } else if (tls12_mac_params->ulServerOrClient == 2) {
3518 label = "client finished";
3519 } else {
3520 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
3521 break;
3522 }
3523 crv = sftk_TLSPRFInit(context, key, key_type, tlsPrfHash,
3524 tls12_mac_params->ulMacLength);
3525 if (crv == CKR_OK0x00000000UL) {
3526 context->hashUpdate(context->hashInfo, (unsigned char *)label, 15);
3527 }
3528 break;
3529 }
3530 case CKM_NSS_TLS_PRF_GENERAL_SHA256((0x80000000UL | 0x4E534350) + 21):
3531 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
3532 break;
3533
3534 case CKM_NSS_HMAC_CONSTANT_TIME((0x80000000UL | 0x4E534350) + 19): {
3535 sftk_MACConstantTimeCtx *ctx =
3536 sftk_HMACConstantTime_New(pMechanism, key);
3537 CK_ULONG *intpointer;
3538
3539 if (ctx == NULL((void*)0)) {
3540 crv = CKR_ARGUMENTS_BAD0x00000007UL;
3541 break;
3542 }
3543 intpointer = PORT_New(CK_ULONG)(CK_ULONG *)PORT_Alloc_Util(sizeof(CK_ULONG));
3544 if (intpointer == NULL((void*)0)) {
3545 PORT_FreePORT_Free_Util(ctx);
3546 crv = CKR_HOST_MEMORY0x00000002UL;
3547 break;
3548 }
3549 *intpointer = ctx->hash->length;
3550
3551 context->cipherInfo = intpointer;
3552 context->hashInfo = ctx;
3553 context->currentMech = pMechanism->mechanism;
3554 context->hashUpdate = sftk_HMACConstantTime_Update;
3555 context->hashdestroy = sftk_MACConstantTime_DestroyContext;
3556 context->end = sftk_MACConstantTime_EndHash;
3557 context->update = sftk_SignCopy;
3558 context->destroy = sftk_Space;
3559 context->maxLen = 64;
3560 context->multi = PR_TRUE1;
3561 break;
3562 }
3563
3564 case CKM_NSS_SSL3_MAC_CONSTANT_TIME((0x80000000UL | 0x4E534350) + 20): {
3565 sftk_MACConstantTimeCtx *ctx =
3566 sftk_SSLv3MACConstantTime_New(pMechanism, key);
3567 CK_ULONG *intpointer;
3568
3569 if (ctx == NULL((void*)0)) {
3570 crv = CKR_ARGUMENTS_BAD0x00000007UL;
3571 break;
3572 }
3573 intpointer = PORT_New(CK_ULONG)(CK_ULONG *)PORT_Alloc_Util(sizeof(CK_ULONG));
3574 if (intpointer == NULL((void*)0)) {
3575 PORT_FreePORT_Free_Util(ctx);
3576 crv = CKR_HOST_MEMORY0x00000002UL;
3577 break;
3578 }
3579 *intpointer = ctx->hash->length;
3580
3581 context->cipherInfo = intpointer;
3582 context->hashInfo = ctx;
3583 context->currentMech = pMechanism->mechanism;
3584 context->hashUpdate = sftk_SSLv3MACConstantTime_Update;
3585 context->hashdestroy = sftk_MACConstantTime_DestroyContext;
3586 context->end = sftk_MACConstantTime_EndHash;
3587 context->update = sftk_SignCopy;
3588 context->destroy = sftk_Space;
3589 context->maxLen = 64;
3590 context->multi = PR_TRUE1;
3591 break;
3592 }
3593
3594 default:
3595 crv = CKR_MECHANISM_INVALID0x00000070UL;
3596 break;
3597 }
3598
3599 if (crv != CKR_OK0x00000000UL) {
3600 if (info)
3601 PORT_FreePORT_Free_Util(info);
3602 if (pinfo)
3603 PORT_ZFreePORT_ZFree_Util(pinfo, pinfo->size);
3604 sftk_FreeContext(context);
3605 sftk_FreeSession(session);
3606 return crv;
3607 }
3608 /* At this point info/pinfo (if allocated) are linked into
3609 * context->cipherInfo and will be freed via sftk_FreeContext. */
3610 crv = sftk_InstallContext(session, SFTK_SIGN, context);
3611 if (crv != CKR_OK0x00000000UL) {
3612 sftk_FreeContext(context);
3613 }
3614 sftk_FreeSession(session);
3615 return crv;
3616}
3617
3618/** MAC one block of data by block cipher
3619 */
3620static CK_RV
3621sftk_MACBlock(SFTKSessionContext *ctx, void *blk)
3622{
3623 unsigned int outlen;
3624 return (SECSuccess == (ctx->update)(ctx->cipherInfo, ctx->macBuf, &outlen,
3625 SFTK_MAX_BLOCK_SIZE16, blk, ctx->blockSize))
3626 ? CKR_OK0x00000000UL
3627 : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
3628}
3629
3630/** MAC last (incomplete) block of data by block cipher
3631 *
3632 * Call once, then terminate MACing operation.
3633 */
3634static CK_RV
3635sftk_MACFinal(SFTKSessionContext *ctx)
3636{
3637 unsigned int padLen = ctx->padDataLength;
3638 /* pad and proceed the residual */
3639 if (ctx->isXCBC) {
3640 CK_RV crv = sftk_xcbc_mac_pad(ctx->padBuf, padLen, ctx->blockSize,
3641 ctx->k2, ctx->k3);
3642 if (crv != CKR_OK0x00000000UL)
3643 return crv;
3644 return sftk_MACBlock(ctx, ctx->padBuf);
3645 }
3646 if (padLen) {
3647 /* shd clr ctx->padLen to make sftk_MACFinal idempotent */
3648 PORT_Memsetmemset(ctx->padBuf + padLen, 0, ctx->blockSize - padLen);
3649 return sftk_MACBlock(ctx, ctx->padBuf);
3650 } else
3651 return CKR_OK0x00000000UL;
3652}
3653
3654/** The common implementation for {Sign,Verify}Update. (S/V only vary in their
3655 * setup and final operations).
3656 *
3657 * A call which results in an error terminates the operation [PKCS#11,v2.11]
3658 */
3659static CK_RV
3660sftk_MACUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
3661 CK_ULONG ulPartLen, SFTKContextType type)
3662{
3663 SFTKSession *session;
3664 SFTKSessionContext *context;
3665 CK_RV crv;
3666
3667 /* make sure we're legal */
3668 crv = sftk_GetContext(hSession, &context, type, PR_TRUE1, &session);
3669 if (crv
3.1
'crv' is equal to CKR_OK
!= CKR_OK0x00000000UL)
4
Taking false branch
3670 return crv;
3671
3672 if (context->hashInfo) {
5
Assuming field 'hashInfo' is null
6
Taking false branch
3673#if (ULONG_MAX(9223372036854775807L *2UL+1UL) > UINT_MAX(2147483647 *2U +1U))
3674 while (ulPartLen > UINT_MAX(2147483647 *2U +1U)) {
3675 (*context->hashUpdate)(context->cipherInfo, pPart, UINT_MAX(2147483647 *2U +1U));
3676 pPart += UINT_MAX(2147483647 *2U +1U);
3677 ulPartLen -= UINT_MAX(2147483647 *2U +1U);
3678 }
3679#endif
3680 (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen);
3681 } else {
3682 /* must be block cipher MACing */
3683
3684 unsigned int blkSize = context->blockSize;
7
'blkSize' initialized here
3685 unsigned char *residual = /* free room in context->padBuf */
3686 context->padBuf + context->padDataLength;
3687 unsigned int minInput = /* min input for MACing at least one block */
3688 blkSize - context->padDataLength;
3689
3690 /* not enough data even for one block */
3691 if (ulPartLen <= minInput) {
8
Assuming 'ulPartLen' is > 'minInput'
9
Taking false branch
3692 PORT_Memcpymemcpy(residual, pPart, ulPartLen);
3693 context->padDataLength += ulPartLen;
3694 goto cleanup;
3695 }
3696 /* MACing residual */
3697 if (context->padDataLength) {
10
Assuming field 'padDataLength' is 0
11
Taking false branch
3698 PORT_Memcpymemcpy(residual, pPart, minInput);
3699 ulPartLen -= minInput;
3700 pPart += minInput;
3701 if (CKR_OK0x00000000UL != (crv = sftk_MACBlock(context, context->padBuf)))
3702 goto terminate;
3703 }
3704 /* MACing full blocks */
3705 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 3712
3706 if (CKR_OK0x00000000UL != (crv = sftk_MACBlock(context, pPart)))
14
Taking false branch
3707 goto terminate;
3708 ulPartLen -= blkSize;
3709 pPart += blkSize;
15
Null pointer value stored to 'pPart'
3710 }
3711 /* save the residual */
3712 if ((context->padDataLength = ulPartLen))
18
Assuming field 'padDataLength' is not equal to 0
19
Taking true branch
3713 PORT_Memcpymemcpy(context->padBuf, pPart, ulPartLen);
20
Null pointer passed to 2nd parameter expecting 'nonnull'
3714 } /* blk cipher MACing */
3715
3716 goto cleanup;
3717
3718terminate:
3719 sftk_TerminateOp(session, type);
3720cleanup:
3721 sftk_FreeSession(session);
3722 return crv;
3723}
3724
3725/* NSC_SignUpdate continues a multiple-part signature operation,
3726 * where the signature is (will be) an appendix to the data,
3727 * and plaintext cannot be recovered from the signature
3728 *
3729 * A call which results in an error terminates the operation [PKCS#11,v2.11]
3730 */
3731CK_RV
3732NSC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
3733 CK_ULONG ulPartLen)
3734{
3735 CHECK_FORK();
3736 return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN);
3737}
3738
3739struct SFTK_SESSION_FLAGS {
3740 CK_FLAGS flag;
3741 SFTKContextType type;
3742};
3743
3744const static struct SFTK_SESSION_FLAGS sftk_session_flags[] = {
3745 { CKF_ENCRYPT0x00000100UL, SFTK_ENCRYPT },
3746 { CKF_DECRYPT0x00000200UL, SFTK_DECRYPT },
3747 { CKF_DIGEST0x00000400UL, SFTK_HASH },
3748 { CKF_SIGN0x00000800UL, SFTK_SIGN },
3749 { CKF_SIGN_RECOVER0x00001000UL, SFTK_SIGN_RECOVER },
3750 { CKF_VERIFY0x00002000, SFTK_VERIFY },
3751 { CKF_VERIFY_RECOVER0x00004000UL, SFTK_VERIFY_RECOVER },
3752 { CKF_MESSAGE_ENCRYPT0x00000002UL, SFTK_MESSAGE_ENCRYPT },
3753 { CKF_MESSAGE_DECRYPT0x00000004UL, SFTK_MESSAGE_DECRYPT },
3754 { CKF_MESSAGE_SIGN0x00000008UL, SFTK_MESSAGE_SIGN },
3755 { CKF_MESSAGE_VERIFY0x00000010UL, SFTK_MESSAGE_VERIFY },
3756};
3757const static int sftk_flag_count = PR_ARRAY_SIZE(sftk_session_flags)(sizeof(sftk_session_flags) / sizeof((sftk_session_flags)[0])
)
;
3758
3759/*
3760 * Cancel one or more operations running on the existing session.
3761 */
3762CK_RV
3763NSC_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags)
3764{
3765 SFTKSession *session;
3766 SFTKSessionContext *context;
3767 CK_RV gcrv = CKR_OK0x00000000UL;
3768 CK_RV crv;
3769 int i;
3770
3771 for (i = 0; i < sftk_flag_count; i++) {
3772 if (flags & sftk_session_flags[i].flag) {
3773 flags &= ~sftk_session_flags[i].flag;
3774 crv = sftk_GetContext(hSession, &context, sftk_session_flags[i].type, PR_TRUE1, &session);
3775 if (crv != CKR_OK0x00000000UL) {
3776 gcrv = CKR_OPERATION_CANCEL_FAILED0x00000202UL;
3777 continue;
3778 }
3779 sftk_TerminateOp(session, sftk_session_flags[i].type);
3780 }
3781 }
3782 if (flags & CKF_FIND_OBJECTS0x00000040UL) {
3783 flags &= ~CKF_FIND_OBJECTS0x00000040UL;
3784 crv = NSC_FindObjectsFinal(hSession);
3785 if (crv != CKR_OK0x00000000UL) {
3786 gcrv = CKR_OPERATION_CANCEL_FAILED0x00000202UL;
3787 }
3788 }
3789 if (flags) {
3790 gcrv = CKR_OPERATION_CANCEL_FAILED0x00000202UL;
3791 }
3792 return gcrv;
3793}
3794
3795/* NSC_SignFinal finishes a multiple-part signature operation,
3796 * returning the signature. */
3797CK_RV
3798NSC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
3799 CK_ULONG_PTR pulSignatureLen)
3800{
3801 SFTKSession *session;
3802 SFTKSessionContext *context;
3803 unsigned int outlen = 0;
3804 unsigned int maxoutlen = *pulSignatureLen;
3805 CK_RV crv;
3806
3807 CHECK_FORK();
3808
3809 /* make sure we're legal */
3810 crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_TRUE1, &session);
3811 if (crv != CKR_OK0x00000000UL)
3812 return crv;
3813
3814 if (context->hashInfo) {
3815 unsigned int digestLen;
3816 unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH64];
3817
3818 if (!pSignature) {
3819 outlen = context->maxLen;
3820 goto finish;
3821 }
3822 (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
3823 if (SECSuccess != (context->update)(context->cipherInfo, pSignature,
3824 &outlen, maxoutlen, tmpbuf, digestLen))
3825 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
3826 /* CKR_BUFFER_TOO_SMALL here isn't continuable, let operation terminate.
3827 * Keeping "too small" CK_RV intact is a standard violation, but allows
3828 * application read EXACT signature length */
3829 PORT_Memsetmemset(tmpbuf, 0, sizeof tmpbuf);
3830 } else {
3831 /* must be block cipher MACing */
3832 outlen = context->macSize;
3833 /* null or "too small" buf doesn't terminate operation [PKCS#11,v2.11]*/
3834 if (!pSignature || maxoutlen < outlen) {
3835 if (pSignature)
3836 crv = CKR_BUFFER_TOO_SMALL0x00000150UL;
3837 goto finish;
3838 }
3839 if (CKR_OK0x00000000UL == (crv = sftk_MACFinal(context)))
3840 PORT_Memcpymemcpy(pSignature, context->macBuf, outlen);
3841 }
3842
3843 sftk_TerminateOp(session, SFTK_SIGN);
3844finish:
3845 *pulSignatureLen = outlen;
3846 sftk_FreeSession(session);
3847 return crv;
3848}
3849
3850/* NSC_Sign signs (encrypts with private key) data in a single part,
3851 * where the signature is (will be) an appendix to the data,
3852 * and plaintext cannot be recovered from the signature */
3853CK_RV
3854NSC_Sign(CK_SESSION_HANDLE hSession,
3855 CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
3856 CK_ULONG_PTR pulSignatureLen)
3857{
3858 SFTKSession *session;
3859 SFTKSessionContext *context;
3860 CK_RV crv;
3861
3862 CHECK_FORK();
3863
3864 /* make sure we're legal */
3865 crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_FALSE0, &session);
3866 if (crv != CKR_OK0x00000000UL)
3867 return crv;
3868
3869 if (!pSignature) {
3870 /* see also how C_SignUpdate implements this */
3871 *pulSignatureLen = (!context->multi || context->hashInfo)
3872 ? context->maxLen
3873 : context->macSize; /* must be block cipher MACing */
3874 goto finish;
3875 }
3876
3877 /* multi part Signing are completely implemented by SignUpdate and
3878 * sign Final */
3879 if (context->multi) {
3880 /* SignFinal can't follow failed SignUpdate */
3881 if (CKR_OK0x00000000UL == (crv = NSC_SignUpdate(hSession, pData, ulDataLen)))
3882 crv = NSC_SignFinal(hSession, pSignature, pulSignatureLen);
3883 } else {
3884 /* single-part PKC signature (e.g. CKM_ECDSA) */
3885 unsigned int outlen;
3886 unsigned int maxoutlen = *pulSignatureLen;
3887 if (SECSuccess != (*context->update)(context->cipherInfo, pSignature,
3888 &outlen, maxoutlen, pData, ulDataLen))
3889 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
3890 *pulSignatureLen = (CK_ULONG)outlen;
3891 /* "too small" here is certainly continuable */
3892 if (crv != CKR_BUFFER_TOO_SMALL0x00000150UL)
3893 sftk_TerminateOp(session, SFTK_SIGN);
3894 } /* single-part */
3895
3896finish:
3897 sftk_FreeSession(session);
3898 return crv;
3899}
3900
3901/*
3902 ************** Crypto Functions: Sign Recover ************************
3903 */
3904/* NSC_SignRecoverInit initializes a signature operation,
3905 * where the (digest) data can be recovered from the signature.
3906 * E.g. encryption with the user's private key */
3907CK_RV
3908NSC_SignRecoverInit(CK_SESSION_HANDLE hSession,
3909 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
3910{
3911 CHECK_FORK();
3912
3913 switch (pMechanism->mechanism) {
3914 case CKM_RSA_PKCS0x00000001UL:
3915 case CKM_RSA_X_5090x00000003UL:
3916 return NSC_SignInit(hSession, pMechanism, hKey);
3917 default:
3918 break;
3919 }
3920 return CKR_MECHANISM_INVALID0x00000070UL;
3921}
3922
3923/* NSC_SignRecover signs data in a single operation
3924 * where the (digest) data can be recovered from the signature.
3925 * E.g. encryption with the user's private key */
3926CK_RV
3927NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
3928 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
3929{
3930 CHECK_FORK();
3931
3932 return NSC_Sign(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
3933}
3934
3935/*
3936 ************** Crypto Functions: verify ************************
3937 */
3938
3939/* Handle RSA Signature formatting */
3940static SECStatus
3941sftk_hashCheckSign(void *ctx, const unsigned char *sig,
3942 unsigned int sigLen, const unsigned char *digest,
3943 unsigned int digestLen)
3944{
3945 SFTKHashVerifyInfo *info = ctx;
3946 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("info->key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 3946))
;
3947 if (info->key->keyType != NSSLOWKEYRSAKey) {
3948 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
3949 return SECFailure;
3950 }
3951
3952 return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, digest,
3953 digestLen);
3954}
3955
3956SECStatus
3957RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key,
3958 const unsigned char *sig, unsigned int sigLen,
3959 const unsigned char *digestData, unsigned int digestLen)
3960{
3961 unsigned char *pkcs1DigestInfoData;
3962 SECItem pkcs1DigestInfo;
3963 SECItem digest;
3964 unsigned int bufferSize;
3965 SECStatus rv;
3966
3967 /* pkcs1DigestInfo.data must be less than key->u.rsa.modulus.len */
3968 bufferSize = key->u.rsa.modulus.len;
3969 pkcs1DigestInfoData = PORT_ZAllocPORT_ZAlloc_Util(bufferSize);
3970 if (!pkcs1DigestInfoData) {
3971 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_NO_MEMORY);
3972 return SECFailure;
3973 }
3974
3975 pkcs1DigestInfo.data = pkcs1DigestInfoData;
3976 pkcs1DigestInfo.len = bufferSize;
3977
3978 /* decrypt the block */
3979 rv = RSA_CheckSignRecover(&key->u.rsa, pkcs1DigestInfo.data,
3980 &pkcs1DigestInfo.len, pkcs1DigestInfo.len,
3981 sig, sigLen);
3982 if (rv != SECSuccess) {
3983 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_SIGNATURE);
3984 } else {
3985 digest.data = (PRUint8 *)digestData;
3986 digest.len = digestLen;
3987 rv = _SGN_VerifyPKCS1DigestInfo(
3988 digestOid, &digest, &pkcs1DigestInfo,
3989 PR_FALSE0 /*XXX: unsafeAllowMissingParameters*/);
3990 }
3991
3992 PORT_ZFreePORT_ZFree_Util(pkcs1DigestInfoData, bufferSize);
3993 return rv;
3994}
3995
3996static SECStatus
3997sftk_RSACheckSign(void *ctx, const unsigned char *sig,
3998 unsigned int sigLen, const unsigned char *digest,
3999 unsigned int digestLen)
4000{
4001 NSSLOWKEYPublicKey *key = ctx;
4002 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4002))
;
4003 if (key->keyType != NSSLOWKEYRSAKey) {
4004 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
4005 return SECFailure;
4006 }
4007
4008 return RSA_CheckSign(&key->u.rsa, sig, sigLen, digest, digestLen);
4009}
4010
4011static SECStatus
4012sftk_RSACheckSignRaw(void *ctx, const unsigned char *sig,
4013 unsigned int sigLen, const unsigned char *digest,
4014 unsigned int digestLen)
4015{
4016 NSSLOWKEYPublicKey *key = ctx;
4017 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4017))
;
4018 if (key->keyType != NSSLOWKEYRSAKey) {
4019 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
4020 return SECFailure;
4021 }
4022
4023 return RSA_CheckSignRaw(&key->u.rsa, sig, sigLen, digest, digestLen);
4024}
4025
4026static SECStatus
4027sftk_RSACheckSignPSS(void *ctx, const unsigned char *sig,
4028 unsigned int sigLen, const unsigned char *digest,
4029 unsigned int digestLen)
4030{
4031 SFTKPSSVerifyInfo *info = ctx;
4032 HASH_HashType hashAlg;
4033 HASH_HashType maskHashAlg;
4034 CK_RSA_PKCS_PSS_PARAMS *params = &info->params;
4035
4036 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey)((info->key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("info->key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4036))
;
4037 if (info->key->keyType != NSSLOWKEYRSAKey) {
4038 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
4039 return SECFailure;
4040 }
4041
4042 hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg);
4043 maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf);
4044
4045 return RSA_CheckSignPSS(&info->key->u.rsa, hashAlg, maskHashAlg,
4046 params->sLen, sig, sigLen, digest, digestLen);
4047}
4048
4049/* NSC_VerifyInit initializes a verification operation,
4050 * where the signature is an appendix to the data,
4051 * and plaintext cannot be recovered from the signature (e.g. DSA) */
4052CK_RV
4053NSC_VerifyInit(CK_SESSION_HANDLE hSession,
4054 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
4055{
4056 SFTKSession *session;
4057 SFTKObject *key;
4058 SFTKSessionContext *context;
4059 CK_KEY_TYPE key_type;
4060 CK_RV crv = CKR_OK0x00000000UL;
4061 NSSLOWKEYPublicKey *pubKey;
4062 SFTKHashVerifyInfo *info = NULL((void*)0);
4063 SFTKPSSVerifyInfo *pinfo = NULL((void*)0);
4064
4065 CHECK_FORK();
4066
4067 /* Block Cipher MACing Algorithms use a different Context init method..*/
4068 crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY0x0000010AUL, SFTK_VERIFY);
4069 if (crv != CKR_FUNCTION_NOT_SUPPORTED0x00000054UL)
4070 return crv;
4071
4072 session = sftk_SessionFromHandle(hSession);
4073 if (session == NULL((void*)0))
4074 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4075 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_VERIFY, &key,
4076 hKey, &key_type, CKO_PUBLIC_KEY0x00000002UL, CKA_VERIFY0x0000010AUL);
4077 if (crv != CKR_OK0x00000000UL) {
4078 sftk_FreeSession(session);
4079 return crv;
4080 }
4081
4082 context->multi = PR_FALSE0;
4083
4084#define INIT_RSA_VFY_MECH(mmm)case CKM_mmm_RSA_PKCS: context->multi = 1; crv = sftk_doSubmmm
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_mmm; goto finish_rsa
;
\
4085 case CKM_##mmm##_RSA_PKCS: \
4086 context->multi = PR_TRUE1; \
4087 crv = sftk_doSub##mmm(context); \
4088 if (crv != CKR_OK0x00000000UL) \
4089 break; \
4090 context->verify = sftk_hashCheckSign; \
4091 info = PORT_New(SFTKHashVerifyInfo)(SFTKHashVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKHashVerifyInfo
))
; \
4092 if (info == NULL((void*)0)) { \
4093 crv = CKR_HOST_MEMORY0x00000002UL; \
4094 break; \
4095 } \
4096 info->hashOid = SEC_OID_##mmm; \
4097 goto finish_rsa;
4098
4099 switch (pMechanism->mechanism) {
4100 INIT_RSA_VFY_MECH(MD5)case 0x00000005UL: context->multi = 1; crv = sftk_doSubMD5
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_MD5; goto finish_rsa
;
4101 INIT_RSA_VFY_MECH(MD2)case 0x00000004UL: context->multi = 1; crv = sftk_doSubMD2
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_MD2; goto finish_rsa
;
4102 INIT_RSA_VFY_MECH(SHA1)case 0x00000006UL: context->multi = 1; crv = sftk_doSubSHA1
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_SHA1; goto
finish_rsa;
4103 INIT_RSA_VFY_MECH(SHA224)case 0x00000046UL: context->multi = 1; crv = sftk_doSubSHA224
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_SHA224; goto
finish_rsa;
4104 INIT_RSA_VFY_MECH(SHA256)case 0x00000040UL: context->multi = 1; crv = sftk_doSubSHA256
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_SHA256; goto
finish_rsa;
4105 INIT_RSA_VFY_MECH(SHA384)case 0x00000041UL: context->multi = 1; crv = sftk_doSubSHA384
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_SHA384; goto
finish_rsa;
4106 INIT_RSA_VFY_MECH(SHA512)case 0x00000042UL: context->multi = 1; crv = sftk_doSubSHA512
(context); if (crv != 0x00000000UL) break; context->verify
= sftk_hashCheckSign; info = (SFTKHashVerifyInfo *)PORT_Alloc_Util
(sizeof(SFTKHashVerifyInfo)); if (info == ((void*)0)) { crv =
0x00000002UL; break; } info->hashOid = SEC_OID_SHA512; goto
finish_rsa;
4107
4108 case CKM_RSA_PKCS0x00000001UL:
4109 context->verify = sftk_RSACheckSign;
4110 goto finish_rsa;
4111 case CKM_RSA_X_5090x00000003UL:
4112 context->verify = sftk_RSACheckSignRaw;
4113 finish_rsa:
4114 if (key_type != CKK_RSA0x00000000UL) {
4115 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4116 break;
4117 }
4118 context->rsa = PR_TRUE1;
4119 pubKey = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv);
4120 if (pubKey == NULL((void*)0)) {
4121 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4122 break;
4123 }
4124 if (info) {
4125 info->key = pubKey;
4126 context->cipherInfo = info;
4127 context->destroy = sftk_Space;
4128 } else {
4129 context->cipherInfo = pubKey;
4130 context->destroy = sftk_Null;
4131 }
4132 break;
4133
4134 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;
4135 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;
4136 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;
4137 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;
4138 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;
4139 case CKM_RSA_PKCS_PSS0x0000000DUL:
4140 finish_rsa_pss:
4141 if (key_type != CKK_RSA0x00000000UL) {
4142 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4143 break;
4144 }
4145 context->rsa = PR_TRUE1;
4146 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
4147 !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) {
4148 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4149 break;
4150 }
4151 pinfo = PORT_New(SFTKPSSVerifyInfo)(SFTKPSSVerifyInfo *)PORT_Alloc_Util(sizeof(SFTKPSSVerifyInfo
))
;
4152 if (pinfo == NULL((void*)0)) {
4153 crv = CKR_HOST_MEMORY0x00000002UL;
4154 break;
4155 }
4156 pinfo->size = sizeof(SFTKPSSVerifyInfo);
4157 pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter;
4158 pinfo->key = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv);
4159 if (pinfo->key == NULL((void*)0)) {
4160 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4161 break;
4162 }
4163 context->cipherInfo = pinfo;
4164 context->destroy = sftk_ZSpace;
4165 context->verify = sftk_RSACheckSignPSS;
4166 break;
4167
4168#ifndef NSS_DISABLE_DSA
4169 INIT_DSA_SIG_MECH(SHA1)case 0x00000012UL: context->multi = 1; crv = sftk_doSubSHA1
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
4170 INIT_DSA_SIG_MECH(SHA224)case 0x00000013UL: context->multi = 1; crv = sftk_doSubSHA224
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
4171 INIT_DSA_SIG_MECH(SHA256)case 0x00000014UL: context->multi = 1; crv = sftk_doSubSHA256
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
4172 INIT_DSA_SIG_MECH(SHA384)case 0x00000015UL: context->multi = 1; crv = sftk_doSubSHA384
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
4173 INIT_DSA_SIG_MECH(SHA512)case 0x00000016UL: context->multi = 1; crv = sftk_doSubSHA512
(context); if (crv != 0x00000000UL) break; goto finish_dsa;
4174 case CKM_DSA0x00000011UL:
4175 finish_dsa:
4176 if (key_type != CKK_DSA0x00000001UL) {
4177 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4178 break;
4179 }
4180 pubKey = sftk_GetPubKey(key, CKK_DSA0x00000001UL, &crv);
4181 if (pubKey == NULL((void*)0)) {
4182 break;
4183 }
4184 context->cipherInfo = pubKey;
4185 context->verify = nsc_DSA_Verify_Stub;
4186 context->destroy = sftk_Null;
4187 break;
4188#endif
4189 case CKM_ML_DSA0x0000001dUL: {
4190 /* set our defaults */
4191 SECItem signCtx = { siBuffer, NULL((void*)0), 0 };
4192 MLDSAContext *ctptr = NULL((void*)0);
4193 SECStatus rv;
4194
4195 /* make sure we have the right key type */
4196 if (key_type != CKK_ML_DSA0x0000004aUL) {
4197 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4198 break;
4199 }
4200 /* fill in our parameters from the mechanism parameters if
4201 * supplied */
4202 if (pMechanism->ulParameterLen != 0) {
4203 CK_SIGN_ADDITIONAL_CONTEXT *param;
4204 if (pMechanism->ulParameterLen !=
4205 sizeof(CK_SIGN_ADDITIONAL_CONTEXT)) {
4206 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4207 break;
4208 }
4209 param = (CK_SIGN_ADDITIONAL_CONTEXT *)pMechanism->pParameter;
4210 signCtx.data = param->pContext;
4211 signCtx.len = param->ulContextLen;
4212 }
4213 /* fetch the key */
4214 pubKey = sftk_GetPubKey(key, key_type, &crv);
4215 if (pubKey == NULL((void*)0)) {
4216 /* crv already set */
4217 break;
4218 }
4219 /* now initialize it the signature */
4220 rv = MLDSA_VerifyInit(&(pubKey->u.mldsa), &signCtx, &ctptr);
4221 if (rv != SECSuccess) {
4222 crv = sftk_MapVerifyError(PORT_GetErrorPORT_GetError_Util());
4223 break;
4224 }
4225 /* set up our cipher info. MLDSA is only a combined hash/sign
4226 * so the hash update is our sign update, the hash end is a null
4227 * function returning a zero length value, and the final gets our
4228 * signature based on the context. cipherInfo and hashInfo are the
4229 * same pointer, so only one of them may free it: destroy does,
4230 * hashdestroy doesn't. Freeing from here rather than from
4231 * MLDSA_VerifyFinal is what releases the context when the
4232 * operation is abandoned instead of finished. */
4233 context->multi = PR_TRUE1;
4234 context->cipherInfo = ctptr;
4235 context->hashInfo = ctptr;
4236 context->hashUpdate = sftk_MLDSAVerifyUpdate;
4237 context->end = sftk_NullHashEnd;
4238 context->hashdestroy = sftk_Null;
4239 context->destroy = sftk_MLDSADestroyContext;
4240 context->verify = sftk_MLDSAVerifyFinal;
4241 context->maxLen = sftk_MLDSAGetSigLen(pubKey->u.mldsa.paramSet);
4242 break;
4243 }
4244
4245 INIT_ECDSA_SIG_MECH(SHA1)case 0x00001042UL: context->multi = 1; crv = sftk_doSubSHA1
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
4246 INIT_ECDSA_SIG_MECH(SHA224)case 0x00001043UL: context->multi = 1; crv = sftk_doSubSHA224
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
4247 INIT_ECDSA_SIG_MECH(SHA256)case 0x00001044UL: context->multi = 1; crv = sftk_doSubSHA256
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
4248 INIT_ECDSA_SIG_MECH(SHA384)case 0x00001045UL: context->multi = 1; crv = sftk_doSubSHA384
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
4249 INIT_ECDSA_SIG_MECH(SHA512)case 0x00001046UL: context->multi = 1; crv = sftk_doSubSHA512
(context); if (crv != 0x00000000UL) break; goto finish_ecdsa;
4250 case CKM_ECDSA0x00001041UL:
4251 finish_ecdsa:
4252 if (key_type != CKK_EC0x00000003UL) {
4253 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4254 break;
4255 }
4256 pubKey = sftk_GetPubKey(key, CKK_EC0x00000003UL, &crv);
4257 if (pubKey == NULL((void*)0)) {
4258 crv = CKR_HOST_MEMORY0x00000002UL;
4259 break;
4260 }
4261 context->cipherInfo = pubKey;
4262 context->verify = nsc_ECDSAVerifyStub;
4263 context->destroy = sftk_Null;
4264 break;
4265
4266 INIT_HMAC_MECH(MD2)case 0x00000202UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4266)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4267 INIT_HMAC_MECH(MD5)case 0x00000212UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4267)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4268 INIT_HMAC_MECH(SHA1)case 0x00000222UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4268)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4269 INIT_HMAC_MECH(SHA224)case 0x00000257UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4269)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4270 INIT_HMAC_MECH(SHA256)case 0x00000252UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4270)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4271 INIT_HMAC_MECH(SHA384)case 0x00000262UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4271)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4272 INIT_HMAC_MECH(SHA512)case 0x00000272UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4272)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4273 INIT_HMAC_MECH(SHA3_224)case 0x000002B7UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4273)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4274 INIT_HMAC_MECH(SHA3_256)case 0x000002B2UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4274)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4275 INIT_HMAC_MECH(SHA3_384)case 0x000002C2UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4275)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4276 INIT_HMAC_MECH(SHA3_512)case 0x000002D2UL: ((pMechanism->pParameter) ? ((void)0) :
PR_Assert("pMechanism->pParameter", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4276)); if ((!pMechanism->pParameter || pMechanism->ulParameterLen
< sizeof(CK_ULONG))) { 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
;
4277
4278 case CKM_EDDSA0x00001057UL:
4279 if (key_type != CKK_EC_EDWARDS0x00000040UL) {
4280 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4281 break;
4282 }
4283 pubKey = sftk_GetPubKey(key, CKK_EC_EDWARDS0x00000040UL, &crv);
4284 if (pubKey == NULL((void*)0)) {
4285 crv = CKR_HOST_MEMORY0x00000002UL;
4286 break;
4287 }
4288
4289 if (pMechanism->pParameter) {
4290 crv = CKR_FUNCTION_NOT_SUPPORTED0x00000054UL;
4291 break;
4292 }
4293
4294 context->cipherInfo = pubKey;
4295 context->verify = nsc_EDDSAVerifyStub;
4296 context->destroy = sftk_Null;
4297 break;
4298
4299 case CKM_SSL3_MD5_MAC0x00000380UL:
4300 PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter) ? ((void)0) : PR_Assert("pMechanism->pParameter"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 4300
))
;
4301 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
4302 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4303 break;
4304 }
4305 crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key,
4306 *(CK_ULONG *)pMechanism->pParameter);
4307 break;
4308 case CKM_SSL3_SHA1_MAC0x00000381UL:
4309 PORT_Assert(pMechanism->pParameter)((pMechanism->pParameter) ? ((void)0) : PR_Assert("pMechanism->pParameter"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 4309
))
;
4310 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_ULONG))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_ULONG))
) {
4311 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4312 break;
4313 }
4314 crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key,
4315 *(CK_ULONG *)pMechanism->pParameter);
4316 break;
4317 case CKM_TLS_PRF_GENERAL0x80000373UL:
4318 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0);
4319 break;
4320 case CKM_NSS_TLS_PRF_GENERAL_SHA256((0x80000000UL | 0x4E534350) + 21):
4321 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0);
4322 break;
4323
4324 default:
4325 crv = CKR_MECHANISM_INVALID0x00000070UL;
4326 break;
4327 }
4328
4329 if (crv != CKR_OK0x00000000UL) {
4330 if (info)
4331 PORT_FreePORT_Free_Util(info);
4332 if (pinfo)
4333 PORT_ZFreePORT_ZFree_Util(pinfo, pinfo->size);
4334 sftk_FreeContext(context);
4335 sftk_FreeSession(session);
4336 return crv;
4337 }
4338 /* At this point info/pinfo (if allocated) are linked into
4339 * context->cipherInfo and will be freed via sftk_FreeContext. */
4340 crv = sftk_InstallContext(session, SFTK_VERIFY, context);
4341 if (crv != CKR_OK0x00000000UL) {
4342 sftk_FreeContext(context);
4343 }
4344 sftk_FreeSession(session);
4345 return crv;
4346}
4347
4348/* NSC_Verify verifies a signature in a single-part operation,
4349 * where the signature is an appendix to the data,
4350 * and plaintext cannot be recovered from the signature */
4351CK_RV
4352NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
4353 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
4354{
4355 SFTKSession *session;
4356 SFTKSessionContext *context;
4357 CK_RV crv;
4358
4359 CHECK_FORK();
4360
4361 /* make sure we're legal */
4362 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE0, &session);
4363 if (crv != CKR_OK0x00000000UL)
4364 return crv;
4365
4366 /* multi part Verifying are completely implemented by VerifyUpdate and
4367 * VerifyFinal */
4368 if (context->multi) {
4369 /* VerifyFinal can't follow failed VerifyUpdate */
4370 if (CKR_OK0x00000000UL == (crv = NSC_VerifyUpdate(hSession, pData, ulDataLen)))
4371 crv = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen);
4372 } else {
4373 if (SECSuccess != (*context->verify)(context->cipherInfo, pSignature,
4374 ulSignatureLen, pData, ulDataLen))
4375 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
4376
4377 sftk_TerminateOp(session, SFTK_VERIFY);
4378 }
4379 sftk_FreeSession(session);
4380 return crv;
4381}
4382
4383/* NSC_VerifyUpdate continues a multiple-part verification operation,
4384 * where the signature is an appendix to the data,
4385 * and plaintext cannot be recovered from the signature
4386 *
4387 * A call which results in an error terminates the operation [PKCS#11,v2.11]
4388 */
4389CK_RV
4390NSC_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
4391 CK_ULONG ulPartLen)
4392{
4393 CHECK_FORK();
4394 return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY);
3
Calling 'sftk_MACUpdate'
4395}
4396
4397/* NSC_VerifyFinal finishes a multiple-part verification operation,
4398 * checking the signature. */
4399CK_RV
4400NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
4401 CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
4402{
4403 SFTKSession *session;
4404 SFTKSessionContext *context;
4405 CK_RV crv;
4406
4407 CHECK_FORK();
4408
4409 if (!pSignature)
4410 return CKR_ARGUMENTS_BAD0x00000007UL;
4411
4412 /* make sure we're legal */
4413 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE1, &session);
4414 if (crv != CKR_OK0x00000000UL)
4415 return crv;
4416
4417 if (context->hashInfo) {
4418 unsigned int digestLen;
4419 unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH64];
4420
4421 (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
4422 if (SECSuccess != (context->verify)(context->cipherInfo, pSignature,
4423 ulSignatureLen, tmpbuf, digestLen))
4424 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
4425 PORT_Memsetmemset(tmpbuf, 0, sizeof tmpbuf);
4426 } else if (ulSignatureLen != context->macSize) {
4427 /* must be block cipher MACing */
4428 crv = CKR_SIGNATURE_LEN_RANGE0x000000C1UL;
4429 } else if (CKR_OK0x00000000UL == (crv = sftk_MACFinal(context))) {
4430 if (NSS_SecureMemcmp(pSignature, context->macBuf, ulSignatureLen))
4431 crv = CKR_SIGNATURE_INVALID0x000000C0UL;
4432 }
4433
4434 sftk_TerminateOp(session, SFTK_VERIFY);
4435 sftk_FreeSession(session);
4436 return crv;
4437}
4438
4439/*
4440 ************** Crypto Functions: Verify Signature ************************
4441 * some algorithms need the signature at the beginning of the verification,
4442 * VerifySignature provides such and API. For algorithms that don't need
4443 * the signature first, we stash the signature and just pass it to
4444 * NSC_VerifyXXX.
4445 */
4446CK_RV
4447NSC_VerifySignatureInit(CK_SESSION_HANDLE hSession,
4448 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey,
4449 CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
4450{
4451 SFTKSession *session;
4452 SFTKSessionContext *context;
4453 CK_RV crv;
4454 SECItem tmpItem;
4455
4456 crv = NSC_VerifyInit(hSession, pMechanism, hKey);
4457 if (crv != CKR_OK0x00000000UL) {
4458 return crv;
4459 }
4460
4461 CHECK_FORK();
4462
4463 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE0, &session);
4464 if (crv != CKR_OK0x00000000UL)
4465 return crv;
4466
4467 tmpItem.type = siBuffer;
4468 tmpItem.data = pSignature;
4469 tmpItem.len = ulSignatureLen;
4470 context->signature = SECITEM_DupItemSECITEM_DupItem_Util(&tmpItem);
4471 if (!context->signature) {
4472 sftk_TerminateOp(session, SFTK_VERIFY);
4473 sftk_FreeSession(session);
4474 return CKR_HOST_MEMORY0x00000002UL;
4475 }
4476 sftk_FreeSession(session);
4477 return CKR_OK0x00000000UL;
4478}
4479
4480CK_RV
4481NSC_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
4482 CK_ULONG ulDataLen)
4483{
4484 SFTKSession *session;
4485 SFTKSessionContext *context;
4486 CK_RV crv;
4487
4488 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE0, &session);
4489 if (crv != CKR_OK0x00000000UL)
4490 return crv;
4491
4492 /* make sure we're legal */
4493 if (!context->signature) {
4494 sftk_FreeSession(session);
4495 return CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
4496 }
4497 crv = NSC_Verify(hSession, pData, ulDataLen,
4498 context->signature->data, context->signature->len);
4499 /* we free the signature here because the context is part of the session and has
4500 * a lifetime tied to the session. So we want to hold our reference to the
4501 * session so it doesn't go away on us */
4502 sftk_FreeSession(session);
4503 return crv;
4504}
4505
4506CK_RV
4507NSC_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
4508 CK_ULONG ulPartLen)
4509{
4510 SFTKSession *session;
4511 SFTKSessionContext *context;
4512 CK_RV crv;
4513
4514 /* make sure we're legal */
4515 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE1, &session);
4516 if (crv != CKR_OK0x00000000UL)
4517 return crv;
4518
4519 /* like verify above, we bother keeping the session to make sure the context
4520 * doesn't go way on use. there's little chance that it will since that application
4521 * must protect against multiple threads calling the same same session at the same
4522 * time (nss has session locks for this), but there are a couple of corner cases,
4523 * (like close all sessions, or shutting down the whole module. Also if the
4524 * application breaks the contract, we want to just fail rather than crash */
4525 if (!context->signature) {
4526 sftk_FreeSession(session);
4527 return CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
4528 }
4529 sftk_FreeSession(session);
4530 return NSC_VerifyUpdate(hSession, pPart, ulPartLen);
4531}
4532
4533CK_RV
4534NSC_VerifySignatureFinal(CK_SESSION_HANDLE hSession)
4535{
4536 SFTKSession *session;
4537 SFTKSessionContext *context;
4538 CK_RV crv;
4539
4540 /* make sure we're legal */
4541 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE1, &session);
4542 if (crv != CKR_OK0x00000000UL)
4543 return crv;
4544
4545 if (!context->signature) {
4546 sftk_FreeSession(session);
4547 return CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
4548 }
4549 crv = NSC_VerifyFinal(hSession, context->signature->data,
4550 context->signature->len);
4551 /* see comment in NSC_VerifySignature() */
4552 sftk_FreeSession(session);
4553 return crv;
4554}
4555
4556/*
4557 ************** Crypto Functions: Verify Recover ************************
4558 */
4559static SECStatus
4560sftk_RSACheckSignRecover(void *ctx, unsigned char *data,
4561 unsigned int *dataLen, unsigned int maxDataLen,
4562 const unsigned char *sig, unsigned int sigLen)
4563{
4564 NSSLOWKEYPublicKey *key = ctx;
4565 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4565))
;
4566 if (key->keyType != NSSLOWKEYRSAKey) {
4567 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
4568 return SECFailure;
4569 }
4570
4571 return RSA_CheckSignRecover(&key->u.rsa, data, dataLen, maxDataLen,
4572 sig, sigLen);
4573}
4574
4575static SECStatus
4576sftk_RSACheckSignRecoverRaw(void *ctx, unsigned char *data,
4577 unsigned int *dataLen, unsigned int maxDataLen,
4578 const unsigned char *sig, unsigned int sigLen)
4579{
4580 NSSLOWKEYPublicKey *key = ctx;
4581 PORT_Assert(key->keyType == NSSLOWKEYRSAKey)((key->keyType == NSSLOWKEYRSAKey) ? ((void)0) : PR_Assert
("key->keyType == NSSLOWKEYRSAKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 4581))
;
4582 if (key->keyType != NSSLOWKEYRSAKey) {
4583 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
4584 return SECFailure;
4585 }
4586
4587 return RSA_CheckSignRecoverRaw(&key->u.rsa, data, dataLen, maxDataLen,
4588 sig, sigLen);
4589}
4590
4591/* NSC_VerifyRecoverInit initializes a signature verification operation,
4592 * where the data is recovered from the signature.
4593 * E.g. Decryption with the user's public key */
4594CK_RV
4595NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
4596 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
4597{
4598 SFTKSession *session;
4599 SFTKObject *key;
4600 SFTKSessionContext *context;
4601 CK_KEY_TYPE key_type;
4602 CK_RV crv = CKR_OK0x00000000UL;
4603 NSSLOWKEYPublicKey *pubKey;
4604
4605 CHECK_FORK();
4606
4607 session = sftk_SessionFromHandle(hSession);
4608 if (session == NULL((void*)0))
4609 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
4610 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_VERIFY_RECOVER,
4611 &key, hKey, &key_type, CKO_PUBLIC_KEY0x00000002UL, CKA_VERIFY_RECOVER0x0000010BUL);
4612 if (crv != CKR_OK0x00000000UL) {
4613 sftk_FreeSession(session);
4614 return crv;
4615 }
4616
4617 context->multi = PR_TRUE1;
4618
4619 switch (pMechanism->mechanism) {
4620 case CKM_RSA_PKCS0x00000001UL:
4621 case CKM_RSA_X_5090x00000003UL:
4622 if (key_type != CKK_RSA0x00000000UL) {
4623 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
4624 break;
4625 }
4626 context->multi = PR_FALSE0;
4627 context->rsa = PR_TRUE1;
4628 pubKey = sftk_GetPubKey(key, CKK_RSA0x00000000UL, &crv);
4629 if (pubKey == NULL((void*)0)) {
4630 break;
4631 }
4632 context->cipherInfo = pubKey;
4633 context->update = pMechanism->mechanism == CKM_RSA_X_5090x00000003UL
4634 ? sftk_RSACheckSignRecoverRaw
4635 : sftk_RSACheckSignRecover;
4636 context->destroy = sftk_Null;
4637 break;
4638 default:
4639 crv = CKR_MECHANISM_INVALID0x00000070UL;
4640 break;
4641 }
4642
4643 if (crv != CKR_OK0x00000000UL) {
4644 PORT_FreePORT_Free_Util(context);
4645 sftk_FreeSession(session);
4646 return crv;
4647 }
4648 crv = sftk_InstallContext(session, SFTK_VERIFY_RECOVER, context);
4649 if (crv != CKR_OK0x00000000UL) {
4650 sftk_FreeContext(context);
4651 }
4652 sftk_FreeSession(session);
4653 return crv;
4654}
4655
4656/* NSC_VerifyRecover verifies a signature in a single-part operation,
4657 * where the data is recovered from the signature.
4658 * E.g. Decryption with the user's public key */
4659CK_RV
4660NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
4661 CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen,
4662 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
4663{
4664 SFTKSession *session;
4665 SFTKSessionContext *context;
4666 unsigned int outlen;
4667 unsigned int maxoutlen = *pulDataLen;
4668 CK_RV crv;
4669 SECStatus rv;
4670
4671 CHECK_FORK();
4672
4673 /* make sure we're legal */
4674 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY_RECOVER,
4675 PR_FALSE0, &session);
4676 if (crv != CKR_OK0x00000000UL)
4677 return crv;
4678 if (pData == NULL((void*)0)) {
4679 /* to return the actual size, we need to do the decrypt, just return
4680 * the max size, which is the size of the input signature. */
4681 *pulDataLen = ulSignatureLen;
4682 rv = SECSuccess;
4683 goto finish;
4684 }
4685
4686 rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
4687 pSignature, ulSignatureLen);
4688 *pulDataLen = (CK_ULONG)outlen;
4689
4690 sftk_TerminateOp(session, SFTK_VERIFY_RECOVER);
4691finish:
4692 sftk_FreeSession(session);
4693 return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapVerifyError(PORT_GetErrorPORT_GetError_Util());
4694}
4695
4696/*
4697 **************************** Random Functions: ************************
4698 */
4699
4700/* NSC_SeedRandom mixes additional seed material into the token's random number
4701 * generator. */
4702CK_RV
4703NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
4704 CK_ULONG ulSeedLen)
4705{
4706 SECStatus rv;
4707
4708 CHECK_FORK();
4709
4710 rv = RNG_RandomUpdate(pSeed, ulSeedLen);
4711 return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
4712}
4713
4714/* NSC_GenerateRandom generates random data. */
4715CK_RV
4716NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
4717 CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
4718{
4719 SECStatus rv;
4720
4721 CHECK_FORK();
4722
4723 rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen);
4724 /*
4725 * This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't
4726 * seeded with enough entropy.
4727 */
4728 return (rv == SECSuccess) ? CKR_OK0x00000000UL : sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
4729}
4730
4731/*
4732 **************************** Key Functions: ************************
4733 */
4734
4735/*
4736 * generate a password based encryption key. This code uses
4737 * PKCS5 to do the work.
4738 */
4739static CK_RV
4740nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
4741 void *buf, CK_ULONG *key_length, PRBool faulty3DES)
4742{
4743 SECItem *pbe_key = NULL((void*)0), iv, pwitem;
4744 CK_PBE_PARAMS *pbe_params = NULL((void*)0);
4745 CK_PKCS5_PBKD2_PARAMS2 *pbkd2_params = NULL((void*)0);
4746
4747 *key_length = 0;
4748 iv.data = NULL((void*)0);
4749 iv.len = 0;
4750
4751 if (pMechanism->mechanism == CKM_PKCS5_PBKD20x000003B0UL) {
4752 pbkd2_params = (CK_PKCS5_PBKD2_PARAMS2 *)pMechanism->pParameter;
4753 if (!pMechanism->pParameter) {
4754 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4755 }
4756
4757#ifdef SOFTOKEN_USE_PKCS5_PBKD2_PARAMS2_ONLY1
4758 if (pMechanism->ulParameterLen < sizeof(CK_PKCS5_PBKD2_PARAMS2)) {
4759 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4760 }
4761 pwitem.len = pbkd2_params->ulPasswordLen;
4762#else
4763 int v2;
4764 if (pMechanism->ulParameterLen < PR_MIN(sizeof(CK_PKCS5_PBKD2_PARAMS),((sizeof(CK_PKCS5_PBKD2_PARAMS)) < (sizeof(CK_PKCS5_PBKD2_PARAMS2
)) ? (sizeof(CK_PKCS5_PBKD2_PARAMS)) : (sizeof(CK_PKCS5_PBKD2_PARAMS2
)))
4765 sizeof(CK_PKCS5_PBKD2_PARAMS2))((sizeof(CK_PKCS5_PBKD2_PARAMS)) < (sizeof(CK_PKCS5_PBKD2_PARAMS2
)) ? (sizeof(CK_PKCS5_PBKD2_PARAMS)) : (sizeof(CK_PKCS5_PBKD2_PARAMS2
)))
) {
4766 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4767 }
4768
4769 if (sizeof(CK_PKCS5_PBKD2_PARAMS2) != sizeof(CK_PKCS5_PBKD2_PARAMS)) {
4770 if (pMechanism->ulParameterLen == sizeof(CK_PKCS5_PBKD2_PARAMS)) {
4771 v2 = 0;
4772 } else if (pMechanism->ulParameterLen == sizeof(CK_PKCS5_PBKD2_PARAMS2)) {
4773 v2 = 1;
4774 } else {
4775 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4776 }
4777 } else {
4778 /* it's unlikely that the password will be longer than 8192 bytes, if so it is
4779 * most likely a pointer => CK_PKCS5_PBKD2_PARAMS */
4780 v2 = pbkd2_params->ulPasswordLen <= CK_PKCS5_PBKD2_PARAMS_PTR_BOUNDARY8192;
4781 }
4782 pwitem.len = v2 ? pbkd2_params->ulPasswordLen : *((CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter)->ulPasswordLen;
4783#endif
4784 pwitem.data = (unsigned char *)pbkd2_params->pPassword;
4785 } else {
4786 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_PBE_PARAMS))
) {
4787 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
4788 }
4789 pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
4790 pwitem.data = (unsigned char *)pbe_params->pPassword;
4791 pwitem.len = pbe_params->ulPasswordLen;
4792 }
4793 pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES);
4794 if (pbe_key == NULL((void*)0)) {
4795 return CKR_HOST_MEMORY0x00000002UL;
4796 }
4797
4798 PORT_Memcpymemcpy(buf, pbe_key->data, pbe_key->len);
4799 *key_length = pbe_key->len;
4800 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(pbe_key, PR_TRUE1);
4801 pbe_key = NULL((void*)0);
4802
4803 if (iv.data) {
4804 if (pbe_params && pbe_params->pInitVector != NULL((void*)0)) {
4805 PORT_Memcpymemcpy(pbe_params->pInitVector, iv.data, iv.len);
4806 }
4807 PORT_FreePORT_Free_Util(iv.data);
4808 }
4809
4810 return CKR_OK0x00000000UL;
4811}
4812
4813/*
4814 * this is coded for "full" support. These selections will be limitted to
4815 * the official subset by freebl.
4816 */
4817static unsigned int
4818sftk_GetSubPrimeFromPrime(unsigned int primeBits)
4819{
4820 if (primeBits <= 1024) {
4821 return 160;
4822 } else if (primeBits <= 2048) {
4823 return 224;
4824 } else if (primeBits <= 3072) {
4825 return 256;
4826 } else if (primeBits <= 7680) {
4827 return 384;
4828 } else {
4829 return 512;
4830 }
4831}
4832
4833static CK_RV
4834nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
4835{
4836 SFTKAttribute *attribute;
4837 CK_ULONG counter;
4838 unsigned int seedBits = 0;
4839 unsigned int subprimeBits = 0;
4840 unsigned int primeBits;
4841 unsigned int j = 8; /* default to 1024 bits */
4842 CK_RV crv = CKR_OK0x00000000UL;
4843 PQGParams *params = NULL((void*)0);
4844 PQGVerify *vfy = NULL((void*)0);
4845 SECStatus rv;
4846
4847 attribute = sftk_FindAttribute(key, CKA_PRIME_BITS0x00000133UL);
4848 if (attribute == NULL((void*)0)) {
4849 attribute = sftk_FindAttribute(key, CKA_PRIME0x00000130UL);
4850 if (attribute == NULL((void*)0)) {
4851 return CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
4852 } else {
4853 primeBits = attribute->attrib.ulValueLen;
4854 sftk_FreeAttribute(attribute);
4855 }
4856 } else {
4857 primeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
4858 sftk_FreeAttribute(attribute);
4859 }
4860 if (primeBits < 1024) {
4861 j = PQG_PBITS_TO_INDEX(primeBits)(((primeBits) < 512 || (primeBits) > 1024 || (primeBits
) % 64) ? -1 : (int)((primeBits) - 512) / 64)
;
4862 if (j == (unsigned int)-1) {
4863 return CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
4864 }
4865 }
4866
4867 attribute = sftk_FindAttribute(key, CKA_NSS_PQG_SEED_BITS((0x80000000UL | 0x4E534350) + 23));
4868 if (attribute != NULL((void*)0)) {
4869 seedBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
4870 sftk_FreeAttribute(attribute);
4871 }
4872
4873 attribute = sftk_FindAttribute(key, CKA_SUBPRIME_BITS0x00000134UL);
4874 if (attribute != NULL((void*)0)) {
4875 subprimeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue;
4876 sftk_FreeAttribute(attribute);
4877 }
4878
4879 /* if P and Q are supplied, we want to generate a new G */
4880 attribute = sftk_FindAttribute(key, CKA_PRIME0x00000130UL);
4881 if (attribute != NULL((void*)0)) {
4882 PLArenaPool *arena;
4883
4884 sftk_FreeAttribute(attribute);
4885 arena = PORT_NewArenaPORT_NewArena_Util(1024);
4886 if (arena == NULL((void*)0)) {
4887 crv = CKR_HOST_MEMORY0x00000002UL;
4888 goto loser;
4889 }
4890 params = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, sizeof(*params));
4891 if (params == NULL((void*)0)) {
4892 crv = CKR_HOST_MEMORY0x00000002UL;
4893 goto loser;
4894 }
4895 params->arena = arena;
4896 crv = sftk_Attribute2SSecItem(arena, &params->prime, key, CKA_PRIME0x00000130UL);
4897 if (crv != CKR_OK0x00000000UL) {
4898 goto loser;
4899 }
4900 crv = sftk_Attribute2SSecItem(arena, &params->subPrime,
4901 key, CKA_SUBPRIME0x00000131UL);
4902 if (crv != CKR_OK0x00000000UL) {
4903 goto loser;
4904 }
4905
4906 arena = PORT_NewArenaPORT_NewArena_Util(1024);
4907 if (arena == NULL((void*)0)) {
4908 crv = CKR_HOST_MEMORY0x00000002UL;
4909 goto loser;
4910 }
4911 vfy = PORT_ArenaAllocPORT_ArenaAlloc_Util(arena, sizeof(*vfy));
4912 if (vfy == NULL((void*)0)) {
4913 crv = CKR_HOST_MEMORY0x00000002UL;
4914 goto loser;
4915 }
4916 vfy->arena = arena;
4917 crv = sftk_Attribute2SSecItem(arena, &vfy->seed, key, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21));
4918 if (crv != CKR_OK0x00000000UL) {
4919 goto loser;
4920 }
4921 crv = sftk_Attribute2SSecItem(arena, &vfy->h, key, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22));
4922 if (crv != CKR_OK0x00000000UL) {
4923 goto loser;
4924 }
4925 sftk_DeleteAttributeType(key, CKA_PRIME0x00000130UL);
4926 sftk_DeleteAttributeType(key, CKA_SUBPRIME0x00000131UL);
4927 sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21));
4928 sftk_DeleteAttributeType(key, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22));
4929 }
4930
4931 sftk_DeleteAttributeType(key, CKA_PRIME_BITS0x00000133UL);
4932 sftk_DeleteAttributeType(key, CKA_SUBPRIME_BITS0x00000134UL);
4933 sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED_BITS((0x80000000UL | 0x4E534350) + 23));
4934
4935 /* use the old PQG interface if we have old input data */
4936 if ((primeBits < 1024) || ((primeBits == 1024) && (subprimeBits == 0))) {
4937 if (seedBits == 0) {
4938 rv = PQG_ParamGen(j, &params, &vfy);
4939 } else {
4940 rv = PQG_ParamGenSeedLen(j, seedBits / 8, &params, &vfy);
4941 }
4942 } else {
4943 if (subprimeBits == 0) {
4944 subprimeBits = sftk_GetSubPrimeFromPrime(primeBits);
4945 }
4946 if (seedBits == 0) {
4947 seedBits = primeBits;
4948 }
4949 rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits / 8, &params, &vfy);
4950 }
4951
4952 if (rv != SECSuccess) {
4953 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
4954 sftk_fatalError = PR_TRUE1;
4955 }
4956 return sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
4957 }
4958 crv = sftk_AddAttributeType(key, CKA_PRIME0x00000130UL,
4959 params->prime.data, params->prime.len);
4960 if (crv != CKR_OK0x00000000UL)
4961 goto loser;
4962 crv = sftk_AddAttributeType(key, CKA_SUBPRIME0x00000131UL,
4963 params->subPrime.data, params->subPrime.len);
4964 if (crv != CKR_OK0x00000000UL)
4965 goto loser;
4966 crv = sftk_AddAttributeType(key, CKA_BASE0x00000132UL,
4967 params->base.data, params->base.len);
4968 if (crv != CKR_OK0x00000000UL)
4969 goto loser;
4970 counter = vfy->counter;
4971 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_COUNTER((0x80000000UL | 0x4E534350) + 20),
4972 &counter, sizeof(counter));
4973 if (crv != CKR_OK0x00000000UL)
4974 goto loser;
4975 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_SEED((0x80000000UL | 0x4E534350) + 21),
4976 vfy->seed.data, vfy->seed.len);
4977 if (crv != CKR_OK0x00000000UL)
4978 goto loser;
4979 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_H((0x80000000UL | 0x4E534350) + 22),
4980 vfy->h.data, vfy->h.len);
4981 if (crv != CKR_OK0x00000000UL)
4982 goto loser;
4983
4984loser:
4985 if (params) {
4986 PQG_DestroyParams(params);
4987 }
4988
4989 if (vfy) {
4990 PQG_DestroyVerify(vfy);
4991 }
4992 return crv;
4993}
4994
4995static CK_RV
4996nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
4997 CK_ULONG *key_length)
4998{
4999 CK_RV crv = CKR_OK0x00000000UL;
5000
5001 switch (mechanism) {
5002#ifndef NSS_DISABLE_DEPRECATED_RC2
5003 case CKM_RC2_KEY_GEN0x00000100UL:
5004 *key_type = CKK_RC20x00000011UL;
5005 if (*key_length == 0)
5006 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5007 break;
5008#endif /* NSS_DISABLE_DEPRECATED_RC2 */
5009#if NSS_SOFTOKEN_DOES_RC5
5010 case CKM_RC5_KEY_GEN0x00000330UL:
5011 *key_type = CKK_RC50x00000019UL;
5012 if (*key_length == 0)
5013 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5014 break;
5015#endif
5016 case CKM_RC4_KEY_GEN0x00000110UL:
5017 *key_type = CKK_RC40x00000012UL;
5018 if (*key_length == 0)
5019 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5020 break;
5021 case CKM_GENERIC_SECRET_KEY_GEN0x00000350UL:
5022 *key_type = CKK_GENERIC_SECRET0x00000010UL;
5023 if (*key_length == 0)
5024 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5025 break;
5026 case CKM_CDMF_KEY_GEN0x00000140UL:
5027 *key_type = CKK_CDMF0x0000001EUL;
5028 *key_length = 8;
5029 break;
5030 case CKM_DES_KEY_GEN0x00000120UL:
5031 *key_type = CKK_DES0x00000013UL;
5032 *key_length = 8;
5033 break;
5034 case CKM_DES2_KEY_GEN0x00000130UL:
5035 *key_type = CKK_DES20x00000014UL;
5036 *key_length = 16;
5037 break;
5038 case CKM_DES3_KEY_GEN0x00000131UL:
5039 *key_type = CKK_DES30x00000015UL;
5040 *key_length = 24;
5041 break;
5042#ifndef NSS_DISABLE_DEPRECATED_SEED
5043 case CKM_SEED_KEY_GEN0x00000650UL:
5044 *key_type = CKK_SEED0x0000002FUL;
5045 *key_length = 16;
5046 break;
5047#endif /* NSS_DISABLE_DEPRECATED_SEED */
5048 case CKM_CAMELLIA_KEY_GEN0x00000550UL:
5049 *key_type = CKK_CAMELLIA0x00000025UL;
5050 if (*key_length == 0)
5051 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5052 break;
5053 case CKM_AES_KEY_GEN0x00001080UL:
5054 *key_type = CKK_AES0x0000001FUL;
5055 if (*key_length == 0)
5056 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5057 break;
5058 case CKM_NSS_CHACHA20_KEY_GEN((0x80000000UL | 0x4E534350) + 27):
5059 *key_type = CKK_NSS_CHACHA20((0x80000000UL | 0x4E534350) + 4);
5060 *key_length = 32;
5061 break;
5062 case CKM_CHACHA20_KEY_GEN0x00001225UL:
5063 *key_type = CKK_CHACHA200x00000033UL;
5064 *key_length = 32;
5065 break;
5066 case CKM_HKDF_KEY_GEN0x0000402cUL:
5067 *key_type = CKK_HKDF0x00000042UL;
5068 if (*key_length == 0)
5069 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5070 break;
5071 default:
5072 PORT_Assert(0)((0) ? ((void)0) : PR_Assert("0", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 5072))
;
5073 crv = CKR_MECHANISM_INVALID0x00000070UL;
5074 break;
5075 }
5076
5077 return crv;
5078}
5079
5080CK_RV
5081nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
5082{
5083 SECItem salt;
5084 CK_PBE_PARAMS *pbe_params = NULL((void*)0);
5085 NSSPKCS5PBEParameter *params;
5086 PLArenaPool *arena = NULL((void*)0);
5087 SECStatus rv;
5088
5089 *pbe = NULL((void*)0);
5090
5091 arena = PORT_NewArenaPORT_NewArena_Util(SEC_ASN1_DEFAULT_ARENA_SIZE(2048));
5092 if (arena == NULL((void*)0)) {
5093 return CKR_HOST_MEMORY0x00000002UL;
5094 }
5095
5096 params = (NSSPKCS5PBEParameter *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
5097 sizeof(NSSPKCS5PBEParameter));
5098 if (params == NULL((void*)0)) {
5099 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
5100 return CKR_HOST_MEMORY0x00000002UL;
5101 }
5102 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_PBE_PARAMS))
) {
5103 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
5104 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5105 }
5106
5107 params->poolp = arena;
5108 params->ivLen = 0;
5109 params->pbeType = NSSPKCS5_PKCS12_V2;
5110 params->hashType = HASH_AlgSHA1;
5111 params->encAlg = SEC_OID_SHA1; /* any invalid value */
5112 params->is2KeyDES = PR_FALSE0;
5113 params->keyID = pbeBitGenIntegrityKey;
5114 pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
5115 params->iter = pbe_params->ulIteration;
5116
5117 salt.data = (unsigned char *)pbe_params->pSalt;
5118 salt.len = (unsigned int)pbe_params->ulSaltLen;
5119 salt.type = siBuffer;
5120 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &params->salt, &salt);
5121 if (rv != SECSuccess) {
5122 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
5123 return CKR_HOST_MEMORY0x00000002UL;
5124 }
5125 switch (pMechanism->mechanism) {
5126 case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN0x80000009UL:
5127 case CKM_PBA_SHA1_WITH_SHA1_HMAC0x000003C0UL:
5128 params->hashType = HASH_AlgSHA1;
5129 params->keyLen = 20;
5130 break;
5131 case CKM_NSS_PBE_MD5_HMAC_KEY_GEN0x8000000aUL:
5132 params->hashType = HASH_AlgMD5;
5133 params->keyLen = 16;
5134 break;
5135 case CKM_NSS_PBE_MD2_HMAC_KEY_GEN0x8000000bUL:
5136 params->hashType = HASH_AlgMD2;
5137 params->keyLen = 16;
5138 break;
5139 case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 29):
5140 params->hashType = HASH_AlgSHA224;
5141 params->keyLen = 28;
5142 break;
5143 case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 30):
5144 params->hashType = HASH_AlgSHA256;
5145 params->keyLen = 32;
5146 break;
5147 case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 31):
5148 params->hashType = HASH_AlgSHA384;
5149 params->keyLen = 48;
5150 break;
5151 case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 32):
5152 params->hashType = HASH_AlgSHA512;
5153 params->keyLen = 64;
5154 break;
5155 default:
5156 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
5157 return CKR_MECHANISM_INVALID0x00000070UL;
5158 }
5159 *pbe = params;
5160 return CKR_OK0x00000000UL;
5161}
5162
5163/* maybe this should be table driven? */
5164static CK_RV
5165nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
5166 CK_KEY_TYPE *key_type, CK_ULONG *key_length)
5167{
5168 CK_RV crv = CKR_OK0x00000000UL;
5169 SECOidData *oid;
5170 CK_PBE_PARAMS *pbe_params = NULL((void*)0);
5171 NSSPKCS5PBEParameter *params = NULL((void*)0);
5172 HASH_HashType hashType = HASH_AlgSHA1;
5173 CK_PKCS5_PBKD2_PARAMS2 *pbkd2_params = NULL((void*)0);
5174 SECItem salt;
5175 CK_ULONG iteration = 0;
5176
5177 *pbe = NULL((void*)0);
5178
5179 oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
5180 if (oid == NULL((void*)0)) {
5181 return CKR_MECHANISM_INVALID0x00000070UL;
5182 }
5183
5184 if (pMechanism->mechanism == CKM_PKCS5_PBKD20x000003B0UL) {
5185 if (pMechanism->ulParameterLen < PR_MIN(sizeof(CK_PKCS5_PBKD2_PARAMS2),((sizeof(CK_PKCS5_PBKD2_PARAMS2)) < (sizeof(CK_PKCS5_PBKD2_PARAMS
)) ? (sizeof(CK_PKCS5_PBKD2_PARAMS2)) : (sizeof(CK_PKCS5_PBKD2_PARAMS
)))
5186 sizeof(CK_PKCS5_PBKD2_PARAMS))((sizeof(CK_PKCS5_PBKD2_PARAMS2)) < (sizeof(CK_PKCS5_PBKD2_PARAMS
)) ? (sizeof(CK_PKCS5_PBKD2_PARAMS2)) : (sizeof(CK_PKCS5_PBKD2_PARAMS
)))
) {
5187 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5188 }
5189 pbkd2_params = (CK_PKCS5_PBKD2_PARAMS2 *)pMechanism->pParameter;
5190 switch (pbkd2_params->prf) {
5191 case CKP_PKCS5_PBKD2_HMAC_SHA10x00000001UL:
5192 hashType = HASH_AlgSHA1;
5193 break;
5194 case CKP_PKCS5_PBKD2_HMAC_SHA2240x00000003UL:
5195 hashType = HASH_AlgSHA224;
5196 break;
5197 case CKP_PKCS5_PBKD2_HMAC_SHA2560x00000004UL:
5198 hashType = HASH_AlgSHA256;
5199 break;
5200 case CKP_PKCS5_PBKD2_HMAC_SHA3840x00000005UL:
5201 hashType = HASH_AlgSHA384;
5202 break;
5203 case CKP_PKCS5_PBKD2_HMAC_SHA5120x00000006UL:
5204 hashType = HASH_AlgSHA512;
5205 break;
5206 default:
5207 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5208 }
5209 if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED0x00000001UL) {
5210 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5211 }
5212 salt.data = (unsigned char *)pbkd2_params->pSaltSourceData;
5213 salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen;
5214 iteration = pbkd2_params->iterations;
5215 } else {
5216 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_PBE_PARAMS))
) {
5217 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5218 }
5219 pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
5220 salt.data = (unsigned char *)pbe_params->pSalt;
5221 salt.len = (unsigned int)pbe_params->ulSaltLen;
5222 iteration = pbe_params->ulIteration;
5223 }
5224 params = nsspkcs5_NewParam(oid->offset, hashType, &salt, iteration);
5225 if (params == NULL((void*)0)) {
5226 return CKR_MECHANISM_INVALID0x00000070UL;
5227 }
5228
5229 switch (params->encAlg) {
5230 case SEC_OID_DES_CBC:
5231 *key_type = CKK_DES0x00000013UL;
5232 *key_length = params->keyLen;
5233 break;
5234 case SEC_OID_DES_EDE3_CBC:
5235 *key_type = params->is2KeyDES ? CKK_DES20x00000014UL : CKK_DES30x00000015UL;
5236 *key_length = params->keyLen;
5237 break;
5238#ifndef NSS_DISABLE_DEPRECATED_RC2
5239 case SEC_OID_RC2_CBC:
5240 *key_type = CKK_RC20x00000011UL;
5241 *key_length = params->keyLen;
5242 break;
5243#endif /* NSS_DISABLE_DEPRECATED_RC2 */
5244 case SEC_OID_RC4:
5245 *key_type = CKK_RC40x00000012UL;
5246 *key_length = params->keyLen;
5247 break;
5248 case SEC_OID_PKCS5_PBKDF2:
5249 /* key type must already be set */
5250 if (*key_type == CKK_INVALID_KEY_TYPE0xffffffffUL) {
5251 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5252 break;
5253 }
5254 /* PBKDF2 needs to calculate the key length from the other parameters
5255 */
5256 if (*key_length == 0) {
5257 *key_length = sftk_MapKeySize(*key_type);
5258 }
5259 if (*key_length == 0) {
5260 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
5261 break;
5262 }
5263 params->keyLen = *key_length;
5264 break;
5265 default:
5266 crv = CKR_MECHANISM_INVALID0x00000070UL;
5267 break;
5268 }
5269 if (crv == CKR_OK0x00000000UL) {
5270 *pbe = params;
5271 } else {
5272 nsspkcs5_DestroyPBEParameter(params);
5273 }
5274 return crv;
5275}
5276
5277/* NSC_GenerateKey generates a secret key, creating a new key object. */
5278CK_RV
5279NSC_GenerateKey(CK_SESSION_HANDLE hSession,
5280 CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
5281 CK_OBJECT_HANDLE_PTR phKey)
5282{
5283 SFTKObject *key;
5284 SFTKSession *session;
5285 PRBool checkWeak = PR_FALSE0;
5286 CK_ULONG key_length = 0;
5287 CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE0xffffffffUL;
5288 CK_OBJECT_CLASS objclass = CKO_SECRET_KEY0x00000004UL;
5289 CK_RV crv = CKR_OK0x00000000UL;
5290 CK_BBOOL cktrue = CK_TRUE1;
5291 NSSPKCS5PBEParameter *pbe_param = NULL((void*)0);
5292 int i;
5293 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
5294 unsigned char buf[MAX_KEY_LEN256];
5295 enum { nsc_pbe,
5296 nsc_ssl,
5297 nsc_bulk,
5298 nsc_param,
5299 nsc_jpake } key_gen_type;
5300 SSL3RSAPreMasterSecret *rsa_pms;
5301 CK_VERSION *version;
5302 /* in very old versions of NSS, there were implementation errors with key
5303 * generation methods. We want to beable to read these, but not
5304 * produce them any more. The affected algorithm was 3DES.
5305 */
5306 PRBool faultyPBE3DES = PR_FALSE0;
5307 HASH_HashType hashType = HASH_AlgNULL;
5308
5309 CHECK_FORK();
5310
5311 if (!slot) {
5312 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5313 }
5314 /*
5315 * now lets create an object to hang the attributes off of
5316 */
5317 key = sftk_NewObject(slot); /* fill in the handle later */
5318 if (key == NULL((void*)0)) {
5319 return CKR_HOST_MEMORY0x00000002UL;
5320 }
5321
5322 /*
5323 * load the template values into the object
5324 */
5325 for (i = 0; i < (int)ulCount; i++) {
5326 if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) {
5327 key_length = *(CK_ULONG *)pTemplate[i].pValue;
5328 continue;
5329 }
5330 /* some algorithms need keytype specified */
5331 if (pTemplate[i].type == CKA_KEY_TYPE0x00000100UL) {
5332 key_type = *(CK_ULONG *)pTemplate[i].pValue;
5333 continue;
5334 }
5335
5336 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
5337 if (crv != CKR_OK0x00000000UL) {
5338 break;
5339 }
5340 }
5341 if (crv != CKR_OK0x00000000UL) {
5342 goto loser;
5343 }
5344
5345 /* make sure we don't have any class, key_type, or value fields */
5346 sftk_DeleteAttributeType(key, CKA_CLASS0x00000000UL);
5347 sftk_DeleteAttributeType(key, CKA_KEY_TYPE0x00000100UL);
5348 sftk_DeleteAttributeType(key, CKA_VALUE0x00000011UL);
5349
5350 /* Now Set up the parameters to generate the key (based on mechanism) */
5351 key_gen_type = nsc_bulk; /* bulk key by default */
5352 switch (pMechanism->mechanism) {
5353 case CKM_CDMF_KEY_GEN0x00000140UL:
5354 case CKM_DES_KEY_GEN0x00000120UL:
5355 case CKM_DES2_KEY_GEN0x00000130UL:
5356 case CKM_DES3_KEY_GEN0x00000131UL:
5357 checkWeak = PR_TRUE1;
5358/* fall through */
5359#ifndef NSS_DISABLE_DEPRECATED_RC2
5360 case CKM_RC2_KEY_GEN0x00000100UL:
5361#endif
5362 case CKM_RC4_KEY_GEN0x00000110UL:
5363 case CKM_GENERIC_SECRET_KEY_GEN0x00000350UL:
5364#ifndef NSS_DISABLE_DEPRECATED_SEED
5365 case CKM_SEED_KEY_GEN0x00000650UL:
5366#endif
5367 case CKM_CAMELLIA_KEY_GEN0x00000550UL:
5368 case CKM_AES_KEY_GEN0x00001080UL:
5369 case CKM_NSS_CHACHA20_KEY_GEN((0x80000000UL | 0x4E534350) + 27):
5370 case CKM_CHACHA20_KEY_GEN0x00001225UL:
5371#if NSS_SOFTOKEN_DOES_RC5
5372 case CKM_RC5_KEY_GEN0x00000330UL:
5373#endif
5374 crv = nsc_SetupBulkKeyGen(pMechanism->mechanism, &key_type, &key_length);
5375 break;
5376 case CKM_SSL3_PRE_MASTER_KEY_GEN0x00000370UL:
5377 key_type = CKK_GENERIC_SECRET0x00000010UL;
5378 key_length = 48;
5379 key_gen_type = nsc_ssl;
5380 break;
5381 case CKM_PBA_SHA1_WITH_SHA1_HMAC0x000003C0UL:
5382 case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN0x80000009UL:
5383 case CKM_NSS_PBE_MD5_HMAC_KEY_GEN0x8000000aUL:
5384 case CKM_NSS_PBE_MD2_HMAC_KEY_GEN0x8000000bUL:
5385 case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 29):
5386 case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 30):
5387 case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 31):
5388 case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN((0x80000000UL | 0x4E534350) + 32):
5389 key_gen_type = nsc_pbe;
5390 key_type = CKK_GENERIC_SECRET0x00000010UL;
5391 crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
5392 break;
5393 case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC0x80000008UL:
5394 faultyPBE3DES = PR_TRUE1;
5395 /* fall through */
5396 case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC0x80000003UL:
5397#ifndef NSS_DISABLE_DEPRECATED_RC2
5398 case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC0x80000004UL:
5399 case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC0x80000005UL:
5400 case CKM_PBE_SHA1_RC2_128_CBC0x000003AAUL:
5401 case CKM_PBE_SHA1_RC2_40_CBC0x000003ABUL:
5402#endif
5403 case CKM_NSS_PBE_SHA1_DES_CBC0x80000002UL:
5404 case CKM_NSS_PBE_SHA1_40_BIT_RC40x80000006UL:
5405 case CKM_NSS_PBE_SHA1_128_BIT_RC40x80000007UL:
5406 case CKM_PBE_SHA1_DES3_EDE_CBC0x000003A8UL:
5407 case CKM_PBE_SHA1_DES2_EDE_CBC0x000003A9UL:
5408 case CKM_PBE_SHA1_RC4_1280x000003A6UL:
5409 case CKM_PBE_SHA1_RC4_400x000003A7UL:
5410 case CKM_PBE_MD5_DES_CBC0x000003A1UL:
5411 case CKM_PBE_MD2_DES_CBC0x000003A0UL:
5412 case CKM_PKCS5_PBKD20x000003B0UL:
5413 key_gen_type = nsc_pbe;
5414 crv = nsc_SetupPBEKeyGen(pMechanism, &pbe_param, &key_type, &key_length);
5415 break;
5416 /*#ifndef NSS_DISABLE_DSA */
5417 /* some applications use CKM_DSA_PARAMETER_GEN for weak DH keys...
5418 * most notably tests and even ssl... continue to allow it for now */
5419 case CKM_DSA_PARAMETER_GEN0x00002000UL:
5420 key_gen_type = nsc_param;
5421 key_type = CKK_DSA0x00000001UL;
5422 objclass = CKO_DOMAIN_PARAMETERS0x00000006UL;
5423 crv = CKR_OK0x00000000UL;
5424 break;
5425 /* #endif */
5426 case CKM_NSS_JPAKE_ROUND1_SHA1((0x80000000UL | 0x4E534350) + 7):
5427 hashType = HASH_AlgSHA1;
5428 goto jpake1;
5429 case CKM_NSS_JPAKE_ROUND1_SHA256((0x80000000UL | 0x4E534350) + 8):
5430 hashType = HASH_AlgSHA256;
5431 goto jpake1;
5432 case CKM_NSS_JPAKE_ROUND1_SHA384((0x80000000UL | 0x4E534350) + 9):
5433 hashType = HASH_AlgSHA384;
5434 goto jpake1;
5435 case CKM_NSS_JPAKE_ROUND1_SHA512((0x80000000UL | 0x4E534350) + 10):
5436 hashType = HASH_AlgSHA512;
5437 goto jpake1;
5438 jpake1:
5439 key_gen_type = nsc_jpake;
5440 key_type = CKK_NSS_JPAKE_ROUND1((0x80000000UL | 0x4E534350) + 2);
5441 objclass = CKO_PRIVATE_KEY0x00000003UL;
5442 if (pMechanism->pParameter == NULL((void*)0) ||
5443 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound1Params)) {
5444 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5445 break;
5446 }
5447 if (sftk_isTrue(key, CKA_TOKEN0x00000001UL)) {
5448 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
5449 break;
5450 }
5451 crv = CKR_OK0x00000000UL;
5452 break;
5453 default:
5454 crv = CKR_MECHANISM_INVALID0x00000070UL;
5455 break;
5456 }
5457
5458 /* make sure we aren't going to overflow the buffer */
5459 if (sizeof(buf) < key_length) {
5460 /* someone is getting pretty optimistic about how big their key can
5461 * be... */
5462 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
5463 }
5464
5465 if (crv != CKR_OK0x00000000UL) {
5466 if (pbe_param) {
5467 nsspkcs5_DestroyPBEParameter(pbe_param);
5468 }
5469 goto loser;
5470 }
5471
5472 /* if there was no error,
5473 * key_type *MUST* be set in the switch statement above */
5474 PORT_Assert(key_type != CKK_INVALID_KEY_TYPE)((key_type != 0xffffffffUL) ? ((void)0) : PR_Assert("key_type != CKK_INVALID_KEY_TYPE"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 5474
))
;
5475
5476 /*
5477 * now to the actual key gen.
5478 */
5479 switch (key_gen_type) {
5480 case nsc_pbe:
5481 crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length,
5482 faultyPBE3DES);
5483 nsspkcs5_DestroyPBEParameter(pbe_param);
5484 break;
5485 case nsc_ssl:
5486 rsa_pms = (SSL3RSAPreMasterSecret *)buf;
5487 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_VERSION))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_VERSION))
) {
5488 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5489 goto loser;
5490 }
5491 version = (CK_VERSION *)pMechanism->pParameter;
5492 rsa_pms->client_version[0] = version->major;
5493 rsa_pms->client_version[1] = version->minor;
5494 crv =
5495 NSC_GenerateRandom(0, &rsa_pms->random[0], sizeof(rsa_pms->random));
5496 break;
5497 case nsc_bulk:
5498 /* get the key, check for weak keys and repeat if found */
5499 do {
5500 crv = NSC_GenerateRandom(0, buf, key_length);
5501 } while (crv == CKR_OK0x00000000UL && checkWeak && sftk_IsWeakKey(buf, key_type));
5502 break;
5503 case nsc_param:
5504 /* generate parameters */
5505 *buf = 0;
5506 crv = nsc_parameter_gen(key_type, key);
5507 break;
5508 case nsc_jpake:
5509 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_NSS_JPAKERound1Params))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_NSS_JPAKERound1Params))
) {
5510 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
5511 goto loser;
5512 }
5513 crv = jpake_Round1(hashType,
5514 (CK_NSS_JPAKERound1Params *)pMechanism->pParameter,
5515 key);
5516 break;
5517 }
5518
5519 if (crv != CKR_OK0x00000000UL) {
5520 goto loser;
5521 }
5522
5523 /* Add the class, key_type, and value */
5524 crv = sftk_AddAttributeType(key, CKA_CLASS0x00000000UL, &objclass, sizeof(CK_OBJECT_CLASS));
5525 if (crv != CKR_OK0x00000000UL) {
5526 goto loser;
5527 }
5528 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &key_type, sizeof(CK_KEY_TYPE));
5529 if (crv != CKR_OK0x00000000UL) {
5530 goto loser;
5531 }
5532 if (key_length != 0) {
5533 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL, buf, key_length);
5534 if (crv != CKR_OK0x00000000UL) {
5535 goto loser;
5536 }
5537 }
5538
5539 /* get the session */
5540 session = sftk_SessionFromHandle(hSession);
5541 if (session == NULL((void*)0)) {
5542 crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
5543 goto loser;
5544 }
5545
5546 /*
5547 * handle the base object stuff
5548 */
5549 crv = sftk_handleObject(key, session);
5550 /* we need to do this check at the end, so we can check the generated key
5551 * length against fips requirements */
5552 sftk_setFIPS(key, sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_GENERATE0x81000001L,
5553 key, 0));
5554 session->lastOpWasFIPS = sftk_hasFIPS(key);
5555 sftk_FreeSession(session);
5556 if (crv != CKR_OK0x00000000UL) {
5557 goto loser;
5558 }
5559 if (sftk_isTrue(key, CKA_SENSITIVE0x00000103UL)) {
5560 crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE0x00000165UL, &cktrue, sizeof(CK_BBOOL));
5561 }
5562 if (crv == CKR_OK0x00000000UL && !sftk_isTrue(key, CKA_EXTRACTABLE0x00000162UL)) {
5563 crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE0x00000164UL, &cktrue, sizeof(CK_BBOOL));
5564 }
5565 if (crv != CKR_OK0x00000000UL) {
5566 NSC_DestroyObject(hSession, key->handle);
5567 goto loser;
5568 }
5569 *phKey = key->handle;
5570loser:
5571 PORT_Memsetmemset(buf, 0, sizeof buf);
5572 sftk_FreeObject(key);
5573 return crv;
5574}
5575
5576/* takes raw sessions and key handles and determines if the keys
5577 * have the same value. */
5578PRBool
5579sftk_compareKeysEqual(CK_SESSION_HANDLE hSession,
5580 CK_OBJECT_HANDLE key1, CK_OBJECT_HANDLE key2)
5581{
5582 PRBool result = PR_FALSE0;
5583 SFTKSession *session;
5584 SFTKObject *key1obj = NULL((void*)0);
5585 SFTKObject *key2obj = NULL((void*)0);
5586 SFTKAttribute *att1 = NULL((void*)0);
5587 SFTKAttribute *att2 = NULL((void*)0);
5588
5589 /* fetch the pkcs11 objects from the handles */
5590 session = sftk_SessionFromHandle(hSession);
5591 if (session == NULL((void*)0)) {
5592 return PR_FALSE0;
5593 }
5594
5595 key1obj = sftk_ObjectFromHandle(key1, session);
5596 key2obj = sftk_ObjectFromHandle(key2, session);
5597 sftk_FreeSession(session);
5598 if ((key1obj == NULL((void*)0)) || (key2obj == NULL((void*)0))) {
5599 goto loser;
5600 }
5601 /* fetch the value attributes */
5602 att1 = sftk_FindAttribute(key1obj, CKA_VALUE0x00000011UL);
5603 if (att1 == NULL((void*)0)) {
5604 goto loser;
5605 }
5606 att2 = sftk_FindAttribute(key2obj, CKA_VALUE0x00000011UL);
5607 if (att2 == NULL((void*)0)) {
5608 goto loser;
5609 }
5610 /* make sure that they are equal */
5611 if (att1->attrib.ulValueLen != att2->attrib.ulValueLen) {
5612 goto loser;
5613 }
5614 if (PORT_Memcmpmemcmp(att1->attrib.pValue, att2->attrib.pValue,
5615 att1->attrib.ulValueLen) != 0) {
5616 goto loser;
5617 }
5618 result = PR_TRUE1;
5619loser:
5620 if (att1) {
5621 sftk_FreeAttribute(att1);
5622 }
5623 if (att2) {
5624 sftk_FreeAttribute(att2);
5625 }
5626 if (key1obj) {
5627 sftk_FreeObject(key1obj);
5628 }
5629 if (key2obj) {
5630 sftk_FreeObject(key2obj);
5631 }
5632 return result;
5633}
5634
5635#define PAIRWISE_MESSAGE_LENGTH20 20 /* 160-bits */
5636
5637/*
5638 * FIPS 140-3 pairwise consistency check utilized to validate key pair.
5639 *
5640 * This function returns
5641 * CKR_OK if pairwise consistency check passed
5642 * CKR_GENERAL_ERROR if pairwise consistency check failed
5643 * other error codes if paiswise consistency check could not be
5644 * performed, for example, CKR_HOST_MEMORY.
5645 */
5646static CK_RV
5647sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, SFTKSlot *slot,
5648 SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
5649{
5650 /*
5651 * Key type Mechanism type
5652 * --------------------------------
5653 * For encrypt/decrypt: CKK_RSA => CKM_RSA_PKCS_OAEP
5654 * others => CKM_INVALID_MECHANISM
5655 *
5656 * For sign/verify: CKK_RSA => CKM_SHA256_RSA_PKCS_PSS
5657 * CKK_DSA => CKM_DSA_SHA256
5658 * CKK_EC => CKM_ECDSA_SHA256
5659 * CKK_ML_DSA => CKM_ML_DSA
5660 * others => CKM_INVALID_MECHANISM
5661 *
5662 * None of these mechanisms has a parameter.
5663 *
5664 * For derive CKK_DH => CKM_DH_PKCS_DERIVE
5665 * CKK_EC => CKM_ECDH1_DERIVE
5666 * CKK_EC_MONTGOMERY => CKM_ECDH1_DERIVE
5667 * others => CKM_INVALID_MECHANISM
5668 *
5669 * For KEM mechanisms:
5670 * CKK_NSS_KYBER => don't
5671 * CKK_NSS_ML_KEM => don't
5672 * CKK_ML_KEM => CM_ML_KEM
5673 *
5674 * The parameters for these mechanisms is the public key.
5675 */
5676 CK_MECHANISM mech = { 0, NULL((void*)0), 0 };
5677
5678 CK_ULONG modulusLen = 0;
5679#ifndef NSS_DISABLE_DSA
5680 CK_ULONG subPrimeLen = 0;
5681#endif
5682 PRBool isEncryptable = PR_FALSE0;
5683 PRBool canSignVerify = PR_FALSE0;
5684 PRBool isDerivable = PR_FALSE0;
5685 PRBool isKEM = PR_FALSE0;
5686 CK_RV crv;
5687
5688 /* Variables used for Encrypt/Decrypt functions. */
5689 unsigned char *known_message = (unsigned char *)"Known Crypto Message";
5690 unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH20];
5691 CK_ULONG bytes_decrypted;
5692 unsigned char *ciphertext;
5693 unsigned char *text_compared;
5694 CK_ULONG bytes_encrypted;
5695 CK_ULONG bytes_compared;
5696
5697 /* Variables used for Signature/Verification functions. */
5698 unsigned char *signature;
5699 CK_ULONG signature_length;
5700 SFTKAttribute *attribute;
5701
5702 switch (keyType) {
5703 case CKK_RSA0x00000000UL:
5704 /* Get modulus length of private key. */
5705 attribute = sftk_FindAttribute(privateKey, CKA_MODULUS0x00000120UL);
5706 if (attribute == NULL((void*)0)) {
5707 return CKR_DEVICE_ERROR0x00000030UL;
5708 }
5709 modulusLen = attribute->attrib.ulValueLen;
5710 if (*(unsigned char *)attribute->attrib.pValue == 0) {
5711 modulusLen--;
5712 }
5713 sftk_FreeAttribute(attribute);
5714#if RSA_MIN_MODULUS_BITS128 < 1023
5715 /* if we allow weak RSA keys, and this is a weak RSA key and
5716 * we aren't in FIPS mode, skip the tests, These keys are
5717 * factorable anyway, the pairwise test doen't matter. */
5718 if ((modulusLen < 1023) && !sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101))) {
5719 return CKR_OK0x00000000UL;
5720 }
5721#endif
5722 break;
5723#ifndef NSS_DISABLE_DSA
5724 case CKK_DSA0x00000001UL:
5725 /* Get subprime length of private key. */
5726 attribute = sftk_FindAttribute(privateKey, CKA_SUBPRIME0x00000131UL);
5727 if (attribute == NULL((void*)0)) {
5728 return CKR_DEVICE_ERROR0x00000030UL;
5729 }
5730 subPrimeLen = attribute->attrib.ulValueLen;
5731 if (subPrimeLen > 1 &&
5732 *(unsigned char *)attribute->attrib.pValue == 0) {
5733 subPrimeLen--;
5734 }
5735 sftk_FreeAttribute(attribute);
5736 break;
5737#endif
5738 case CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5):
5739 case CKK_NSS_ML_KEM((0x80000000UL | 0x4E534350) + 6):
5740 /* these aren't FIPS. we use them to generate keys without a
5741 * pairwise consistency check */
5742 return CKR_OK0x00000000UL;
5743 }
5744
5745 /**************************************************/
5746 /* Pairwise Consistency Check of Encrypt/Decrypt. */
5747 /**************************************************/
5748
5749 isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT0x00000105UL);
5750
5751 /*
5752 * If the decryption attribute is set, attempt to encrypt
5753 * with the public key and decrypt with the private key.
5754 */
5755 if (isEncryptable) {
5756 if (keyType != CKK_RSA0x00000000UL) {
5757 return CKR_DEVICE_ERROR0x00000030UL;
5758 }
5759 bytes_encrypted = modulusLen;
5760 mech.mechanism = CKM_RSA_PKCS_OAEP0x00000009UL;
5761 CK_RSA_PKCS_OAEP_PARAMS oaepParams;
5762 oaepParams.hashAlg = CKM_SHA2560x00000250UL;
5763 oaepParams.mgf = CKG_MGF1_SHA2560x00000002UL;
5764 oaepParams.source = CKZ_DATA_SPECIFIED0x00000001UL;
5765 oaepParams.pSourceData = NULL((void*)0);
5766 oaepParams.ulSourceDataLen = 0;
5767 mech.pParameter = &oaepParams;
5768 mech.ulParameterLen = sizeof(oaepParams);
5769
5770 /* Allocate space for ciphertext. */
5771 ciphertext = (unsigned char *)PORT_ZAllocPORT_ZAlloc_Util(bytes_encrypted);
5772 if (ciphertext == NULL((void*)0)) {
5773 return CKR_HOST_MEMORY0x00000002UL;
5774 }
5775
5776 /* Prepare for encryption using the public key. */
5777 crv = NSC_EncryptInit(hSession, &mech, publicKey->handle);
5778 if (crv != CKR_OK0x00000000UL) {
5779 PORT_FreePORT_Free_Util(ciphertext);
5780 return crv;
5781 }
5782
5783 /* Encrypt using the public key. */
5784 crv = NSC_Encrypt(hSession,
5785 known_message,
5786 PAIRWISE_MESSAGE_LENGTH20,
5787 ciphertext,
5788 &bytes_encrypted);
5789 if (crv != CKR_OK0x00000000UL) {
5790 PORT_FreePORT_Free_Util(ciphertext);
5791 return crv;
5792 }
5793
5794 /* Always use the smaller of these two values . . . */
5795 bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH)((bytes_encrypted) < (20) ? (bytes_encrypted) : (20));
5796
5797 /*
5798 * If there was a failure, the plaintext
5799 * goes at the end, therefore . . .
5800 */
5801 text_compared = ciphertext + bytes_encrypted - bytes_compared;
5802
5803 /*
5804 * Check to ensure that ciphertext does
5805 * NOT EQUAL known input message text
5806 * per FIPS PUB 140-2 directive.
5807 */
5808 if (PORT_Memcmpmemcmp(text_compared, known_message,
5809 bytes_compared) == 0) {
5810 /* Set error to Invalid PRIVATE Key. */
5811 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_INVALID_KEY);
5812 PORT_FreePORT_Free_Util(ciphertext);
5813 return CKR_GENERAL_ERROR0x00000005UL;
5814 }
5815
5816 /* Prepare for decryption using the private key. */
5817 crv = NSC_DecryptInit(hSession, &mech, privateKey->handle);
5818 if (crv != CKR_OK0x00000000UL) {
5819 PORT_FreePORT_Free_Util(ciphertext);
5820 return crv;
5821 }
5822
5823 memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH20);
5824
5825 /*
5826 * Initialize bytes decrypted to be the
5827 * expected PAIRWISE_MESSAGE_LENGTH.
5828 */
5829 bytes_decrypted = PAIRWISE_MESSAGE_LENGTH20;
5830
5831 /*
5832 * Decrypt using the private key.
5833 * NOTE: No need to reset the
5834 * value of bytes_encrypted.
5835 */
5836 crv = NSC_Decrypt(hSession,
5837 ciphertext,
5838 bytes_encrypted,
5839 plaintext,
5840 &bytes_decrypted);
5841
5842 /* Finished with ciphertext; free it. */
5843 PORT_FreePORT_Free_Util(ciphertext);
5844
5845 if (crv != CKR_OK0x00000000UL) {
5846 return crv;
5847 }
5848
5849 /*
5850 * Check to ensure that the output plaintext
5851 * does EQUAL known input message text.
5852 */
5853 if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH20) ||
5854 (PORT_Memcmpmemcmp(plaintext, known_message,
5855 PAIRWISE_MESSAGE_LENGTH20) != 0)) {
5856 /* Set error to Bad PUBLIC Key. */
5857 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY);
5858 return CKR_GENERAL_ERROR0x00000005UL;
5859 }
5860 }
5861
5862 /**********************************************/
5863 /* Pairwise Consistency Check of Sign/Verify. */
5864 /**********************************************/
5865
5866 canSignVerify = sftk_isTrue(privateKey, CKA_SIGN0x00000108UL);
5867 /* Unfortunately CKA_SIGN is always true in lg dbs. We have to check the
5868 * actual curve to determine if we can do sign/verify. */
5869 if (canSignVerify && keyType == CKK_EC0x00000003UL) {
5870 NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(privateKey, CKK_EC0x00000003UL, &crv);
5871 if (privKey && privKey->u.ec.ecParams.name == ECCurve25519) {
5872 canSignVerify = PR_FALSE0;
5873 }
5874 }
5875
5876 if (canSignVerify) {
5877 CK_RSA_PKCS_PSS_PARAMS pssParams;
5878 /* Determine length of signature. */
5879 switch (keyType) {
5880 case CKK_RSA0x00000000UL:
5881 signature_length = modulusLen;
5882 mech.mechanism = CKM_SHA256_RSA_PKCS_PSS0x00000043UL;
5883 pssParams.hashAlg = CKM_SHA2560x00000250UL;
5884 pssParams.mgf = CKG_MGF1_SHA2560x00000002UL;
5885 pssParams.sLen = 0;
5886 mech.pParameter = &pssParams;
5887 mech.ulParameterLen = sizeof(pssParams);
5888 break;
5889#ifndef NSS_DISABLE_DSA
5890 case CKK_DSA0x00000001UL:
5891 signature_length = DSA_MAX_SIGNATURE_LEN(32 * 2);
5892 mech.mechanism = CKM_DSA_SHA2560x00000014UL;
5893 break;
5894#endif
5895 case CKK_EC0x00000003UL:
5896 signature_length = MAX_ECKEY_LEN72 * 2;
5897 mech.mechanism = CKM_ECDSA_SHA2560x00001044UL;
5898 break;
5899 case CKK_ML_DSA0x0000004aUL:
5900 signature_length = MAX_ML_DSA_SIGNATURE_LEN4627;
5901 mech.mechanism = CKM_ML_DSA0x0000001dUL;
5902 break;
5903 case CKK_EC_EDWARDS0x00000040UL:
5904 signature_length = ED25519_SIGN_LEN64U;
5905 mech.mechanism = CKM_EDDSA0x00001057UL;
5906 break;
5907 default:
5908 return CKR_DEVICE_ERROR0x00000030UL;
5909 }
5910
5911 /* Allocate space for signature data. */
5912 signature = (unsigned char *)PORT_ZAllocPORT_ZAlloc_Util(signature_length);
5913 if (signature == NULL((void*)0)) {
5914 return CKR_HOST_MEMORY0x00000002UL;
5915 }
5916
5917 /* Sign the known hash using the private key. */
5918 crv = NSC_SignInit(hSession, &mech, privateKey->handle);
5919 if (crv != CKR_OK0x00000000UL) {
5920 PORT_FreePORT_Free_Util(signature);
5921 return crv;
5922 }
5923
5924 crv = NSC_Sign(hSession,
5925 known_message,
5926 PAIRWISE_MESSAGE_LENGTH20,
5927 signature,
5928 &signature_length);
5929 if (crv != CKR_OK0x00000000UL) {
5930 PORT_FreePORT_Free_Util(signature);
5931 return crv;
5932 }
5933
5934 /* detect trivial signing transforms */
5935 if ((signature_length >= PAIRWISE_MESSAGE_LENGTH20) &&
5936 (PORT_Memcmpmemcmp(known_message, signature + (signature_length - PAIRWISE_MESSAGE_LENGTH20), PAIRWISE_MESSAGE_LENGTH20) == 0)) {
5937 PORT_FreePORT_Free_Util(signature);
5938 return CKR_GENERAL_ERROR0x00000005UL;
5939 }
5940
5941 /* Verify the known hash using the public key. */
5942 crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
5943 if (crv != CKR_OK0x00000000UL) {
5944 PORT_FreePORT_Free_Util(signature);
5945 return crv;
5946 }
5947
5948 crv = NSC_Verify(hSession,
5949 known_message,
5950 PAIRWISE_MESSAGE_LENGTH20,
5951 signature,
5952 signature_length);
5953
5954 /* Free signature data. */
5955 PORT_FreePORT_Free_Util(signature);
5956
5957 if ((crv == CKR_SIGNATURE_LEN_RANGE0x000000C1UL) ||
5958 (crv == CKR_SIGNATURE_INVALID0x000000C0UL)) {
5959 return CKR_GENERAL_ERROR0x00000005UL;
5960 }
5961 if (crv != CKR_OK0x00000000UL) {
5962 return crv;
5963 }
5964 }
5965
5966 /**********************************************/
5967 /* Pairwise Consistency Check for Derivation */
5968 /**********************************************/
5969
5970 isDerivable = sftk_isTrue(privateKey, CKA_DERIVE0x0000010CUL);
5971
5972 if (isDerivable) {
5973 SFTKAttribute *pubAttribute = NULL((void*)0);
5974 PRBool isFIPS = sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101));
5975 NSSLOWKEYPrivateKey *lowPrivKey = NULL((void*)0);
5976 ECPrivateKey *ecPriv = NULL((void*)0);
5977 SECItem *lowPubValue = NULL((void*)0);
5978 SECItem item = { siBuffer, NULL((void*)0), 0 };
5979 SECStatus rv;
5980
5981 crv = CKR_OK0x00000000UL; /*paranoia, already get's set before we drop to the end */
5982
5983 /* FIPS 140-3 requires we verify that the resulting key is a valid key
5984 * by recalculating the public can an compare it to our own public
5985 * key. */
5986 lowPrivKey = sftk_GetPrivKey(privateKey, keyType, &crv);
5987 if (lowPrivKey == NULL((void*)0)) {
5988 return sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
5989 }
5990 /* recalculate the public key from the private key */
5991 switch (keyType) {
5992 case CKK_DH0x00000002UL:
5993 rv = DH_Derive(&lowPrivKey->u.dh.base, &lowPrivKey->u.dh.prime,
5994 &lowPrivKey->u.dh.privateValue, &item, 0);
5995 if (rv != SECSuccess) {
5996 return CKR_GENERAL_ERROR0x00000005UL;
5997 }
5998 lowPubValue = SECITEM_DupItemSECITEM_DupItem_Util(&item);
5999 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&item, PR_FALSE0);
6000 pubAttribute = sftk_FindAttribute(publicKey, CKA_VALUE0x00000011UL);
6001 break;
6002 case CKK_EC_MONTGOMERY0x00000041UL:
6003 case CKK_EC0x00000003UL:
6004 rv = EC_NewKeyFromSeed(&lowPrivKey->u.ec.ecParams, &ecPriv,
6005 lowPrivKey->u.ec.privateValue.data,
6006 lowPrivKey->u.ec.privateValue.len);
6007 if (rv != SECSuccess) {
6008 return CKR_GENERAL_ERROR0x00000005UL;
6009 }
6010 /* make sure it has the same encoding */
6011 if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
6012 lowPrivKey->u.ec.ecParams.type != ec_params_named) {
6013 lowPubValue = SECITEM_DupItemSECITEM_DupItem_Util(&ecPriv->publicValue);
6014 } else {
6015 lowPubValue = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), &ecPriv->publicValue,
6016 SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util);
6017 }
6018 pubAttribute = sftk_FindAttribute(publicKey, CKA_EC_POINT0x00000181UL);
6019 /* clear out our generated private key */
6020 PORT_FreeArenaPORT_FreeArena_Util(ecPriv->ecParams.arena, PR_TRUE1);
6021 break;
6022 default:
6023 return CKR_DEVICE_ERROR0x00000030UL;
6024 }
6025
6026 /* now compare new public key with our already generated key */
6027 if ((pubAttribute == NULL((void*)0)) || (lowPubValue == NULL((void*)0)) ||
6028 (pubAttribute->attrib.ulValueLen != lowPubValue->len) ||
6029 (PORT_Memcmpmemcmp(pubAttribute->attrib.pValue, lowPubValue->data,
6030 lowPubValue->len) != 0)) {
6031 if (pubAttribute)
6032 sftk_FreeAttribute(pubAttribute);
6033 if (lowPubValue)
6034 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(lowPubValue, PR_TRUE1);
6035 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY);
6036 return CKR_GENERAL_ERROR0x00000005UL;
6037 }
6038 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(lowPubValue, PR_TRUE1);
6039
6040 /* FIPS requires full validation, but in fipx mode NSC_Derive
6041 * only does partial validation with approved primes, now handle
6042 * full validation */
6043 if (isFIPS && keyType == CKK_DH0x00000002UL) {
6044 SECItem pubKey = { siBuffer, pubAttribute->attrib.pValue,
6045 pubAttribute->attrib.ulValueLen };
6046 SECItem base = { siBuffer, NULL((void*)0), 0 };
6047 SECItem prime = { siBuffer, NULL((void*)0), 0 };
6048 SECItem subPrime = { siBuffer, NULL((void*)0), 0 };
6049 SECItem generator = { siBuffer, NULL((void*)0), 0 };
6050 const SECItem *subPrimePtr = &subPrime;
6051
6052 crv = sftk_Attribute2SecItem(NULL((void*)0), &prime, privateKey, CKA_PRIME0x00000130UL);
6053 if (crv != CKR_OK0x00000000UL) {
6054 goto done;
6055 }
6056 crv = sftk_Attribute2SecItem(NULL((void*)0), &base, privateKey, CKA_BASE0x00000132UL);
6057 if (crv != CKR_OK0x00000000UL) {
6058 goto done;
6059 }
6060 /* we ignore the return code an only look at the length */
6061 /* do we have a known prime ? */
6062 subPrimePtr = sftk_VerifyDH_Prime(&prime, &generator, isFIPS);
6063 if (subPrimePtr == NULL((void*)0)) {
6064 if (subPrime.len == 0) {
6065 /* if not a known prime, subprime must be supplied */
6066 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6067 goto done;
6068 } else {
6069 /* not a known prime, check for primality of prime
6070 * and subPrime */
6071 if (!KEA_PrimeCheck(&prime)) {
6072 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6073 goto done;
6074 }
6075 if (!KEA_PrimeCheck(&subPrime)) {
6076 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6077 goto done;
6078 }
6079 /* if we aren't using a defined group, make sure base is in the
6080 * subgroup. If it's not, then our key could fail or succeed sometimes.
6081 * This makes the failure reliable */
6082 if (!KEA_Verify(&base, &prime, &subPrime)) {
6083 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6084 }
6085 }
6086 subPrimePtr = &subPrime;
6087 } else {
6088 /* we're using a known group, make sure we are using the known generator for that group */
6089 if (SECITEM_CompareItemSECITEM_CompareItem_Util(&generator, &base) != 0) {
6090 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6091 goto done;
6092 }
6093 if (subPrime.len != 0) {
6094 /* we have a known prime and a supplied subPrime,
6095 * make sure the subPrime matches the subPrime for
6096 * the known Prime */
6097 if (SECITEM_CompareItemSECITEM_CompareItem_Util(subPrimePtr, &subPrime) != 0) {
6098 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6099 goto done;
6100 }
6101 }
6102 }
6103 if (!KEA_Verify(&pubKey, &prime, (SECItem *)subPrimePtr)) {
6104 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6105 }
6106 done:
6107 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&base, PR_FALSE0);
6108 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&subPrime, PR_FALSE0);
6109 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&prime, PR_FALSE0);
6110 }
6111 /* clean up before we return */
6112 sftk_FreeAttribute(pubAttribute);
6113 if (crv != CKR_OK0x00000000UL) {
6114 return crv;
6115 }
6116 }
6117
6118 isKEM = sftk_isTrue(privateKey, CKA_DECAPSULATE0x00000634UL);
6119 if (isKEM) {
6120 unsigned char *cipher_text = NULL((void*)0);
6121 CK_ULONG cipher_text_length = 0;
6122 CK_OBJECT_HANDLE key1 = CK_INVALID_HANDLE0;
6123 CK_OBJECT_HANDLE key2 = CK_INVALID_HANDLE0;
6124 CK_KEY_TYPE genClass = CKO_SECRET_KEY0x00000004UL;
6125 CK_ATTRIBUTE template = { CKA_CLASS0x00000000UL, NULL((void*)0), 0 };
6126
6127 template.pValue = &genClass;
6128 template.ulValueLen = sizeof(genClass);
6129 crv = CKR_OK0x00000000UL;
6130 switch (keyType) {
6131 case CKK_ML_KEM0x00000049UL:
6132 cipher_text_length = MAX_ML_KEM_CIPHER_LENGTH1568U;
6133 mech.mechanism = CKM_ML_KEM0x00000017UL;
6134 break;
6135 default:
6136 return CKR_DEVICE_ERROR0x00000030UL;
6137 }
6138 /* Allocate space for kem cipher text. */
6139 cipher_text = (unsigned char *)PORT_ZAllocPORT_ZAlloc_Util(cipher_text_length);
6140 if (cipher_text == NULL((void*)0)) {
6141 return CKR_HOST_MEMORY0x00000002UL;
6142 }
6143 crv = NSC_Encapsulate(hSession, &mech, publicKey->handle, &template, 1,
6144 &key1, cipher_text, &cipher_text_length);
6145 if (crv != CKR_OK0x00000000UL) {
6146 goto kem_done;
6147 }
6148 crv = NSC_Decapsulate(hSession, &mech, privateKey->handle,
6149 cipher_text, cipher_text_length, &template, 1,
6150 &key2);
6151 if (crv != CKR_OK0x00000000UL) {
6152 goto kem_done;
6153 }
6154 if (!sftk_compareKeysEqual(hSession, key1, key2)) {
6155 crv = CKR_GENERAL_ERROR0x00000005UL;
6156 goto kem_done;
6157 }
6158 kem_done:
6159 /* PORT_Free already checks for NULL */
6160 PORT_FreePORT_Free_Util(cipher_text);
6161 if (key1 != CK_INVALID_HANDLE0) {
6162 NSC_DestroyObject(hSession, key1);
6163 }
6164 if (key2 != CK_INVALID_HANDLE0) {
6165 NSC_DestroyObject(hSession, key2);
6166 }
6167 if (crv != CKR_OK0x00000000UL) {
6168 return crv;
6169 }
6170 }
6171
6172 return CKR_OK0x00000000UL;
6173}
6174
6175/* NSC_GenerateKeyPair generates a public-key/private-key pair,
6176 * creating new key objects. */
6177CK_RV
6178NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession,
6179 CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
6180 CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
6181 CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
6182 CK_OBJECT_HANDLE_PTR phPrivateKey)
6183{
6184 SFTKObject *publicKey, *privateKey;
6185 SFTKSession *session;
6186 CK_KEY_TYPE key_type;
6187 CK_RV crv = CKR_OK0x00000000UL;
6188 CK_BBOOL cktrue = CK_TRUE1;
6189 SECStatus rv;
6190 CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY0x00000002UL;
6191 CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY0x00000003UL;
6192 int i;
6193 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
6194 unsigned int bitSize;
6195
6196 /* RSA */
6197 int public_modulus_bits = 0;
6198 SECItem pubExp;
6199 RSAPrivateKey *rsaPriv;
6200
6201 DHParams dhParam;
6202#ifndef NSS_DISABLE_DSA
6203 /* DSA */
6204 PQGParams pqgParam;
6205 DSAPrivateKey *dsaPriv;
6206#endif
6207 MLDSAPrivateKey mldsaPriv;
6208 MLDSAPublicKey mldsaPub;
6209
6210 /* Diffie Hellman */
6211 DHPrivateKey *dhPriv;
6212
6213 /* Elliptic Curve Cryptography */
6214 SECItem ecEncodedParams; /* DER Encoded parameters */
6215 ECPrivateKey *ecPriv;
6216 ECParams *ecParams;
6217
6218 /* parameter set, mostly pq keys */
6219 CK_ULONG genParamSet = 0;
6220
6221 CHECK_FORK();
6222
6223 if (!slot) {
6224 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
6225 }
6226 /*
6227 * now lets create an object to hang the attributes off of
6228 */
6229 publicKey = sftk_NewObject(slot); /* fill in the handle later */
6230 if (publicKey == NULL((void*)0)) {
6231 return CKR_HOST_MEMORY0x00000002UL;
6232 }
6233
6234 /*
6235 * load the template values into the publicKey
6236 */
6237 for (i = 0; i < (int)ulPublicKeyAttributeCount; i++) {
6238 if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS0x00000121UL) {
6239 public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue;
6240 continue;
6241 }
6242
6243 if ((pPublicKeyTemplate[i].type == CKA_PARAMETER_SET0x0000061dUL) ||
6244 (pPublicKeyTemplate[i].type == CKA_NSS_PARAMETER_SET((0x80000000UL | 0x4E534350) + 40))) {
6245 genParamSet = *(CK_ULONG *)pPublicKeyTemplate[i].pValue;
6246 continue;
6247 }
6248
6249 crv = sftk_AddAttributeType(publicKey,
6250 sftk_attr_expand(&pPublicKeyTemplate[i])(&pPublicKeyTemplate[i])->type, (&pPublicKeyTemplate
[i])->pValue, (&pPublicKeyTemplate[i])->ulValueLen
);
6251 if (crv != CKR_OK0x00000000UL)
6252 break;
6253 }
6254
6255 if (crv != CKR_OK0x00000000UL) {
6256 sftk_FreeObject(publicKey);
6257 return CKR_HOST_MEMORY0x00000002UL;
6258 }
6259
6260 privateKey = sftk_NewObject(slot); /* fill in the handle later */
6261 if (privateKey == NULL((void*)0)) {
6262 sftk_FreeObject(publicKey);
6263 return CKR_HOST_MEMORY0x00000002UL;
6264 }
6265 /*
6266 * now load the private key template
6267 */
6268 for (i = 0; i < (int)ulPrivateKeyAttributeCount; i++) {
6269 if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS0x00000160UL) {
6270 continue;
6271 }
6272
6273 crv = sftk_AddAttributeType(privateKey,
6274 sftk_attr_expand(&pPrivateKeyTemplate[i])(&pPrivateKeyTemplate[i])->type, (&pPrivateKeyTemplate
[i])->pValue, (&pPrivateKeyTemplate[i])->ulValueLen
);
6275 if (crv != CKR_OK0x00000000UL)
6276 break;
6277 }
6278
6279 if (crv != CKR_OK0x00000000UL) {
6280 sftk_FreeObject(publicKey);
6281 sftk_FreeObject(privateKey);
6282 return CKR_HOST_MEMORY0x00000002UL;
6283 }
6284 sftk_DeleteAttributeType(privateKey, CKA_CLASS0x00000000UL);
6285 sftk_DeleteAttributeType(privateKey, CKA_KEY_TYPE0x00000100UL);
6286 sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL);
6287 sftk_DeleteAttributeType(publicKey, CKA_CLASS0x00000000UL);
6288 sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE0x00000100UL);
6289 sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL);
6290
6291 /* Now Set up the parameters to generate the key (based on mechanism) */
6292 switch (pMechanism->mechanism) {
6293 case CKM_RSA_PKCS_KEY_PAIR_GEN0x00000000UL:
6294 /* format the keys */
6295 sftk_DeleteAttributeType(publicKey, CKA_MODULUS0x00000120UL);
6296 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6297 sftk_DeleteAttributeType(privateKey, CKA_MODULUS0x00000120UL);
6298 sftk_DeleteAttributeType(privateKey, CKA_PRIVATE_EXPONENT0x00000123UL);
6299 sftk_DeleteAttributeType(privateKey, CKA_PUBLIC_EXPONENT0x00000122UL);
6300 sftk_DeleteAttributeType(privateKey, CKA_PRIME_10x00000124UL);
6301 sftk_DeleteAttributeType(privateKey, CKA_PRIME_20x00000125UL);
6302 sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_10x00000126UL);
6303 sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_20x00000127UL);
6304 sftk_DeleteAttributeType(privateKey, CKA_COEFFICIENT0x00000128UL);
6305 key_type = CKK_RSA0x00000000UL;
6306 if (public_modulus_bits == 0) {
6307 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6308 break;
6309 }
6310 if (public_modulus_bits < RSA_MIN_MODULUS_BITS128) {
6311 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6312 break;
6313 }
6314 if (public_modulus_bits % 2 != 0) {
6315 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6316 break;
6317 }
6318
6319 /* extract the exponent */
6320 crv = sftk_Attribute2SSecItem(NULL((void*)0), &pubExp, publicKey, CKA_PUBLIC_EXPONENT0x00000122UL);
6321 if (crv != CKR_OK0x00000000UL)
6322 break;
6323 bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len);
6324 if (bitSize < 2) {
6325 crv = CKR_ATTRIBUTE_VALUE_INVALID0x00000013UL;
6326 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubExp, PR_FALSE0);
6327 break;
6328 }
6329 crv = sftk_AddAttributeType(privateKey, CKA_PUBLIC_EXPONENT0x00000122UL,
6330 sftk_item_expand(&pubExp)(&pubExp)->data, (&pubExp)->len);
6331 if (crv != CKR_OK0x00000000UL) {
6332 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubExp, PR_FALSE0);
6333 break;
6334 }
6335
6336 rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
6337 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pubExp, PR_FALSE0);
6338 if (rsaPriv == NULL((void*)0)) {
6339 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6340 sftk_fatalError = PR_TRUE1;
6341 }
6342 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6343 break;
6344 }
6345 /* now fill in the RSA dependent paramenters in the public key */
6346 crv = sftk_AddAttributeType(publicKey, CKA_MODULUS0x00000120UL,
6347 sftk_item_expand(&rsaPriv->modulus)(&rsaPriv->modulus)->data, (&rsaPriv->modulus
)->len
);
6348 if (crv != CKR_OK0x00000000UL)
6349 goto kpg_done;
6350 /* now fill in the RSA dependent paramenters in the private key */
6351 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6352 sftk_item_expand(&rsaPriv->modulus)(&rsaPriv->modulus)->data, (&rsaPriv->modulus
)->len
);
6353 if (crv != CKR_OK0x00000000UL)
6354 goto kpg_done;
6355 crv = sftk_AddAttributeType(privateKey, CKA_MODULUS0x00000120UL,
6356 sftk_item_expand(&rsaPriv->modulus)(&rsaPriv->modulus)->data, (&rsaPriv->modulus
)->len
);
6357 if (crv != CKR_OK0x00000000UL)
6358 goto kpg_done;
6359 crv = sftk_AddAttributeType(privateKey, CKA_PRIVATE_EXPONENT0x00000123UL,
6360 sftk_item_expand(&rsaPriv->privateExponent)(&rsaPriv->privateExponent)->data, (&rsaPriv->
privateExponent)->len
);
6361 if (crv != CKR_OK0x00000000UL)
6362 goto kpg_done;
6363 crv = sftk_AddAttributeType(privateKey, CKA_PRIME_10x00000124UL,
6364 sftk_item_expand(&rsaPriv->prime1)(&rsaPriv->prime1)->data, (&rsaPriv->prime1)
->len
);
6365 if (crv != CKR_OK0x00000000UL)
6366 goto kpg_done;
6367 crv = sftk_AddAttributeType(privateKey, CKA_PRIME_20x00000125UL,
6368 sftk_item_expand(&rsaPriv->prime2)(&rsaPriv->prime2)->data, (&rsaPriv->prime2)
->len
);
6369 if (crv != CKR_OK0x00000000UL)
6370 goto kpg_done;
6371 crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_10x00000126UL,
6372 sftk_item_expand(&rsaPriv->exponent1)(&rsaPriv->exponent1)->data, (&rsaPriv->exponent1
)->len
);
6373 if (crv != CKR_OK0x00000000UL)
6374 goto kpg_done;
6375 crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_20x00000127UL,
6376 sftk_item_expand(&rsaPriv->exponent2)(&rsaPriv->exponent2)->data, (&rsaPriv->exponent2
)->len
);
6377 if (crv != CKR_OK0x00000000UL)
6378 goto kpg_done;
6379 crv = sftk_AddAttributeType(privateKey, CKA_COEFFICIENT0x00000128UL,
6380 sftk_item_expand(&rsaPriv->coefficient)(&rsaPriv->coefficient)->data, (&rsaPriv->coefficient
)->len
);
6381 kpg_done:
6382 /* Should zeroize the contents first, since this func doesn't. */
6383 PORT_FreeArenaPORT_FreeArena_Util(rsaPriv->arena, PR_TRUE1);
6384 break;
6385#ifndef NSS_DISABLE_DSA
6386 case CKM_DSA_KEY_PAIR_GEN0x00000010UL:
6387 sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL);
6388 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6389 sftk_DeleteAttributeType(privateKey, CKA_PRIME0x00000130UL);
6390 sftk_DeleteAttributeType(privateKey, CKA_SUBPRIME0x00000131UL);
6391 sftk_DeleteAttributeType(privateKey, CKA_BASE0x00000132UL);
6392 key_type = CKK_DSA0x00000001UL;
6393
6394 /* extract the necessary parameters and copy them to the private key */
6395 crv = sftk_Attribute2SSecItem(NULL((void*)0), &pqgParam.prime, publicKey, CKA_PRIME0x00000130UL);
6396 if (crv != CKR_OK0x00000000UL)
6397 break;
6398 crv = sftk_Attribute2SSecItem(NULL((void*)0), &pqgParam.subPrime, publicKey,
6399 CKA_SUBPRIME0x00000131UL);
6400 if (crv != CKR_OK0x00000000UL) {
6401 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6402 break;
6403 }
6404 crv = sftk_Attribute2SSecItem(NULL((void*)0), &pqgParam.base, publicKey, CKA_BASE0x00000132UL);
6405 if (crv != CKR_OK0x00000000UL) {
6406 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6407 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6408 break;
6409 }
6410 crv = sftk_AddAttributeType(privateKey, CKA_PRIME0x00000130UL,
6411 sftk_item_expand(&pqgParam.prime)(&pqgParam.prime)->data, (&pqgParam.prime)->len);
6412 if (crv != CKR_OK0x00000000UL) {
6413 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6414 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6415 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0);
6416 break;
6417 }
6418 crv = sftk_AddAttributeType(privateKey, CKA_SUBPRIME0x00000131UL,
6419 sftk_item_expand(&pqgParam.subPrime)(&pqgParam.subPrime)->data, (&pqgParam.subPrime)->
len
);
6420 if (crv != CKR_OK0x00000000UL) {
6421 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6422 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6423 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0);
6424 break;
6425 }
6426 crv = sftk_AddAttributeType(privateKey, CKA_BASE0x00000132UL,
6427 sftk_item_expand(&pqgParam.base)(&pqgParam.base)->data, (&pqgParam.base)->len);
6428 if (crv != CKR_OK0x00000000UL) {
6429 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6430 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6431 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0);
6432 break;
6433 }
6434
6435 /*
6436 * these are checked by DSA_NewKey
6437 */
6438 bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data,
6439 pqgParam.subPrime.len);
6440 if ((bitSize < DSA_MIN_Q_BITS160) || (bitSize > DSA_MAX_Q_BITS256)) {
6441 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6442 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6443 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6444 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0);
6445 break;
6446 }
6447 bitSize = sftk_GetLengthInBits(pqgParam.prime.data, pqgParam.prime.len);
6448 if ((bitSize < DSA_MIN_P_BITS512) || (bitSize > DSA_MAX_P_BITS3072)) {
6449 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6450 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6451 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6452 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0);
6453 break;
6454 }
6455 bitSize = sftk_GetLengthInBits(pqgParam.base.data, pqgParam.base.len);
6456 if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS3072)) {
6457 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6458 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6459 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6460 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0);
6461 break;
6462 }
6463
6464 /* Generate the key */
6465 rv = DSA_NewKey(&pqgParam, &dsaPriv);
6466
6467 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.prime, PR_FALSE0);
6468 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.subPrime, PR_FALSE0);
6469 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&pqgParam.base, PR_FALSE0);
6470
6471 if (rv != SECSuccess) {
6472 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6473 sftk_fatalError = PR_TRUE1;
6474 }
6475 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6476 break;
6477 }
6478
6479 /* store the generated key into the attributes */
6480 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL,
6481 sftk_item_expand(&dsaPriv->publicValue)(&dsaPriv->publicValue)->data, (&dsaPriv->publicValue
)->len
);
6482 if (crv != CKR_OK0x00000000UL)
6483 goto dsagn_done;
6484
6485 /* now fill in the RSA dependent paramenters in the private key */
6486 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6487 sftk_item_expand(&dsaPriv->publicValue)(&dsaPriv->publicValue)->data, (&dsaPriv->publicValue
)->len
);
6488 if (crv != CKR_OK0x00000000UL)
6489 goto dsagn_done;
6490 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6491 sftk_item_expand(&dsaPriv->privateValue)(&dsaPriv->privateValue)->data, (&dsaPriv->privateValue
)->len
);
6492
6493 dsagn_done:
6494 /* should zeroize, since this function doesn't. */
6495 PORT_FreeArenaPORT_FreeArena_Util(dsaPriv->params.arena, PR_TRUE1);
6496 break;
6497#endif
6498 case CKM_DH_PKCS_KEY_PAIR_GEN0x00000020UL:
6499 sftk_DeleteAttributeType(privateKey, CKA_PRIME0x00000130UL);
6500 sftk_DeleteAttributeType(privateKey, CKA_BASE0x00000132UL);
6501 sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL);
6502 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6503 key_type = CKK_DH0x00000002UL;
6504
6505 /* extract the necessary parameters and copy them to private keys */
6506 crv = sftk_Attribute2SSecItem(NULL((void*)0), &dhParam.prime, publicKey,
6507 CKA_PRIME0x00000130UL);
6508 if (crv != CKR_OK0x00000000UL)
6509 break;
6510 crv = sftk_Attribute2SSecItem(NULL((void*)0), &dhParam.base, publicKey, CKA_BASE0x00000132UL);
6511 if (crv != CKR_OK0x00000000UL) {
6512 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0);
6513 break;
6514 }
6515 crv = sftk_AddAttributeType(privateKey, CKA_PRIME0x00000130UL,
6516 sftk_item_expand(&dhParam.prime)(&dhParam.prime)->data, (&dhParam.prime)->len);
6517 if (crv != CKR_OK0x00000000UL) {
6518 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0);
6519 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0);
6520 break;
6521 }
6522 crv = sftk_AddAttributeType(privateKey, CKA_BASE0x00000132UL,
6523 sftk_item_expand(&dhParam.base)(&dhParam.base)->data, (&dhParam.base)->len);
6524 if (crv != CKR_OK0x00000000UL) {
6525 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0);
6526 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0);
6527 break;
6528 }
6529 bitSize = sftk_GetLengthInBits(dhParam.prime.data, dhParam.prime.len);
6530 if ((bitSize < DH_MIN_P_BITS128) || (bitSize > DH_MAX_P_BITS16384)) {
6531 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6532 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0);
6533 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0);
6534 break;
6535 }
6536 bitSize = sftk_GetLengthInBits(dhParam.base.data, dhParam.base.len);
6537 if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS16384)) {
6538 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6539 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0);
6540 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0);
6541 break;
6542 }
6543
6544 rv = DH_NewKey(&dhParam, &dhPriv);
6545 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.prime, PR_FALSE0);
6546 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhParam.base, PR_FALSE0);
6547 if (rv != SECSuccess) {
6548 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6549 sftk_fatalError = PR_TRUE1;
6550 }
6551 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6552 break;
6553 }
6554
6555 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL,
6556 sftk_item_expand(&dhPriv->publicValue)(&dhPriv->publicValue)->data, (&dhPriv->publicValue
)->len
);
6557 if (crv != CKR_OK0x00000000UL)
6558 goto dhgn_done;
6559
6560 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6561 sftk_item_expand(&dhPriv->publicValue)(&dhPriv->publicValue)->data, (&dhPriv->publicValue
)->len
);
6562 if (crv != CKR_OK0x00000000UL)
6563 goto dhgn_done;
6564
6565 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6566 sftk_item_expand(&dhPriv->privateValue)(&dhPriv->privateValue)->data, (&dhPriv->privateValue
)->len
);
6567
6568 dhgn_done:
6569 /* should zeroize, since this function doesn't. */
6570 PORT_FreeArenaPORT_FreeArena_Util(dhPriv->arena, PR_TRUE1);
6571 break;
6572
6573 case CKM_EC_KEY_PAIR_GEN0x00001040UL:
6574 case CKM_NSS_ECDHE_NO_PAIRWISE_CHECK_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 47):
6575 sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL);
6576 sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL);
6577 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6578 key_type = CKK_EC0x00000003UL;
6579
6580 /* extract the necessary parameters and copy them to private keys */
6581 crv = sftk_Attribute2SSecItem(NULL((void*)0), &ecEncodedParams, publicKey,
6582 CKA_EC_PARAMS0x00000180UL);
6583 if (crv != CKR_OK0x00000000UL)
6584 break;
6585
6586 crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL,
6587 sftk_item_expand(&ecEncodedParams)(&ecEncodedParams)->data, (&ecEncodedParams)->len);
6588 if (crv != CKR_OK0x00000000UL) {
6589 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0);
6590 break;
6591 }
6592
6593 /* Decode ec params before calling EC_NewKey */
6594 rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
6595 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0);
6596 if (rv != SECSuccess) {
6597 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6598 break;
6599 }
6600 rv = EC_NewKey(ecParams, &ecPriv);
6601 if (rv != SECSuccess) {
6602 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6603 sftk_fatalError = PR_TRUE1;
6604 }
6605 PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1);
6606 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6607 break;
6608 }
6609
6610 if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") ||
6611 ecParams->type != ec_params_named) {
6612 PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1);
6613 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL,
6614 sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue
)->len
);
6615 } else {
6616 PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1);
6617 SECItem *pubValue = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0),
6618 &ecPriv->publicValue,
6619 SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util);
6620 if (!pubValue) {
6621 crv = CKR_ARGUMENTS_BAD0x00000007UL;
6622 goto ecgn_done;
6623 }
6624 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL,
6625 sftk_item_expand(pubValue)(pubValue)->data, (pubValue)->len);
6626 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(pubValue, PR_TRUE1);
6627 }
6628 if (crv != CKR_OK0x00000000UL)
6629 goto ecgn_done;
6630
6631 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6632 sftk_item_expand(&ecPriv->privateValue)(&ecPriv->privateValue)->data, (&ecPriv->privateValue
)->len
);
6633 if (crv != CKR_OK0x00000000UL)
6634 goto ecgn_done;
6635
6636 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6637 sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue
)->len
);
6638 ecgn_done:
6639 /* should zeroize, since this function doesn't. */
6640 PORT_FreeArenaPORT_FreeArena_Util(ecPriv->ecParams.arena, PR_TRUE1);
6641 break;
6642
6643 case CKM_NSS_ML_KEM_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 48):
6644 key_type = CKK_NSS_ML_KEM((0x80000000UL | 0x4E534350) + 6);
6645 goto do_ml_kem;
6646
6647 case CKM_ML_KEM_KEY_PAIR_GEN0x0000000fUL:
6648 key_type = CKK_ML_KEM0x00000049UL;
6649
6650 do_ml_kem:
6651 sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL);
6652 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6653 sftk_DeleteAttributeType(privateKey, CKA_SEED0x00000637UL);
6654 sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL);
6655 SECItem privKey = { siBuffer, NULL((void*)0), 0 };
6656 SECItem pubKey = { siBuffer, NULL((void*)0), 0 };
6657 SECItem seed = { siBuffer, NULL((void*)0), 0 };
6658 unsigned char seedData[KYBER_KEYPAIR_COIN_BYTES64U];
6659
6660 /* generate the seed here so we can record it with
6661 * the private key */
6662 seed.data = seedData;
6663 seed.len = sizeof(seedData);
6664 rv = RNG_GenerateGlobalRandomBytes(seed.data, seed.len);
6665 if (rv != SECSuccess) {
6666 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6667 goto kyber_done;
6668 }
6669
6670 KyberParams kyberParams = sftk_kyber_PK11ParamToInternal(genParamSet);
6671 if (!sftk_kyber_AllocPrivKeyItem(kyberParams, &privKey)) {
6672 crv = CKR_HOST_MEMORY0x00000002UL;
6673 goto kyber_done;
6674 }
6675 if (!sftk_kyber_AllocPubKeyItem(kyberParams, &pubKey)) {
6676 crv = CKR_HOST_MEMORY0x00000002UL;
6677 goto kyber_done;
6678 }
6679 rv = Kyber_NewKey(kyberParams, &seed, &privKey, &pubKey);
6680 if (rv != SECSuccess) {
6681 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6682 goto kyber_done;
6683 }
6684
6685 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL, sftk_item_expand(&pubKey)(&pubKey)->data, (&pubKey)->len);
6686 if (crv != CKR_OK0x00000000UL) {
6687 goto kyber_done;
6688 }
6689 crv = sftk_AddAttributeType(publicKey, CKA_PARAMETER_SET0x0000061dUL,
6690 &genParamSet,
6691 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE));
6692 if (crv != CKR_OK0x00000000UL) {
6693 goto kyber_done;
6694 }
6695 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6696 sftk_item_expand(&privKey)(&privKey)->data, (&privKey)->len);
6697 if (crv != CKR_OK0x00000000UL) {
6698 goto kyber_done;
6699 }
6700 crv = sftk_AddAttributeType(privateKey, CKA_SEED0x00000637UL,
6701 sftk_item_expand(&seed)(&seed)->data, (&seed)->len);
6702 if (crv != CKR_OK0x00000000UL) {
6703 goto kyber_done;
6704 }
6705 /* pseudo attribute that says the seed came with the key
6706 * so don't try to regenerate the key in handleObject.
6707 * it will be removed before the object sees the light of
6708 * day. */
6709 crv = sftk_AddAttributeType(privateKey, CKA_NSS_SEED_OK((0x80000000UL | 0x4E534350) + 41),
6710 NULL((void*)0), 0);
6711 if (crv != CKR_OK0x00000000UL) {
6712 goto kyber_done;
6713 }
6714 crv = sftk_AddAttributeType(privateKey, CKA_PARAMETER_SET0x0000061dUL,
6715 &genParamSet,
6716 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE));
6717 if (crv != CKR_OK0x00000000UL) {
6718 goto kyber_done;
6719 }
6720 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6721 sftk_item_expand(&pubKey)(&pubKey)->data, (&pubKey)->len);
6722 kyber_done:
6723 PORT_SafeZero(seed.data, seed.len);
6724 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&privKey, PR_FALSE0);
6725 SECITEM_FreeItemSECITEM_FreeItem_Util(&pubKey, PR_FALSE0);
6726 break;
6727
6728 case CKM_ML_DSA_KEY_PAIR_GEN0x0000001cUL:
6729 sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL);
6730 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6731 sftk_DeleteAttributeType(privateKey, CKA_SEED0x00000637UL);
6732 key_type = CKK_ML_DSA0x0000004aUL;
6733
6734 /*
6735 * the parameters are recognized by us
6736 */
6737 bitSize = sftk_MLDSAGetSigLen(genParamSet);
6738 if (bitSize == 0) {
6739 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6740 break;
6741 }
6742
6743 /* Generate the key */
6744 rv = MLDSA_NewKey(genParamSet, NULL((void*)0), &mldsaPriv, &mldsaPub);
6745
6746 if (rv != SECSuccess) {
6747 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6748 sftk_fatalError = PR_TRUE1;
6749 }
6750 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6751 break;
6752 }
6753
6754 /* store the generated key into the attributes */
6755 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL,
6756 mldsaPub.keyVal, mldsaPub.keyValLen);
6757 if (crv != CKR_OK0x00000000UL)
6758 goto mldsagn_done;
6759 crv = sftk_AddAttributeType(publicKey, CKA_PARAMETER_SET0x0000061dUL,
6760 &genParamSet, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE));
6761 if (crv != CKR_OK0x00000000UL) {
6762 goto mldsagn_done;
6763 }
6764
6765 /* now fill in the ML-DSA specfic paramenters in the private key */
6766 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6767 mldsaPub.keyVal, mldsaPub.keyValLen);
6768 if (crv != CKR_OK0x00000000UL)
6769 goto mldsagn_done;
6770
6771 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6772 mldsaPriv.keyVal,
6773 mldsaPriv.keyValLen);
6774 if (crv != CKR_OK0x00000000UL)
6775 goto mldsagn_done;
6776 crv = sftk_AddAttributeType(privateKey, CKA_PARAMETER_SET0x0000061dUL,
6777 &genParamSet, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE));
6778 if (crv != CKR_OK0x00000000UL) {
6779 goto mldsagn_done;
6780 }
6781
6782 if (mldsaPriv.seedLen != 0) {
6783 crv = sftk_AddAttributeType(privateKey, CKA_SEED0x00000637UL,
6784 mldsaPriv.seed, mldsaPriv.seedLen);
6785 if (crv != CKR_OK0x00000000UL) {
6786 goto mldsagn_done;
6787 }
6788 /* pseudo attribute that says the seed came with the key
6789 * so don't try to regenerate the key in handleObject.
6790 * it will be removed before the object sees the light of
6791 * day. */
6792 crv = sftk_AddAttributeType(privateKey, CKA_NSS_SEED_OK((0x80000000UL | 0x4E534350) + 41),
6793 NULL((void*)0), 0);
6794 /* it was either this or a comment 'fall through' which would
6795 * be cryptic to some users */
6796 if (crv != CKR_OK0x00000000UL) {
6797 goto mldsagn_done;
6798 }
6799 }
6800 mldsagn_done:
6801 PORT_SafeZero(&mldsaPriv, sizeof(mldsaPriv));
6802 PORT_SafeZero(&mldsaPub, sizeof(mldsaPub));
6803 break;
6804
6805 case CKM_EC_MONTGOMERY_KEY_PAIR_GEN0x00001056UL:
6806 case CKM_EC_EDWARDS_KEY_PAIR_GEN0x00001055UL:
6807 sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL);
6808 sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL);
6809 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6810 key_type = (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN0x00001055UL) ? CKK_EC_EDWARDS0x00000040UL : CKK_EC_MONTGOMERY0x00000041UL;
6811
6812 /* extract the necessary parameters and copy them to private keys */
6813 crv = sftk_Attribute2SSecItem(NULL((void*)0), &ecEncodedParams, publicKey,
6814 CKA_EC_PARAMS0x00000180UL);
6815 if (crv != CKR_OK0x00000000UL) {
6816 break;
6817 }
6818
6819 crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL,
6820 sftk_item_expand(&ecEncodedParams)(&ecEncodedParams)->data, (&ecEncodedParams)->len);
6821 if (crv != CKR_OK0x00000000UL) {
6822 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0);
6823 break;
6824 }
6825
6826 /* Decode ec params before calling EC_NewKey */
6827 rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
6828 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0);
6829 if (rv != SECSuccess) {
6830 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6831 break;
6832 }
6833
6834 rv = EC_NewKey(ecParams, &ecPriv);
6835 if (rv != SECSuccess) {
6836 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6837 sftk_fatalError = PR_TRUE1;
6838 }
6839 PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1);
6840 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6841 break;
6842 }
6843 PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1);
6844 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL,
6845 sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue
)->len
);
6846 if (crv != CKR_OK0x00000000UL)
6847 goto edgn_done;
6848
6849 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6850 sftk_item_expand(&ecPriv->privateValue)(&ecPriv->privateValue)->data, (&ecPriv->privateValue
)->len
);
6851 if (crv != CKR_OK0x00000000UL)
6852 goto edgn_done;
6853
6854 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6855 sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue
)->len
);
6856 edgn_done:
6857 /* should zeroize, since this function doesn't. */
6858 PORT_FreeArenaPORT_FreeArena_Util(ecPriv->ecParams.arena, PR_TRUE1);
6859 break;
6860
6861 default:
6862 crv = CKR_MECHANISM_INVALID0x00000070UL;
6863 }
6864
6865 if (crv != CKR_OK0x00000000UL) {
6866 sftk_FreeObject(privateKey);
6867 sftk_FreeObject(publicKey);
6868 return crv;
6869 }
6870
6871 /* Add the class, key_type The loop lets us check errors blow out
6872 * on errors and clean up at the bottom */
6873 session = NULL((void*)0); /* make pedtantic happy... session cannot leave the*/
6874 /* loop below NULL unless an error is set... */
6875 do {
6876 crv = sftk_AddAttributeType(privateKey, CKA_CLASS0x00000000UL, &privClass,
6877 sizeof(CK_OBJECT_CLASS));
6878 if (crv != CKR_OK0x00000000UL)
6879 break;
6880 crv = sftk_AddAttributeType(publicKey, CKA_CLASS0x00000000UL, &pubClass,
6881 sizeof(CK_OBJECT_CLASS));
6882 if (crv != CKR_OK0x00000000UL)
6883 break;
6884 crv = sftk_AddAttributeType(privateKey, CKA_KEY_TYPE0x00000100UL, &key_type,
6885 sizeof(CK_KEY_TYPE));
6886 if (crv != CKR_OK0x00000000UL)
6887 break;
6888 crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE0x00000100UL, &key_type,
6889 sizeof(CK_KEY_TYPE));
6890 if (crv != CKR_OK0x00000000UL)
6891 break;
6892 session = sftk_SessionFromHandle(hSession);
6893 if (session == NULL((void*)0))
6894 crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
6895 } while (0);
6896
6897 if (crv != CKR_OK0x00000000UL) {
6898 sftk_FreeObject(privateKey);
6899 sftk_FreeObject(publicKey);
6900 return crv;
6901 }
6902
6903 /*
6904 * handle the base object cleanup for the public Key
6905 */
6906 crv = sftk_handleObject(privateKey, session);
6907 if (crv != CKR_OK0x00000000UL) {
6908 sftk_FreeSession(session);
6909 sftk_FreeObject(privateKey);
6910 sftk_FreeObject(publicKey);
6911 return crv;
6912 }
6913
6914 /*
6915 * handle the base object cleanup for the private Key
6916 * If we have any problems, we destroy the public Key we've
6917 * created and linked.
6918 */
6919 crv = sftk_handleObject(publicKey, session);
6920 if (crv != CKR_OK0x00000000UL) {
6921 sftk_FreeSession(session);
6922 sftk_FreeObject(publicKey);
6923 NSC_DestroyObject(hSession, privateKey->handle);
6924 sftk_FreeObject(privateKey);
6925 return crv;
6926 }
6927 if (sftk_isTrue(privateKey, CKA_SENSITIVE0x00000103UL)) {
6928 crv = sftk_forceAttribute(privateKey, CKA_ALWAYS_SENSITIVE0x00000165UL,
6929 &cktrue, sizeof(CK_BBOOL));
6930 }
6931 if (crv == CKR_OK0x00000000UL && sftk_isTrue(publicKey, CKA_SENSITIVE0x00000103UL)) {
6932 crv = sftk_forceAttribute(publicKey, CKA_ALWAYS_SENSITIVE0x00000165UL,
6933 &cktrue, sizeof(CK_BBOOL));
6934 }
6935 if (crv == CKR_OK0x00000000UL && !sftk_isTrue(privateKey, CKA_EXTRACTABLE0x00000162UL)) {
6936 crv = sftk_forceAttribute(privateKey, CKA_NEVER_EXTRACTABLE0x00000164UL,
6937 &cktrue, sizeof(CK_BBOOL));
6938 }
6939 if (crv == CKR_OK0x00000000UL && !sftk_isTrue(publicKey, CKA_EXTRACTABLE0x00000162UL)) {
6940 crv = sftk_forceAttribute(publicKey, CKA_NEVER_EXTRACTABLE0x00000164UL,
6941 &cktrue, sizeof(CK_BBOOL));
6942 }
6943
6944 if (crv == CKR_OK0x00000000UL &&
6945 pMechanism->mechanism != CKM_NSS_ECDHE_NO_PAIRWISE_CHECK_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 47)) {
6946 /* Perform FIPS 140-2 pairwise consistency check. */
6947 crv = sftk_PairwiseConsistencyCheck(hSession, slot,
6948 publicKey, privateKey, key_type);
6949 if (crv != CKR_OK0x00000000UL) {
6950 if (sftk_audit_enabled) {
6951 char msg[128];
6952 PR_snprintf(msg, sizeof msg,
6953 "C_GenerateKeyPair(hSession=0x%08lX, "
6954 "pMechanism->mechanism=0x%08lX)=0x%08lX "
6955 "self-test: pair-wise consistency test failed",
6956 (PRUint32)hSession, (PRUint32)pMechanism->mechanism,
6957 (PRUint32)crv);
6958 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
6959 }
6960 }
6961 }
6962
6963 if (crv != CKR_OK0x00000000UL) {
6964 sftk_FreeSession(session);
6965 NSC_DestroyObject(hSession, publicKey->handle);
6966 sftk_FreeObject(publicKey);
6967 NSC_DestroyObject(hSession, privateKey->handle);
6968 sftk_FreeObject(privateKey);
6969 return crv;
6970 }
6971 /* we need to do this check at the end to make sure the generated key
6972 * meets the key length requirements */
6973 sftk_setFIPS(privateKey, sftk_operationIsFIPS(slot, pMechanism,
6974 CKA_NSS_GENERATE_KEY_PAIR0x81000002L,
6975 privateKey, 0));
6976 session->lastOpWasFIPS = sftk_hasFIPS(privateKey);
6977 sftk_setFIPS(publicKey, session->lastOpWasFIPS);
6978 sftk_FreeSession(session);
6979 *phPrivateKey = privateKey->handle;
6980 *phPublicKey = publicKey->handle;
6981 sftk_FreeObject(publicKey);
6982 sftk_FreeObject(privateKey);
6983
6984 return CKR_OK0x00000000UL;
6985}
6986
6987static SECItem *
6988sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
6989{
6990 NSSLOWKEYPrivateKey *lk = NULL((void*)0);
6991 NSSLOWKEYPrivateKeyInfo *pki = NULL((void*)0);
6992 SFTKAttribute *attribute = NULL((void*)0);
6993 PLArenaPool *arena = NULL((void*)0);
6994 SECOidTag algorithm = SEC_OID_UNKNOWN;
6995 void *dummy, *param = NULL((void*)0);
6996 SECStatus rv = SECSuccess;
6997 SECItem *encodedKey = NULL((void*)0);
6998#ifdef EC_DEBUG
6999 SECItem *fordebug;
7000#endif
7001 int savelen;
7002
7003 if (!key) {
7004 *crvp = CKR_KEY_HANDLE_INVALID0x00000060UL; /* really can't happen */
7005 return NULL((void*)0);
7006 }
7007
7008 attribute = sftk_FindAttribute(key, CKA_KEY_TYPE0x00000100UL);
7009 if (!attribute) {
7010 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7011 return NULL((void*)0);
7012 }
7013
7014 lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp);
7015 sftk_FreeAttribute(attribute);
7016 if (!lk) {
7017 return NULL((void*)0);
7018 }
7019
7020 arena = PORT_NewArenaPORT_NewArena_Util(2048); /* XXX different size? */
7021 if (!arena) {
7022 *crvp = CKR_HOST_MEMORY0x00000002UL;
7023 rv = SECFailure;
7024 goto loser;
7025 }
7026
7027 pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7028 sizeof(NSSLOWKEYPrivateKeyInfo));
7029 if (!pki) {
7030 *crvp = CKR_HOST_MEMORY0x00000002UL;
7031 rv = SECFailure;
7032 goto loser;
7033 }
7034 pki->arena = arena;
7035
7036 param = NULL((void*)0);
7037 switch (lk->keyType) {
7038 case NSSLOWKEYRSAKey:
7039 prepare_low_rsa_priv_key_for_asn1(lk);
7040 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7041 nsslowkey_RSAPrivateKeyTemplate);
7042
7043 /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */
7044 attribute = sftk_FindAttribute(key, CKA_PUBLIC_KEY_INFO0x00000129UL);
7045 if (attribute) {
7046 NSSLOWKEYSubjectPublicKeyInfo *publicKeyInfo;
7047 SECItem spki;
7048
7049 spki.data = attribute->attrib.pValue;
7050 spki.len = attribute->attrib.ulValueLen;
7051
7052 publicKeyInfo = PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7053 sizeof(NSSLOWKEYSubjectPublicKeyInfo));
7054 if (!publicKeyInfo) {
7055 sftk_FreeAttribute(attribute);
7056 *crvp = CKR_HOST_MEMORY0x00000002UL;
7057 rv = SECFailure;
7058 goto loser;
7059 }
7060 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, publicKeyInfo,
7061 nsslowkey_SubjectPublicKeyInfoTemplate,
7062 &spki);
7063 if (rv != SECSuccess) {
7064 sftk_FreeAttribute(attribute);
7065 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7066 goto loser;
7067 }
7068 algorithm = SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&publicKeyInfo->algorithm);
7069 if (algorithm != SEC_OID_PKCS1_RSA_ENCRYPTION &&
7070 algorithm != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
7071 sftk_FreeAttribute(attribute);
7072 rv = SECFailure;
7073 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7074 goto loser;
7075 }
7076 param = SECITEM_DupItemSECITEM_DupItem_Util(&publicKeyInfo->algorithm.parameters);
7077 if (!param) {
7078 sftk_FreeAttribute(attribute);
7079 rv = SECFailure;
7080 *crvp = CKR_HOST_MEMORY0x00000002UL;
7081 goto loser;
7082 }
7083 sftk_FreeAttribute(attribute);
7084 } else {
7085 /* default to PKCS #1 */
7086 algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
7087 }
7088 break;
7089 case NSSLOWKEYDSAKey:
7090 prepare_low_dsa_priv_key_export_for_asn1(lk);
7091 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7092 nsslowkey_DSAPrivateKeyExportTemplate);
7093 prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);
7094 param = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), &(lk->u.dsa.params),
7095 nsslowkey_PQGParamsTemplate);
7096 algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
7097 break;
7098 case NSSLOWKEYECKey:
7099 algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
7100 prepare_low_ec_priv_key_for_asn1(lk);
7101 /* Public value is encoded as a bit string so adjust length
7102 * to be in bits before ASN encoding and readjust
7103 * immediately after.
7104 *
7105 * Since the SECG specification recommends not including the
7106 * parameters as part of ECPrivateKey, we zero out the curveOID
7107 * length before encoding and restore it later.
7108 */
7109 lk->u.ec.publicValue.len <<= 3;
7110 savelen = lk->u.ec.ecParams.curveOID.len;
7111 lk->u.ec.ecParams.curveOID.len = 0;
7112 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7113 nsslowkey_ECPrivateKeyTemplate);
7114 lk->u.ec.ecParams.curveOID.len = savelen;
7115 lk->u.ec.publicValue.len >>= 3;
7116
7117#ifdef EC_DEBUG
7118 fordebug = &pki->privateKey;
7119 SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
7120 fordebug);
7121#endif
7122
7123 param = SECITEM_DupItemSECITEM_DupItem_Util(&lk->u.ec.ecParams.DEREncoding);
7124 break;
7125 /* X25519, ED25519, X448, and ED448 encode the private key
7126 * as just a single Octect String. Unlike ECC we don't encode
7127 * the public key nor the curve, so no need to use a
7128 * special template */
7129 case NSSLOWKEYECEdwardsKey:
7130 algorithm = SEC_OID_ED25519;
7131 goto ec_continue;
7132 case NSSLOWKEYECMontgomeryKey:
7133 algorithm = SEC_OID_X25519;
7134 ec_continue:
7135 prepare_low_ec_priv_key_for_asn1(lk);
7136 /* don't set the public key, we only encode
7137 * v1 versions for maximal compatibility. We
7138 * can decode v2 versions */
7139 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey,
7140 &lk->u.ec.privateValue,
7141 SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util);
7142 param = NULL((void*)0);
7143 break;
7144 case NSSLOWKEYMLKEMKey: {
7145 SECItem seed = { siBuffer, NULL((void*)0), 0 };
7146 SECItem rawKey = { siBuffer, NULL((void*)0), 0 };
7147 dummy = NULL((void*)0);
7148
7149 switch (lk->u.mlkem.mlkemParams) {
7150 case params_ml_kem512:
7151 case params_ml_kem512_test_mode:
7152 algorithm = SEC_OID_ML_KEM_512;
7153 break;
7154 case params_ml_kem768:
7155 case params_ml_kem768_test_mode:
7156 algorithm = SEC_OID_ML_KEM_768;
7157 break;
7158 case params_ml_kem1024:
7159 case params_ml_kem1024_test_mode:
7160 algorithm = SEC_OID_ML_KEM_1024;
7161 break;
7162 default:
7163 algorithm = SEC_OID_UNKNOWN;
7164 break;
7165 }
7166 if (algorithm == SEC_OID_UNKNOWN) {
7167 break;
7168 }
7169 /* save the seed and key items before they are overwritten */
7170 if (lk->u.mlkem.seed.len != 0) {
7171 seed = lk->u.mlkem.seed;
7172 }
7173 rawKey = lk->u.mlkem.key;
7174 if (lk == key->objectInfo) {
7175 /* we have a cached key, and we are about to
7176 * overwrite it, let's get a duplicate first */
7177 lk = nsslowkey_CopyPrivateKey(lk);
7178 if (lk == NULL((void*)0)) {
7179 break;
7180 }
7181 }
7182 /* this overwrites the mlkem data, but we don't need it any
7183 * more because we are discarding lk once we encode. This
7184 * allows us to use the same template for mlkem and mldsa
7185 * (and presumably other pq algorithms, though mlfn and mlshl
7186 * don't have additional seeds) */
7187 lk->u.genpq.seedItem = seed;
7188 lk->u.genpq.keyItem = rawKey;
7189 if (seed.len) {
7190 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7191 nsslowkey_PQBothSeedAndPrivateKeyTemplate);
7192 } else {
7193 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7194 nsslowkey_PQPrivateKeyTemplate);
7195 }
7196 } break;
7197 case NSSLOWKEYMLDSAKey: {
7198 SECItem seed = { siBuffer, NULL((void*)0), 0 };
7199 SECItem keyVal = { siBuffer, NULL((void*)0), 0 };
7200 dummy = NULL((void*)0);
7201
7202 /* paramSet sets the algorithm */
7203 switch (lk->u.mldsa.paramSet) {
7204 case CKP_ML_DSA_440x00000001UL:
7205 algorithm = SEC_OID_ML_DSA_44_PUBLIC_KEYSEC_OID_ML_DSA_44;
7206 break;
7207 case CKP_ML_DSA_650x00000002UL:
7208 algorithm = SEC_OID_ML_DSA_65_PUBLIC_KEYSEC_OID_ML_DSA_65;
7209 break;
7210 case CKP_ML_DSA_870x00000003UL:
7211 algorithm = SEC_OID_ML_DSA_87_PUBLIC_KEYSEC_OID_ML_DSA_87;
7212 break;
7213 default:
7214 algorithm = SEC_OID_UNKNOWN;
7215 break;
7216 }
7217 if (algorithm == SEC_OID_UNKNOWN) {
7218 break;
7219 }
7220
7221 /* if we have the seed, copy it */
7222 if (lk->u.mldsa.seedLen != 0) {
7223 rv = SECITEM_MakeItem(arena, &seed, lk->u.mldsa.seed,
7224 lk->u.mldsa.seedLen);
7225 if (rv != SECSuccess) {
7226 break;
7227 }
7228 }
7229 rv = SECITEM_MakeItem(arena, &keyVal, lk->u.mldsa.keyVal,
7230 lk->u.mldsa.keyValLen);
7231 if (rv != SECSuccess) {
7232 break;
7233 }
7234 if (lk == key->objectInfo) {
7235 /* we have a cached key, and we are about to
7236 * overwrite it, let's get a duplicate first */
7237 lk = nsslowkey_CopyPrivateKey(lk);
7238 if (lk == NULL((void*)0)) {
7239 break;
7240 }
7241 }
7242 /* this overwrites the mldsa data, but we don't need it any
7243 * more because we are discarding lk once we encode */
7244 lk->u.genpq.seedItem = seed;
7245 lk->u.genpq.keyItem = keyVal;
7246
7247 if (seed.len) {
7248 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7249 nsslowkey_PQBothSeedAndPrivateKeyTemplate);
7250 } else {
7251 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7252 nsslowkey_PQPrivateKeyTemplate);
7253 }
7254 } break;
7255
7256 case NSSLOWKEYDHKey:
7257 default:
7258 dummy = NULL((void*)0);
7259 break;
7260 }
7261
7262 if (!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {
7263 *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */
7264 rv = SECFailure;
7265 goto loser;
7266 }
7267
7268 rv = SECOID_SetAlgorithmIDSECOID_SetAlgorithmID_Util(arena, &pki->algorithm, algorithm,
7269 (SECItem *)param);
7270 if (rv != SECSuccess) {
7271 *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */
7272 rv = SECFailure;
7273 goto loser;
7274 }
7275
7276 dummy = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, &pki->version,
7277 NSSLOWKEY_PRIVATE_KEY_INFO_VERSION0);
7278 if (!dummy) {
7279 *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */
7280 rv = SECFailure;
7281 goto loser;
7282 }
7283
7284 encodedKey = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), pki,
7285 nsslowkey_PrivateKeyInfoTemplate);
7286 *crvp = encodedKey ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL;
7287
7288#ifdef EC_DEBUG
7289 fordebug = encodedKey;
7290 SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,
7291 fordebug);
7292#endif
7293loser:
7294 if (arena) {
7295 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
7296 }
7297
7298 if (lk && (lk != key->objectInfo)) {
7299 nsslowkey_DestroyPrivateKey(lk);
7300 }
7301
7302 if (param) {
7303 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util((SECItem *)param, PR_TRUE1);
7304 }
7305
7306 if (rv != SECSuccess) {
7307 return NULL((void*)0);
7308 }
7309
7310 return encodedKey;
7311}
7312
7313/* it doesn't matter yet, since we colapse error conditions in the
7314 * level above, but we really should map those few key error differences */
7315static CK_RV
7316sftk_mapWrap(CK_RV crv)
7317{
7318 switch (crv) {
7319 case CKR_ENCRYPTED_DATA_INVALID0x00000040UL:
7320 crv = CKR_WRAPPED_KEY_INVALID0x00000110UL;
7321 break;
7322 }
7323 return crv;
7324}
7325
7326/* NSC_WrapKey wraps (i.e., encrypts) a key. */
7327CK_RV
7328NSC_WrapKey(CK_SESSION_HANDLE hSession,
7329 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
7330 CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
7331 CK_ULONG_PTR pulWrappedKeyLen)
7332{
7333 SFTKSession *session;
7334 SFTKAttribute *attribute;
7335 SFTKObject *key;
7336 CK_RV crv;
7337
7338 CHECK_FORK();
7339
7340 session = sftk_SessionFromHandle(hSession);
7341 if (session == NULL((void*)0)) {
7342 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
7343 }
7344
7345 key = sftk_ObjectFromHandle(hKey, session);
7346 if (key == NULL((void*)0)) {
7347 sftk_FreeSession(session);
7348 return CKR_KEY_HANDLE_INVALID0x00000060UL;
7349 }
7350
7351 switch (key->objclass) {
7352 case CKO_SECRET_KEY0x00000004UL: {
7353 SFTKSessionContext *context = NULL((void*)0);
7354 SECItem pText;
7355
7356 attribute = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
7357
7358 if (attribute == NULL((void*)0)) {
7359 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7360 break;
7361 }
7362 crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
7363 CKA_WRAP0x00000106UL, CKA_WRAP0x00000106UL, SFTK_ENCRYPT, PR_TRUE1);
7364 if (crv != CKR_OK0x00000000UL) {
7365 sftk_FreeAttribute(attribute);
7366 break;
7367 }
7368
7369 pText.type = siBuffer;
7370 pText.data = (unsigned char *)attribute->attrib.pValue;
7371 pText.len = attribute->attrib.ulValueLen;
7372
7373 /* Find out if this is a block cipher. The context was just
7374 * installed by sftk_CryptInit above, so we already hold a
7375 * session reference and the context's type is SFTK_ENCRYPT
7376 * by construction. */
7377 context = sftk_ReturnContextByType(session, SFTK_ENCRYPT);
7378 if (!context) {
7379 sftk_FreeAttribute(attribute);
7380 crv = CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
7381 break;
7382 }
7383 if (context->blockSize > 1) {
7384 unsigned int remainder = pText.len % context->blockSize;
7385 if (!context->doPad && remainder) {
7386 /* When wrapping secret keys with unpadded block ciphers,
7387 ** the keys are zero padded, if necessary, to fill out
7388 ** a full block.
7389 */
7390 pText.len += context->blockSize - remainder;
7391 pText.data = PORT_ZAllocPORT_ZAlloc_Util(pText.len);
7392 if (pText.data)
7393 memcpy(pText.data, attribute->attrib.pValue,
7394 attribute->attrib.ulValueLen);
7395 else {
7396 sftk_FreeAttribute(attribute);
7397 crv = CKR_HOST_MEMORY0x00000002UL;
7398 break;
7399 }
7400 }
7401 }
7402
7403 crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data,
7404 pText.len, pWrappedKey, pulWrappedKeyLen);
7405 /* always force a finalize, both on errors and when
7406 * we are just getting the size */
7407 if (crv != CKR_OK0x00000000UL || pWrappedKey == NULL((void*)0)) {
7408 sftk_UninstallContext(session, SFTK_ENCRYPT);
7409 }
7410
7411 if (pText.data != (unsigned char *)attribute->attrib.pValue)
7412 PORT_ZFreePORT_ZFree_Util(pText.data, pText.len);
7413 sftk_FreeAttribute(attribute);
7414 break;
7415 }
7416
7417 case CKO_PRIVATE_KEY0x00000003UL: {
7418 SECItem *bpki = sftk_PackagePrivateKey(key, &crv);
7419
7420 if (!bpki) {
7421 break;
7422 }
7423
7424 crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
7425 CKA_WRAP0x00000106UL, CKA_WRAP0x00000106UL, SFTK_ENCRYPT, PR_TRUE1);
7426 if (crv != CKR_OK0x00000000UL) {
7427 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(bpki, PR_TRUE1);
7428 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7429 break;
7430 }
7431
7432 crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
7433 pWrappedKey, pulWrappedKeyLen);
7434 /* always force a finalize */
7435 if (crv != CKR_OK0x00000000UL || pWrappedKey == NULL((void*)0)) {
7436 sftk_UninstallContext(session, SFTK_ENCRYPT);
7437 }
7438 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(bpki, PR_TRUE1);
7439 break;
7440 }
7441
7442 default:
7443 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7444 break;
7445 }
7446 sftk_FreeObject(key);
7447 sftk_FreeSession(session);
7448 return sftk_mapWrap(crv);
7449}
7450
7451/*
7452 * import a pprivate key info into the desired slot
7453 */
7454static SECStatus
7455sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
7456{
7457 CK_BBOOL cktrue = CK_TRUE1;
7458 CK_BBOOL ckfalse = CK_FALSE0;
7459 CK_KEY_TYPE keyType = CKK_RSA0x00000000UL;
7460 SECStatus rv = SECFailure;
7461 const SEC_ASN1Template *keyTemplate, *paramTemplate;
7462 void *paramDest = NULL((void*)0);
7463 PLArenaPool *arena;
7464 NSSLOWKEYPrivateKey *lpk = NULL((void*)0);
7465 NSSLOWKEYPrivateKeyInfo *pki = NULL((void*)0);
7466 CK_RV crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7467 CK_ULONG paramSet = 0;
7468 const SECOidData *oidData = NULL((void*)0);
7469 SECOidTag pkiAlg = SEC_OID_UNKNOWN;
7470 CK_BBOOL ec_sign = CK_FALSE0;
7471 CK_BBOOL ec_derive = CK_FALSE0;
7472 unsigned long version;
7473
7474 arena = PORT_NewArenaPORT_NewArena_Util(2048);
7475 if (!arena) {
7476 return SECFailure;
7477 }
7478
7479 pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7480 sizeof(NSSLOWKEYPrivateKeyInfo));
7481 if (!pki) {
7482 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
7483 return SECFailure;
7484 }
7485
7486 if (SEC_ASN1DecodeItemSEC_ASN1DecodeItem_Util(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) != SECSuccess) {
7487 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
7488 return SECFailure;
7489 }
7490
7491 /* verify the version number */
7492 if ((SEC_ASN1DecodeIntegerSEC_ASN1DecodeInteger_Util(&pki->version, &version) != SECSuccess) ||
7493 (version > 1) || ((version == 0) && (pki->publicKey.data != NULL((void*)0)))) {
7494 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
7495 return SECFailure;
7496 }
7497
7498 lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7499 sizeof(NSSLOWKEYPrivateKey));
7500 if (lpk == NULL((void*)0)) {
7501 goto loser;
7502 }
7503 lpk->arena = arena;
7504
7505 pkiAlg = SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&pki->algorithm);
7506 switch (pkiAlg) {
7507 case SEC_OID_PKCS1_RSA_ENCRYPTION:
7508 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
7509 keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
7510 paramTemplate = NULL((void*)0);
7511 paramDest = NULL((void*)0);
7512 lpk->keyType = NSSLOWKEYRSAKey;
7513 prepare_low_rsa_priv_key_for_asn1(lpk);
7514 break;
7515 case SEC_OID_ANSIX9_DSA_SIGNATURE:
7516 keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
7517 paramTemplate = nsslowkey_PQGParamsTemplate;
7518 paramDest = &(lpk->u.dsa.params);
7519 lpk->keyType = NSSLOWKEYDSAKey;
7520 prepare_low_dsa_priv_key_export_for_asn1(lpk);
7521 prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params);
7522 break;
7523 /* case NSSLOWKEYDHKey: */
7524 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
7525 keyTemplate = nsslowkey_ECPrivateKeyTemplate;
7526 paramTemplate = NULL((void*)0);
7527 paramDest = &(lpk->u.ec.ecParams.DEREncoding);
7528 lpk->keyType = NSSLOWKEYECKey;
7529 prepare_low_ec_priv_key_for_asn1(lpk);
7530 prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams);
7531 break;
7532 case SEC_OID_X25519:
7533 lpk->keyType = NSSLOWKEYECMontgomeryKey;
7534 goto ecx_continue;
7535 case SEC_OID_ED25519:
7536 lpk->keyType = NSSLOWKEYECEdwardsKey;
7537 ecx_continue:
7538 /* we decode the whole key here rather than do the normal
7539 * later decode step */
7540 keyTemplate = NULL((void*)0);
7541 paramTemplate = NULL((void*)0);
7542 paramDest = NULL((void*)0);
7543 oidData = SECOID_FindOIDByTagSECOID_FindOIDByTag_Util(pkiAlg);
7544 if (oidData == NULL((void*)0)) {
7545 goto loser;
7546 }
7547 /* CURVE is provided by the tag, not encoded in the parameters
7548 * for the x25519, x448, ed25519 and ed448 keys */
7549 if (SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &(lpk->u.ec.ecParams.DEREncoding),
7550 &oidData->oid,
7551 SEC_ASN1_GET(SEC_ObjectIDTemplate)SEC_ObjectIDTemplate_Util) == NULL((void*)0)) {
7552 goto loser;
7553 }
7554 prepare_low_ec_priv_key_for_asn1(lpk);
7555 /* private key is a simple octet string, just decode it now */
7556 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, &(lpk->u.ec.privateValue),
7557 SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util,
7558 &(pki->privateKey));
7559 if (rv != SECSuccess) {
7560 goto loser;
7561 }
7562 /* ignore any v2 publicKey; we can derived it from the private key */
7563 break;
7564 case SEC_OID_ML_KEM_512:
7565 paramSet = CKP_ML_KEM_5120x00000001UL;
7566 goto mlkem_next;
7567 case SEC_OID_ML_KEM_768:
7568 paramSet = CKP_ML_KEM_7680x00000002UL;
7569 goto mlkem_next;
7570 case SEC_OID_ML_KEM_1024:
7571 paramSet = CKP_ML_KEM_10240x00000003UL;
7572 mlkem_next:
7573 lpk->keyType = NSSLOWKEYMLKEMKey;
7574 goto pq_next;
7575 case SEC_OID_ML_DSA_44_PUBLIC_KEYSEC_OID_ML_DSA_44:
7576 paramSet = CKP_ML_DSA_440x00000001UL;
7577 goto mldsa_next;
7578 case SEC_OID_ML_DSA_65_PUBLIC_KEYSEC_OID_ML_DSA_65:
7579 paramSet = CKP_ML_DSA_650x00000002UL;
7580 goto mldsa_next;
7581 case SEC_OID_ML_DSA_87_PUBLIC_KEYSEC_OID_ML_DSA_87:
7582 paramSet = CKP_ML_DSA_870x00000003UL;
7583 mldsa_next:
7584 lpk->keyType = NSSLOWKEYMLDSAKey;
7585 pq_next:
7586 if (pki->privateKey.data == NULL((void*)0) || pki->privateKey.len == 0) {
7587 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY);
7588 goto loser;
7589 }
7590 switch (pki->privateKey.data[0]) {
7591 case SEC_ASN1_CONTEXT_SPECIFIC0x80 | 0:
7592 keyTemplate = nsslowkey_PQSeedTemplate;
7593 break;
7594 case SEC_ASN1_OCTET_STRING0x04:
7595 keyTemplate = nsslowkey_PQPrivateKeyTemplate;
7596 break;
7597 case SEC_ASN1_CONSTRUCTED0x20 | SEC_ASN1_SEQUENCE0x10:
7598 keyTemplate = nsslowkey_PQBothSeedAndPrivateKeyTemplate;
7599 break;
7600 default:
7601 keyTemplate = NULL((void*)0);
7602 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY);
7603 goto loser;
7604 }
7605
7606 paramTemplate = NULL((void*)0);
7607 paramDest = NULL((void*)0);
7608 /* genpq encodes ocect, not integer, so no need to prep it */
7609 break;
7610 default:
7611 keyTemplate = NULL((void*)0);
7612 paramTemplate = NULL((void*)0);
7613 paramDest = NULL((void*)0);
7614 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY);
7615 goto loser;
7616 }
7617
7618 /* decode the private key and any algorithm parameters */
7619 rv = SECSuccess;
7620 if (keyTemplate) {
7621 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, lpk, keyTemplate, &pki->privateKey);
7622 }
7623
7624 if (lpk->keyType == NSSLOWKEYECKey) {
7625 /* convert length in bits to length in bytes */
7626 lpk->u.ec.publicValue.len >>= 3;
7627 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena,
7628 &(lpk->u.ec.ecParams.DEREncoding),
7629 &(pki->algorithm.parameters));
7630 if (rv != SECSuccess) {
7631 goto loser;
7632 }
7633 }
7634
7635 if (rv != SECSuccess) {
7636 goto loser;
7637 }
7638 if (paramDest && paramTemplate) {
7639 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, paramDest, paramTemplate,
7640 &(pki->algorithm.parameters));
7641 if (rv != SECSuccess) {
7642 goto loser;
7643 }
7644 }
7645
7646 rv = SECFailure;
7647
7648 switch (lpk->keyType) {
7649 case NSSLOWKEYRSAKey:
7650 keyType = CKK_RSA0x00000000UL;
7651 if (sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) {
7652 sftk_DeleteAttributeType(key, CKA_NSS_DB0xD5A0DB00L);
7653 }
7654 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7655 sizeof(keyType));
7656 if (crv != CKR_OK0x00000000UL)
7657 break;
7658 crv = sftk_AddAttributeType(key, CKA_UNWRAP0x00000107UL, &cktrue,
7659 sizeof(CK_BBOOL));
7660 if (crv != CKR_OK0x00000000UL)
7661 break;
7662 crv = sftk_AddAttributeType(key, CKA_DECRYPT0x00000105UL, &cktrue,
7663 sizeof(CK_BBOOL));
7664 if (crv != CKR_OK0x00000000UL)
7665 break;
7666 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue,
7667 sizeof(CK_BBOOL));
7668 if (crv != CKR_OK0x00000000UL)
7669 break;
7670 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &cktrue,
7671 sizeof(CK_BBOOL));
7672 if (crv != CKR_OK0x00000000UL)
7673 break;
7674 crv = sftk_AddAttributeType(key, CKA_MODULUS0x00000120UL,
7675 sftk_item_expand(&lpk->u.rsa.modulus)(&lpk->u.rsa.modulus)->data, (&lpk->u.rsa.modulus
)->len
);
7676 if (crv != CKR_OK0x00000000UL)
7677 break;
7678 crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT0x00000122UL,
7679 sftk_item_expand(&lpk->u.rsa.publicExponent)(&lpk->u.rsa.publicExponent)->data, (&lpk->u
.rsa.publicExponent)->len
);
7680 if (crv != CKR_OK0x00000000UL)
7681 break;
7682 crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT0x00000123UL,
7683 sftk_item_expand(&lpk->u.rsa.privateExponent)(&lpk->u.rsa.privateExponent)->data, (&lpk->
u.rsa.privateExponent)->len
);
7684 if (crv != CKR_OK0x00000000UL)
7685 break;
7686 crv = sftk_AddAttributeType(key, CKA_PRIME_10x00000124UL,
7687 sftk_item_expand(&lpk->u.rsa.prime1)(&lpk->u.rsa.prime1)->data, (&lpk->u.rsa.prime1
)->len
);
7688 if (crv != CKR_OK0x00000000UL)
7689 break;
7690 crv = sftk_AddAttributeType(key, CKA_PRIME_20x00000125UL,
7691 sftk_item_expand(&lpk->u.rsa.prime2)(&lpk->u.rsa.prime2)->data, (&lpk->u.rsa.prime2
)->len
);
7692 if (crv != CKR_OK0x00000000UL)
7693 break;
7694 crv = sftk_AddAttributeType(key, CKA_EXPONENT_10x00000126UL,
7695 sftk_item_expand(&lpk->u.rsa.exponent1)(&lpk->u.rsa.exponent1)->data, (&lpk->u.rsa.
exponent1)->len
);
7696 if (crv != CKR_OK0x00000000UL)
7697 break;
7698 crv = sftk_AddAttributeType(key, CKA_EXPONENT_20x00000127UL,
7699 sftk_item_expand(&lpk->u.rsa.exponent2)(&lpk->u.rsa.exponent2)->data, (&lpk->u.rsa.
exponent2)->len
);
7700 if (crv != CKR_OK0x00000000UL)
7701 break;
7702 crv = sftk_AddAttributeType(key, CKA_COEFFICIENT0x00000128UL,
7703 sftk_item_expand(&lpk->u.rsa.coefficient)(&lpk->u.rsa.coefficient)->data, (&lpk->u.rsa
.coefficient)->len
);
7704 break;
7705 case NSSLOWKEYDSAKey:
7706 keyType = CKK_DSA0x00000001UL;
7707 crv = (sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) ? CKR_OK0x00000000UL : CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7708 if (crv != CKR_OK0x00000000UL)
7709 break;
7710 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7711 sizeof(keyType));
7712 if (crv != CKR_OK0x00000000UL)
7713 break;
7714 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue,
7715 sizeof(CK_BBOOL));
7716 if (crv != CKR_OK0x00000000UL)
7717 break;
7718 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &ckfalse,
7719 sizeof(CK_BBOOL));
7720 if (crv != CKR_OK0x00000000UL)
7721 break;
7722 crv = sftk_AddAttributeType(key, CKA_PRIME0x00000130UL,
7723 sftk_item_expand(&lpk->u.dsa.params.prime)(&lpk->u.dsa.params.prime)->data, (&lpk->u.dsa
.params.prime)->len
);
7724 if (crv != CKR_OK0x00000000UL)
7725 break;
7726 crv = sftk_AddAttributeType(key, CKA_SUBPRIME0x00000131UL,
7727 sftk_item_expand(&lpk->u.dsa.params.subPrime)(&lpk->u.dsa.params.subPrime)->data, (&lpk->
u.dsa.params.subPrime)->len
);
7728 if (crv != CKR_OK0x00000000UL)
7729 break;
7730 crv = sftk_AddAttributeType(key, CKA_BASE0x00000132UL,
7731 sftk_item_expand(&lpk->u.dsa.params.base)(&lpk->u.dsa.params.base)->data, (&lpk->u.dsa
.params.base)->len
);
7732 if (crv != CKR_OK0x00000000UL)
7733 break;
7734 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7735 sftk_item_expand(&lpk->u.dsa.privateValue)(&lpk->u.dsa.privateValue)->data, (&lpk->u.dsa
.privateValue)->len
);
7736 if (crv != CKR_OK0x00000000UL)
7737 break;
7738 break;
7739 case NSSLOWKEYMLKEMKey:
7740 keyType = CKK_ML_KEM0x00000049UL;
7741 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7742 sizeof(keyType));
7743 if (crv != CKR_OK0x00000000UL)
7744 break;
7745 crv = sftk_AddAttributeType(key, CKA_DECAPSULATE0x00000634UL, &cktrue,
7746 sizeof(CK_BBOOL));
7747 if (crv != CKR_OK0x00000000UL)
7748 break;
7749 crv = sftk_AddAttributeType(key, CKA_PARAMETER_SET0x0000061dUL, &paramSet,
7750 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE));
7751 if (crv != CKR_OK0x00000000UL)
7752 break;
7753 if (lpk->u.genpq.seedItem.len != 0) {
7754 crv = sftk_AddAttributeType(key, CKA_SEED0x00000637UL,
7755 sftk_item_expand(&lpk->u.genpq.seedItem)(&lpk->u.genpq.seedItem)->data, (&lpk->u.genpq
.seedItem)->len
);
7756 if (crv != CKR_OK0x00000000UL)
7757 break;
7758 }
7759
7760 /* if we were given just the seed, we'll regenerate the key
7761 * from the seed in handleObject */
7762 if (lpk->u.genpq.keyItem.len != 0) {
7763 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7764 sftk_item_expand(&lpk->u.genpq.keyItem)(&lpk->u.genpq.keyItem)->data, (&lpk->u.genpq
.keyItem)->len
);
7765 /* I know, this is redundant, but it would be too easy
7766 * for someone to add another sftk_AddAttributeType after
7767 * this without adding this check back because of the if */
7768 if (crv != CKR_OK0x00000000UL)
7769 break;
7770 }
7771 break;
7772 case NSSLOWKEYMLDSAKey:
7773 keyType = CKK_ML_DSA0x0000004aUL;
7774 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7775 sizeof(keyType));
7776 if (crv != CKR_OK0x00000000UL)
7777 break;
7778 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue,
7779 sizeof(CK_BBOOL));
7780 if (crv != CKR_OK0x00000000UL)
7781 break;
7782 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &ckfalse,
7783 sizeof(CK_BBOOL));
7784 if (crv != CKR_OK0x00000000UL)
7785 break;
7786 crv = sftk_AddAttributeType(key, CKA_PARAMETER_SET0x0000061dUL, &paramSet,
7787 sizeof(CK_ML_DSA_PARAMETER_SET_TYPE));
7788 if (crv != CKR_OK0x00000000UL)
7789 break;
7790 if (lpk->u.genpq.seedItem.len != 0) {
7791 crv = sftk_AddAttributeType(key, CKA_SEED0x00000637UL,
7792 sftk_item_expand(&lpk->u.genpq.seedItem)(&lpk->u.genpq.seedItem)->data, (&lpk->u.genpq
.seedItem)->len
);
7793 if (crv != CKR_OK0x00000000UL)
7794 break;
7795 }
7796
7797 /* if we were given just the seed, we'll regenerate the key
7798 * from the seed in handleObject */
7799 if (lpk->u.genpq.keyItem.len != 0) {
7800 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7801 sftk_item_expand(&lpk->u.genpq.keyItem)(&lpk->u.genpq.keyItem)->data, (&lpk->u.genpq
.keyItem)->len
);
7802 /* I know, this is redundant, but it would be too easy
7803 * for someone to add another sftk_AddAttributeType after
7804 * this without adding this check back because of the if */
7805 if (crv != CKR_OK0x00000000UL)
7806 break;
7807 }
7808 break;
7809#ifdef notdef
7810 case NSSLOWKEYDHKey:
7811 template = dhTemplate;
7812 templateCount = sizeof(dhTemplate) / sizeof(CK_ATTRIBUTE);
7813 keyType = CKK_DH0x00000002UL;
7814 break;
7815#endif
7816 case NSSLOWKEYECEdwardsKey:
7817 keyType = CKK_EC_EDWARDS0x00000040UL;
7818 ec_derive = CK_FALSE0;
7819 ec_sign = CK_TRUE1;
7820 goto ec_import_continue;
7821 case NSSLOWKEYECMontgomeryKey:
7822 keyType = CKK_EC_MONTGOMERY0x00000041UL;
7823 ec_derive = CK_TRUE1;
7824 ec_sign = CK_FALSE0;
7825 goto ec_import_continue;
7826 case NSSLOWKEYECKey:
7827 keyType = CKK_EC0x00000003UL;
7828 ec_derive = CK_TRUE1;
7829 ec_sign = CK_TRUE1;
7830 /* if we weren't passed the CKA_NSS_DB, get it
7831 * from the public key. only do this for
7832 * CKK_EC keys. */
7833 if (!sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) {
7834 if (lpk->u.ec.publicValue.len == 0) {
7835 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7836 goto loser;
7837 }
7838 crv = sftk_AddAttributeType(key, CKA_NSS_DB0xD5A0DB00L,
7839 sftk_item_expand(&lpk->u.ec.publicValue)(&lpk->u.ec.publicValue)->data, (&lpk->u.ec.
publicValue)->len
);
7840 if (crv != CKR_OK0x00000000UL) {
7841 goto loser;
7842 }
7843 }
7844 ec_import_continue:
7845 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7846 sizeof(keyType));
7847 if (crv != CKR_OK0x00000000UL)
7848 break;
7849 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &ec_sign,
7850 sizeof(CK_BBOOL));
7851 if (crv != CKR_OK0x00000000UL)
7852 break;
7853 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &ckfalse,
7854 sizeof(CK_BBOOL));
7855 if (crv != CKR_OK0x00000000UL)
7856 break;
7857 crv = sftk_AddAttributeType(key, CKA_DERIVE0x0000010CUL, &ec_derive,
7858 sizeof(CK_BBOOL));
7859 if (crv != CKR_OK0x00000000UL)
7860 break;
7861 crv = sftk_AddAttributeType(key, CKA_EC_PARAMS0x00000180UL,
7862 sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding)(&lpk->u.ec.ecParams.DEREncoding)->data, (&lpk->
u.ec.ecParams.DEREncoding)->len
);
7863 if (crv != CKR_OK0x00000000UL)
7864 break;
7865 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7866 sftk_item_expand(&lpk->u.ec.privateValue)(&lpk->u.ec.privateValue)->data, (&lpk->u.ec
.privateValue)->len
);
7867 if (crv != CKR_OK0x00000000UL)
7868 break;
7869 /* XXX Do we need to decode the EC Params here ?? */
7870 break;
7871 default:
7872 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7873 break;
7874 }
7875
7876 if (crv != CKR_OK0x00000000UL) {
7877 goto loser;
7878 }
7879
7880 /* For RSA-PSS, record the original algorithm parameters so
7881 * they can be encrypted altoghether when wrapping */
7882 if (SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&pki->algorithm) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
7883 NSSLOWKEYSubjectPublicKeyInfo spki;
7884 NSSLOWKEYPublicKey pubk;
7885 SECItem *publicKeyInfo;
7886
7887 memset(&spki, 0, sizeof(NSSLOWKEYSubjectPublicKeyInfo));
7888 rv = SECOID_CopyAlgorithmIDSECOID_CopyAlgorithmID_Util(arena, &spki.algorithm, &pki->algorithm);
7889 if (rv != SECSuccess) {
7890 crv = CKR_HOST_MEMORY0x00000002UL;
7891 goto loser;
7892 }
7893
7894 prepare_low_rsa_pub_key_for_asn1(&pubk);
7895
7896 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk.u.rsa.modulus, &lpk->u.rsa.modulus);
7897 if (rv != SECSuccess) {
7898 crv = CKR_HOST_MEMORY0x00000002UL;
7899 goto loser;
7900 }
7901 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk.u.rsa.publicExponent, &lpk->u.rsa.publicExponent);
7902 if (rv != SECSuccess) {
7903 crv = CKR_HOST_MEMORY0x00000002UL;
7904 goto loser;
7905 }
7906 pubk.u.rsa.needVerify = PR_FALSE0; /* We're just encoding the key from the
7907 * private key */
7908
7909 if (SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &spki.subjectPublicKey,
7910 &pubk, nsslowkey_RSAPublicKeyTemplate) == NULL((void*)0)) {
7911 crv = CKR_HOST_MEMORY0x00000002UL;
7912 goto loser;
7913 }
7914
7915 publicKeyInfo = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, NULL((void*)0),
7916 &spki, nsslowkey_SubjectPublicKeyInfoTemplate);
7917 if (!publicKeyInfo) {
7918 crv = CKR_HOST_MEMORY0x00000002UL;
7919 goto loser;
7920 }
7921 crv = sftk_AddAttributeType(key, CKA_PUBLIC_KEY_INFO0x00000129UL,
7922 sftk_item_expand(publicKeyInfo)(publicKeyInfo)->data, (publicKeyInfo)->len);
7923 }
7924
7925loser:
7926 if (lpk) {
7927 nsslowkey_DestroyPrivateKey(lpk);
7928 }
7929
7930 if (crv != CKR_OK0x00000000UL) {
7931 return SECFailure;
7932 }
7933
7934 return SECSuccess;
7935}
7936
7937/* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
7938CK_RV
7939NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
7940 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
7941 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
7942 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
7943 CK_OBJECT_HANDLE_PTR phKey)
7944{
7945 SFTKObject *key = NULL((void*)0);
7946 SFTKSession *session;
7947 CK_ULONG key_length = 0;
7948 unsigned char *buf = NULL((void*)0);
7949 CK_RV crv = CKR_OK0x00000000UL;
7950 int i;
7951 CK_ULONG bsize = ulWrappedKeyLen;
7952 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
7953 SECItem bpki;
7954 CK_OBJECT_CLASS target_type = CKO_SECRET_KEY0x00000004UL;
7955
7956 CHECK_FORK();
7957
7958 if (!slot) {
7959 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
7960 }
7961 /*
7962 * now lets create an object to hang the attributes off of
7963 */
7964 key = sftk_NewObject(slot); /* fill in the handle later */
7965 if (key == NULL((void*)0)) {
7966 return CKR_HOST_MEMORY0x00000002UL;
7967 }
7968
7969 /*
7970 * load the template values into the object
7971 */
7972 for (i = 0; i < (int)ulAttributeCount; i++) {
7973 if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) {
7974 key_length = *(CK_ULONG *)pTemplate[i].pValue;
7975 continue;
7976 }
7977 if (pTemplate[i].type == CKA_CLASS0x00000000UL) {
7978 target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
7979 }
7980 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
7981 if (crv != CKR_OK0x00000000UL)
7982 break;
7983 }
7984 if (crv != CKR_OK0x00000000UL) {
7985 sftk_FreeObject(key);
7986 return crv;
7987 }
7988
7989 crv = sftk_CryptInit(hSession, pMechanism, hUnwrappingKey, CKA_UNWRAP0x00000107UL,
7990 CKA_UNWRAP0x00000107UL, SFTK_DECRYPT, PR_FALSE0);
7991 if (crv != CKR_OK0x00000000UL) {
7992 sftk_FreeObject(key);
7993 return sftk_mapWrap(crv);
7994 }
7995
7996 /* allocate the buffer to decrypt into
7997 * this assumes the unwrapped key is never larger than the
7998 * wrapped key. For all the mechanisms we support this is true */
7999 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(ulWrappedKeyLen);
8000 bsize = ulWrappedKeyLen;
8001
8002 crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize);
8003 if (crv != CKR_OK0x00000000UL) {
8004 sftk_FreeObject(key);
8005 PORT_FreePORT_Free_Util(buf);
8006 return sftk_mapWrap(crv);
8007 }
8008
8009 switch (target_type) {
8010 case CKO_SECRET_KEY0x00000004UL:
8011 if (!sftk_hasAttribute(key, CKA_KEY_TYPE0x00000100UL)) {
8012 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
8013 break;
8014 }
8015
8016 if (key_length == 0 || key_length > bsize) {
8017 key_length = bsize;
8018 }
8019 if (key_length > MAX_KEY_LEN256) {
8020 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
8021 break;
8022 }
8023
8024 /* add the value */
8025 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL, buf, key_length);
8026 break;
8027 case CKO_PRIVATE_KEY0x00000003UL:
8028 bpki.data = (unsigned char *)buf;
8029 bpki.len = bsize;
8030 crv = CKR_OK0x00000000UL;
8031 if (sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) {
8032 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
8033 }
8034 break;
8035 default:
8036 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
8037 break;
8038 }
8039
8040 PORT_ZFreePORT_ZFree_Util(buf, bsize);
8041 if (crv != CKR_OK0x00000000UL) {
8042 sftk_FreeObject(key);
8043 return crv;
8044 }
8045
8046 /* get the session */
8047 session = sftk_SessionFromHandle(hSession);
8048 if (session == NULL((void*)0)) {
8049 sftk_FreeObject(key);
8050 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
8051 }
8052
8053 /* mark the key as FIPS if the previous operation was all FIPS */
8054 sftk_setFIPS(key, session->lastOpWasFIPS);
8055 /*
8056 * handle the base object stuff
8057 */
8058 crv = sftk_handleObject(key, session);
8059 *phKey = key->handle;
8060 sftk_FreeSession(session);
8061 sftk_FreeObject(key);
8062
8063 return crv;
8064}
8065
8066CK_RV
8067NSC_WrapKeyAuthenticated(CK_SESSION_HANDLE hSession,
8068 CK_MECHANISM_PTR pMechanism,
8069 CK_OBJECT_HANDLE hWrappingKey,
8070 CK_OBJECT_HANDLE hKey,
8071 CK_BYTE_PTR pAssociatedData,
8072 CK_ULONG ulAssociatedDataLen,
8073 CK_BYTE_PTR pWrappedKey,
8074 CK_ULONG_PTR pulWrappedKeyLen)
8075{
8076 CHECK_FORK();
8077
8078 return CKR_FUNCTION_NOT_SUPPORTED0x00000054UL;
8079}
8080
8081CK_RV
8082NSC_UnwrapKeyAuthenticated(CK_SESSION_HANDLE hSession,
8083 CK_MECHANISM_PTR pMechanism,
8084 CK_OBJECT_HANDLE hUnwrappingKey,
8085 CK_BYTE_PTR pWrappedKey,
8086 CK_ULONG ulWrappedKeyLen,
8087 CK_ATTRIBUTE_PTR pTemplate,
8088 CK_ULONG ulAttributeCount,
8089 CK_BYTE_PTR pAssociatedData,
8090 CK_ULONG ulAssociatedDataLen,
8091 CK_OBJECT_HANDLE_PTR phKey)
8092{
8093 CHECK_FORK();
8094
8095 return CKR_FUNCTION_NOT_SUPPORTED0x00000054UL;
8096}
8097
8098/*
8099 * The SSL key gen mechanism create's lots of keys. This function handles the
8100 * details of each of these key creation.
8101 */
8102static CK_RV
8103sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey,
8104 PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize,
8105 CK_OBJECT_HANDLE *keyHandle)
8106{
8107 SFTKObject *key;
8108 SFTKSession *session;
8109 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET0x00000010UL;
8110 CK_BBOOL cktrue = CK_TRUE1;
8111 CK_BBOOL ckfalse = CK_FALSE0;
8112 CK_RV crv = CKR_HOST_MEMORY0x00000002UL;
8113
8114 /*
8115 * now lets create an object to hang the attributes off of
8116 */
8117 *keyHandle = CK_INVALID_HANDLE0;
8118 key = sftk_NewObject(baseKey->slot);
8119 if (key == NULL((void*)0))
8120 return CKR_HOST_MEMORY0x00000002UL;
8121 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
8122 PORT_Assert(sessKey)((sessKey) ? ((void)0) : PR_Assert("sessKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 8122))
;
8123 sessKey->wasDerived = PR_TRUE1;
8124
8125 crv = sftk_CopyObject(key, baseKey);
8126 if (crv != CKR_OK0x00000000UL)
8127 goto loser;
8128 if (isMacKey) {
8129 crv = sftk_forceAttribute(key, CKA_KEY_TYPE0x00000100UL, &keyType, sizeof(keyType));
8130 if (crv != CKR_OK0x00000000UL)
8131 goto loser;
8132 crv = sftk_forceAttribute(key, CKA_DERIVE0x0000010CUL, &cktrue, sizeof(CK_BBOOL));
8133 if (crv != CKR_OK0x00000000UL)
8134 goto loser;
8135 crv = sftk_forceAttribute(key, CKA_ENCRYPT0x00000104UL, &ckfalse, sizeof(CK_BBOOL));
8136 if (crv != CKR_OK0x00000000UL)
8137 goto loser;
8138 crv = sftk_forceAttribute(key, CKA_DECRYPT0x00000105UL, &ckfalse, sizeof(CK_BBOOL));
8139 if (crv != CKR_OK0x00000000UL)
8140 goto loser;
8141 crv = sftk_forceAttribute(key, CKA_SIGN0x00000108UL, &cktrue, sizeof(CK_BBOOL));
8142 if (crv != CKR_OK0x00000000UL)
8143 goto loser;
8144 crv = sftk_forceAttribute(key, CKA_VERIFY0x0000010AUL, &cktrue, sizeof(CK_BBOOL));
8145 if (crv != CKR_OK0x00000000UL)
8146 goto loser;
8147 crv = sftk_forceAttribute(key, CKA_WRAP0x00000106UL, &ckfalse, sizeof(CK_BBOOL));
8148 if (crv != CKR_OK0x00000000UL)
8149 goto loser;
8150 crv = sftk_forceAttribute(key, CKA_UNWRAP0x00000107UL, &ckfalse, sizeof(CK_BBOOL));
8151 if (crv != CKR_OK0x00000000UL)
8152 goto loser;
8153 }
8154 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, keyBlock, keySize);
8155 if (crv != CKR_OK0x00000000UL)
8156 goto loser;
8157
8158 /* get the session */
8159 crv = CKR_HOST_MEMORY0x00000002UL;
8160 session = sftk_SessionFromHandle(hSession);
8161 if (session == NULL((void*)0)) {
8162 goto loser;
8163 }
8164
8165 crv = sftk_handleObject(key, session);
8166 sftk_FreeSession(session);
8167 *keyHandle = key->handle;
8168loser:
8169 if (key)
8170 sftk_FreeObject(key);
8171 return crv;
8172}
8173
8174/*
8175 * if there is an error, we need to free the keys we already created in SSL
8176 * This is the routine that will do it..
8177 */
8178static void
8179sftk_freeSSLKeys(CK_SESSION_HANDLE session,
8180 CK_SSL3_KEY_MAT_OUT *returnedMaterial)
8181{
8182 if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE0) {
8183 NSC_DestroyObject(session, returnedMaterial->hClientMacSecret);
8184 }
8185 if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE0) {
8186 NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
8187 }
8188 if (returnedMaterial->hClientKey != CK_INVALID_HANDLE0) {
8189 NSC_DestroyObject(session, returnedMaterial->hClientKey);
8190 }
8191 if (returnedMaterial->hServerKey != CK_INVALID_HANDLE0) {
8192 NSC_DestroyObject(session, returnedMaterial->hServerKey);
8193 }
8194}
8195
8196/*
8197 * when deriving from sensitive and extractable keys, we need to preserve some
8198 * of the semantics in the derived key. This helper routine maintains these
8199 * semantics.
8200 */
8201static CK_RV
8202sftk_DeriveSensitiveCheck(SFTKObject *baseKey, SFTKObject *destKey,
8203 PRBool canBeData)
8204{
8205 PRBool hasSensitive;
8206 PRBool sensitive = PR_FALSE0;
8207 CK_BBOOL bFalse = CK_FALSE0;
8208 PRBool hasExtractable;
8209 PRBool extractable = PR_TRUE1;
8210 CK_BBOOL bTrue = CK_TRUE1;
8211 CK_RV crv = CKR_OK0x00000000UL;
8212 SFTKAttribute *att;
8213 PRBool isData = PR_TRUE1;
8214
8215 if (canBeData) {
8216 CK_OBJECT_CLASS objClass;
8217
8218 /* if the target key is actually data, don't set the unexpected
8219 * attributes */
8220 crv = sftk_GetULongAttribute(destKey, CKA_CLASS0x00000000UL, &objClass);
8221 if (crv != CKR_OK0x00000000UL) {
8222 return crv;
8223 }
8224 if (objClass == CKO_DATA0x00000000UL) {
8225 return CKR_OK0x00000000UL;
8226 }
8227
8228 /* if the base key is data, it doesn't have sensitive attributes,
8229 * allow the destKey to get it's own */
8230 crv = sftk_GetULongAttribute(baseKey, CKA_CLASS0x00000000UL, &objClass);
8231 if (crv != CKR_OK0x00000000UL) {
8232 return crv;
8233 }
8234 if (objClass == CKO_DATA0x00000000UL) {
8235 isData = PR_TRUE1;
8236 }
8237 }
8238
8239 hasSensitive = PR_FALSE0;
8240 att = sftk_FindAttribute(destKey, CKA_SENSITIVE0x00000103UL);
8241 if (att) {
8242 hasSensitive = PR_TRUE1;
8243 sensitive = (PRBool) * (CK_BBOOL *)att->attrib.pValue;
8244 sftk_FreeAttribute(att);
8245 }
8246
8247 hasExtractable = PR_FALSE0;
8248 att = sftk_FindAttribute(destKey, CKA_EXTRACTABLE0x00000162UL);
8249 if (att) {
8250 hasExtractable = PR_TRUE1;
8251 extractable = (PRBool) * (CK_BBOOL *)att->attrib.pValue;
8252 sftk_FreeAttribute(att);
8253 }
8254
8255 /* don't make a key more accessible */
8256 if (sftk_isTrue(baseKey, CKA_SENSITIVE0x00000103UL) && hasSensitive &&
8257 (sensitive == PR_FALSE0)) {
8258 return CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
8259 }
8260 if (!sftk_isTrue(baseKey, CKA_EXTRACTABLE0x00000162UL) && hasExtractable &&
8261 (extractable == PR_TRUE1)) {
8262 return CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
8263 }
8264
8265 /* inherit parent's sensitivity */
8266 if (!hasSensitive) {
8267 att = sftk_FindAttribute(baseKey, CKA_SENSITIVE0x00000103UL);
8268 if (att != NULL((void*)0)) {
8269 crv = sftk_defaultAttribute(destKey,
8270 sftk_attr_expand(&att->attrib)(&att->attrib)->type, (&att->attrib)->pValue
, (&att->attrib)->ulValueLen
);
8271 sftk_FreeAttribute(att);
8272 } else if (isData) {
8273 crv = sftk_defaultAttribute(destKey, CKA_SENSITIVE0x00000103UL,
8274 &bFalse, sizeof(bFalse));
8275 } else {
8276 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
8277 }
8278 if (crv != CKR_OK0x00000000UL)
8279 return crv;
8280 }
8281 if (!hasExtractable) {
8282 att = sftk_FindAttribute(baseKey, CKA_EXTRACTABLE0x00000162UL);
8283 if (att != NULL((void*)0)) {
8284 crv = sftk_defaultAttribute(destKey,
8285 sftk_attr_expand(&att->attrib)(&att->attrib)->type, (&att->attrib)->pValue
, (&att->attrib)->ulValueLen
);
8286 sftk_FreeAttribute(att);
8287 } else if (isData) {
8288 crv = sftk_defaultAttribute(destKey, CKA_EXTRACTABLE0x00000162UL,
8289 &bTrue, sizeof(bTrue));
8290 } else {
8291 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
8292 }
8293 if (crv != CKR_OK0x00000000UL)
8294 return crv;
8295 }
8296
8297 /* we should inherit the parent's always extractable/ never sensitive info,
8298 * but handleObject always forces this attributes, so we would need to do
8299 * something special. */
8300 return CKR_OK0x00000000UL;
8301}
8302
8303/*
8304 * make known fixed PKCS #11 key types to their sizes in bytes
8305 */
8306unsigned long
8307sftk_MapKeySize(CK_KEY_TYPE keyType)
8308{
8309 switch (keyType) {
8310 case CKK_CDMF0x0000001EUL:
8311 return 8;
8312 case CKK_DES0x00000013UL:
8313 return 8;
8314 case CKK_DES20x00000014UL:
8315 return 16;
8316 case CKK_DES30x00000015UL:
8317 return 24;
8318 /* IDEA and CAST need to be added */
8319 default:
8320 break;
8321 }
8322 return 0;
8323}
8324
8325/* Inputs:
8326 * key_len: Length of derived key to be generated.
8327 * SharedSecret: a shared secret that is the output of a key agreement primitive.
8328 * SharedInfo: (Optional) some data shared by the entities computing the secret key.
8329 * SharedInfoLen: the length in octets of SharedInfo
8330 * Hash: The hash function to be used in the KDF
8331 * HashLen: the length in octets of the output of Hash
8332 * Output:
8333 * key: Pointer to a buffer containing derived key, if return value is SECSuccess.
8334 */
8335static CK_RV
8336sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECItem *SharedSecret,
8337 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
8338 SECStatus Hash(unsigned char *, const unsigned char *, PRUint32),
8339 CK_ULONG HashLen)
8340{
8341 unsigned char *buffer = NULL((void*)0), *output_buffer = NULL((void*)0);
8342 PRUint32 buffer_len, max_counter, i;
8343 SECStatus rv;
8344 CK_RV crv;
8345
8346 /* Check that key_len isn't too long. The maximum key length could be
8347 * greatly increased if the code below did not limit the 4-byte counter
8348 * to a maximum value of 255. */
8349 if (key_len > 254 * HashLen)
8350 return CKR_ARGUMENTS_BAD0x00000007UL;
8351
8352 if (SharedInfo == NULL((void*)0))
8353 SharedInfoLen = 0;
8354
8355 if (SharedSecret->len > PR_UINT32_MAX4294967295U - 4 ||
8356 SharedInfoLen > PR_UINT32_MAX4294967295U - 4 - SharedSecret->len)
8357 return CKR_ARGUMENTS_BAD0x00000007UL;
8358
8359 buffer_len = SharedSecret->len + 4 + SharedInfoLen;
8360 buffer = (CK_BYTE *)PORT_AllocPORT_Alloc_Util(buffer_len);
8361 if (buffer == NULL((void*)0)) {
8362 crv = CKR_HOST_MEMORY0x00000002UL;
8363 goto loser;
8364 }
8365
8366 max_counter = key_len / HashLen;
8367 if (key_len > max_counter * HashLen)
8368 max_counter++;
8369
8370 output_buffer = (CK_BYTE *)PORT_AllocPORT_Alloc_Util(max_counter * HashLen);
8371 if (output_buffer == NULL((void*)0)) {
8372 crv = CKR_HOST_MEMORY0x00000002UL;
8373 goto loser;
8374 }
8375
8376 /* Populate buffer with SharedSecret || Counter || [SharedInfo]
8377 * where Counter is 0x00000001 */
8378 PORT_Memcpymemcpy(buffer, SharedSecret->data, SharedSecret->len);
8379 buffer[SharedSecret->len] = 0;
8380 buffer[SharedSecret->len + 1] = 0;
8381 buffer[SharedSecret->len + 2] = 0;
8382 buffer[SharedSecret->len + 3] = 1;
8383 if (SharedInfo) {
8384 PORT_Memcpymemcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen);
8385 }
8386
8387 for (i = 0; i < max_counter; i++) {
8388 rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len);
8389 if (rv != SECSuccess) {
8390 /* 'Hash' should not fail. */
8391 crv = CKR_FUNCTION_FAILED0x00000006UL;
8392 goto loser;
8393 }
8394
8395 /* Increment counter (assumes max_counter < 255) */
8396 buffer[SharedSecret->len + 3]++;
8397 }
8398
8399 PORT_ZFreePORT_ZFree_Util(buffer, buffer_len);
8400 if (key_len < max_counter * HashLen) {
8401 PORT_Memsetmemset(output_buffer + key_len, 0, max_counter * HashLen - key_len);
8402 }
8403 *key = output_buffer;
8404
8405 return CKR_OK0x00000000UL;
8406
8407loser:
8408 if (buffer) {
8409 PORT_ZFreePORT_ZFree_Util(buffer, buffer_len);
8410 }
8411 if (output_buffer) {
8412 PORT_ZFreePORT_ZFree_Util(output_buffer, max_counter * HashLen);
8413 }
8414 return crv;
8415}
8416
8417static CK_RV
8418sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len,
8419 SECItem *SharedSecret,
8420 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
8421 CK_EC_KDF_TYPE kdf)
8422{
8423 if (kdf == CKD_SHA1_KDF0x00000002UL)
8424 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8425 SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH20);
8426 else if (kdf == CKD_SHA224_KDF0x00000005UL)
8427 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8428 SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH28);
8429 else if (kdf == CKD_SHA256_KDF0x00000006UL)
8430 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8431 SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH32);
8432 else if (kdf == CKD_SHA384_KDF0x00000007UL)
8433 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8434 SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH48);
8435 else if (kdf == CKD_SHA512_KDF0x00000008UL)
8436 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8437 SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH64);
8438 else
8439 return CKR_MECHANISM_INVALID0x00000070UL;
8440}
8441
8442/*
8443 * Handle the derive from a block encryption cipher
8444 */
8445CK_RV
8446sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo,
8447 int blockSize, SFTKObject *key, CK_ULONG keySize,
8448 unsigned char *data, CK_ULONG len)
8449{
8450 /* large enough for a 512-bit key */
8451 unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE64];
8452 SECStatus rv;
8453 unsigned int outLen;
8454 CK_RV crv;
8455
8456 if ((len % blockSize) != 0) {
8457 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8458 }
8459 if (len > SFTK_MAX_DERIVE_KEY_SIZE64) {
8460 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8461 }
8462 if (keySize && (len < keySize)) {
8463 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8464 }
8465 if (keySize == 0) {
8466 keySize = len;
8467 }
8468
8469 rv = (*encrypt)(cipherInfo, (unsigned char *)&tmpdata, &outLen, len, data, len);
8470 if (rv != SECSuccess) {
8471 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
8472 return crv;
8473 }
8474
8475 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, tmpdata, keySize);
8476 PORT_Memsetmemset(tmpdata, 0, sizeof tmpdata);
8477 return crv;
8478}
8479
8480CK_RV
8481sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_SESSION_HANDLE hSession,
8482 SFTKObject *sourceKey, const unsigned char *sourceKeyBytes,
8483 int sourceKeyLen, SFTKObject *key, unsigned char *outKeyBytes,
8484 int keySize, PRBool canBeData, PRBool isFIPS)
8485{
8486 SFTKSession *session;
8487 SFTKAttribute *saltKey_att = NULL((void*)0);
8488 const SECHashObject *rawHash;
8489 unsigned hashLen;
8490 unsigned genLen = 0;
8491 unsigned char hashbuf[HASH_LENGTH_MAX64];
8492 unsigned char keyBlock[9 * SFTK_MAX_MAC_LENGTH64];
8493 unsigned char *keyBlockAlloc = NULL((void*)0); /* allocated keyBlock */
8494 unsigned char *keyBlockData = keyBlock; /* pointer to current keyBlock */
8495 const unsigned char *prk; /* psuedo-random key */
8496 CK_ULONG prkLen;
8497 const unsigned char *okm; /* output keying material */
8498 HASH_HashType hashType = sftk_GetHashTypeFromMechanism(params->prfHashMechanism);
8499 SFTKObject *saltKey = NULL((void*)0);
8500 CK_RV crv = CKR_OK0x00000000UL;
8501
8502 /* Spec says it should be the base hash, but also accept the HMAC */
8503 if (hashType == HASH_AlgNULL) {
8504 hashType = sftk_HMACMechanismToHash(params->prfHashMechanism);
8505 }
8506 rawHash = HASH_GetRawHashObject(hashType);
8507 if (rawHash == NULL((void*)0) || rawHash->length > sizeof(hashbuf)) {
8508 return CKR_MECHANISM_INVALID0x00000070UL;
8509 }
8510 hashLen = rawHash->length;
8511
8512 if ((!params->bExpand && !params->bExtract) ||
8513 (params->bExtract && params->ulSaltLen > 0 && !params->pSalt) ||
8514 (params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) {
8515 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8516 }
8517 if ((params->bExpand && keySize == 0) ||
8518 (!params->bExpand && keySize > hashLen) ||
8519 (params->bExpand && keySize > 255 * hashLen)) {
8520 return CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
8521 }
8522
8523 if (!params->bExpand) {
8524 keySize = hashLen;
8525 }
8526
8527 /* sourceKey is NULL if we are called from the POST, skip the
8528 * sensitiveCheck */
8529 if (sourceKey != NULL((void*)0)) {
8530 crv = sftk_DeriveSensitiveCheck(sourceKey, key, canBeData);
8531 if (crv != CKR_OK0x00000000UL)
8532 return crv;
8533 /* if the source key is data, clear the FIPS flag
8534 * and only get the FIPS state from the salt */
8535 if (sourceKey->objclass == CKO_DATA0x00000000UL) {
8536 sftk_setFIPS(key, PR_FALSE0);
8537 }
8538 }
8539
8540 /* HKDF-Extract(salt, base key value) */
8541 if (params->bExtract) {
8542 CK_BYTE *salt;
8543 CK_ULONG saltLen;
8544 HMACContext *hmac;
8545 unsigned int bufLen;
8546 SFTKSource saltKeySource = SFTK_SOURCE_DEFAULT;
8547
8548 switch (params->ulSaltType) {
8549 case CKF_HKDF_SALT_NULL0x00000001UL:
8550 saltLen = hashLen;
8551 salt = hashbuf;
8552 memset(salt, 0, saltLen);
8553 break;
8554 case CKF_HKDF_SALT_DATA0x00000002UL:
8555 salt = params->pSalt;
8556 saltLen = params->ulSaltLen;
8557 if ((salt == NULL((void*)0)) || (params->ulSaltLen == 0)) {
8558 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8559 }
8560 break;
8561 case CKF_HKDF_SALT_KEY0x00000004UL:
8562 /* lookup key */
8563 session = sftk_SessionFromHandle(hSession);
8564 if (session == NULL((void*)0)) {
8565 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
8566 }
8567
8568 saltKey = sftk_ObjectFromHandle(params->hSaltKey, session);
8569 sftk_FreeSession(session);
8570 if (saltKey == NULL((void*)0)) {
8571 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8572 }
8573 /* if the base key is not fips, but the salt key is, the
8574 * resulting key can be fips */
8575 if (isFIPS && !sftk_hasFIPS(key) && sftk_hasFIPS(saltKey)) {
8576 CK_MECHANISM mech;
8577 mech.mechanism = CKM_HKDF_DERIVE0x0000402aUL;
8578 mech.pParameter = params;
8579 mech.ulParameterLen = sizeof(*params);
8580 sftk_setFIPS(key, sftk_operationIsFIPS(saltKey->slot,
8581 &mech, CKA_DERIVE0x0000010CUL,
8582 saltKey,
8583 keySize * PR_BITS_PER_BYTE8));
8584 }
8585 saltKeySource = saltKey->source;
8586 saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE0x00000011UL);
8587 if (saltKey_att == NULL((void*)0)) {
8588 sftk_FreeObject(saltKey);
8589 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8590 }
8591 /* save the resulting salt */
8592 salt = saltKey_att->attrib.pValue;
8593 saltLen = saltKey_att->attrib.ulValueLen;
8594 break;
8595 default:
8596 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8597 break;
8598 }
8599 /* only TLS style usage is FIPS approved,
8600 * turn off the FIPS indicator for other usages */
8601 if (isFIPS && key && sourceKey) {
8602 PRBool fipsOK = PR_FALSE0;
8603 /* case one: mix the kea with a previous or default
8604 * salt */
8605 if ((sourceKey->source == SFTK_SOURCE_KEA) &&
8606 (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
8607 (saltLen == rawHash->length)) {
8608 fipsOK = PR_TRUE1;
8609 }
8610 /* case two: restart, remix the previous secret as a salt */
8611 if ((sourceKey->objclass == CKO_DATA0x00000000UL) &&
8612 (NSS_SecureMemcmpZero(sourceKeyBytes, sourceKeyLen) == 0) &&
8613 (sourceKeyLen == rawHash->length) &&
8614 (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
8615 (saltLen == rawHash->length)) {
8616 fipsOK = PR_TRUE1;
8617 }
8618 if (!fipsOK) {
8619 sftk_setFIPS(key, PR_FALSE0);
8620 }
8621 }
8622 if (key)
8623 key->source = SFTK_SOURCE_HKDF_EXTRACT;
8624
8625 hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
8626 if (saltKey_att) {
8627 sftk_FreeAttribute(saltKey_att);
8628 }
8629 if (saltKey) {
8630 sftk_FreeObject(saltKey);
8631 }
8632 if (!hmac) {
8633 return CKR_HOST_MEMORY0x00000002UL;
8634 }
8635 HMAC_Begin(hmac);
8636 HMAC_Update(hmac, sourceKeyBytes, sourceKeyLen);
8637 HMAC_Finish(hmac, hashbuf, &bufLen, sizeof(hashbuf));
8638 HMAC_Destroy(hmac, PR_TRUE1);
8639 PORT_Assert(bufLen == rawHash->length)((bufLen == rawHash->length) ? ((void)0) : PR_Assert("bufLen == rawHash->length"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 8639
))
;
8640 prk = hashbuf;
8641 prkLen = bufLen;
8642 } else {
8643 /* PRK = base key value */
8644 prk = sourceKeyBytes;
8645 prkLen = sourceKeyLen;
8646 }
8647
8648 /* HKDF-Expand */
8649 if (!params->bExpand) {
8650 okm = prk;
8651 genLen = hashLen;
8652 } else {
8653 /* T(1) = HMAC-Hash(prk, "" | info | 0x01)
8654 * T(n) = HMAC-Hash(prk, T(n-1) | info | n
8655 * key material = T(1) | ... | T(n)
8656 */
8657 HMACContext *hmac;
8658 CK_BYTE bi;
8659 unsigned iterations;
8660
8661 /* only TLS style usage is FIPS approved,
8662 * turn off the FIPS indicator for other usages */
8663 if (isFIPS && key && sftk_hasFIPS(key) && sourceKey) {
8664 /* only one case,
8665 * 1) Expand only
8666 * 2) with a key whose source was
8667 * SFTK_SOURCE_HKDF_EXPAND or SFTK_SOURCE_HKDF_EXTRACT
8668 * 3) source key length == rawHash->length
8669 * 4) Info has tls or dtls
8670 * If any of those conditions aren't met, then we turn
8671 * off the fips indicator */
8672 if (params->bExtract ||
8673 ((sourceKey->source != SFTK_SOURCE_HKDF_EXTRACT) &&
8674 (sourceKey->source != SFTK_SOURCE_HKDF_EXPAND)) ||
8675 (sourceKeyLen != rawHash->length) ||
8676 (params->ulInfoLen < 7) ||
8677 ((PORT_Memcmpmemcmp(&params->pInfo[3], "tls", 3) != 0) &&
8678 (PORT_Memcmpmemcmp(&params->pInfo[3], "dtls", 4) != 0))) {
8679 sftk_setFIPS(key, PR_FALSE0);
8680 }
8681 }
8682 if (key)
8683 key->source = SFTK_SOURCE_HKDF_EXPAND;
8684
8685 genLen = PR_ROUNDUP(keySize, hashLen)((((keySize) + ((hashLen) - 1)) / (hashLen)) * (hashLen));
8686 iterations = genLen / hashLen;
8687
8688 if (genLen > sizeof(keyBlock)) {
8689 keyBlockAlloc = PORT_AllocPORT_Alloc_Util(genLen);
8690 if (keyBlockAlloc == NULL((void*)0)) {
8691 return CKR_HOST_MEMORY0x00000002UL;
8692 }
8693 keyBlockData = keyBlockAlloc;
8694 }
8695 hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
8696 if (hmac == NULL((void*)0)) {
8697 PORT_FreePORT_Free_Util(keyBlockAlloc);
8698 return CKR_HOST_MEMORY0x00000002UL;
8699 }
8700 for (bi = 1; bi <= iterations && bi > 0; ++bi) {
8701 unsigned len;
8702 HMAC_Begin(hmac);
8703 if (bi > 1) {
8704 HMAC_Update(hmac, &keyBlockData[(bi - 2) * hashLen], hashLen);
8705 }
8706 if (params->ulInfoLen != 0) {
8707 HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
8708 }
8709 HMAC_Update(hmac, &bi, 1);
8710 HMAC_Finish(hmac, &keyBlockData[(bi - 1) * hashLen], &len,
8711 hashLen);
8712 PORT_Assert(len == hashLen)((len == hashLen) ? ((void)0) : PR_Assert("len == hashLen", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 8712))
;
8713 }
8714 HMAC_Destroy(hmac, PR_TRUE1);
8715 okm = &keyBlockData[0];
8716 }
8717 /* key material = okm */
8718 crv = CKR_OK0x00000000UL;
8719 if (key) {
8720 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, okm, keySize);
8721 } else {
8722 PORT_Assert(outKeyBytes != NULL)((outKeyBytes != ((void*)0)) ? ((void)0) : PR_Assert("outKeyBytes != NULL"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 8722
))
;
8723 PORT_Memcpymemcpy(outKeyBytes, okm, keySize);
8724 }
8725 PORT_Memsetmemset(keyBlockData, 0, genLen);
8726 PORT_Memsetmemset(hashbuf, 0, sizeof(hashbuf));
8727 PORT_FreePORT_Free_Util(keyBlockAlloc);
8728 return crv;
8729}
8730
8731/*
8732 * SSL Key generation given pre master secret
8733 */
8734#define NUM_MIXERS9 9
8735static const char *const mixers[NUM_MIXERS9] = {
8736 "A",
8737 "BB",
8738 "CCC",
8739 "DDDD",
8740 "EEEEE",
8741 "FFFFFF",
8742 "GGGGGGG",
8743 "HHHHHHHH",
8744 "IIIIIIIII"
8745};
8746#define SSL3_PMS_LENGTH48 48
8747#define SSL3_MASTER_SECRET_LENGTH48 48
8748#define SSL3_RANDOM_LENGTH32 32
8749
8750/* NSC_DeriveKey derives a key from a base key, creating a new key object. */
8751CK_RV
8752NSC_DeriveKey(CK_SESSION_HANDLE hSession,
8753 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
8754 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
8755 CK_OBJECT_HANDLE_PTR phKey)
8756{
8757 SFTKSession *session;
8758 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
8759 SFTKObject *key;
8760 SFTKObject *sourceKey;
8761 SFTKAttribute *att = NULL((void*)0);
8762 SFTKAttribute *att2 = NULL((void*)0);
8763 unsigned char *buf;
8764 SHA1Context *sha;
8765 MD5Context *md5;
8766 MD2Context *md2;
8767 CK_ULONG macSize;
8768 CK_ULONG tmpKeySize;
8769 CK_ULONG IVSize;
8770 CK_ULONG keySize = 0;
8771 CK_RV crv = CKR_OK0x00000000UL;
8772 CK_BBOOL cktrue = CK_TRUE1;
8773 CK_BBOOL ckfalse = CK_FALSE0;
8774 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET0x00000010UL;
8775 CK_OBJECT_CLASS classType = CKO_SECRET_KEY0x00000004UL;
8776 CK_KEY_DERIVATION_STRING_DATA *stringPtr;
8777 PRBool isTLS = PR_FALSE0;
8778 PRBool isDH = PR_FALSE0;
8779 HASH_HashType tlsPrfHash = HASH_AlgNULL;
8780 SECStatus rv;
8781 int i;
8782 unsigned int outLen;
8783 unsigned char sha_out[SHA1_LENGTH20];
8784 unsigned char key_block[NUM_MIXERS9 * SFTK_MAX_MAC_LENGTH64];
8785 PRBool isFIPS;
8786 HASH_HashType hashType;
8787 CK_MECHANISM_TYPE hashMech;
8788 PRBool extractValue = PR_TRUE1;
8789 CK_IKE1_EXTENDED_DERIVE_PARAMS ikeAppB;
8790 CK_IKE1_EXTENDED_DERIVE_PARAMS *pIkeAppB;
8791
8792 CHECK_FORK();
8793
8794 if (!slot) {
8795 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
8796 }
8797 if (!pMechanism) {
8798 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8799 }
8800 CK_MECHANISM_TYPE mechanism = pMechanism->mechanism;
8801
8802 /*
8803 * now lets create an object to hang the attributes off of
8804 */
8805 if (phKey) {
8806 *phKey = CK_INVALID_HANDLE0;
8807 }
8808
8809 key = sftk_NewObject(slot); /* fill in the handle later */
8810 if (key == NULL((void*)0)) {
8811 return CKR_HOST_MEMORY0x00000002UL;
8812 }
8813 isFIPS = sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101));
8814
8815 /*
8816 * load the template values into the object
8817 */
8818 for (i = 0; i < (int)ulAttributeCount; i++) {
8819 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
8820 if (crv != CKR_OK0x00000000UL)
8821 break;
8822
8823 if (pTemplate[i].type == CKA_KEY_TYPE0x00000100UL) {
8824 keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue;
8825 }
8826 if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) {
8827 keySize = *(CK_ULONG *)pTemplate[i].pValue;
8828 }
8829 }
8830 if (crv != CKR_OK0x00000000UL) {
8831 sftk_FreeObject(key);
8832 return crv;
8833 }
8834
8835 if (keySize == 0) {
8836 keySize = sftk_MapKeySize(keyType);
8837 }
8838
8839 switch (mechanism) {
8840 case CKM_NSS_JPAKE_ROUND2_SHA1((0x80000000UL | 0x4E534350) + 11): /* fall through */
8841 case CKM_NSS_JPAKE_ROUND2_SHA256((0x80000000UL | 0x4E534350) + 12): /* fall through */
8842 case CKM_NSS_JPAKE_ROUND2_SHA384((0x80000000UL | 0x4E534350) + 13): /* fall through */
8843 case CKM_NSS_JPAKE_ROUND2_SHA512((0x80000000UL | 0x4E534350) + 14):
8844 extractValue = PR_FALSE0;
8845 classType = CKO_PRIVATE_KEY0x00000003UL;
8846 break;
8847 case CKM_NSS_PUB_FROM_PRIV((0x80000000UL | 0x4E534350) + 40):
8848 extractValue = PR_FALSE0;
8849 classType = CKO_PUBLIC_KEY0x00000002UL;
8850 break;
8851 case CKM_HKDF_DATA0x0000402bUL: /* fall through */
8852 case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 42): /* fall through */
8853 case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 43): /* fall through */
8854 case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 44):
8855 classType = CKO_DATA0x00000000UL;
8856 break;
8857 case CKM_NSS_JPAKE_FINAL_SHA1((0x80000000UL | 0x4E534350) + 15): /* fall through */
8858 case CKM_NSS_JPAKE_FINAL_SHA256((0x80000000UL | 0x4E534350) + 16): /* fall through */
8859 case CKM_NSS_JPAKE_FINAL_SHA384((0x80000000UL | 0x4E534350) + 17): /* fall through */
8860 case CKM_NSS_JPAKE_FINAL_SHA512((0x80000000UL | 0x4E534350) + 18):
8861 extractValue = PR_FALSE0;
8862 /* fall through */
8863 default:
8864 classType = CKO_SECRET_KEY0x00000004UL;
8865 }
8866
8867 crv = sftk_forceAttribute(key, CKA_CLASS0x00000000UL, &classType, sizeof(classType));
8868 if (crv != CKR_OK0x00000000UL) {
8869 sftk_FreeObject(key);
8870 return crv;
8871 }
8872
8873 /* look up the base key we're deriving with */
8874 session = sftk_SessionFromHandle(hSession);
8875 if (session == NULL((void*)0)) {
8876 sftk_FreeObject(key);
8877 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
8878 }
8879
8880 sourceKey = sftk_ObjectFromHandle(hBaseKey, session);
8881 /* is this eventually succeeds, lastOpWasFIPS will be set the resulting key's
8882 * FIPS state below. */
8883 session->lastOpWasFIPS = PR_FALSE0;
8884 sftk_FreeSession(session);
8885 if (sourceKey == NULL((void*)0)) {
8886 sftk_FreeObject(key);
8887 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8888 }
8889
8890 if (extractValue) {
8891 /* get the value of the base key */
8892 att = sftk_FindAttribute(sourceKey, CKA_VALUE0x00000011UL);
8893 if (att == NULL((void*)0)) {
8894 sftk_FreeObject(key);
8895 sftk_FreeObject(sourceKey);
8896 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8897 }
8898 }
8899 sftk_setFIPS(key, sftk_operationIsFIPS(slot, pMechanism,
8900 CKA_DERIVE0x0000010CUL, sourceKey,
8901 keySize * PR_BITS_PER_BYTE8));
8902
8903 switch (mechanism) {
8904 /* get a public key from a private key. nsslowkey_ConvertToPublickey()
8905 * will generate the public portion if it doesn't already exist. */
8906 case CKM_NSS_PUB_FROM_PRIV((0x80000000UL | 0x4E534350) + 40): {
8907 NSSLOWKEYPrivateKey *privKey;
8908 NSSLOWKEYPublicKey *pubKey;
8909 int error;
8910
8911 crv = sftk_GetULongAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL, &keyType);
8912 if (crv != CKR_OK0x00000000UL) {
8913 break;
8914 }
8915
8916 /* privKey is stored in sourceKey and will be destroyed when
8917 * the sourceKey is freed. */
8918 privKey = sftk_GetPrivKey(sourceKey, keyType, &crv);
8919 if (privKey == NULL((void*)0)) {
8920 break;
8921 }
8922 pubKey = nsslowkey_ConvertToPublicKey(privKey);
8923 if (pubKey == NULL((void*)0)) {
8924 error = PORT_GetErrorPORT_GetError_Util();
8925 crv = sftk_MapCryptError(error);
8926 break;
8927 }
8928 crv = sftk_PutPubKey(key, sourceKey, keyType, pubKey);
8929 nsslowkey_DestroyPublicKey(pubKey);
8930 break;
8931 }
8932 case CKM_NSS_IKE_PRF_DERIVE((0x80000000UL | 0x4E534350) + 35):
8933 case CKM_IKE_PRF_DERIVE0x0000402fUL:
8934 if (pMechanism->ulParameterLen !=
8935 sizeof(CK_IKE_PRF_DERIVE_PARAMS)) {
8936 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8937 break;
8938 }
8939 crv = sftk_ike_prf(hSession, att,
8940 (CK_IKE_PRF_DERIVE_PARAMS *)pMechanism->pParameter, key);
8941 break;
8942 case CKM_NSS_IKE1_PRF_DERIVE((0x80000000UL | 0x4E534350) + 36):
8943 case CKM_IKE1_PRF_DERIVE0x00004030UL:
8944 if (pMechanism->ulParameterLen !=
8945 sizeof(CK_IKE1_PRF_DERIVE_PARAMS)) {
8946 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8947 break;
8948 }
8949 crv = sftk_ike1_prf(hSession, att,
8950 (CK_IKE1_PRF_DERIVE_PARAMS *)pMechanism->pParameter,
8951 key, keySize);
8952 break;
8953 case CKM_NSS_IKE1_APP_B_PRF_DERIVE((0x80000000UL | 0x4E534350) + 37):
8954 case CKM_IKE1_EXTENDED_DERIVE0x00004031UL:
8955 pIkeAppB = (CK_IKE1_EXTENDED_DERIVE_PARAMS *)pMechanism->pParameter;
8956 if (pMechanism->ulParameterLen ==
8957 sizeof(CK_MECHANISM_TYPE)) {
8958 ikeAppB.prfMechanism = *(CK_MECHANISM_TYPE *)pMechanism->pParameter;
8959 ikeAppB.bHasKeygxy = PR_FALSE0;
8960 ikeAppB.hKeygxy = CK_INVALID_HANDLE0;
8961 ikeAppB.pExtraData = NULL((void*)0);
8962 ikeAppB.ulExtraDataLen = 0;
8963 pIkeAppB = &ikeAppB;
8964 } else if (pMechanism->ulParameterLen !=
8965 sizeof(CK_IKE1_EXTENDED_DERIVE_PARAMS)) {
8966 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8967 break;
8968 }
8969 crv = sftk_ike1_appendix_b_prf(hSession, att, pIkeAppB, key,
8970 keySize);
8971 break;
8972 case CKM_NSS_IKE_PRF_PLUS_DERIVE((0x80000000UL | 0x4E534350) + 34):
8973 case CKM_IKE2_PRF_PLUS_DERIVE0x0000402eUL:
8974 if (pMechanism->ulParameterLen !=
8975 sizeof(CK_IKE2_PRF_PLUS_DERIVE_PARAMS)) {
8976 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8977 break;
8978 }
8979 crv = sftk_ike_prf_plus(hSession, att,
8980 (CK_IKE2_PRF_PLUS_DERIVE_PARAMS *)pMechanism->pParameter,
8981 key, keySize);
8982 break;
8983 /*
8984 * generate the master secret
8985 */
8986 case CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL:
8987 case CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL:
8988 case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 22):
8989 case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24):
8990 case CKM_TLS_MASTER_KEY_DERIVE0x00000375UL:
8991 case CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377UL:
8992 case CKM_SSL3_MASTER_KEY_DERIVE0x00000371UL:
8993 case CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL: {
8994 CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
8995 SSL3RSAPreMasterSecret *rsa_pms;
8996 unsigned char crsrdata[SSL3_RANDOM_LENGTH32 * 2];
8997
8998 if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL) ||
8999 (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL)) {
9000 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))
) {
9001 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9002 break;
9003 }
9004 CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
9005 (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter;
9006 tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
9007 if (tlsPrfHash == HASH_AlgNULL) {
9008 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9009 break;
9010 }
9011 } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 22)) ||
9012 (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24))) {
9013 tlsPrfHash = HASH_AlgSHA256;
9014 }
9015
9016 if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE0x00000371UL) &&
9017 (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL)) {
9018 isTLS = PR_TRUE1;
9019 }
9020 if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL) ||
9021 (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377UL) ||
9022 (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24)) ||
9023 (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL)) {
9024 isDH = PR_TRUE1;
9025 }
9026
9027 /* first do the consistency checks */
9028 if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH48)) {
9029 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
9030 break;
9031 }
9032 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL);
9033 if ((att2 == NULL((void*)0)) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
9034 CKK_GENERIC_SECRET0x00000010UL)) {
9035 if (att2)
9036 sftk_FreeAttribute(att2);
9037 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9038 break;
9039 }
9040 sftk_FreeAttribute(att2);
9041 if (keyType != CKK_GENERIC_SECRET0x00000010UL) {
9042 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9043 break;
9044 }
9045 if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH48)) {
9046 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9047 break;
9048 }
9049
9050 /* finally do the key gen */
9051 ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
9052 pMechanism->pParameter;
9053
9054 if (ssl3_master->pVersion) {
9055 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
9056 rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue;
9057 /* don't leak more key material then necessary for SSL to work */
9058 if ((sessKey == NULL((void*)0)) || sessKey->wasDerived) {
9059 ssl3_master->pVersion->major = 0xff;
9060 ssl3_master->pVersion->minor = 0xff;
9061 } else {
9062 ssl3_master->pVersion->major = rsa_pms->client_version[0];
9063 ssl3_master->pVersion->minor = rsa_pms->client_version[1];
9064 }
9065 }
9066 if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH32) {
9067 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9068 break;
9069 }
9070 if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH32) {
9071 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9072 break;
9073 }
9074 PORT_Memcpymemcpy(crsrdata,
9075 ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH32);
9076 PORT_Memcpymemcpy(crsrdata + SSL3_RANDOM_LENGTH32,
9077 ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH32);
9078
9079 if (isTLS) {
9080 SECStatus status;
9081 SECItem crsr = { siBuffer, NULL((void*)0), 0 };
9082 SECItem master = { siBuffer, NULL((void*)0), 0 };
9083 SECItem pms = { siBuffer, NULL((void*)0), 0 };
9084
9085 crsr.data = crsrdata;
9086 crsr.len = sizeof crsrdata;
9087 master.data = key_block;
9088 master.len = SSL3_MASTER_SECRET_LENGTH48;
9089 pms.data = (unsigned char *)att->attrib.pValue;
9090 pms.len = att->attrib.ulValueLen;
9091
9092 if (tlsPrfHash != HASH_AlgNULL) {
9093 status = TLS_P_hash(tlsPrfHash, &pms, "master secret",
9094 &crsr, &master, isFIPS);
9095 } else {
9096 status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
9097 }
9098 if (status != SECSuccess) {
9099 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9100 crv = CKR_FUNCTION_FAILED0x00000006UL;
9101 break;
9102 }
9103 } else {
9104 /* now allocate the hash contexts */
9105 md5 = MD5_NewContext();
9106 if (md5 == NULL((void*)0)) {
9107 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9108 crv = CKR_HOST_MEMORY0x00000002UL;
9109 break;
9110 }
9111 sha = SHA1_NewContext();
9112 if (sha == NULL((void*)0)) {
9113 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9114 PORT_FreePORT_Free_Util(md5);
9115 crv = CKR_HOST_MEMORY0x00000002UL;
9116 break;
9117 }
9118 for (i = 0; i < 3; i++) {
9119 SHA1_Begin(sha);
9120 SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i]));
9121 SHA1_Update(sha, (const unsigned char *)att->attrib.pValue,
9122 att->attrib.ulValueLen);
9123 SHA1_Update(sha, crsrdata, sizeof crsrdata);
9124 SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH20);
9125 PORT_Assert(outLen == SHA1_LENGTH)((outLen == 20) ? ((void)0) : PR_Assert("outLen == SHA1_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9125
))
;
9126
9127 MD5_Begin(md5);
9128 MD5_Update(md5, (const unsigned char *)att->attrib.pValue,
9129 att->attrib.ulValueLen);
9130 MD5_Update(md5, sha_out, outLen);
9131 MD5_End(md5, &key_block[i * MD5_LENGTH16], &outLen, MD5_LENGTH16);
9132 PORT_Assert(outLen == MD5_LENGTH)((outLen == 16) ? ((void)0) : PR_Assert("outLen == MD5_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9132
))
;
9133 }
9134 PORT_FreePORT_Free_Util(md5);
9135 PORT_FreePORT_Free_Util(sha);
9136 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9137 PORT_Memsetmemset(sha_out, 0, sizeof sha_out);
9138 }
9139
9140 /* store the results */
9141 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, SSL3_MASTER_SECRET_LENGTH48);
9142 PORT_Memsetmemset(key_block, 0, sizeof key_block);
9143 if (crv != CKR_OK0x00000000UL)
9144 break;
9145 keyType = CKK_GENERIC_SECRET0x00000010UL;
9146 crv = sftk_forceAttribute(key, CKA_KEY_TYPE0x00000100UL, &keyType, sizeof(keyType));
9147 if (isTLS) {
9148 /* TLS's master secret is used to "sign" finished msgs with PRF. */
9149 /* XXX This seems like a hack. But SFTK_Derive only accepts
9150 * one "operation" argument. */
9151 crv = sftk_forceAttribute(key, CKA_SIGN0x00000108UL, &cktrue, sizeof(CK_BBOOL));
9152 if (crv != CKR_OK0x00000000UL)
9153 break;
9154 crv = sftk_forceAttribute(key, CKA_VERIFY0x0000010AUL, &cktrue, sizeof(CK_BBOOL));
9155 if (crv != CKR_OK0x00000000UL)
9156 break;
9157 /* While we're here, we might as well force this, too. */
9158 crv = sftk_forceAttribute(key, CKA_DERIVE0x0000010CUL, &cktrue, sizeof(CK_BBOOL));
9159 if (crv != CKR_OK0x00000000UL)
9160 break;
9161 }
9162 break;
9163 }
9164
9165 /* Extended master key derivation [draft-ietf-tls-session-hash] */
9166 case CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE0x00000056UL:
9167 case CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH0x00000057UL:
9168 case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE((0x80000000UL | 0x4E534350) + 25):
9169 case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH((0x80000000UL | 0x4E534350) + 26): {
9170 CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params;
9171 SSL3RSAPreMasterSecret *rsa_pms;
9172 SECStatus status;
9173 SECItem pms = { siBuffer, NULL((void*)0), 0 };
9174 SECItem seed = { siBuffer, NULL((void*)0), 0 };
9175 SECItem master = { siBuffer, NULL((void*)0), 0 };
9176
9177 ems_params = (CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS *)
9178 pMechanism->pParameter;
9179
9180 /* First do the consistency checks */
9181 if (((mechanism == CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE0x00000056UL) ||
9182 (mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE((0x80000000UL | 0x4E534350) + 25))) &&
9183 (att->attrib.ulValueLen != SSL3_PMS_LENGTH48)) {
9184 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
9185 break;
9186 }
9187 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL);
9188 if ((att2 == NULL((void*)0)) ||
9189 (*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET0x00000010UL)) {
9190 if (att2)
9191 sftk_FreeAttribute(att2);
9192 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9193 break;
9194 }
9195 sftk_FreeAttribute(att2);
9196 if (keyType != CKK_GENERIC_SECRET0x00000010UL) {
9197 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9198 break;
9199 }
9200 if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH48)) {
9201 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9202 break;
9203 }
9204
9205 /* Do the key derivation */
9206 pms.data = (unsigned char *)att->attrib.pValue;
9207 pms.len = att->attrib.ulValueLen;
9208 seed.data = ems_params->pSessionHash;
9209 seed.len = ems_params->ulSessionHashLen;
9210 master.data = key_block;
9211 master.len = SSL3_MASTER_SECRET_LENGTH48;
9212 if (ems_params->prfHashMechanism == CKM_TLS_PRF0x00000378UL) {
9213 /*
9214 * In this case, the session hash is the concatenation of SHA-1
9215 * and MD5, so it should be 36 bytes long.
9216 */
9217 if (seed.len != MD5_LENGTH16 + SHA1_LENGTH20) {
9218 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9219 break;
9220 }
9221
9222 status = TLS_PRF(&pms, "extended master secret",
9223 &seed, &master, isFIPS);
9224 } else {
9225 const SECHashObject *hashObj;
9226
9227 tlsPrfHash = sftk_GetHashTypeFromMechanism(ems_params->prfHashMechanism);
9228 if (tlsPrfHash == HASH_AlgNULL) {
9229 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9230 break;
9231 }
9232
9233 hashObj = HASH_GetRawHashObject(tlsPrfHash);
9234 if (seed.len != hashObj->length) {
9235 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9236 break;
9237 }
9238
9239 status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret",
9240 &seed, &master, isFIPS);
9241 }
9242 if (status != SECSuccess) {
9243 crv = CKR_FUNCTION_FAILED0x00000006UL;
9244 break;
9245 }
9246
9247 /* Reflect the version if required */
9248 if (ems_params->pVersion) {
9249 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
9250 rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue;
9251 /* don't leak more key material than necessary for SSL to work */
9252 if ((sessKey == NULL((void*)0)) || sessKey->wasDerived) {
9253 ems_params->pVersion->major = 0xff;
9254 ems_params->pVersion->minor = 0xff;
9255 } else {
9256 ems_params->pVersion->major = rsa_pms->client_version[0];
9257 ems_params->pVersion->minor = rsa_pms->client_version[1];
9258 }
9259 }
9260
9261 /* Store the results */
9262 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block,
9263 SSL3_MASTER_SECRET_LENGTH48);
9264 PORT_Memsetmemset(key_block, 0, sizeof key_block);
9265 break;
9266 }
9267
9268 case CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL:
9269 case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 23):
9270 case CKM_TLS_KEY_AND_MAC_DERIVE0x00000376UL:
9271 case CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372UL: {
9272 CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
9273 CK_SSL3_KEY_MAT_OUT *ssl3_keys_out;
9274 CK_ULONG effKeySize;
9275 unsigned int block_needed;
9276 unsigned char srcrdata[SSL3_RANDOM_LENGTH32 * 2];
9277
9278 if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL) {
9279 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_KEY_MAT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_TLS12_KEY_MAT_PARAMS))
) {
9280 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9281 break;
9282 }
9283 CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
9284 (CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter;
9285 tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
9286 if (tlsPrfHash == HASH_AlgNULL) {
9287 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9288 break;
9289 }
9290 } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 23)) {
9291 tlsPrfHash = HASH_AlgSHA256;
9292 }
9293
9294 if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372UL) {
9295 isTLS = PR_TRUE1;
9296 }
9297
9298 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9299 if (crv != CKR_OK0x00000000UL)
9300 break;
9301
9302 if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH48) {
9303 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9304 break;
9305 }
9306 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL);
9307 if ((att2 == NULL((void*)0)) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
9308 CKK_GENERIC_SECRET0x00000010UL)) {
9309 if (att2)
9310 sftk_FreeAttribute(att2);
9311 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9312 break;
9313 }
9314 sftk_FreeAttribute(att2);
9315 md5 = MD5_NewContext();
9316 if (md5 == NULL((void*)0)) {
9317 crv = CKR_HOST_MEMORY0x00000002UL;
9318 break;
9319 }
9320 sha = SHA1_NewContext();
9321 if (sha == NULL((void*)0)) {
9322 MD5_DestroyContext(md5, PR_TRUE1);
9323 crv = CKR_HOST_MEMORY0x00000002UL;
9324 break;
9325 }
9326
9327 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_SSL3_KEY_MAT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_SSL3_KEY_MAT_PARAMS))
) {
9328 MD5_DestroyContext(md5, PR_TRUE1);
9329 SHA1_DestroyContext(sha, PR_TRUE1);
9330 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9331 break;
9332 }
9333 ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter;
9334
9335 PORT_Memcpymemcpy(srcrdata,
9336 ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH32);
9337 PORT_Memcpymemcpy(srcrdata + SSL3_RANDOM_LENGTH32,
9338 ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH32);
9339
9340 /*
9341 * clear out our returned keys so we can recover on failure
9342 */
9343 ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
9344 ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE0;
9345 ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE0;
9346 ssl3_keys_out->hClientKey = CK_INVALID_HANDLE0;
9347 ssl3_keys_out->hServerKey = CK_INVALID_HANDLE0;
9348
9349 /*
9350 * How much key material do we need?
9351 */
9352 macSize = ssl3_keys->ulMacSizeInBits / 8;
9353 effKeySize = ssl3_keys->ulKeySizeInBits / 8;
9354 IVSize = ssl3_keys->ulIVSizeInBits / 8;
9355 if (keySize == 0) {
9356 effKeySize = keySize;
9357 }
9358
9359 /* bIsExport must be false. */
9360 if (ssl3_keys->bIsExport) {
9361 MD5_DestroyContext(md5, PR_TRUE1);
9362 SHA1_DestroyContext(sha, PR_TRUE1);
9363 PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata);
9364 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9365 break;
9366 }
9367
9368 /* Compute the amount of key material consumed using keySize
9369 * (from CKA_VALUE_LEN, which is what actually indexes key_block
9370 * below), not effKeySize. Bound each term first to prevent
9371 * integer overflow in the sum, then reject if the total exceeds
9372 * the buffer -- clamping block_needed would not bound the later
9373 * indexing and would permit a stack OOB read. */
9374 (void)effKeySize;
9375 if (macSize > sizeof key_block || IVSize > sizeof key_block ||
9376 keySize > sizeof key_block ||
9377 2 * (macSize + keySize + IVSize) > sizeof key_block) {
9378 MD5_DestroyContext(md5, PR_TRUE1);
9379 SHA1_DestroyContext(sha, PR_TRUE1);
9380 PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata);
9381 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9382 break;
9383 }
9384 block_needed = 2 * (macSize + keySize + IVSize);
9385
9386 /*
9387 * generate the key material: This looks amazingly similar to the
9388 * PMS code, and is clearly crying out for a function to provide it.
9389 */
9390 if (isTLS) {
9391 SECStatus status;
9392 SECItem srcr = { siBuffer, NULL((void*)0), 0 };
9393 SECItem keyblk = { siBuffer, NULL((void*)0), 0 };
9394 SECItem master = { siBuffer, NULL((void*)0), 0 };
9395
9396 srcr.data = srcrdata;
9397 srcr.len = sizeof srcrdata;
9398 keyblk.data = key_block;
9399 keyblk.len = block_needed;
9400 master.data = (unsigned char *)att->attrib.pValue;
9401 master.len = att->attrib.ulValueLen;
9402
9403 if (tlsPrfHash != HASH_AlgNULL) {
9404 status = TLS_P_hash(tlsPrfHash, &master, "key expansion",
9405 &srcr, &keyblk, isFIPS);
9406 } else {
9407 status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
9408 isFIPS);
9409 }
9410 if (status != SECSuccess) {
9411 goto key_and_mac_derive_fail;
9412 }
9413 } else {
9414 unsigned int block_bytes = 0;
9415 /* key_block =
9416 * MD5(master_secret + SHA('A' + master_secret +
9417 * ServerHello.random + ClientHello.random)) +
9418 * MD5(master_secret + SHA('BB' + master_secret +
9419 * ServerHello.random + ClientHello.random)) +
9420 * MD5(master_secret + SHA('CCC' + master_secret +
9421 * ServerHello.random + ClientHello.random)) +
9422 * [...];
9423 */
9424 for (i = 0; i < NUM_MIXERS9 && block_bytes < block_needed; i++) {
9425 SHA1_Begin(sha);
9426 SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i]));
9427 SHA1_Update(sha, (const unsigned char *)att->attrib.pValue,
9428 att->attrib.ulValueLen);
9429 SHA1_Update(sha, srcrdata, sizeof srcrdata);
9430 SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH20);
9431 PORT_Assert(outLen == SHA1_LENGTH)((outLen == 20) ? ((void)0) : PR_Assert("outLen == SHA1_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9431
))
;
9432 MD5_Begin(md5);
9433 MD5_Update(md5, (const unsigned char *)att->attrib.pValue,
9434 att->attrib.ulValueLen);
9435 MD5_Update(md5, sha_out, outLen);
9436 MD5_End(md5, &key_block[i * MD5_LENGTH16], &outLen, MD5_LENGTH16);
9437 PORT_Assert(outLen == MD5_LENGTH)((outLen == 16) ? ((void)0) : PR_Assert("outLen == MD5_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9437
))
;
9438 block_bytes += outLen;
9439 }
9440 PORT_Memsetmemset(sha_out, 0, sizeof sha_out);
9441 }
9442
9443 /*
9444 * Put the key material where it goes.
9445 */
9446 i = 0; /* now shows how much consumed */
9447
9448 /*
9449 * The key_block is partitioned as follows:
9450 * client_write_MAC_secret[CipherSpec.hash_size]
9451 */
9452 crv = sftk_buildSSLKey(hSession, key, PR_TRUE1, &key_block[i], macSize,
9453 &ssl3_keys_out->hClientMacSecret);
9454 if (crv != CKR_OK0x00000000UL)
9455 goto key_and_mac_derive_fail;
9456
9457 i += macSize;
9458
9459 /*
9460 * server_write_MAC_secret[CipherSpec.hash_size]
9461 */
9462 crv = sftk_buildSSLKey(hSession, key, PR_TRUE1, &key_block[i], macSize,
9463 &ssl3_keys_out->hServerMacSecret);
9464 if (crv != CKR_OK0x00000000UL) {
9465 goto key_and_mac_derive_fail;
9466 }
9467 i += macSize;
9468
9469 if (keySize) {
9470 /*
9471 ** Generate Domestic write keys and IVs.
9472 ** client_write_key[CipherSpec.key_material]
9473 */
9474 crv = sftk_buildSSLKey(hSession, key, PR_FALSE0, &key_block[i],
9475 keySize, &ssl3_keys_out->hClientKey);
9476 if (crv != CKR_OK0x00000000UL) {
9477 goto key_and_mac_derive_fail;
9478 }
9479 i += keySize;
9480
9481 /*
9482 ** server_write_key[CipherSpec.key_material]
9483 */
9484 crv = sftk_buildSSLKey(hSession, key, PR_FALSE0, &key_block[i],
9485 keySize, &ssl3_keys_out->hServerKey);
9486 if (crv != CKR_OK0x00000000UL) {
9487 goto key_and_mac_derive_fail;
9488 }
9489 i += keySize;
9490
9491 /*
9492 ** client_write_IV[CipherSpec.IV_size]
9493 */
9494 if (IVSize > 0) {
9495 PORT_Memcpymemcpy(ssl3_keys_out->pIVClient,
9496 &key_block[i], IVSize);
9497 i += IVSize;
9498 }
9499
9500 /*
9501 ** server_write_IV[CipherSpec.IV_size]
9502 */
9503 if (IVSize > 0) {
9504 PORT_Memcpymemcpy(ssl3_keys_out->pIVServer,
9505 &key_block[i], IVSize);
9506 i += IVSize;
9507 }
9508 PORT_Assert(i <= sizeof key_block)((i <= sizeof key_block) ? ((void)0) : PR_Assert("i <= sizeof key_block"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9508
))
;
9509 }
9510
9511 crv = CKR_OK0x00000000UL;
9512
9513 if (0) {
9514 key_and_mac_derive_fail:
9515 if (crv == CKR_OK0x00000000UL)
9516 crv = CKR_FUNCTION_FAILED0x00000006UL;
9517 sftk_freeSSLKeys(hSession, ssl3_keys_out);
9518 }
9519 PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata);
9520 PORT_Memsetmemset(key_block, 0, sizeof key_block);
9521 MD5_DestroyContext(md5, PR_TRUE1);
9522 SHA1_DestroyContext(sha, PR_TRUE1);
9523 sftk_FreeObject(key);
9524 key = NULL((void*)0);
9525 break;
9526 }
9527
9528 case CKM_DES3_ECB_ENCRYPT_DATA0x00001102UL:
9529 case CKM_DES3_CBC_ENCRYPT_DATA0x00001103UL: {
9530 void *cipherInfo;
9531 unsigned char des3key[MAX_DES3_KEY_SIZE24];
9532 CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr;
9533 int mode;
9534 unsigned char *iv;
9535 unsigned char *data;
9536 CK_ULONG len;
9537
9538 if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA0x00001102UL) {
9539 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9540 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9541 break;
9542 }
9543 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
9544 pMechanism->pParameter;
9545 mode = NSS_DES_EDE32;
9546 iv = NULL((void*)0);
9547 data = stringPtr->pData;
9548 len = stringPtr->ulLen;
9549 } else {
9550 mode = NSS_DES_EDE3_CBC3;
9551 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_DES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_DES_CBC_ENCRYPT_DATA_PARAMS))
) {
9552 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9553 break;
9554 }
9555 desEncryptPtr =
9556 (CK_DES_CBC_ENCRYPT_DATA_PARAMS *)
9557 pMechanism->pParameter;
9558 iv = desEncryptPtr->iv;
9559 data = desEncryptPtr->pData;
9560 len = desEncryptPtr->length;
9561 }
9562 if (att->attrib.ulValueLen == 16) {
9563 PORT_Memcpymemcpy(des3key, att->attrib.pValue, 16);
9564 PORT_Memcpymemcpy(des3key + 16, des3key, 8);
9565 } else if (att->attrib.ulValueLen == 24) {
9566 PORT_Memcpymemcpy(des3key, att->attrib.pValue, 24);
9567 } else {
9568 crv = CKR_KEY_SIZE_RANGE0x00000062UL;
9569 break;
9570 }
9571 cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE1);
9572 PORT_Memsetmemset(des3key, 0, 24);
9573 if (cipherInfo == NULL((void*)0)) {
9574 crv = CKR_HOST_MEMORY0x00000002UL;
9575 break;
9576 }
9577 crv = sftk_DeriveEncrypt(SFTKCipher_DES_Encrypt,
9578 cipherInfo, 8, key, keySize,
9579 data, len);
9580 DES_DestroyContext(cipherInfo, PR_TRUE1);
9581 break;
9582 }
9583
9584 case CKM_AES_ECB_ENCRYPT_DATA0x00001104UL:
9585 case CKM_AES_CBC_ENCRYPT_DATA0x00001105UL: {
9586 void *cipherInfo;
9587 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
9588 int mode;
9589 unsigned char *iv;
9590 unsigned char *data;
9591 CK_ULONG len;
9592
9593 if (mechanism == CKM_AES_ECB_ENCRYPT_DATA0x00001104UL) {
9594 mode = NSS_AES0;
9595 iv = NULL((void*)0);
9596 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9597 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9598 break;
9599 }
9600 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9601 data = stringPtr->pData;
9602 len = stringPtr->ulLen;
9603 } else {
9604 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))
) {
9605 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9606 break;
9607 }
9608 aesEncryptPtr =
9609 (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter;
9610 mode = NSS_AES_CBC1;
9611 iv = aesEncryptPtr->iv;
9612 data = aesEncryptPtr->pData;
9613 len = aesEncryptPtr->length;
9614 }
9615
9616 cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue,
9617 iv, mode, PR_TRUE1,
9618 att->attrib.ulValueLen, 16);
9619 if (cipherInfo == NULL((void*)0)) {
9620 crv = CKR_HOST_MEMORY0x00000002UL;
9621 break;
9622 }
9623 crv = sftk_DeriveEncrypt(SFTKCipher_AES_Encrypt,
9624 cipherInfo, 16, key, keySize,
9625 data, len);
9626 AES_DestroyContext(cipherInfo, PR_TRUE1);
9627 break;
9628 }
9629
9630 case CKM_CAMELLIA_ECB_ENCRYPT_DATA0x00000556UL:
9631 case CKM_CAMELLIA_CBC_ENCRYPT_DATA0x00000557UL: {
9632 void *cipherInfo;
9633 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
9634 int mode;
9635 unsigned char *iv;
9636 unsigned char *data;
9637 CK_ULONG len;
9638
9639 if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA0x00000556UL) {
9640 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9641 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9642 break;
9643 }
9644 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
9645 pMechanism->pParameter;
9646 aesEncryptPtr = NULL((void*)0);
9647 mode = NSS_CAMELLIA0;
9648 data = stringPtr->pData;
9649 len = stringPtr->ulLen;
9650 iv = NULL((void*)0);
9651 } else {
9652 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))
) {
9653 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9654 break;
9655 }
9656 stringPtr = NULL((void*)0);
9657 aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
9658 pMechanism->pParameter;
9659 mode = NSS_CAMELLIA_CBC1;
9660 iv = aesEncryptPtr->iv;
9661 data = aesEncryptPtr->pData;
9662 len = aesEncryptPtr->length;
9663 }
9664
9665 cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue,
9666 iv, mode, PR_TRUE1,
9667 att->attrib.ulValueLen);
9668 if (cipherInfo == NULL((void*)0)) {
9669 crv = CKR_HOST_MEMORY0x00000002UL;
9670 break;
9671 }
9672 crv = sftk_DeriveEncrypt(SFTKCipher_Camellia_Encrypt,
9673 cipherInfo, 16, key, keySize,
9674 data, len);
9675 Camellia_DestroyContext(cipherInfo, PR_TRUE1);
9676 break;
9677 }
9678
9679#ifndef NSS_DISABLE_DEPRECATED_SEED
9680 case CKM_SEED_ECB_ENCRYPT_DATA0x00000656UL:
9681 case CKM_SEED_CBC_ENCRYPT_DATA0x00000657UL: {
9682 void *cipherInfo;
9683 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
9684 int mode;
9685 unsigned char *iv;
9686 unsigned char *data;
9687 CK_ULONG len;
9688
9689 if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA0x00000656UL) {
9690 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9691 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9692 break;
9693 }
9694 mode = NSS_SEED0;
9695 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
9696 pMechanism->pParameter;
9697 aesEncryptPtr = NULL((void*)0);
9698 data = stringPtr->pData;
9699 len = stringPtr->ulLen;
9700 iv = NULL((void*)0);
9701 } else {
9702 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))
) {
9703 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9704 break;
9705 }
9706 mode = NSS_SEED_CBC1;
9707 aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
9708 pMechanism->pParameter;
9709 iv = aesEncryptPtr->iv;
9710 data = aesEncryptPtr->pData;
9711 len = aesEncryptPtr->length;
9712 }
9713
9714 cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue,
9715 iv, mode, PR_TRUE1);
9716 if (cipherInfo == NULL((void*)0)) {
9717 crv = CKR_HOST_MEMORY0x00000002UL;
9718 break;
9719 }
9720 crv = sftk_DeriveEncrypt(SFTKCipher_SEED_Encrypt,
9721 cipherInfo, 16, key, keySize,
9722 data, len);
9723 SEED_DestroyContext(cipherInfo, PR_TRUE1);
9724 break;
9725 }
9726#endif /* NSS_DISABLE_DEPRECATED_SEED */
9727
9728 case CKM_CONCATENATE_BASE_AND_KEY0x00000360UL: {
9729 SFTKObject *paramKey;
9730
9731 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9732 if (crv != CKR_OK0x00000000UL)
9733 break;
9734
9735 session = sftk_SessionFromHandle(hSession);
9736 if (session == NULL((void*)0)) {
9737 crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
9738 break;
9739 }
9740
9741 paramKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *)
9742 pMechanism->pParameter,
9743 session);
9744 sftk_FreeSession(session);
9745 if (paramKey == NULL((void*)0)) {
9746 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
9747 break;
9748 }
9749
9750 if (sftk_isTrue(paramKey, CKA_SENSITIVE0x00000103UL)) {
9751 crv = sftk_forceAttribute(key, CKA_SENSITIVE0x00000103UL, &cktrue,
9752 sizeof(CK_BBOOL));
9753 if (crv != CKR_OK0x00000000UL) {
9754 sftk_FreeObject(paramKey);
9755 break;
9756 }
9757 }
9758
9759 if (sftk_hasAttribute(paramKey, CKA_EXTRACTABLE0x00000162UL) && !sftk_isTrue(paramKey, CKA_EXTRACTABLE0x00000162UL)) {
9760 crv = sftk_forceAttribute(key, CKA_EXTRACTABLE0x00000162UL, &ckfalse, sizeof(CK_BBOOL));
9761 if (crv != CKR_OK0x00000000UL) {
9762 sftk_FreeObject(paramKey);
9763 break;
9764 }
9765 }
9766
9767 att2 = sftk_FindAttribute(paramKey, CKA_VALUE0x00000011UL);
9768 if (att2 == NULL((void*)0)) {
9769 sftk_FreeObject(paramKey);
9770 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
9771 break;
9772 }
9773 tmpKeySize = att->attrib.ulValueLen + att2->attrib.ulValueLen;
9774 if (keySize == 0)
9775 keySize = tmpKeySize;
9776 if (keySize > tmpKeySize) {
9777 sftk_FreeAttribute(att2);
9778 sftk_FreeObject(paramKey);
9779 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9780 break;
9781 }
9782 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize);
9783 if (buf == NULL((void*)0)) {
9784 sftk_FreeAttribute(att2);
9785 sftk_FreeObject(paramKey);
9786 crv = CKR_HOST_MEMORY0x00000002UL;
9787 break;
9788 }
9789
9790 PORT_Memcpymemcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
9791 PORT_Memcpymemcpy(buf + att->attrib.ulValueLen,
9792 att2->attrib.pValue, att2->attrib.ulValueLen);
9793
9794 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9795 PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize);
9796 /* preserve the source of the original base key */
9797 key->source = sourceKey->source;
9798
9799 /* make sure this is fully fips approved, and mark it
9800 * unapproved if not */
9801 if (sftk_hasFIPS(key)) {
9802 sftk_setFIPS(key, sftk_hasFIPS(paramKey));
9803 }
9804 sftk_FreeAttribute(att2);
9805 sftk_FreeObject(paramKey);
9806 break;
9807 }
9808
9809 case CKM_CONCATENATE_BASE_AND_DATA0x00000362UL:
9810 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9811 if (crv != CKR_OK0x00000000UL)
9812 break;
9813
9814 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9815 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9816 break;
9817 }
9818 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9819 tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
9820 if (keySize == 0)
9821 keySize = tmpKeySize;
9822 if (keySize > tmpKeySize) {
9823 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9824 break;
9825 }
9826 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize);
9827 if (buf == NULL((void*)0)) {
9828 crv = CKR_HOST_MEMORY0x00000002UL;
9829 break;
9830 }
9831
9832 PORT_Memcpymemcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
9833 PORT_Memcpymemcpy(buf + att->attrib.ulValueLen, stringPtr->pData,
9834 stringPtr->ulLen);
9835
9836 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9837 PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize);
9838 break;
9839 case CKM_CONCATENATE_DATA_AND_BASE0x00000363UL:
9840 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9841 if (crv != CKR_OK0x00000000UL)
9842 break;
9843
9844 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9845 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9846 break;
9847 }
9848 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9849 tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
9850 if (keySize == 0)
9851 keySize = tmpKeySize;
9852 if (keySize > tmpKeySize) {
9853 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9854 break;
9855 }
9856 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize);
9857 if (buf == NULL((void*)0)) {
9858 crv = CKR_HOST_MEMORY0x00000002UL;
9859 break;
9860 }
9861
9862 PORT_Memcpymemcpy(buf, stringPtr->pData, stringPtr->ulLen);
9863 PORT_Memcpymemcpy(buf + stringPtr->ulLen, att->attrib.pValue,
9864 att->attrib.ulValueLen);
9865
9866 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9867 PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize);
9868 break;
9869 case CKM_XOR_BASE_AND_DATA0x00000364UL:
9870 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9871 if (crv != CKR_OK0x00000000UL)
9872 break;
9873
9874 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9875 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9876 break;
9877 }
9878 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9879 tmpKeySize = PR_MIN(att->attrib.ulValueLen, stringPtr->ulLen)((att->attrib.ulValueLen) < (stringPtr->ulLen) ? (att
->attrib.ulValueLen) : (stringPtr->ulLen))
;
9880 if (keySize == 0)
9881 keySize = tmpKeySize;
9882 if (keySize > tmpKeySize) {
9883 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9884 break;
9885 }
9886 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(keySize);
9887 if (buf == NULL((void*)0)) {
9888 crv = CKR_HOST_MEMORY0x00000002UL;
9889 break;
9890 }
9891
9892 PORT_Memcpymemcpy(buf, att->attrib.pValue, keySize);
9893 for (i = 0; i < (int)keySize; i++) {
9894 buf[i] ^= stringPtr->pData[i];
9895 }
9896
9897 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9898 PORT_ZFreePORT_ZFree_Util(buf, keySize);
9899 break;
9900
9901 case CKM_EXTRACT_KEY_FROM_KEY0x00000365UL: {
9902 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_EXTRACT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_EXTRACT_PARAMS))
) {
9903 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9904 break;
9905 }
9906 /* the following assumes 8 bits per byte */
9907 CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
9908 CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */
9909 CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */
9910
9911 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9912 if (crv != CKR_OK0x00000000UL)
9913 break;
9914
9915 if (keySize == 0) {
9916 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
9917 break;
9918 }
9919 /* make sure we have enough bits in the original key */
9920 if (att->attrib.ulValueLen <
9921 (offset + keySize + ((shift != 0) ? 1 : 0))) {
9922 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9923 break;
9924 }
9925 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(keySize);
9926 if (buf == NULL((void*)0)) {
9927 crv = CKR_HOST_MEMORY0x00000002UL;
9928 break;
9929 }
9930
9931 /* copy the bits we need into the new key */
9932 for (i = 0; i < (int)keySize; i++) {
9933 unsigned char *value =
9934 ((unsigned char *)att->attrib.pValue) + offset + i;
9935 if (shift) {
9936 buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift));
9937 } else {
9938 buf[i] = value[0];
9939 }
9940 }
9941
9942 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9943 PORT_ZFreePORT_ZFree_Util(buf, keySize);
9944 break;
9945 }
9946 case CKM_MD2_KEY_DERIVATION0x00000391UL:
9947 if (keySize == 0)
9948 keySize = MD2_LENGTH16;
9949 if (keySize > MD2_LENGTH16) {
9950 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9951 break;
9952 }
9953 /* now allocate the hash contexts */
9954 md2 = MD2_NewContext();
9955 if (md2 == NULL((void*)0)) {
9956 crv = CKR_HOST_MEMORY0x00000002UL;
9957 break;
9958 }
9959 MD2_Begin(md2);
9960 MD2_Update(md2, (const unsigned char *)att->attrib.pValue,
9961 att->attrib.ulValueLen);
9962 MD2_End(md2, key_block, &outLen, MD2_LENGTH16);
9963 MD2_DestroyContext(md2, PR_TRUE1);
9964
9965 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, keySize);
9966 PORT_Memsetmemset(key_block, 0, MD2_LENGTH16);
9967 break;
9968#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;
\
9969 case CKM_##hash##_KEY_DERIVATION: \
9970 if (keySize == 0) \
9971 keySize = hash##_LENGTH; \
9972 if (keySize > hash##_LENGTH) { \
9973 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; \
9974 break; \
9975 } \
9976 hash##_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, \
9977 att->attrib.ulValueLen); \
9978 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, keySize); \
9979 PORT_Memsetmemset(key_block, 0, hash##_LENGTH); \
9980 break;
9981 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;
9982 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;
9983 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;
9984 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;
9985 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;
9986 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;
9987 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;
9988 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;
9989 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;
9990 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;
9991
9992 case CKM_DH_PKCS_DERIVE0x00000021UL: {
9993 SECItem derived, dhPublic;
9994 SECItem dhPrime, dhValue;
9995 const SECItem *subPrime;
9996 /* sourceKey - values for the local existing low key */
9997 /* get prime and value attributes */
9998 crv = sftk_Attribute2SecItem(NULL((void*)0), &dhPrime, sourceKey, CKA_PRIME0x00000130UL);
9999 if (crv != CKR_OK0x00000000UL)
10000 break;
10001
10002 dhPublic.data = pMechanism->pParameter;
10003 dhPublic.len = pMechanism->ulParameterLen;
10004
10005 /* if the prime is an approved prime, we can skip all the other
10006 * checks. */
10007 subPrime = sftk_VerifyDH_Prime(&dhPrime, NULL((void*)0), isFIPS);
10008 if (subPrime == NULL((void*)0)) {
10009 SECItem dhSubPrime;
10010 /* If the caller set the subprime value, it means that
10011 * either the caller knows the subprime value and wants us
10012 * to validate the key against the subprime, or that the
10013 * caller wants us to verify that the prime is a safe prime
10014 * by passing in subprime = (prime-1)/2 */
10015 dhSubPrime.data = NULL((void*)0);
10016 dhSubPrime.len = 0;
10017 crv = sftk_Attribute2SecItem(NULL((void*)0), &dhSubPrime,
10018 sourceKey, CKA_SUBPRIME0x00000131UL);
10019 /* we ignore the value of crv here, We treat a valid
10020 * return of len = 0 and a failure to find a subrime the same
10021 * NOTE: we free the subprime in both cases depending on
10022 * PORT_Free of NULL to be a noop */
10023 if (dhSubPrime.len != 0) {
10024 PRBool isSafe = PR_FALSE0;
10025
10026 /* Callers can set dhSubPrime to q=(p-1)/2 to force
10027 * checks for safe primes. If so we only need to check
10028 * q and p for primality and skip the group test. */
10029 rv = sftk_IsSafePrime(&dhPrime, &dhSubPrime, &isSafe);
10030 if (rv != SECSuccess) {
10031 /* either p or q was even and therefore not prime,
10032 * we can stop processing here and fail now */
10033 crv = CKR_ARGUMENTS_BAD0x00000007UL;
10034 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10035 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
10036 break;
10037 }
10038
10039 /* first make sure the primes are really prime */
10040 if (!KEA_PrimeCheck(&dhPrime)) {
10041 crv = CKR_ARGUMENTS_BAD0x00000007UL;
10042 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10043 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
10044 break;
10045 }
10046 if (!KEA_PrimeCheck(&dhSubPrime)) {
10047 crv = CKR_ARGUMENTS_BAD0x00000007UL;
10048 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10049 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
10050 break;
10051 }
10052 if (isFIPS || !isSafe) {
10053 /* With safe primes, there is only one other small
10054 * subgroup. As long as y isn't 0, 1, or -1 mod p,
10055 * any other y is safe. Only do the full check for
10056 * non-safe primes, except in FIPS mode we need
10057 * to do this check on all primes in which
10058 * we receive the subprime value */
10059 if (!KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime)) {
10060 crv = CKR_ARGUMENTS_BAD0x00000007UL;
10061 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10062 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
10063 break;
10064 }
10065 }
10066 } else if (isFIPS) {
10067 /* In FIPS mode we only accept approved primes, or
10068 * primes with the full subprime value */
10069 crv = CKR_ARGUMENTS_BAD0x00000007UL;
10070 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10071 break;
10072 }
10073 /* checks are complete, no need for the subPrime any longer */
10074 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
10075 }
10076
10077 /* now that the prime is validated, get the private value */
10078 crv = sftk_Attribute2SecItem(NULL((void*)0), &dhValue, sourceKey, CKA_VALUE0x00000011UL);
10079 if (crv != CKR_OK0x00000000UL) {
10080 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10081 break;
10082 }
10083
10084 /* calculate private value - oct */
10085 rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
10086
10087 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10088 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhValue, PR_FALSE0);
10089
10090 if (rv == SECSuccess) {
10091 key->source = SFTK_SOURCE_KEA;
10092 sftk_forceAttribute(key, CKA_VALUE0x00000011UL, derived.data, derived.len);
10093 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&derived, PR_FALSE0);
10094 crv = CKR_OK0x00000000UL;
10095 } else
10096 crv = CKR_HOST_MEMORY0x00000002UL;
10097
10098 break;
10099 }
10100
10101 case CKM_ECDH1_DERIVE0x00001050UL:
10102 case CKM_ECDH1_COFACTOR_DERIVE0x00001051UL: {
10103 SECItem ecScalar, ecPoint;
10104 SECItem tmp;
10105 PRBool withCofactor = PR_FALSE0;
10106 unsigned char *secret;
10107 unsigned char *keyData = NULL((void*)0);
10108 unsigned int secretlen, pubKeyLen;
10109 CK_ECDH1_DERIVE_PARAMS *mechParams;
10110 NSSLOWKEYPrivateKey *privKey;
10111 PLArenaPool *arena = NULL((void*)0);
10112
10113 /* Check mechanism parameters */
10114 mechParams = (CK_ECDH1_DERIVE_PARAMS *)pMechanism->pParameter;
10115 if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) ||
10116 ((mechParams->kdf == CKD_NULL0x00000001UL) &&
10117 ((mechParams->ulSharedDataLen != 0) ||
10118 (mechParams->pSharedData != NULL((void*)0))))) {
10119 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10120 break;
10121 }
10122
10123 privKey = sftk_GetPrivKey(sourceKey, CKK_EC0x00000003UL, &crv);
10124 if (privKey == NULL((void*)0)) {
10125 break;
10126 }
10127
10128 /* Now we are working with a non-NULL private key */
10129 SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &ecScalar, &privKey->u.ec.privateValue);
10130
10131 ecPoint.data = mechParams->pPublicData;
10132 ecPoint.len = mechParams->ulPublicDataLen;
10133
10134 pubKeyLen = EC_GetPointSize(&privKey->u.ec.ecParams);
10135
10136 /* if the len is too large, might be an encoded point */
10137 if (ecPoint.len > pubKeyLen) {
10138 SECItem newPoint;
10139
10140 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
10141 if (arena == NULL((void*)0)) {
10142 goto ec_loser;
10143 }
10144
10145 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, &newPoint,
10146 SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util,
10147 &ecPoint);
10148 if (rv != SECSuccess) {
10149 goto ec_loser;
10150 }
10151 ecPoint = newPoint;
10152 }
10153
10154 if (mechanism == CKM_ECDH1_COFACTOR_DERIVE0x00001051UL) {
10155 withCofactor = PR_TRUE1;
10156 }
10157
10158 rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar,
10159 withCofactor, &tmp);
10160 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecScalar, PR_FALSE0);
10161 ecScalar.data = NULL((void*)0);
10162 if (privKey != sourceKey->objectInfo) {
10163 nsslowkey_DestroyPrivateKey(privKey);
10164 privKey = NULL((void*)0);
10165 }
10166 if (arena) {
10167 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
10168 arena = NULL((void*)0);
10169 }
10170
10171 if (rv != SECSuccess) {
10172 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
10173 break;
10174 }
10175
10176 /*
10177 * apply the kdf function.
10178 */
10179 if (mechParams->kdf == CKD_NULL0x00000001UL) {
10180 /*
10181 * tmp is the raw data created by ECDH_Derive,
10182 * secret and secretlen are the values we will
10183 * eventually pass as our generated key.
10184 */
10185 secret = tmp.data;
10186 secretlen = tmp.len;
10187 } else {
10188 secretlen = keySize;
10189 sftk_setFIPS(key, PR_FALSE0);
10190 crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
10191 &tmp, mechParams->pSharedData,
10192 mechParams->ulSharedDataLen, mechParams->kdf);
10193 PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len);
10194 if (crv != CKR_OK0x00000000UL) {
10195 break;
10196 }
10197 tmp.data = secret;
10198 tmp.len = secretlen;
10199 }
10200
10201 /*
10202 * if keySize is supplied, then we are generating a key of a specific
10203 * length. This is done by taking the least significant 'keySize'
10204 * bytes from the unsigned value calculated by ECDH. Note: this may
10205 * mean padding temp with extra leading zeros from what ECDH_Derive
10206 * already returned (which itself may contain leading zeros).
10207 */
10208 if (keySize) {
10209 if (secretlen < keySize) {
10210 keyData = PORT_ZAllocPORT_ZAlloc_Util(keySize);
10211 if (!keyData) {
10212 PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len);
10213 crv = CKR_HOST_MEMORY0x00000002UL;
10214 break;
10215 }
10216 PORT_Memcpymemcpy(&keyData[keySize - secretlen], secret, secretlen);
10217 secret = keyData;
10218 } else {
10219 secret += (secretlen - keySize);
10220 }
10221 secretlen = keySize;
10222 }
10223 key->source = SFTK_SOURCE_KEA;
10224
10225 sftk_forceAttribute(key, CKA_VALUE0x00000011UL, secret, secretlen);
10226 PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len);
10227 if (keyData) {
10228 PORT_ZFreePORT_ZFree_Util(keyData, keySize);
10229 }
10230 break;
10231
10232 ec_loser:
10233 crv = CKR_ARGUMENTS_BAD0x00000007UL;
10234 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecScalar, PR_FALSE0);
10235 if (privKey != sourceKey->objectInfo)
10236 nsslowkey_DestroyPrivateKey(privKey);
10237 if (arena) {
10238 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
10239 }
10240 break;
10241 }
10242 /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */
10243 case CKM_NSS_HKDF_SHA1((0x80000000UL | 0x4E534350) + 3):
10244 hashMech = CKM_SHA_10x00000220UL;
10245 goto hkdf;
10246 case CKM_NSS_HKDF_SHA256((0x80000000UL | 0x4E534350) + 4):
10247 hashMech = CKM_SHA2560x00000250UL;
10248 goto hkdf;
10249 case CKM_NSS_HKDF_SHA384((0x80000000UL | 0x4E534350) + 5):
10250 hashMech = CKM_SHA3840x00000260UL;
10251 goto hkdf;
10252 case CKM_NSS_HKDF_SHA512((0x80000000UL | 0x4E534350) + 6):
10253 hashMech = CKM_SHA5120x00000270UL;
10254 goto hkdf;
10255 hkdf: {
10256 const CK_NSS_HKDFParams *params =
10257 (const CK_NSS_HKDFParams *)pMechanism->pParameter;
10258 CK_HKDF_PARAMS hkdfParams;
10259
10260 if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams)) {
10261 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10262 break;
10263 }
10264 hkdfParams.bExtract = params->bExtract;
10265 hkdfParams.bExpand = params->bExpand;
10266 if (params->pSalt) {
10267 hkdfParams.ulSaltType = CKF_HKDF_SALT_DATA0x00000002UL;
10268 } else {
10269 hkdfParams.ulSaltType = CKF_HKDF_SALT_NULL0x00000001UL;
10270 }
10271 hkdfParams.pSalt = params->pSalt;
10272 hkdfParams.ulSaltLen = params->ulSaltLen;
10273 hkdfParams.hSaltKey = CK_INVALID_HANDLE0;
10274 hkdfParams.pInfo = params->pInfo;
10275 hkdfParams.ulInfoLen = params->ulInfoLen;
10276 hkdfParams.prfHashMechanism = hashMech;
10277
10278 crv = sftk_HKDF(&hkdfParams, hSession, sourceKey,
10279 att->attrib.pValue, att->attrib.ulValueLen,
10280 key, NULL((void*)0), keySize, PR_FALSE0, isFIPS);
10281 } break;
10282 case CKM_HKDF_DERIVE0x0000402aUL:
10283 case CKM_HKDF_DATA0x0000402bUL: /* only difference is the class of key */
10284 if ((pMechanism->pParameter == NULL((void*)0)) ||
10285 (pMechanism->ulParameterLen != sizeof(CK_HKDF_PARAMS))) {
10286 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10287 break;
10288 }
10289 crv = sftk_HKDF((CK_HKDF_PARAMS_PTR)pMechanism->pParameter,
10290 hSession, sourceKey, att->attrib.pValue,
10291 att->attrib.ulValueLen, key, NULL((void*)0), keySize, PR_TRUE1,
10292 isFIPS);
10293 break;
10294 case CKM_NSS_JPAKE_ROUND2_SHA1((0x80000000UL | 0x4E534350) + 11):
10295 hashType = HASH_AlgSHA1;
10296 goto jpake2;
10297 case CKM_NSS_JPAKE_ROUND2_SHA256((0x80000000UL | 0x4E534350) + 12):
10298 hashType = HASH_AlgSHA256;
10299 goto jpake2;
10300 case CKM_NSS_JPAKE_ROUND2_SHA384((0x80000000UL | 0x4E534350) + 13):
10301 hashType = HASH_AlgSHA384;
10302 goto jpake2;
10303 case CKM_NSS_JPAKE_ROUND2_SHA512((0x80000000UL | 0x4E534350) + 14):
10304 hashType = HASH_AlgSHA512;
10305 goto jpake2;
10306 jpake2:
10307 if (pMechanism->pParameter == NULL((void*)0) ||
10308 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params))
10309 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10310 if (crv == CKR_OK0x00000000UL && sftk_isTrue(key, CKA_TOKEN0x00000001UL))
10311 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
10312 if (crv == CKR_OK0x00000000UL)
10313 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
10314 if (crv == CKR_OK0x00000000UL)
10315 crv = jpake_Round2(hashType,
10316 (CK_NSS_JPAKERound2Params *)pMechanism->pParameter,
10317 sourceKey, key);
10318 break;
10319
10320 case CKM_NSS_JPAKE_FINAL_SHA1((0x80000000UL | 0x4E534350) + 15):
10321 hashType = HASH_AlgSHA1;
10322 goto jpakeFinal;
10323 case CKM_NSS_JPAKE_FINAL_SHA256((0x80000000UL | 0x4E534350) + 16):
10324 hashType = HASH_AlgSHA256;
10325 goto jpakeFinal;
10326 case CKM_NSS_JPAKE_FINAL_SHA384((0x80000000UL | 0x4E534350) + 17):
10327 hashType = HASH_AlgSHA384;
10328 goto jpakeFinal;
10329 case CKM_NSS_JPAKE_FINAL_SHA512((0x80000000UL | 0x4E534350) + 18):
10330 hashType = HASH_AlgSHA512;
10331 goto jpakeFinal;
10332 jpakeFinal:
10333 if (pMechanism->pParameter == NULL((void*)0) ||
10334 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams))
10335 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10336 /* We purposely do not do the derive sensitivity check; we want to be
10337 able to derive non-sensitive keys while allowing the ROUND1 and
10338 ROUND2 keys to be sensitive (which they always are, since they are
10339 in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE
10340 in the template in order for the resultant keyblock key to be
10341 sensitive.
10342 */
10343 if (crv == CKR_OK0x00000000UL)
10344 crv = jpake_Final(hashType,
10345 (CK_NSS_JPAKEFinalParams *)pMechanism->pParameter,
10346 sourceKey, key);
10347 break;
10348
10349 case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 42): /* fall through */
10350 case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 43): /* fall through */
10351 case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 44): /* fall through */
10352 case CKM_SP800_108_COUNTER_KDF0x000003acUL: /* fall through */
10353 case CKM_SP800_108_FEEDBACK_KDF0x000003adUL: /* fall through */
10354 case CKM_SP800_108_DOUBLE_PIPELINE_KDF0x000003aeUL:
10355 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
10356 if (crv != CKR_OK0x00000000UL) {
10357 break;
10358 }
10359
10360 crv = kbkdf_Dispatch(mechanism, hSession, pMechanism, sourceKey, key, keySize);
10361 break;
10362 default:
10363 crv = CKR_MECHANISM_INVALID0x00000070UL;
10364 }
10365 if (att) {
10366 sftk_FreeAttribute(att);
10367 }
10368 sftk_FreeObject(sourceKey);
10369 if (crv != CKR_OK0x00000000UL) {
10370 if (key)
10371 sftk_FreeObject(key);
10372 return crv;
10373 }
10374
10375 /* link the key object into the list */
10376 if (key) {
10377 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
10378 if (sessKey == NULL((void*)0)) {
10379 sftk_FreeObject(key);
10380 return CKR_DEVICE_ERROR0x00000030UL;
10381 }
10382 sessKey->wasDerived = PR_TRUE1;
10383 session = sftk_SessionFromHandle(hSession);
10384 if (session == NULL((void*)0)) {
10385 sftk_FreeObject(key);
10386 return CKR_HOST_MEMORY0x00000002UL;
10387 }
10388
10389 crv = sftk_handleObject(key, session);
10390 session->lastOpWasFIPS = sftk_hasFIPS(key);
10391 sftk_FreeSession(session);
10392 if (phKey) {
10393 *phKey = key->handle;
10394 }
10395 sftk_FreeObject(key);
10396 }
10397 return crv;
10398}
10399
10400/* NSC_GetFunctionStatus obtains an updated status of a function running
10401 * in parallel with an application. */
10402CK_RV
10403NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
10404{
10405 CHECK_FORK();
10406
10407 return CKR_FUNCTION_NOT_PARALLEL0x00000051UL;
10408}
10409
10410/* NSC_CancelFunction cancels a function running in parallel */
10411CK_RV
10412NSC_CancelFunction(CK_SESSION_HANDLE hSession)
10413{
10414 CHECK_FORK();
10415
10416 return CKR_FUNCTION_NOT_PARALLEL0x00000051UL;
10417}
10418
10419/* NSC_GetOperationState saves the state of the cryptographic
10420 * operation in a session.
10421 * NOTE: This code only works for digest functions for now. eventually need
10422 * to add full flatten/resurect to our state stuff so that all types of state
10423 * can be saved */
10424CK_RV
10425NSC_GetOperationState(CK_SESSION_HANDLE hSession,
10426 CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
10427{
10428 SFTKSessionContext *context;
10429 SFTKSession *session;
10430 CK_RV crv;
10431 CK_ULONG pOSLen = *pulOperationStateLen;
10432
10433 CHECK_FORK();
10434
10435 /* make sure we're legal */
10436 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, &session);
10437 if (crv != CKR_OK0x00000000UL)
10438 return crv;
10439
10440 /* a zero cipherInfoLen signals that this context cannot be serialized */
10441 if (context->cipherInfoLen == 0) {
10442 sftk_FreeSession(session);
10443 return CKR_STATE_UNSAVEABLE0x00000180UL;
10444 }
10445
10446 *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE) + sizeof(SFTKContextType);
10447 if (pOperationState == NULL((void*)0)) {
10448 sftk_FreeSession(session);
10449 return CKR_OK0x00000000UL;
10450 } else {
10451 if (pOSLen < *pulOperationStateLen) {
10452 sftk_FreeSession(session);
10453 return CKR_BUFFER_TOO_SMALL0x00000150UL;
10454 }
10455 }
10456 PORT_Memcpymemcpy(pOperationState, &context->type, sizeof(SFTKContextType));
10457 pOperationState += sizeof(SFTKContextType);
10458 PORT_Memcpymemcpy(pOperationState, &context->currentMech,
10459 sizeof(CK_MECHANISM_TYPE));
10460 pOperationState += sizeof(CK_MECHANISM_TYPE);
10461 PORT_Memcpymemcpy(pOperationState, context->cipherInfo, context->cipherInfoLen);
10462 sftk_FreeSession(session);
10463 return CKR_OK0x00000000UL;
10464}
10465
10466#define sftk_Decrement(stateSize, len)stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize)
- (CK_ULONG)(len)) : 0;
\
10467 stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize) - (CK_ULONG)(len)) : 0;
10468
10469/* NSC_SetOperationState restores the state of the cryptographic
10470 * operation in a session. This is coded like it can restore lots of
10471 * states, but it only works for truly flat cipher structures. */
10472CK_RV
10473NSC_SetOperationState(CK_SESSION_HANDLE hSession,
10474 CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
10475 CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
10476{
10477 SFTKSessionContext *context;
10478 SFTKSession *session;
10479 SFTKContextType type;
10480 CK_MECHANISM mech;
10481 CK_RV crv = CKR_OK0x00000000UL;
10482
10483 CHECK_FORK();
10484
10485 while (ulOperationStateLen != 0) {
10486 /* get what type of state we're dealing with... */
10487 PORT_Memcpymemcpy(&type, pOperationState, sizeof(SFTKContextType));
10488
10489 /* fix up session contexts based on type */
10490 session = sftk_SessionFromHandle(hSession);
10491 if (session == NULL((void*)0))
10492 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
10493 sftk_UninstallContext(session, type);
10494 pOperationState += sizeof(SFTKContextType);
10495 sftk_Decrement(ulOperationStateLen, sizeof(SFTKContextType))ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)(
sizeof(SFTKContextType))) ? ((ulOperationStateLen) - (CK_ULONG
)(sizeof(SFTKContextType))) : 0;
;
10496
10497 /* get the mechanism structure */
10498 PORT_Memcpymemcpy(&mech.mechanism, pOperationState, sizeof(CK_MECHANISM_TYPE));
10499 pOperationState += sizeof(CK_MECHANISM_TYPE);
10500 sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE))ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)(
sizeof(CK_MECHANISM_TYPE))) ? ((ulOperationStateLen) - (CK_ULONG
)(sizeof(CK_MECHANISM_TYPE))) : 0;
;
10501 /* should be filled in... but not necessary for hash */
10502 mech.pParameter = NULL((void*)0);
10503 mech.ulParameterLen = 0;
10504 switch (type) {
10505 case SFTK_HASH:
10506 crv = NSC_DigestInit(hSession, &mech);
10507 if (crv != CKR_OK0x00000000UL)
10508 break;
10509 /* NSC_DigestInit just installed a SFTK_HASH context on
10510 * this session; the outer session reference keeps it
10511 * alive across the load below. */
10512 context = sftk_ReturnContextByType(session, SFTK_HASH);
10513 if (context == NULL((void*)0) || context->type != SFTK_HASH) {
10514 crv = CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
10515 break;
10516 }
10517 if (context->cipherInfoLen == 0) {
10518 crv = CKR_SAVED_STATE_INVALID0x00000160UL;
10519 break;
10520 }
10521 PORT_Memcpymemcpy(context->cipherInfo, pOperationState,
10522 context->cipherInfoLen);
10523 pOperationState += context->cipherInfoLen;
10524 sftk_Decrement(ulOperationStateLen, context->cipherInfoLen)ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)(
context->cipherInfoLen)) ? ((ulOperationStateLen) - (CK_ULONG
)(context->cipherInfoLen)) : 0;
;
10525 break;
10526 default:
10527 /* do sign/encrypt/decrypt later */
10528 crv = CKR_SAVED_STATE_INVALID0x00000160UL;
10529 }
10530 sftk_FreeSession(session);
10531 if (crv != CKR_OK0x00000000UL)
10532 break;
10533 }
10534 return crv;
10535}
10536
10537/* Dual-function cryptographic operations */
10538
10539/* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption
10540 * operation. */
10541CK_RV
10542NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
10543 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
10544 CK_ULONG_PTR pulEncryptedPartLen)
10545{
10546 CK_RV crv;
10547
10548 CHECK_FORK();
10549
10550 crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
10551 pulEncryptedPartLen);
10552 if (crv != CKR_OK0x00000000UL)
10553 return crv;
10554 crv = NSC_DigestUpdate(hSession, pPart, ulPartLen);
10555
10556 return crv;
10557}
10558
10559/* NSC_DecryptDigestUpdate continues a multiple-part decryption and
10560 * digesting operation. */
10561CK_RV
10562NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
10563 CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
10564 CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
10565{
10566 CK_RV crv;
10567
10568 CHECK_FORK();
10569
10570 crv = NSC_DecryptUpdate(hSession, pEncryptedPart, ulEncryptedPartLen,
10571 pPart, pulPartLen);
10572 if (crv != CKR_OK0x00000000UL)
10573 return crv;
10574 crv = NSC_DigestUpdate(hSession, pPart, *pulPartLen);
10575
10576 return crv;
10577}
10578
10579/* NSC_SignEncryptUpdate continues a multiple-part signing and
10580 * encryption operation. */
10581CK_RV
10582NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
10583 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
10584 CK_ULONG_PTR pulEncryptedPartLen)
10585{
10586 CK_RV crv;
10587
10588 CHECK_FORK();
10589
10590 crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
10591 pulEncryptedPartLen);
10592 if (crv != CKR_OK0x00000000UL)
10593 return crv;
10594 crv = NSC_SignUpdate(hSession, pPart, ulPartLen);
10595
10596 return crv;
10597}
10598
10599/* NSC_DecryptVerifyUpdate continues a multiple-part decryption
10600 * and verify operation. */
10601CK_RV
10602NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
10603 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
10604 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
10605{
10606 CK_RV crv;
10607
10608 CHECK_FORK();
10609
10610 crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
10611 pData, pulDataLen);
10612 if (crv
0.1
'crv' is equal to CKR_OK
!= CKR_OK0x00000000UL)
1
Taking false branch
10613 return crv;
10614 crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);
2
Calling 'NSC_VerifyUpdate'
10615
10616 return crv;
10617}
10618
10619/* NSC_DigestKey continues a multi-part message-digesting operation,
10620 * by digesting the value of a secret key as part of the data already digested.
10621 */
10622CK_RV
10623NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
10624{
10625 SFTKSession *session = NULL((void*)0);
10626 SFTKObject *key = NULL((void*)0);
10627 SFTKAttribute *att;
10628 CK_RV crv;
10629
10630 CHECK_FORK();
10631
10632 session = sftk_SessionFromHandle(hSession);
10633 if (session == NULL((void*)0))
10634 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
10635
10636 key = sftk_ObjectFromHandle(hKey, session);
10637 sftk_FreeSession(session);
10638 if (key == NULL((void*)0))
10639 return CKR_KEY_HANDLE_INVALID0x00000060UL;
10640
10641 /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */
10642
10643 /* make sure it's a valid key for this operation */
10644 if (key->objclass != CKO_SECRET_KEY0x00000004UL) {
10645 sftk_FreeObject(key);
10646 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
10647 }
10648 /* get the key value */
10649 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
10650 if (!att) {
10651 sftk_FreeObject(key);
10652 return CKR_KEY_HANDLE_INVALID0x00000060UL;
10653 }
10654 crv = NSC_DigestUpdate(hSession, (CK_BYTE_PTR)att->attrib.pValue,
10655 att->attrib.ulValueLen);
10656 sftk_FreeAttribute(att);
10657 sftk_FreeObject(key);
10658 return crv;
10659}