Bug Summary

File:root/firefox-clang/security/nss/lib/softoken/pkcs11c.c
Warning:line 7584, column 5
Value stored to 'rv' is never read

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-09-01-224014-2642839-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 != CKR_OK0x00000000UL)
3670 return crv;
3671
3672 if (context->hashInfo) {
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;
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) {
3692 PORT_Memcpymemcpy(residual, pPart, ulPartLen);
3693 context->padDataLength += ulPartLen;
3694 goto cleanup;
3695 }
3696 /* MACing residual */
3697 if (context->padDataLength) {
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) {
3706 if (CKR_OK0x00000000UL != (crv = sftk_MACBlock(context, pPart)))
3707 goto terminate;
3708 ulPartLen -= blkSize;
3709 pPart += blkSize;
3710 }
3711 /* save the residual */
3712 if ((context->padDataLength = ulPartLen))
3713 PORT_Memcpymemcpy(context->padBuf, pPart, ulPartLen);
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);
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#ifndef NSS_DISABLE_KYBER
6644 case CKM_NSS_KYBER_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 45):
6645 key_type = CKK_NSS_KYBER((0x80000000UL | 0x4E534350) + 5);
6646 goto do_ml_kem;
6647#endif
6648 case CKM_NSS_ML_KEM_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 48):
6649 key_type = CKK_NSS_ML_KEM((0x80000000UL | 0x4E534350) + 6);
6650 goto do_ml_kem;
6651
6652 case CKM_ML_KEM_KEY_PAIR_GEN0x0000000fUL:
6653 key_type = CKK_ML_KEM0x00000049UL;
6654
6655 do_ml_kem:
6656 sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL);
6657 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6658 sftk_DeleteAttributeType(privateKey, CKA_SEED0x00000637UL);
6659 sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL);
6660 SECItem privKey = { siBuffer, NULL((void*)0), 0 };
6661 SECItem pubKey = { siBuffer, NULL((void*)0), 0 };
6662 SECItem seed = { siBuffer, NULL((void*)0), 0 };
6663 unsigned char seedData[KYBER_KEYPAIR_COIN_BYTES64U];
6664
6665 /* generate the seed here so we can record it with
6666 * the private key */
6667 seed.data = seedData;
6668 seed.len = sizeof(seedData);
6669 rv = RNG_GenerateGlobalRandomBytes(seed.data, seed.len);
6670 if (rv != SECSuccess) {
6671 fprintf(stderrstderr, "Generate bytes failed nbytes=%d err=%d\n",
6672 seed.len, PORT_GetErrorPORT_GetError_Util());
6673 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6674 goto kyber_done;
6675 }
6676
6677 KyberParams kyberParams = sftk_kyber_PK11ParamToInternal(genParamSet);
6678 if (!sftk_kyber_AllocPrivKeyItem(kyberParams, &privKey)) {
6679 crv = CKR_HOST_MEMORY0x00000002UL;
6680 goto kyber_done;
6681 }
6682 if (!sftk_kyber_AllocPubKeyItem(kyberParams, &pubKey)) {
6683 crv = CKR_HOST_MEMORY0x00000002UL;
6684 goto kyber_done;
6685 }
6686 rv = Kyber_NewKey(kyberParams, &seed, &privKey, &pubKey);
6687 if (rv != SECSuccess) {
6688 fprintf(stderrstderr, "Generate Kyber_NewKey failed nbytes=%d err=%d\n",
6689 seed.len, PORT_GetErrorPORT_GetError_Util());
6690 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6691 goto kyber_done;
6692 }
6693
6694 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL, sftk_item_expand(&pubKey)(&pubKey)->data, (&pubKey)->len);
6695 if (crv != CKR_OK0x00000000UL) {
6696 goto kyber_done;
6697 }
6698 crv = sftk_AddAttributeType(publicKey, CKA_PARAMETER_SET0x0000061dUL,
6699 &genParamSet,
6700 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE));
6701 if (crv != CKR_OK0x00000000UL) {
6702 goto kyber_done;
6703 }
6704 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6705 sftk_item_expand(&privKey)(&privKey)->data, (&privKey)->len);
6706 if (crv != CKR_OK0x00000000UL) {
6707 goto kyber_done;
6708 }
6709 crv = sftk_AddAttributeType(privateKey, CKA_SEED0x00000637UL,
6710 sftk_item_expand(&seed)(&seed)->data, (&seed)->len);
6711 if (crv != CKR_OK0x00000000UL) {
6712 goto kyber_done;
6713 }
6714 /* pseudo attribute that says the seed came with the key
6715 * so don't try to regenerate the key in handleObject.
6716 * it will be removed before the object sees the light of
6717 * day. */
6718 crv = sftk_AddAttributeType(privateKey, CKA_NSS_SEED_OK((0x80000000UL | 0x4E534350) + 41),
6719 NULL((void*)0), 0);
6720 if (crv != CKR_OK0x00000000UL) {
6721 goto kyber_done;
6722 }
6723 crv = sftk_AddAttributeType(privateKey, CKA_PARAMETER_SET0x0000061dUL,
6724 &genParamSet,
6725 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE));
6726 if (crv != CKR_OK0x00000000UL) {
6727 goto kyber_done;
6728 }
6729 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6730 sftk_item_expand(&pubKey)(&pubKey)->data, (&pubKey)->len);
6731 kyber_done:
6732 PORT_SafeZero(seed.data, seed.len);
6733 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&privKey, PR_FALSE0);
6734 SECITEM_FreeItemSECITEM_FreeItem_Util(&pubKey, PR_FALSE0);
6735 break;
6736
6737 case CKM_ML_DSA_KEY_PAIR_GEN0x0000001cUL:
6738 sftk_DeleteAttributeType(publicKey, CKA_VALUE0x00000011UL);
6739 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6740 sftk_DeleteAttributeType(privateKey, CKA_SEED0x00000637UL);
6741 key_type = CKK_ML_DSA0x0000004aUL;
6742
6743 /*
6744 * the parameters are recognized by us
6745 */
6746 bitSize = sftk_MLDSAGetSigLen(genParamSet);
6747 if (bitSize == 0) {
6748 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
6749 break;
6750 }
6751
6752 /* Generate the key */
6753 rv = MLDSA_NewKey(genParamSet, NULL((void*)0), &mldsaPriv, &mldsaPub);
6754
6755 if (rv != SECSuccess) {
6756 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6757 sftk_fatalError = PR_TRUE1;
6758 }
6759 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6760 break;
6761 }
6762
6763 /* store the generated key into the attributes */
6764 crv = sftk_AddAttributeType(publicKey, CKA_VALUE0x00000011UL,
6765 mldsaPub.keyVal, mldsaPub.keyValLen);
6766 if (crv != CKR_OK0x00000000UL)
6767 goto mldsagn_done;
6768 crv = sftk_AddAttributeType(publicKey, CKA_PARAMETER_SET0x0000061dUL,
6769 &genParamSet, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE));
6770 if (crv != CKR_OK0x00000000UL) {
6771 goto mldsagn_done;
6772 }
6773
6774 /* now fill in the ML-DSA specfic paramenters in the private key */
6775 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6776 mldsaPub.keyVal, mldsaPub.keyValLen);
6777 if (crv != CKR_OK0x00000000UL)
6778 goto mldsagn_done;
6779
6780 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6781 mldsaPriv.keyVal,
6782 mldsaPriv.keyValLen);
6783 if (crv != CKR_OK0x00000000UL)
6784 goto mldsagn_done;
6785 crv = sftk_AddAttributeType(privateKey, CKA_PARAMETER_SET0x0000061dUL,
6786 &genParamSet, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE));
6787 if (crv != CKR_OK0x00000000UL) {
6788 goto mldsagn_done;
6789 }
6790
6791 if (mldsaPriv.seedLen != 0) {
6792 crv = sftk_AddAttributeType(privateKey, CKA_SEED0x00000637UL,
6793 mldsaPriv.seed, mldsaPriv.seedLen);
6794 if (crv != CKR_OK0x00000000UL) {
6795 goto mldsagn_done;
6796 }
6797 /* pseudo attribute that says the seed came with the key
6798 * so don't try to regenerate the key in handleObject.
6799 * it will be removed before the object sees the light of
6800 * day. */
6801 crv = sftk_AddAttributeType(privateKey, CKA_NSS_SEED_OK((0x80000000UL | 0x4E534350) + 41),
6802 NULL((void*)0), 0);
6803 /* it was either this or a comment 'fall through' which would
6804 * be cryptic to some users */
6805 if (crv != CKR_OK0x00000000UL) {
6806 goto mldsagn_done;
6807 }
6808 }
6809 mldsagn_done:
6810 PORT_SafeZero(&mldsaPriv, sizeof(mldsaPriv));
6811 PORT_SafeZero(&mldsaPub, sizeof(mldsaPub));
6812 break;
6813
6814 case CKM_EC_MONTGOMERY_KEY_PAIR_GEN0x00001056UL:
6815 case CKM_EC_EDWARDS_KEY_PAIR_GEN0x00001055UL:
6816 sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL);
6817 sftk_DeleteAttributeType(privateKey, CKA_VALUE0x00000011UL);
6818 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L);
6819 key_type = (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN0x00001055UL) ? CKK_EC_EDWARDS0x00000040UL : CKK_EC_MONTGOMERY0x00000041UL;
6820
6821 /* extract the necessary parameters and copy them to private keys */
6822 crv = sftk_Attribute2SSecItem(NULL((void*)0), &ecEncodedParams, publicKey,
6823 CKA_EC_PARAMS0x00000180UL);
6824 if (crv != CKR_OK0x00000000UL) {
6825 break;
6826 }
6827
6828 crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS0x00000180UL,
6829 sftk_item_expand(&ecEncodedParams)(&ecEncodedParams)->data, (&ecEncodedParams)->len);
6830 if (crv != CKR_OK0x00000000UL) {
6831 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0);
6832 break;
6833 }
6834
6835 /* Decode ec params before calling EC_NewKey */
6836 rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
6837 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecEncodedParams, PR_FALSE0);
6838 if (rv != SECSuccess) {
6839 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6840 break;
6841 }
6842
6843 rv = EC_NewKey(ecParams, &ecPriv);
6844 if (rv != SECSuccess) {
6845 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_LIBRARY_FAILURE) {
6846 sftk_fatalError = PR_TRUE1;
6847 }
6848 PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1);
6849 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
6850 break;
6851 }
6852 PORT_FreeArenaPORT_FreeArena_Util(ecParams->arena, PR_TRUE1);
6853 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT0x00000181UL,
6854 sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue
)->len
);
6855 if (crv != CKR_OK0x00000000UL)
6856 goto edgn_done;
6857
6858 crv = sftk_AddAttributeType(privateKey, CKA_VALUE0x00000011UL,
6859 sftk_item_expand(&ecPriv->privateValue)(&ecPriv->privateValue)->data, (&ecPriv->privateValue
)->len
);
6860 if (crv != CKR_OK0x00000000UL)
6861 goto edgn_done;
6862
6863 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB0xD5A0DB00L,
6864 sftk_item_expand(&ecPriv->publicValue)(&ecPriv->publicValue)->data, (&ecPriv->publicValue
)->len
);
6865 edgn_done:
6866 /* should zeroize, since this function doesn't. */
6867 PORT_FreeArenaPORT_FreeArena_Util(ecPriv->ecParams.arena, PR_TRUE1);
6868 break;
6869
6870 default:
6871 crv = CKR_MECHANISM_INVALID0x00000070UL;
6872 }
6873
6874 if (crv != CKR_OK0x00000000UL) {
6875 sftk_FreeObject(privateKey);
6876 sftk_FreeObject(publicKey);
6877 return crv;
6878 }
6879
6880 /* Add the class, key_type The loop lets us check errors blow out
6881 * on errors and clean up at the bottom */
6882 session = NULL((void*)0); /* make pedtantic happy... session cannot leave the*/
6883 /* loop below NULL unless an error is set... */
6884 do {
6885 crv = sftk_AddAttributeType(privateKey, CKA_CLASS0x00000000UL, &privClass,
6886 sizeof(CK_OBJECT_CLASS));
6887 if (crv != CKR_OK0x00000000UL)
6888 break;
6889 crv = sftk_AddAttributeType(publicKey, CKA_CLASS0x00000000UL, &pubClass,
6890 sizeof(CK_OBJECT_CLASS));
6891 if (crv != CKR_OK0x00000000UL)
6892 break;
6893 crv = sftk_AddAttributeType(privateKey, CKA_KEY_TYPE0x00000100UL, &key_type,
6894 sizeof(CK_KEY_TYPE));
6895 if (crv != CKR_OK0x00000000UL)
6896 break;
6897 crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE0x00000100UL, &key_type,
6898 sizeof(CK_KEY_TYPE));
6899 if (crv != CKR_OK0x00000000UL)
6900 break;
6901 session = sftk_SessionFromHandle(hSession);
6902 if (session == NULL((void*)0))
6903 crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
6904 } while (0);
6905
6906 if (crv != CKR_OK0x00000000UL) {
6907 sftk_FreeObject(privateKey);
6908 sftk_FreeObject(publicKey);
6909 return crv;
6910 }
6911
6912 /*
6913 * handle the base object cleanup for the public Key
6914 */
6915 crv = sftk_handleObject(privateKey, session);
6916 if (crv != CKR_OK0x00000000UL) {
6917 sftk_FreeSession(session);
6918 sftk_FreeObject(privateKey);
6919 sftk_FreeObject(publicKey);
6920 return crv;
6921 }
6922
6923 /*
6924 * handle the base object cleanup for the private Key
6925 * If we have any problems, we destroy the public Key we've
6926 * created and linked.
6927 */
6928 crv = sftk_handleObject(publicKey, session);
6929 if (crv != CKR_OK0x00000000UL) {
6930 sftk_FreeSession(session);
6931 sftk_FreeObject(publicKey);
6932 NSC_DestroyObject(hSession, privateKey->handle);
6933 sftk_FreeObject(privateKey);
6934 return crv;
6935 }
6936 if (sftk_isTrue(privateKey, CKA_SENSITIVE0x00000103UL)) {
6937 crv = sftk_forceAttribute(privateKey, CKA_ALWAYS_SENSITIVE0x00000165UL,
6938 &cktrue, sizeof(CK_BBOOL));
6939 }
6940 if (crv == CKR_OK0x00000000UL && sftk_isTrue(publicKey, CKA_SENSITIVE0x00000103UL)) {
6941 crv = sftk_forceAttribute(publicKey, CKA_ALWAYS_SENSITIVE0x00000165UL,
6942 &cktrue, sizeof(CK_BBOOL));
6943 }
6944 if (crv == CKR_OK0x00000000UL && !sftk_isTrue(privateKey, CKA_EXTRACTABLE0x00000162UL)) {
6945 crv = sftk_forceAttribute(privateKey, CKA_NEVER_EXTRACTABLE0x00000164UL,
6946 &cktrue, sizeof(CK_BBOOL));
6947 }
6948 if (crv == CKR_OK0x00000000UL && !sftk_isTrue(publicKey, CKA_EXTRACTABLE0x00000162UL)) {
6949 crv = sftk_forceAttribute(publicKey, CKA_NEVER_EXTRACTABLE0x00000164UL,
6950 &cktrue, sizeof(CK_BBOOL));
6951 }
6952
6953 if (crv == CKR_OK0x00000000UL &&
6954 pMechanism->mechanism != CKM_NSS_ECDHE_NO_PAIRWISE_CHECK_KEY_PAIR_GEN((0x80000000UL | 0x4E534350) + 47)) {
6955 /* Perform FIPS 140-2 pairwise consistency check. */
6956 crv = sftk_PairwiseConsistencyCheck(hSession, slot,
6957 publicKey, privateKey, key_type);
6958 if (crv != CKR_OK0x00000000UL) {
6959 if (sftk_audit_enabled) {
6960 char msg[128];
6961 PR_snprintf(msg, sizeof msg,
6962 "C_GenerateKeyPair(hSession=0x%08lX, "
6963 "pMechanism->mechanism=0x%08lX)=0x%08lX "
6964 "self-test: pair-wise consistency test failed",
6965 (PRUint32)hSession, (PRUint32)pMechanism->mechanism,
6966 (PRUint32)crv);
6967 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
6968 }
6969 }
6970 }
6971
6972 if (crv != CKR_OK0x00000000UL) {
6973 sftk_FreeSession(session);
6974 NSC_DestroyObject(hSession, publicKey->handle);
6975 sftk_FreeObject(publicKey);
6976 NSC_DestroyObject(hSession, privateKey->handle);
6977 sftk_FreeObject(privateKey);
6978 return crv;
6979 }
6980 /* we need to do this check at the end to make sure the generated key
6981 * meets the key length requirements */
6982 sftk_setFIPS(privateKey, sftk_operationIsFIPS(slot, pMechanism,
6983 CKA_NSS_GENERATE_KEY_PAIR0x81000002L,
6984 privateKey, 0));
6985 session->lastOpWasFIPS = sftk_hasFIPS(privateKey);
6986 sftk_setFIPS(publicKey, session->lastOpWasFIPS);
6987 sftk_FreeSession(session);
6988 *phPrivateKey = privateKey->handle;
6989 *phPublicKey = publicKey->handle;
6990 sftk_FreeObject(publicKey);
6991 sftk_FreeObject(privateKey);
6992
6993 return CKR_OK0x00000000UL;
6994}
6995
6996static SECItem *
6997sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
6998{
6999 NSSLOWKEYPrivateKey *lk = NULL((void*)0);
7000 NSSLOWKEYPrivateKeyInfo *pki = NULL((void*)0);
7001 SFTKAttribute *attribute = NULL((void*)0);
7002 PLArenaPool *arena = NULL((void*)0);
7003 SECOidTag algorithm = SEC_OID_UNKNOWN;
7004 void *dummy, *param = NULL((void*)0);
7005 SECStatus rv = SECSuccess;
7006 SECItem *encodedKey = NULL((void*)0);
7007#ifdef EC_DEBUG
7008 SECItem *fordebug;
7009#endif
7010 int savelen;
7011
7012 if (!key) {
7013 *crvp = CKR_KEY_HANDLE_INVALID0x00000060UL; /* really can't happen */
7014 return NULL((void*)0);
7015 }
7016
7017 attribute = sftk_FindAttribute(key, CKA_KEY_TYPE0x00000100UL);
7018 if (!attribute) {
7019 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7020 return NULL((void*)0);
7021 }
7022
7023 lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp);
7024 sftk_FreeAttribute(attribute);
7025 if (!lk) {
7026 return NULL((void*)0);
7027 }
7028
7029 arena = PORT_NewArenaPORT_NewArena_Util(2048); /* XXX different size? */
7030 if (!arena) {
7031 *crvp = CKR_HOST_MEMORY0x00000002UL;
7032 rv = SECFailure;
7033 goto loser;
7034 }
7035
7036 pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7037 sizeof(NSSLOWKEYPrivateKeyInfo));
7038 if (!pki) {
7039 *crvp = CKR_HOST_MEMORY0x00000002UL;
7040 rv = SECFailure;
7041 goto loser;
7042 }
7043 pki->arena = arena;
7044
7045 param = NULL((void*)0);
7046 switch (lk->keyType) {
7047 case NSSLOWKEYRSAKey:
7048 prepare_low_rsa_priv_key_for_asn1(lk);
7049 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7050 nsslowkey_RSAPrivateKeyTemplate);
7051
7052 /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */
7053 attribute = sftk_FindAttribute(key, CKA_PUBLIC_KEY_INFO0x00000129UL);
7054 if (attribute) {
7055 NSSLOWKEYSubjectPublicKeyInfo *publicKeyInfo;
7056 SECItem spki;
7057
7058 spki.data = attribute->attrib.pValue;
7059 spki.len = attribute->attrib.ulValueLen;
7060
7061 publicKeyInfo = PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7062 sizeof(NSSLOWKEYSubjectPublicKeyInfo));
7063 if (!publicKeyInfo) {
7064 sftk_FreeAttribute(attribute);
7065 *crvp = CKR_HOST_MEMORY0x00000002UL;
7066 rv = SECFailure;
7067 goto loser;
7068 }
7069 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, publicKeyInfo,
7070 nsslowkey_SubjectPublicKeyInfoTemplate,
7071 &spki);
7072 if (rv != SECSuccess) {
7073 sftk_FreeAttribute(attribute);
7074 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7075 goto loser;
7076 }
7077 algorithm = SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&publicKeyInfo->algorithm);
7078 if (algorithm != SEC_OID_PKCS1_RSA_ENCRYPTION &&
7079 algorithm != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
7080 sftk_FreeAttribute(attribute);
7081 rv = SECFailure;
7082 *crvp = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7083 goto loser;
7084 }
7085 param = SECITEM_DupItemSECITEM_DupItem_Util(&publicKeyInfo->algorithm.parameters);
7086 if (!param) {
7087 sftk_FreeAttribute(attribute);
7088 rv = SECFailure;
7089 *crvp = CKR_HOST_MEMORY0x00000002UL;
7090 goto loser;
7091 }
7092 sftk_FreeAttribute(attribute);
7093 } else {
7094 /* default to PKCS #1 */
7095 algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
7096 }
7097 break;
7098 case NSSLOWKEYDSAKey:
7099 prepare_low_dsa_priv_key_export_for_asn1(lk);
7100 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7101 nsslowkey_DSAPrivateKeyExportTemplate);
7102 prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);
7103 param = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), &(lk->u.dsa.params),
7104 nsslowkey_PQGParamsTemplate);
7105 algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
7106 break;
7107 case NSSLOWKEYECKey:
7108 prepare_low_ec_priv_key_for_asn1(lk);
7109 /* Public value is encoded as a bit string so adjust length
7110 * to be in bits before ASN encoding and readjust
7111 * immediately after.
7112 *
7113 * Since the SECG specification recommends not including the
7114 * parameters as part of ECPrivateKey, we zero out the curveOID
7115 * length before encoding and restore it later.
7116 */
7117 lk->u.ec.publicValue.len <<= 3;
7118 savelen = lk->u.ec.ecParams.curveOID.len;
7119 lk->u.ec.ecParams.curveOID.len = 0;
7120 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7121 nsslowkey_ECPrivateKeyTemplate);
7122 lk->u.ec.ecParams.curveOID.len = savelen;
7123 lk->u.ec.publicValue.len >>= 3;
7124
7125#ifdef EC_DEBUG
7126 fordebug = &pki->privateKey;
7127 SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
7128 fordebug);
7129#endif
7130
7131 param = SECITEM_DupItemSECITEM_DupItem_Util(&lk->u.ec.ecParams.DEREncoding);
7132
7133 algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
7134 break;
7135 case NSSLOWKEYMLKEMKey: {
7136 SECItem seed = { siBuffer, NULL((void*)0), 0 };
7137 SECItem rawKey = { siBuffer, NULL((void*)0), 0 };
7138 dummy = NULL((void*)0);
7139
7140 switch (lk->u.mlkem.mlkemParams) {
7141 case params_ml_kem768:
7142 case params_ml_kem768_test_mode:
7143 algorithm = SEC_OID_ML_KEM_768;
7144 break;
7145 case params_ml_kem1024:
7146 case params_ml_kem1024_test_mode:
7147 algorithm = SEC_OID_ML_KEM_1024;
7148 break;
7149 default:
7150 algorithm = SEC_OID_UNKNOWN;
7151 break;
7152 }
7153 if (algorithm == SEC_OID_UNKNOWN) {
7154 break;
7155 }
7156 /* save the seed and key items before they are overwritten */
7157 if (lk->u.mlkem.seed.len != 0) {
7158 seed = lk->u.mlkem.seed;
7159 }
7160 rawKey = lk->u.mlkem.key;
7161 if (lk == key->objectInfo) {
7162 /* we have a cached key, and we are about to
7163 * overwrite it, let's get a duplicate first */
7164 lk = nsslowkey_CopyPrivateKey(lk);
7165 if (lk == NULL((void*)0)) {
7166 break;
7167 }
7168 }
7169 /* this overwrites the mlkem data, but we don't need it any
7170 * more because we are discarding lk once we encode. This
7171 * allows us to use the same template for mlkem and mldsa
7172 * (and presumably other pq algorithms, though mlfn and mlshl
7173 * don't have additional seeds) */
7174 lk->u.genpq.seedItem = seed;
7175 lk->u.genpq.keyItem = rawKey;
7176 if (seed.len) {
7177 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7178 nsslowkey_PQBothSeedAndPrivateKeyTemplate);
7179 } else {
7180 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7181 nsslowkey_PQPrivateKeyTemplate);
7182 }
7183 } break;
7184 case NSSLOWKEYMLDSAKey: {
7185 SECItem seed = { siBuffer, NULL((void*)0), 0 };
7186 SECItem keyVal = { siBuffer, NULL((void*)0), 0 };
7187 dummy = NULL((void*)0);
7188
7189 /* paramSet sets the algorithm */
7190 switch (lk->u.mldsa.paramSet) {
7191 case CKP_ML_DSA_440x00000001UL:
7192 algorithm = SEC_OID_ML_DSA_44_PUBLIC_KEYSEC_OID_ML_DSA_44;
7193 break;
7194 case CKP_ML_DSA_650x00000002UL:
7195 algorithm = SEC_OID_ML_DSA_65_PUBLIC_KEYSEC_OID_ML_DSA_65;
7196 break;
7197 case CKP_ML_DSA_870x00000003UL:
7198 algorithm = SEC_OID_ML_DSA_87_PUBLIC_KEYSEC_OID_ML_DSA_87;
7199 break;
7200 default:
7201 algorithm = SEC_OID_UNKNOWN;
7202 break;
7203 }
7204 if (algorithm == SEC_OID_UNKNOWN) {
7205 break;
7206 }
7207
7208 /* if we have the seed, copy it */
7209 if (lk->u.mldsa.seedLen != 0) {
7210 rv = SECITEM_MakeItem(arena, &seed, lk->u.mldsa.seed,
7211 lk->u.mldsa.seedLen);
7212 if (rv != SECSuccess) {
7213 break;
7214 }
7215 }
7216 rv = SECITEM_MakeItem(arena, &keyVal, lk->u.mldsa.keyVal,
7217 lk->u.mldsa.keyValLen);
7218 if (rv != SECSuccess) {
7219 break;
7220 }
7221 if (lk == key->objectInfo) {
7222 /* we have a cached key, and we are about to
7223 * overwrite it, let's get a duplicate first */
7224 lk = nsslowkey_CopyPrivateKey(lk);
7225 if (lk == NULL((void*)0)) {
7226 break;
7227 }
7228 }
7229 /* this overwrites the mldsa data, but we don't need it any
7230 * more because we are discarding lk once we encode */
7231 lk->u.genpq.seedItem = seed;
7232 lk->u.genpq.keyItem = keyVal;
7233
7234 if (seed.len) {
7235 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7236 nsslowkey_PQBothSeedAndPrivateKeyTemplate);
7237 } else {
7238 dummy = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &pki->privateKey, lk,
7239 nsslowkey_PQPrivateKeyTemplate);
7240 }
7241 } break;
7242
7243 case NSSLOWKEYDHKey:
7244 default:
7245 dummy = NULL((void*)0);
7246 break;
7247 }
7248
7249 if (!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {
7250 *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */
7251 rv = SECFailure;
7252 goto loser;
7253 }
7254
7255 rv = SECOID_SetAlgorithmIDSECOID_SetAlgorithmID_Util(arena, &pki->algorithm, algorithm,
7256 (SECItem *)param);
7257 if (rv != SECSuccess) {
7258 *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */
7259 rv = SECFailure;
7260 goto loser;
7261 }
7262
7263 dummy = SEC_ASN1EncodeIntegerSEC_ASN1EncodeInteger_Util(arena, &pki->version,
7264 NSSLOWKEY_PRIVATE_KEY_INFO_VERSION0);
7265 if (!dummy) {
7266 *crvp = CKR_DEVICE_ERROR0x00000030UL; /* should map NSS SECError */
7267 rv = SECFailure;
7268 goto loser;
7269 }
7270
7271 encodedKey = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), pki,
7272 nsslowkey_PrivateKeyInfoTemplate);
7273 *crvp = encodedKey ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL;
7274
7275#ifdef EC_DEBUG
7276 fordebug = encodedKey;
7277 SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,
7278 fordebug);
7279#endif
7280loser:
7281 if (arena) {
7282 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
7283 }
7284
7285 if (lk && (lk != key->objectInfo)) {
7286 nsslowkey_DestroyPrivateKey(lk);
7287 }
7288
7289 if (param) {
7290 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util((SECItem *)param, PR_TRUE1);
7291 }
7292
7293 if (rv != SECSuccess) {
7294 return NULL((void*)0);
7295 }
7296
7297 return encodedKey;
7298}
7299
7300/* it doesn't matter yet, since we colapse error conditions in the
7301 * level above, but we really should map those few key error differences */
7302static CK_RV
7303sftk_mapWrap(CK_RV crv)
7304{
7305 switch (crv) {
7306 case CKR_ENCRYPTED_DATA_INVALID0x00000040UL:
7307 crv = CKR_WRAPPED_KEY_INVALID0x00000110UL;
7308 break;
7309 }
7310 return crv;
7311}
7312
7313/* NSC_WrapKey wraps (i.e., encrypts) a key. */
7314CK_RV
7315NSC_WrapKey(CK_SESSION_HANDLE hSession,
7316 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
7317 CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
7318 CK_ULONG_PTR pulWrappedKeyLen)
7319{
7320 SFTKSession *session;
7321 SFTKAttribute *attribute;
7322 SFTKObject *key;
7323 CK_RV crv;
7324
7325 CHECK_FORK();
7326
7327 session = sftk_SessionFromHandle(hSession);
7328 if (session == NULL((void*)0)) {
7329 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
7330 }
7331
7332 key = sftk_ObjectFromHandle(hKey, session);
7333 if (key == NULL((void*)0)) {
7334 sftk_FreeSession(session);
7335 return CKR_KEY_HANDLE_INVALID0x00000060UL;
7336 }
7337
7338 switch (key->objclass) {
7339 case CKO_SECRET_KEY0x00000004UL: {
7340 SFTKSessionContext *context = NULL((void*)0);
7341 SECItem pText;
7342
7343 attribute = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
7344
7345 if (attribute == NULL((void*)0)) {
7346 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7347 break;
7348 }
7349 crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
7350 CKA_WRAP0x00000106UL, CKA_WRAP0x00000106UL, SFTK_ENCRYPT, PR_TRUE1);
7351 if (crv != CKR_OK0x00000000UL) {
7352 sftk_FreeAttribute(attribute);
7353 break;
7354 }
7355
7356 pText.type = siBuffer;
7357 pText.data = (unsigned char *)attribute->attrib.pValue;
7358 pText.len = attribute->attrib.ulValueLen;
7359
7360 /* Find out if this is a block cipher. The context was just
7361 * installed by sftk_CryptInit above, so we already hold a
7362 * session reference and the context's type is SFTK_ENCRYPT
7363 * by construction. */
7364 context = sftk_ReturnContextByType(session, SFTK_ENCRYPT);
7365 if (!context) {
7366 sftk_FreeAttribute(attribute);
7367 crv = CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
7368 break;
7369 }
7370 if (context->blockSize > 1) {
7371 unsigned int remainder = pText.len % context->blockSize;
7372 if (!context->doPad && remainder) {
7373 /* When wrapping secret keys with unpadded block ciphers,
7374 ** the keys are zero padded, if necessary, to fill out
7375 ** a full block.
7376 */
7377 pText.len += context->blockSize - remainder;
7378 pText.data = PORT_ZAllocPORT_ZAlloc_Util(pText.len);
7379 if (pText.data)
7380 memcpy(pText.data, attribute->attrib.pValue,
7381 attribute->attrib.ulValueLen);
7382 else {
7383 sftk_FreeAttribute(attribute);
7384 crv = CKR_HOST_MEMORY0x00000002UL;
7385 break;
7386 }
7387 }
7388 }
7389
7390 crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data,
7391 pText.len, pWrappedKey, pulWrappedKeyLen);
7392 /* always force a finalize, both on errors and when
7393 * we are just getting the size */
7394 if (crv != CKR_OK0x00000000UL || pWrappedKey == NULL((void*)0)) {
7395 sftk_UninstallContext(session, SFTK_ENCRYPT);
7396 }
7397
7398 if (pText.data != (unsigned char *)attribute->attrib.pValue)
7399 PORT_ZFreePORT_ZFree_Util(pText.data, pText.len);
7400 sftk_FreeAttribute(attribute);
7401 break;
7402 }
7403
7404 case CKO_PRIVATE_KEY0x00000003UL: {
7405 SECItem *bpki = sftk_PackagePrivateKey(key, &crv);
7406
7407 if (!bpki) {
7408 break;
7409 }
7410
7411 crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
7412 CKA_WRAP0x00000106UL, CKA_WRAP0x00000106UL, SFTK_ENCRYPT, PR_TRUE1);
7413 if (crv != CKR_OK0x00000000UL) {
7414 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(bpki, PR_TRUE1);
7415 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7416 break;
7417 }
7418
7419 crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
7420 pWrappedKey, pulWrappedKeyLen);
7421 /* always force a finalize */
7422 if (crv != CKR_OK0x00000000UL || pWrappedKey == NULL((void*)0)) {
7423 sftk_UninstallContext(session, SFTK_ENCRYPT);
7424 }
7425 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(bpki, PR_TRUE1);
7426 break;
7427 }
7428
7429 default:
7430 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7431 break;
7432 }
7433 sftk_FreeObject(key);
7434 sftk_FreeSession(session);
7435 return sftk_mapWrap(crv);
7436}
7437
7438/*
7439 * import a pprivate key info into the desired slot
7440 */
7441static SECStatus
7442sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
7443{
7444 CK_BBOOL cktrue = CK_TRUE1;
7445 CK_BBOOL ckfalse = CK_FALSE0;
7446 CK_KEY_TYPE keyType = CKK_RSA0x00000000UL;
7447 SECStatus rv = SECFailure;
7448 const SEC_ASN1Template *keyTemplate, *paramTemplate;
7449 void *paramDest = NULL((void*)0);
7450 PLArenaPool *arena;
7451 NSSLOWKEYPrivateKey *lpk = NULL((void*)0);
7452 NSSLOWKEYPrivateKeyInfo *pki = NULL((void*)0);
7453 CK_RV crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7454 CK_ULONG paramSet = 0;
7455
7456 arena = PORT_NewArenaPORT_NewArena_Util(2048);
7457 if (!arena) {
7458 return SECFailure;
7459 }
7460
7461 pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7462 sizeof(NSSLOWKEYPrivateKeyInfo));
7463 if (!pki) {
7464 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
7465 return SECFailure;
7466 }
7467
7468 if (SEC_ASN1DecodeItemSEC_ASN1DecodeItem_Util(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) != SECSuccess) {
7469 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
7470 return SECFailure;
7471 }
7472
7473 lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(arena,
7474 sizeof(NSSLOWKEYPrivateKey));
7475 if (lpk == NULL((void*)0)) {
7476 goto loser;
7477 }
7478 lpk->arena = arena;
7479
7480 switch (SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&pki->algorithm)) {
7481 case SEC_OID_PKCS1_RSA_ENCRYPTION:
7482 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
7483 keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
7484 paramTemplate = NULL((void*)0);
7485 paramDest = NULL((void*)0);
7486 lpk->keyType = NSSLOWKEYRSAKey;
7487 prepare_low_rsa_priv_key_for_asn1(lpk);
7488 break;
7489 case SEC_OID_ANSIX9_DSA_SIGNATURE:
7490 keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
7491 paramTemplate = nsslowkey_PQGParamsTemplate;
7492 paramDest = &(lpk->u.dsa.params);
7493 lpk->keyType = NSSLOWKEYDSAKey;
7494 prepare_low_dsa_priv_key_export_for_asn1(lpk);
7495 prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params);
7496 break;
7497 /* case NSSLOWKEYDHKey: */
7498 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
7499 keyTemplate = nsslowkey_ECPrivateKeyTemplate;
7500 paramTemplate = NULL((void*)0);
7501 paramDest = &(lpk->u.ec.ecParams.DEREncoding);
7502 lpk->keyType = NSSLOWKEYECKey;
7503 prepare_low_ec_priv_key_for_asn1(lpk);
7504 prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams);
7505 break;
7506 case SEC_OID_ML_KEM_768:
7507 paramSet = CKP_ML_KEM_7680x00000002UL;
7508 goto mlkem_next;
7509 case SEC_OID_ML_KEM_1024:
7510 paramSet = CKP_ML_KEM_10240x00000003UL;
7511 mlkem_next:
7512 lpk->keyType = NSSLOWKEYMLKEMKey;
7513 goto pq_next;
7514 case SEC_OID_ML_DSA_44_PUBLIC_KEYSEC_OID_ML_DSA_44:
7515 paramSet = CKP_ML_DSA_440x00000001UL;
7516 goto mldsa_next;
7517 case SEC_OID_ML_DSA_65_PUBLIC_KEYSEC_OID_ML_DSA_65:
7518 paramSet = CKP_ML_DSA_650x00000002UL;
7519 goto mldsa_next;
7520 case SEC_OID_ML_DSA_87_PUBLIC_KEYSEC_OID_ML_DSA_87:
7521 paramSet = CKP_ML_DSA_870x00000003UL;
7522 mldsa_next:
7523 lpk->keyType = NSSLOWKEYMLDSAKey;
7524 pq_next:
7525 if (pki->privateKey.data == NULL((void*)0) || pki->privateKey.len == 0) {
7526 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_BAD_KEY);
7527 goto loser;
7528 }
7529 switch (pki->privateKey.data[0]) {
7530 case SEC_ASN1_CONTEXT_SPECIFIC0x80 | 0:
7531 keyTemplate = nsslowkey_PQSeedTemplate;
7532 break;
7533 case SEC_ASN1_OCTET_STRING0x04:
7534 keyTemplate = nsslowkey_PQPrivateKeyTemplate;
7535 break;
7536 case SEC_ASN1_CONSTRUCTED0x20 | SEC_ASN1_SEQUENCE0x10:
7537 keyTemplate = nsslowkey_PQBothSeedAndPrivateKeyTemplate;
7538 break;
7539 default:
7540 keyTemplate = NULL((void*)0);
7541 break;
7542 }
7543
7544 paramTemplate = NULL((void*)0);
7545 paramDest = NULL((void*)0);
7546 /* genpq encodes ocect, not integer, so no need to prep it */
7547 break;
7548 default:
7549 keyTemplate = NULL((void*)0);
7550 paramTemplate = NULL((void*)0);
7551 paramDest = NULL((void*)0);
7552 break;
7553 }
7554
7555 if (!keyTemplate) {
7556 goto loser;
7557 }
7558
7559 /* decode the private key and any algorithm parameters */
7560 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, lpk, keyTemplate, &pki->privateKey);
7561
7562 if (lpk->keyType == NSSLOWKEYECKey) {
7563 /* convert length in bits to length in bytes */
7564 lpk->u.ec.publicValue.len >>= 3;
7565 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena,
7566 &(lpk->u.ec.ecParams.DEREncoding),
7567 &(pki->algorithm.parameters));
7568 if (rv != SECSuccess) {
7569 goto loser;
7570 }
7571 }
7572
7573 if (rv != SECSuccess) {
7574 goto loser;
7575 }
7576 if (paramDest && paramTemplate) {
7577 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, paramDest, paramTemplate,
7578 &(pki->algorithm.parameters));
7579 if (rv != SECSuccess) {
7580 goto loser;
7581 }
7582 }
7583
7584 rv = SECFailure;
Value stored to 'rv' is never read
7585
7586 switch (lpk->keyType) {
7587 case NSSLOWKEYRSAKey:
7588 keyType = CKK_RSA0x00000000UL;
7589 if (sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) {
7590 sftk_DeleteAttributeType(key, CKA_NSS_DB0xD5A0DB00L);
7591 }
7592 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7593 sizeof(keyType));
7594 if (crv != CKR_OK0x00000000UL)
7595 break;
7596 crv = sftk_AddAttributeType(key, CKA_UNWRAP0x00000107UL, &cktrue,
7597 sizeof(CK_BBOOL));
7598 if (crv != CKR_OK0x00000000UL)
7599 break;
7600 crv = sftk_AddAttributeType(key, CKA_DECRYPT0x00000105UL, &cktrue,
7601 sizeof(CK_BBOOL));
7602 if (crv != CKR_OK0x00000000UL)
7603 break;
7604 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue,
7605 sizeof(CK_BBOOL));
7606 if (crv != CKR_OK0x00000000UL)
7607 break;
7608 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &cktrue,
7609 sizeof(CK_BBOOL));
7610 if (crv != CKR_OK0x00000000UL)
7611 break;
7612 crv = sftk_AddAttributeType(key, CKA_MODULUS0x00000120UL,
7613 sftk_item_expand(&lpk->u.rsa.modulus)(&lpk->u.rsa.modulus)->data, (&lpk->u.rsa.modulus
)->len
);
7614 if (crv != CKR_OK0x00000000UL)
7615 break;
7616 crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT0x00000122UL,
7617 sftk_item_expand(&lpk->u.rsa.publicExponent)(&lpk->u.rsa.publicExponent)->data, (&lpk->u
.rsa.publicExponent)->len
);
7618 if (crv != CKR_OK0x00000000UL)
7619 break;
7620 crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT0x00000123UL,
7621 sftk_item_expand(&lpk->u.rsa.privateExponent)(&lpk->u.rsa.privateExponent)->data, (&lpk->
u.rsa.privateExponent)->len
);
7622 if (crv != CKR_OK0x00000000UL)
7623 break;
7624 crv = sftk_AddAttributeType(key, CKA_PRIME_10x00000124UL,
7625 sftk_item_expand(&lpk->u.rsa.prime1)(&lpk->u.rsa.prime1)->data, (&lpk->u.rsa.prime1
)->len
);
7626 if (crv != CKR_OK0x00000000UL)
7627 break;
7628 crv = sftk_AddAttributeType(key, CKA_PRIME_20x00000125UL,
7629 sftk_item_expand(&lpk->u.rsa.prime2)(&lpk->u.rsa.prime2)->data, (&lpk->u.rsa.prime2
)->len
);
7630 if (crv != CKR_OK0x00000000UL)
7631 break;
7632 crv = sftk_AddAttributeType(key, CKA_EXPONENT_10x00000126UL,
7633 sftk_item_expand(&lpk->u.rsa.exponent1)(&lpk->u.rsa.exponent1)->data, (&lpk->u.rsa.
exponent1)->len
);
7634 if (crv != CKR_OK0x00000000UL)
7635 break;
7636 crv = sftk_AddAttributeType(key, CKA_EXPONENT_20x00000127UL,
7637 sftk_item_expand(&lpk->u.rsa.exponent2)(&lpk->u.rsa.exponent2)->data, (&lpk->u.rsa.
exponent2)->len
);
7638 if (crv != CKR_OK0x00000000UL)
7639 break;
7640 crv = sftk_AddAttributeType(key, CKA_COEFFICIENT0x00000128UL,
7641 sftk_item_expand(&lpk->u.rsa.coefficient)(&lpk->u.rsa.coefficient)->data, (&lpk->u.rsa
.coefficient)->len
);
7642 break;
7643 case NSSLOWKEYDSAKey:
7644 keyType = CKK_DSA0x00000001UL;
7645 crv = (sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) ? CKR_OK0x00000000UL : CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7646 if (crv != CKR_OK0x00000000UL)
7647 break;
7648 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7649 sizeof(keyType));
7650 if (crv != CKR_OK0x00000000UL)
7651 break;
7652 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue,
7653 sizeof(CK_BBOOL));
7654 if (crv != CKR_OK0x00000000UL)
7655 break;
7656 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &ckfalse,
7657 sizeof(CK_BBOOL));
7658 if (crv != CKR_OK0x00000000UL)
7659 break;
7660 crv = sftk_AddAttributeType(key, CKA_PRIME0x00000130UL,
7661 sftk_item_expand(&lpk->u.dsa.params.prime)(&lpk->u.dsa.params.prime)->data, (&lpk->u.dsa
.params.prime)->len
);
7662 if (crv != CKR_OK0x00000000UL)
7663 break;
7664 crv = sftk_AddAttributeType(key, CKA_SUBPRIME0x00000131UL,
7665 sftk_item_expand(&lpk->u.dsa.params.subPrime)(&lpk->u.dsa.params.subPrime)->data, (&lpk->
u.dsa.params.subPrime)->len
);
7666 if (crv != CKR_OK0x00000000UL)
7667 break;
7668 crv = sftk_AddAttributeType(key, CKA_BASE0x00000132UL,
7669 sftk_item_expand(&lpk->u.dsa.params.base)(&lpk->u.dsa.params.base)->data, (&lpk->u.dsa
.params.base)->len
);
7670 if (crv != CKR_OK0x00000000UL)
7671 break;
7672 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7673 sftk_item_expand(&lpk->u.dsa.privateValue)(&lpk->u.dsa.privateValue)->data, (&lpk->u.dsa
.privateValue)->len
);
7674 if (crv != CKR_OK0x00000000UL)
7675 break;
7676 break;
7677 case NSSLOWKEYMLKEMKey:
7678 keyType = CKK_ML_KEM0x00000049UL;
7679 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7680 sizeof(keyType));
7681 if (crv != CKR_OK0x00000000UL)
7682 break;
7683 crv = sftk_AddAttributeType(key, CKA_DECAPSULATE0x00000634UL, &cktrue,
7684 sizeof(CK_BBOOL));
7685 if (crv != CKR_OK0x00000000UL)
7686 break;
7687 crv = sftk_AddAttributeType(key, CKA_PARAMETER_SET0x0000061dUL, &paramSet,
7688 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE));
7689 if (crv != CKR_OK0x00000000UL)
7690 break;
7691 if (lpk->u.genpq.seedItem.len != 0) {
7692 crv = sftk_AddAttributeType(key, CKA_SEED0x00000637UL,
7693 sftk_item_expand(&lpk->u.genpq.seedItem)(&lpk->u.genpq.seedItem)->data, (&lpk->u.genpq
.seedItem)->len
);
7694 if (crv != CKR_OK0x00000000UL)
7695 break;
7696 }
7697
7698 /* if we were given just the seed, we'll regenerate the key
7699 * from the seed in handleObject */
7700 if (lpk->u.genpq.keyItem.len != 0) {
7701 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7702 sftk_item_expand(&lpk->u.genpq.keyItem)(&lpk->u.genpq.keyItem)->data, (&lpk->u.genpq
.keyItem)->len
);
7703 /* I know, this is redundant, but it would be too easy
7704 * for someone to add another sftk_AddAttributeType after
7705 * this without adding this check back because of the if */
7706 if (crv != CKR_OK0x00000000UL)
7707 break;
7708 }
7709 break;
7710 case NSSLOWKEYMLDSAKey:
7711 keyType = CKK_ML_DSA0x0000004aUL;
7712 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7713 sizeof(keyType));
7714 if (crv != CKR_OK0x00000000UL)
7715 break;
7716 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue,
7717 sizeof(CK_BBOOL));
7718 if (crv != CKR_OK0x00000000UL)
7719 break;
7720 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &ckfalse,
7721 sizeof(CK_BBOOL));
7722 if (crv != CKR_OK0x00000000UL)
7723 break;
7724 crv = sftk_AddAttributeType(key, CKA_PARAMETER_SET0x0000061dUL, &paramSet,
7725 sizeof(CK_ML_DSA_PARAMETER_SET_TYPE));
7726 if (crv != CKR_OK0x00000000UL)
7727 break;
7728 if (lpk->u.genpq.seedItem.len != 0) {
7729 crv = sftk_AddAttributeType(key, CKA_SEED0x00000637UL,
7730 sftk_item_expand(&lpk->u.genpq.seedItem)(&lpk->u.genpq.seedItem)->data, (&lpk->u.genpq
.seedItem)->len
);
7731 if (crv != CKR_OK0x00000000UL)
7732 break;
7733 }
7734
7735 /* if we were given just the seed, we'll regenerate the key
7736 * from the seed in handleObject */
7737 if (lpk->u.genpq.keyItem.len != 0) {
7738 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7739 sftk_item_expand(&lpk->u.genpq.keyItem)(&lpk->u.genpq.keyItem)->data, (&lpk->u.genpq
.keyItem)->len
);
7740 /* I know, this is redundant, but it would be too easy
7741 * for someone to add another sftk_AddAttributeType after
7742 * this without adding this check back because of the if */
7743 if (crv != CKR_OK0x00000000UL)
7744 break;
7745 }
7746 break;
7747#ifdef notdef
7748 case NSSLOWKEYDHKey:
7749 template = dhTemplate;
7750 templateCount = sizeof(dhTemplate) / sizeof(CK_ATTRIBUTE);
7751 keyType = CKK_DH0x00000002UL;
7752 break;
7753#endif
7754 /* what about fortezza??? */
7755 case NSSLOWKEYECKey:
7756 keyType = CKK_EC0x00000003UL;
7757 /* if we weren't passed the CKA_NSS_DB, get it
7758 * from the public key */
7759 if (!sftk_hasAttribute(key, CKA_NSS_DB0xD5A0DB00L)) {
7760 if (lpk->u.ec.publicValue.len == 0) {
7761 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7762 goto loser;
7763 }
7764 crv = sftk_AddAttributeType(key, CKA_NSS_DB0xD5A0DB00L,
7765 sftk_item_expand(&lpk->u.ec.publicValue)(&lpk->u.ec.publicValue)->data, (&lpk->u.ec.
publicValue)->len
);
7766 if (crv != CKR_OK0x00000000UL) {
7767 goto loser;
7768 }
7769 }
7770 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE0x00000100UL, &keyType,
7771 sizeof(keyType));
7772 if (crv != CKR_OK0x00000000UL)
7773 break;
7774 crv = sftk_AddAttributeType(key, CKA_SIGN0x00000108UL, &cktrue,
7775 sizeof(CK_BBOOL));
7776 if (crv != CKR_OK0x00000000UL)
7777 break;
7778 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER0x00000109UL, &ckfalse,
7779 sizeof(CK_BBOOL));
7780 if (crv != CKR_OK0x00000000UL)
7781 break;
7782 crv = sftk_AddAttributeType(key, CKA_DERIVE0x0000010CUL, &cktrue,
7783 sizeof(CK_BBOOL));
7784 if (crv != CKR_OK0x00000000UL)
7785 break;
7786 crv = sftk_AddAttributeType(key, CKA_EC_PARAMS0x00000180UL,
7787 sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding)(&lpk->u.ec.ecParams.DEREncoding)->data, (&lpk->
u.ec.ecParams.DEREncoding)->len
);
7788 if (crv != CKR_OK0x00000000UL)
7789 break;
7790 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL,
7791 sftk_item_expand(&lpk->u.ec.privateValue)(&lpk->u.ec.privateValue)->data, (&lpk->u.ec
.privateValue)->len
);
7792 if (crv != CKR_OK0x00000000UL)
7793 break;
7794 /* XXX Do we need to decode the EC Params here ?? */
7795 break;
7796 default:
7797 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
7798 break;
7799 }
7800
7801 if (crv != CKR_OK0x00000000UL) {
7802 goto loser;
7803 }
7804
7805 /* For RSA-PSS, record the original algorithm parameters so
7806 * they can be encrypted altoghether when wrapping */
7807 if (SECOID_GetAlgorithmTagSECOID_GetAlgorithmTag_Util(&pki->algorithm) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
7808 NSSLOWKEYSubjectPublicKeyInfo spki;
7809 NSSLOWKEYPublicKey pubk;
7810 SECItem *publicKeyInfo;
7811
7812 memset(&spki, 0, sizeof(NSSLOWKEYSubjectPublicKeyInfo));
7813 rv = SECOID_CopyAlgorithmIDSECOID_CopyAlgorithmID_Util(arena, &spki.algorithm, &pki->algorithm);
7814 if (rv != SECSuccess) {
7815 crv = CKR_HOST_MEMORY0x00000002UL;
7816 goto loser;
7817 }
7818
7819 prepare_low_rsa_pub_key_for_asn1(&pubk);
7820
7821 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk.u.rsa.modulus, &lpk->u.rsa.modulus);
7822 if (rv != SECSuccess) {
7823 crv = CKR_HOST_MEMORY0x00000002UL;
7824 goto loser;
7825 }
7826 rv = SECITEM_CopyItemSECITEM_CopyItem_Util(arena, &pubk.u.rsa.publicExponent, &lpk->u.rsa.publicExponent);
7827 if (rv != SECSuccess) {
7828 crv = CKR_HOST_MEMORY0x00000002UL;
7829 goto loser;
7830 }
7831 pubk.u.rsa.needVerify = PR_FALSE0; /* We're just encoding the key from the
7832 * private key */
7833
7834 if (SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, &spki.subjectPublicKey,
7835 &pubk, nsslowkey_RSAPublicKeyTemplate) == NULL((void*)0)) {
7836 crv = CKR_HOST_MEMORY0x00000002UL;
7837 goto loser;
7838 }
7839
7840 publicKeyInfo = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(arena, NULL((void*)0),
7841 &spki, nsslowkey_SubjectPublicKeyInfoTemplate);
7842 if (!publicKeyInfo) {
7843 crv = CKR_HOST_MEMORY0x00000002UL;
7844 goto loser;
7845 }
7846 crv = sftk_AddAttributeType(key, CKA_PUBLIC_KEY_INFO0x00000129UL,
7847 sftk_item_expand(publicKeyInfo)(publicKeyInfo)->data, (publicKeyInfo)->len);
7848 }
7849
7850loser:
7851 if (lpk) {
7852 nsslowkey_DestroyPrivateKey(lpk);
7853 }
7854
7855 if (crv != CKR_OK0x00000000UL) {
7856 return SECFailure;
7857 }
7858
7859 return SECSuccess;
7860}
7861
7862/* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
7863CK_RV
7864NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
7865 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
7866 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
7867 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
7868 CK_OBJECT_HANDLE_PTR phKey)
7869{
7870 SFTKObject *key = NULL((void*)0);
7871 SFTKSession *session;
7872 CK_ULONG key_length = 0;
7873 unsigned char *buf = NULL((void*)0);
7874 CK_RV crv = CKR_OK0x00000000UL;
7875 int i;
7876 CK_ULONG bsize = ulWrappedKeyLen;
7877 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
7878 SECItem bpki;
7879 CK_OBJECT_CLASS target_type = CKO_SECRET_KEY0x00000004UL;
7880
7881 CHECK_FORK();
7882
7883 if (!slot) {
7884 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
7885 }
7886 /*
7887 * now lets create an object to hang the attributes off of
7888 */
7889 key = sftk_NewObject(slot); /* fill in the handle later */
7890 if (key == NULL((void*)0)) {
7891 return CKR_HOST_MEMORY0x00000002UL;
7892 }
7893
7894 /*
7895 * load the template values into the object
7896 */
7897 for (i = 0; i < (int)ulAttributeCount; i++) {
7898 if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) {
7899 key_length = *(CK_ULONG *)pTemplate[i].pValue;
7900 continue;
7901 }
7902 if (pTemplate[i].type == CKA_CLASS0x00000000UL) {
7903 target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
7904 }
7905 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
7906 if (crv != CKR_OK0x00000000UL)
7907 break;
7908 }
7909 if (crv != CKR_OK0x00000000UL) {
7910 sftk_FreeObject(key);
7911 return crv;
7912 }
7913
7914 crv = sftk_CryptInit(hSession, pMechanism, hUnwrappingKey, CKA_UNWRAP0x00000107UL,
7915 CKA_UNWRAP0x00000107UL, SFTK_DECRYPT, PR_FALSE0);
7916 if (crv != CKR_OK0x00000000UL) {
7917 sftk_FreeObject(key);
7918 return sftk_mapWrap(crv);
7919 }
7920
7921 /* allocate the buffer to decrypt into
7922 * this assumes the unwrapped key is never larger than the
7923 * wrapped key. For all the mechanisms we support this is true */
7924 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(ulWrappedKeyLen);
7925 bsize = ulWrappedKeyLen;
7926
7927 crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize);
7928 if (crv != CKR_OK0x00000000UL) {
7929 sftk_FreeObject(key);
7930 PORT_FreePORT_Free_Util(buf);
7931 return sftk_mapWrap(crv);
7932 }
7933
7934 switch (target_type) {
7935 case CKO_SECRET_KEY0x00000004UL:
7936 if (!sftk_hasAttribute(key, CKA_KEY_TYPE0x00000100UL)) {
7937 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
7938 break;
7939 }
7940
7941 if (key_length == 0 || key_length > bsize) {
7942 key_length = bsize;
7943 }
7944 if (key_length > MAX_KEY_LEN256) {
7945 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
7946 break;
7947 }
7948
7949 /* add the value */
7950 crv = sftk_AddAttributeType(key, CKA_VALUE0x00000011UL, buf, key_length);
7951 break;
7952 case CKO_PRIVATE_KEY0x00000003UL:
7953 bpki.data = (unsigned char *)buf;
7954 bpki.len = bsize;
7955 crv = CKR_OK0x00000000UL;
7956 if (sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) {
7957 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
7958 }
7959 break;
7960 default:
7961 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
7962 break;
7963 }
7964
7965 PORT_ZFreePORT_ZFree_Util(buf, bsize);
7966 if (crv != CKR_OK0x00000000UL) {
7967 sftk_FreeObject(key);
7968 return crv;
7969 }
7970
7971 /* get the session */
7972 session = sftk_SessionFromHandle(hSession);
7973 if (session == NULL((void*)0)) {
7974 sftk_FreeObject(key);
7975 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
7976 }
7977
7978 /* mark the key as FIPS if the previous operation was all FIPS */
7979 sftk_setFIPS(key, session->lastOpWasFIPS);
7980 /*
7981 * handle the base object stuff
7982 */
7983 crv = sftk_handleObject(key, session);
7984 *phKey = key->handle;
7985 sftk_FreeSession(session);
7986 sftk_FreeObject(key);
7987
7988 return crv;
7989}
7990
7991CK_RV
7992NSC_WrapKeyAuthenticated(CK_SESSION_HANDLE hSession,
7993 CK_MECHANISM_PTR pMechanism,
7994 CK_OBJECT_HANDLE hWrappingKey,
7995 CK_OBJECT_HANDLE hKey,
7996 CK_BYTE_PTR pAssociatedData,
7997 CK_ULONG ulAssociatedDataLen,
7998 CK_BYTE_PTR pWrappedKey,
7999 CK_ULONG_PTR pulWrappedKeyLen)
8000{
8001 CHECK_FORK();
8002
8003 return CKR_FUNCTION_NOT_SUPPORTED0x00000054UL;
8004}
8005
8006CK_RV
8007NSC_UnwrapKeyAuthenticated(CK_SESSION_HANDLE hSession,
8008 CK_MECHANISM_PTR pMechanism,
8009 CK_OBJECT_HANDLE hUnwrappingKey,
8010 CK_BYTE_PTR pWrappedKey,
8011 CK_ULONG ulWrappedKeyLen,
8012 CK_ATTRIBUTE_PTR pTemplate,
8013 CK_ULONG ulAttributeCount,
8014 CK_BYTE_PTR pAssociatedData,
8015 CK_ULONG ulAssociatedDataLen,
8016 CK_OBJECT_HANDLE_PTR phKey)
8017{
8018 CHECK_FORK();
8019
8020 return CKR_FUNCTION_NOT_SUPPORTED0x00000054UL;
8021}
8022
8023/*
8024 * The SSL key gen mechanism create's lots of keys. This function handles the
8025 * details of each of these key creation.
8026 */
8027static CK_RV
8028sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey,
8029 PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize,
8030 CK_OBJECT_HANDLE *keyHandle)
8031{
8032 SFTKObject *key;
8033 SFTKSession *session;
8034 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET0x00000010UL;
8035 CK_BBOOL cktrue = CK_TRUE1;
8036 CK_BBOOL ckfalse = CK_FALSE0;
8037 CK_RV crv = CKR_HOST_MEMORY0x00000002UL;
8038
8039 /*
8040 * now lets create an object to hang the attributes off of
8041 */
8042 *keyHandle = CK_INVALID_HANDLE0;
8043 key = sftk_NewObject(baseKey->slot);
8044 if (key == NULL((void*)0))
8045 return CKR_HOST_MEMORY0x00000002UL;
8046 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
8047 PORT_Assert(sessKey)((sessKey) ? ((void)0) : PR_Assert("sessKey", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 8047))
;
8048 sessKey->wasDerived = PR_TRUE1;
8049
8050 crv = sftk_CopyObject(key, baseKey);
8051 if (crv != CKR_OK0x00000000UL)
8052 goto loser;
8053 if (isMacKey) {
8054 crv = sftk_forceAttribute(key, CKA_KEY_TYPE0x00000100UL, &keyType, sizeof(keyType));
8055 if (crv != CKR_OK0x00000000UL)
8056 goto loser;
8057 crv = sftk_forceAttribute(key, CKA_DERIVE0x0000010CUL, &cktrue, sizeof(CK_BBOOL));
8058 if (crv != CKR_OK0x00000000UL)
8059 goto loser;
8060 crv = sftk_forceAttribute(key, CKA_ENCRYPT0x00000104UL, &ckfalse, sizeof(CK_BBOOL));
8061 if (crv != CKR_OK0x00000000UL)
8062 goto loser;
8063 crv = sftk_forceAttribute(key, CKA_DECRYPT0x00000105UL, &ckfalse, sizeof(CK_BBOOL));
8064 if (crv != CKR_OK0x00000000UL)
8065 goto loser;
8066 crv = sftk_forceAttribute(key, CKA_SIGN0x00000108UL, &cktrue, sizeof(CK_BBOOL));
8067 if (crv != CKR_OK0x00000000UL)
8068 goto loser;
8069 crv = sftk_forceAttribute(key, CKA_VERIFY0x0000010AUL, &cktrue, sizeof(CK_BBOOL));
8070 if (crv != CKR_OK0x00000000UL)
8071 goto loser;
8072 crv = sftk_forceAttribute(key, CKA_WRAP0x00000106UL, &ckfalse, sizeof(CK_BBOOL));
8073 if (crv != CKR_OK0x00000000UL)
8074 goto loser;
8075 crv = sftk_forceAttribute(key, CKA_UNWRAP0x00000107UL, &ckfalse, sizeof(CK_BBOOL));
8076 if (crv != CKR_OK0x00000000UL)
8077 goto loser;
8078 }
8079 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, keyBlock, keySize);
8080 if (crv != CKR_OK0x00000000UL)
8081 goto loser;
8082
8083 /* get the session */
8084 crv = CKR_HOST_MEMORY0x00000002UL;
8085 session = sftk_SessionFromHandle(hSession);
8086 if (session == NULL((void*)0)) {
8087 goto loser;
8088 }
8089
8090 crv = sftk_handleObject(key, session);
8091 sftk_FreeSession(session);
8092 *keyHandle = key->handle;
8093loser:
8094 if (key)
8095 sftk_FreeObject(key);
8096 return crv;
8097}
8098
8099/*
8100 * if there is an error, we need to free the keys we already created in SSL
8101 * This is the routine that will do it..
8102 */
8103static void
8104sftk_freeSSLKeys(CK_SESSION_HANDLE session,
8105 CK_SSL3_KEY_MAT_OUT *returnedMaterial)
8106{
8107 if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE0) {
8108 NSC_DestroyObject(session, returnedMaterial->hClientMacSecret);
8109 }
8110 if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE0) {
8111 NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
8112 }
8113 if (returnedMaterial->hClientKey != CK_INVALID_HANDLE0) {
8114 NSC_DestroyObject(session, returnedMaterial->hClientKey);
8115 }
8116 if (returnedMaterial->hServerKey != CK_INVALID_HANDLE0) {
8117 NSC_DestroyObject(session, returnedMaterial->hServerKey);
8118 }
8119}
8120
8121/*
8122 * when deriving from sensitive and extractable keys, we need to preserve some
8123 * of the semantics in the derived key. This helper routine maintains these
8124 * semantics.
8125 */
8126static CK_RV
8127sftk_DeriveSensitiveCheck(SFTKObject *baseKey, SFTKObject *destKey,
8128 PRBool canBeData)
8129{
8130 PRBool hasSensitive;
8131 PRBool sensitive = PR_FALSE0;
8132 CK_BBOOL bFalse = CK_FALSE0;
8133 PRBool hasExtractable;
8134 PRBool extractable = PR_TRUE1;
8135 CK_BBOOL bTrue = CK_TRUE1;
8136 CK_RV crv = CKR_OK0x00000000UL;
8137 SFTKAttribute *att;
8138 PRBool isData = PR_TRUE1;
8139
8140 if (canBeData) {
8141 CK_OBJECT_CLASS objClass;
8142
8143 /* if the target key is actually data, don't set the unexpected
8144 * attributes */
8145 crv = sftk_GetULongAttribute(destKey, CKA_CLASS0x00000000UL, &objClass);
8146 if (crv != CKR_OK0x00000000UL) {
8147 return crv;
8148 }
8149 if (objClass == CKO_DATA0x00000000UL) {
8150 return CKR_OK0x00000000UL;
8151 }
8152
8153 /* if the base key is data, it doesn't have sensitive attributes,
8154 * allow the destKey to get it's own */
8155 crv = sftk_GetULongAttribute(baseKey, CKA_CLASS0x00000000UL, &objClass);
8156 if (crv != CKR_OK0x00000000UL) {
8157 return crv;
8158 }
8159 if (objClass == CKO_DATA0x00000000UL) {
8160 isData = PR_TRUE1;
8161 }
8162 }
8163
8164 hasSensitive = PR_FALSE0;
8165 att = sftk_FindAttribute(destKey, CKA_SENSITIVE0x00000103UL);
8166 if (att) {
8167 hasSensitive = PR_TRUE1;
8168 sensitive = (PRBool) * (CK_BBOOL *)att->attrib.pValue;
8169 sftk_FreeAttribute(att);
8170 }
8171
8172 hasExtractable = PR_FALSE0;
8173 att = sftk_FindAttribute(destKey, CKA_EXTRACTABLE0x00000162UL);
8174 if (att) {
8175 hasExtractable = PR_TRUE1;
8176 extractable = (PRBool) * (CK_BBOOL *)att->attrib.pValue;
8177 sftk_FreeAttribute(att);
8178 }
8179
8180 /* don't make a key more accessible */
8181 if (sftk_isTrue(baseKey, CKA_SENSITIVE0x00000103UL) && hasSensitive &&
8182 (sensitive == PR_FALSE0)) {
8183 return CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
8184 }
8185 if (!sftk_isTrue(baseKey, CKA_EXTRACTABLE0x00000162UL) && hasExtractable &&
8186 (extractable == PR_TRUE1)) {
8187 return CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
8188 }
8189
8190 /* inherit parent's sensitivity */
8191 if (!hasSensitive) {
8192 att = sftk_FindAttribute(baseKey, CKA_SENSITIVE0x00000103UL);
8193 if (att != NULL((void*)0)) {
8194 crv = sftk_defaultAttribute(destKey,
8195 sftk_attr_expand(&att->attrib)(&att->attrib)->type, (&att->attrib)->pValue
, (&att->attrib)->ulValueLen
);
8196 sftk_FreeAttribute(att);
8197 } else if (isData) {
8198 crv = sftk_defaultAttribute(destKey, CKA_SENSITIVE0x00000103UL,
8199 &bFalse, sizeof(bFalse));
8200 } else {
8201 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
8202 }
8203 if (crv != CKR_OK0x00000000UL)
8204 return crv;
8205 }
8206 if (!hasExtractable) {
8207 att = sftk_FindAttribute(baseKey, CKA_EXTRACTABLE0x00000162UL);
8208 if (att != NULL((void*)0)) {
8209 crv = sftk_defaultAttribute(destKey,
8210 sftk_attr_expand(&att->attrib)(&att->attrib)->type, (&att->attrib)->pValue
, (&att->attrib)->ulValueLen
);
8211 sftk_FreeAttribute(att);
8212 } else if (isData) {
8213 crv = sftk_defaultAttribute(destKey, CKA_EXTRACTABLE0x00000162UL,
8214 &bTrue, sizeof(bTrue));
8215 } else {
8216 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
8217 }
8218 if (crv != CKR_OK0x00000000UL)
8219 return crv;
8220 }
8221
8222 /* we should inherit the parent's always extractable/ never sensitive info,
8223 * but handleObject always forces this attributes, so we would need to do
8224 * something special. */
8225 return CKR_OK0x00000000UL;
8226}
8227
8228/*
8229 * make known fixed PKCS #11 key types to their sizes in bytes
8230 */
8231unsigned long
8232sftk_MapKeySize(CK_KEY_TYPE keyType)
8233{
8234 switch (keyType) {
8235 case CKK_CDMF0x0000001EUL:
8236 return 8;
8237 case CKK_DES0x00000013UL:
8238 return 8;
8239 case CKK_DES20x00000014UL:
8240 return 16;
8241 case CKK_DES30x00000015UL:
8242 return 24;
8243 /* IDEA and CAST need to be added */
8244 default:
8245 break;
8246 }
8247 return 0;
8248}
8249
8250/* Inputs:
8251 * key_len: Length of derived key to be generated.
8252 * SharedSecret: a shared secret that is the output of a key agreement primitive.
8253 * SharedInfo: (Optional) some data shared by the entities computing the secret key.
8254 * SharedInfoLen: the length in octets of SharedInfo
8255 * Hash: The hash function to be used in the KDF
8256 * HashLen: the length in octets of the output of Hash
8257 * Output:
8258 * key: Pointer to a buffer containing derived key, if return value is SECSuccess.
8259 */
8260static CK_RV
8261sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECItem *SharedSecret,
8262 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
8263 SECStatus Hash(unsigned char *, const unsigned char *, PRUint32),
8264 CK_ULONG HashLen)
8265{
8266 unsigned char *buffer = NULL((void*)0), *output_buffer = NULL((void*)0);
8267 PRUint32 buffer_len, max_counter, i;
8268 SECStatus rv;
8269 CK_RV crv;
8270
8271 /* Check that key_len isn't too long. The maximum key length could be
8272 * greatly increased if the code below did not limit the 4-byte counter
8273 * to a maximum value of 255. */
8274 if (key_len > 254 * HashLen)
8275 return CKR_ARGUMENTS_BAD0x00000007UL;
8276
8277 if (SharedInfo == NULL((void*)0))
8278 SharedInfoLen = 0;
8279
8280 if (SharedSecret->len > PR_UINT32_MAX4294967295U - 4 ||
8281 SharedInfoLen > PR_UINT32_MAX4294967295U - 4 - SharedSecret->len)
8282 return CKR_ARGUMENTS_BAD0x00000007UL;
8283
8284 buffer_len = SharedSecret->len + 4 + SharedInfoLen;
8285 buffer = (CK_BYTE *)PORT_AllocPORT_Alloc_Util(buffer_len);
8286 if (buffer == NULL((void*)0)) {
8287 crv = CKR_HOST_MEMORY0x00000002UL;
8288 goto loser;
8289 }
8290
8291 max_counter = key_len / HashLen;
8292 if (key_len > max_counter * HashLen)
8293 max_counter++;
8294
8295 output_buffer = (CK_BYTE *)PORT_AllocPORT_Alloc_Util(max_counter * HashLen);
8296 if (output_buffer == NULL((void*)0)) {
8297 crv = CKR_HOST_MEMORY0x00000002UL;
8298 goto loser;
8299 }
8300
8301 /* Populate buffer with SharedSecret || Counter || [SharedInfo]
8302 * where Counter is 0x00000001 */
8303 PORT_Memcpymemcpy(buffer, SharedSecret->data, SharedSecret->len);
8304 buffer[SharedSecret->len] = 0;
8305 buffer[SharedSecret->len + 1] = 0;
8306 buffer[SharedSecret->len + 2] = 0;
8307 buffer[SharedSecret->len + 3] = 1;
8308 if (SharedInfo) {
8309 PORT_Memcpymemcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen);
8310 }
8311
8312 for (i = 0; i < max_counter; i++) {
8313 rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len);
8314 if (rv != SECSuccess) {
8315 /* 'Hash' should not fail. */
8316 crv = CKR_FUNCTION_FAILED0x00000006UL;
8317 goto loser;
8318 }
8319
8320 /* Increment counter (assumes max_counter < 255) */
8321 buffer[SharedSecret->len + 3]++;
8322 }
8323
8324 PORT_ZFreePORT_ZFree_Util(buffer, buffer_len);
8325 if (key_len < max_counter * HashLen) {
8326 PORT_Memsetmemset(output_buffer + key_len, 0, max_counter * HashLen - key_len);
8327 }
8328 *key = output_buffer;
8329
8330 return CKR_OK0x00000000UL;
8331
8332loser:
8333 if (buffer) {
8334 PORT_ZFreePORT_ZFree_Util(buffer, buffer_len);
8335 }
8336 if (output_buffer) {
8337 PORT_ZFreePORT_ZFree_Util(output_buffer, max_counter * HashLen);
8338 }
8339 return crv;
8340}
8341
8342static CK_RV
8343sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len,
8344 SECItem *SharedSecret,
8345 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
8346 CK_EC_KDF_TYPE kdf)
8347{
8348 if (kdf == CKD_SHA1_KDF0x00000002UL)
8349 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8350 SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH20);
8351 else if (kdf == CKD_SHA224_KDF0x00000005UL)
8352 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8353 SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH28);
8354 else if (kdf == CKD_SHA256_KDF0x00000006UL)
8355 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8356 SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH32);
8357 else if (kdf == CKD_SHA384_KDF0x00000007UL)
8358 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8359 SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH48);
8360 else if (kdf == CKD_SHA512_KDF0x00000008UL)
8361 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
8362 SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH64);
8363 else
8364 return CKR_MECHANISM_INVALID0x00000070UL;
8365}
8366
8367/*
8368 * Handle the derive from a block encryption cipher
8369 */
8370CK_RV
8371sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo,
8372 int blockSize, SFTKObject *key, CK_ULONG keySize,
8373 unsigned char *data, CK_ULONG len)
8374{
8375 /* large enough for a 512-bit key */
8376 unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE64];
8377 SECStatus rv;
8378 unsigned int outLen;
8379 CK_RV crv;
8380
8381 if ((len % blockSize) != 0) {
8382 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8383 }
8384 if (len > SFTK_MAX_DERIVE_KEY_SIZE64) {
8385 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8386 }
8387 if (keySize && (len < keySize)) {
8388 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8389 }
8390 if (keySize == 0) {
8391 keySize = len;
8392 }
8393
8394 rv = (*encrypt)(cipherInfo, (unsigned char *)&tmpdata, &outLen, len, data, len);
8395 if (rv != SECSuccess) {
8396 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
8397 return crv;
8398 }
8399
8400 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, tmpdata, keySize);
8401 PORT_Memsetmemset(tmpdata, 0, sizeof tmpdata);
8402 return crv;
8403}
8404
8405CK_RV
8406sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_SESSION_HANDLE hSession,
8407 SFTKObject *sourceKey, const unsigned char *sourceKeyBytes,
8408 int sourceKeyLen, SFTKObject *key, unsigned char *outKeyBytes,
8409 int keySize, PRBool canBeData, PRBool isFIPS)
8410{
8411 SFTKSession *session;
8412 SFTKAttribute *saltKey_att = NULL((void*)0);
8413 const SECHashObject *rawHash;
8414 unsigned hashLen;
8415 unsigned genLen = 0;
8416 unsigned char hashbuf[HASH_LENGTH_MAX64];
8417 unsigned char keyBlock[9 * SFTK_MAX_MAC_LENGTH64];
8418 unsigned char *keyBlockAlloc = NULL((void*)0); /* allocated keyBlock */
8419 unsigned char *keyBlockData = keyBlock; /* pointer to current keyBlock */
8420 const unsigned char *prk; /* psuedo-random key */
8421 CK_ULONG prkLen;
8422 const unsigned char *okm; /* output keying material */
8423 HASH_HashType hashType = sftk_GetHashTypeFromMechanism(params->prfHashMechanism);
8424 SFTKObject *saltKey = NULL((void*)0);
8425 CK_RV crv = CKR_OK0x00000000UL;
8426
8427 /* Spec says it should be the base hash, but also accept the HMAC */
8428 if (hashType == HASH_AlgNULL) {
8429 hashType = sftk_HMACMechanismToHash(params->prfHashMechanism);
8430 }
8431 rawHash = HASH_GetRawHashObject(hashType);
8432 if (rawHash == NULL((void*)0) || rawHash->length > sizeof(hashbuf)) {
8433 return CKR_MECHANISM_INVALID0x00000070UL;
8434 }
8435 hashLen = rawHash->length;
8436
8437 if ((!params->bExpand && !params->bExtract) ||
8438 (params->bExtract && params->ulSaltLen > 0 && !params->pSalt) ||
8439 (params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) {
8440 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8441 }
8442 if ((params->bExpand && keySize == 0) ||
8443 (!params->bExpand && keySize > hashLen) ||
8444 (params->bExpand && keySize > 255 * hashLen)) {
8445 return CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
8446 }
8447
8448 if (!params->bExpand) {
8449 keySize = hashLen;
8450 }
8451
8452 /* sourceKey is NULL if we are called from the POST, skip the
8453 * sensitiveCheck */
8454 if (sourceKey != NULL((void*)0)) {
8455 crv = sftk_DeriveSensitiveCheck(sourceKey, key, canBeData);
8456 if (crv != CKR_OK0x00000000UL)
8457 return crv;
8458 /* if the source key is data, clear the FIPS flag
8459 * and only get the FIPS state from the salt */
8460 if (sourceKey->objclass == CKO_DATA0x00000000UL) {
8461 sftk_setFIPS(key, PR_FALSE0);
8462 }
8463 }
8464
8465 /* HKDF-Extract(salt, base key value) */
8466 if (params->bExtract) {
8467 CK_BYTE *salt;
8468 CK_ULONG saltLen;
8469 HMACContext *hmac;
8470 unsigned int bufLen;
8471 SFTKSource saltKeySource = SFTK_SOURCE_DEFAULT;
8472
8473 switch (params->ulSaltType) {
8474 case CKF_HKDF_SALT_NULL0x00000001UL:
8475 saltLen = hashLen;
8476 salt = hashbuf;
8477 memset(salt, 0, saltLen);
8478 break;
8479 case CKF_HKDF_SALT_DATA0x00000002UL:
8480 salt = params->pSalt;
8481 saltLen = params->ulSaltLen;
8482 if ((salt == NULL((void*)0)) || (params->ulSaltLen == 0)) {
8483 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8484 }
8485 break;
8486 case CKF_HKDF_SALT_KEY0x00000004UL:
8487 /* lookup key */
8488 session = sftk_SessionFromHandle(hSession);
8489 if (session == NULL((void*)0)) {
8490 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
8491 }
8492
8493 saltKey = sftk_ObjectFromHandle(params->hSaltKey, session);
8494 sftk_FreeSession(session);
8495 if (saltKey == NULL((void*)0)) {
8496 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8497 }
8498 /* if the base key is not fips, but the salt key is, the
8499 * resulting key can be fips */
8500 if (isFIPS && !sftk_hasFIPS(key) && sftk_hasFIPS(saltKey)) {
8501 CK_MECHANISM mech;
8502 mech.mechanism = CKM_HKDF_DERIVE0x0000402aUL;
8503 mech.pParameter = params;
8504 mech.ulParameterLen = sizeof(*params);
8505 sftk_setFIPS(key, sftk_operationIsFIPS(saltKey->slot,
8506 &mech, CKA_DERIVE0x0000010CUL,
8507 saltKey,
8508 keySize * PR_BITS_PER_BYTE8));
8509 }
8510 saltKeySource = saltKey->source;
8511 saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE0x00000011UL);
8512 if (saltKey_att == NULL((void*)0)) {
8513 sftk_FreeObject(saltKey);
8514 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8515 }
8516 /* save the resulting salt */
8517 salt = saltKey_att->attrib.pValue;
8518 saltLen = saltKey_att->attrib.ulValueLen;
8519 break;
8520 default:
8521 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8522 break;
8523 }
8524 /* only TLS style usage is FIPS approved,
8525 * turn off the FIPS indicator for other usages */
8526 if (isFIPS && key && sourceKey) {
8527 PRBool fipsOK = PR_FALSE0;
8528 /* case one: mix the kea with a previous or default
8529 * salt */
8530 if ((sourceKey->source == SFTK_SOURCE_KEA) &&
8531 (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
8532 (saltLen == rawHash->length)) {
8533 fipsOK = PR_TRUE1;
8534 }
8535 /* case two: restart, remix the previous secret as a salt */
8536 if ((sourceKey->objclass == CKO_DATA0x00000000UL) &&
8537 (NSS_SecureMemcmpZero(sourceKeyBytes, sourceKeyLen) == 0) &&
8538 (sourceKeyLen == rawHash->length) &&
8539 (saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
8540 (saltLen == rawHash->length)) {
8541 fipsOK = PR_TRUE1;
8542 }
8543 if (!fipsOK) {
8544 sftk_setFIPS(key, PR_FALSE0);
8545 }
8546 }
8547 if (key)
8548 key->source = SFTK_SOURCE_HKDF_EXTRACT;
8549
8550 hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
8551 if (saltKey_att) {
8552 sftk_FreeAttribute(saltKey_att);
8553 }
8554 if (saltKey) {
8555 sftk_FreeObject(saltKey);
8556 }
8557 if (!hmac) {
8558 return CKR_HOST_MEMORY0x00000002UL;
8559 }
8560 HMAC_Begin(hmac);
8561 HMAC_Update(hmac, sourceKeyBytes, sourceKeyLen);
8562 HMAC_Finish(hmac, hashbuf, &bufLen, sizeof(hashbuf));
8563 HMAC_Destroy(hmac, PR_TRUE1);
8564 PORT_Assert(bufLen == rawHash->length)((bufLen == rawHash->length) ? ((void)0) : PR_Assert("bufLen == rawHash->length"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 8564
))
;
8565 prk = hashbuf;
8566 prkLen = bufLen;
8567 } else {
8568 /* PRK = base key value */
8569 prk = sourceKeyBytes;
8570 prkLen = sourceKeyLen;
8571 }
8572
8573 /* HKDF-Expand */
8574 if (!params->bExpand) {
8575 okm = prk;
8576 genLen = hashLen;
8577 } else {
8578 /* T(1) = HMAC-Hash(prk, "" | info | 0x01)
8579 * T(n) = HMAC-Hash(prk, T(n-1) | info | n
8580 * key material = T(1) | ... | T(n)
8581 */
8582 HMACContext *hmac;
8583 CK_BYTE bi;
8584 unsigned iterations;
8585
8586 /* only TLS style usage is FIPS approved,
8587 * turn off the FIPS indicator for other usages */
8588 if (isFIPS && key && sftk_hasFIPS(key) && sourceKey) {
8589 /* only one case,
8590 * 1) Expand only
8591 * 2) with a key whose source was
8592 * SFTK_SOURCE_HKDF_EXPAND or SFTK_SOURCE_HKDF_EXTRACT
8593 * 3) source key length == rawHash->length
8594 * 4) Info has tls or dtls
8595 * If any of those conditions aren't met, then we turn
8596 * off the fips indicator */
8597 if (params->bExtract ||
8598 ((sourceKey->source != SFTK_SOURCE_HKDF_EXTRACT) &&
8599 (sourceKey->source != SFTK_SOURCE_HKDF_EXPAND)) ||
8600 (sourceKeyLen != rawHash->length) ||
8601 (params->ulInfoLen < 7) ||
8602 ((PORT_Memcmpmemcmp(&params->pInfo[3], "tls", 3) != 0) &&
8603 (PORT_Memcmpmemcmp(&params->pInfo[3], "dtls", 4) != 0))) {
8604 sftk_setFIPS(key, PR_FALSE0);
8605 }
8606 }
8607 if (key)
8608 key->source = SFTK_SOURCE_HKDF_EXPAND;
8609
8610 genLen = PR_ROUNDUP(keySize, hashLen)((((keySize) + ((hashLen) - 1)) / (hashLen)) * (hashLen));
8611 iterations = genLen / hashLen;
8612
8613 if (genLen > sizeof(keyBlock)) {
8614 keyBlockAlloc = PORT_AllocPORT_Alloc_Util(genLen);
8615 if (keyBlockAlloc == NULL((void*)0)) {
8616 return CKR_HOST_MEMORY0x00000002UL;
8617 }
8618 keyBlockData = keyBlockAlloc;
8619 }
8620 hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
8621 if (hmac == NULL((void*)0)) {
8622 PORT_FreePORT_Free_Util(keyBlockAlloc);
8623 return CKR_HOST_MEMORY0x00000002UL;
8624 }
8625 for (bi = 1; bi <= iterations && bi > 0; ++bi) {
8626 unsigned len;
8627 HMAC_Begin(hmac);
8628 if (bi > 1) {
8629 HMAC_Update(hmac, &keyBlockData[(bi - 2) * hashLen], hashLen);
8630 }
8631 if (params->ulInfoLen != 0) {
8632 HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
8633 }
8634 HMAC_Update(hmac, &bi, 1);
8635 HMAC_Finish(hmac, &keyBlockData[(bi - 1) * hashLen], &len,
8636 hashLen);
8637 PORT_Assert(len == hashLen)((len == hashLen) ? ((void)0) : PR_Assert("len == hashLen", "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c"
, 8637))
;
8638 }
8639 HMAC_Destroy(hmac, PR_TRUE1);
8640 okm = &keyBlockData[0];
8641 }
8642 /* key material = okm */
8643 crv = CKR_OK0x00000000UL;
8644 if (key) {
8645 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, okm, keySize);
8646 } else {
8647 PORT_Assert(outKeyBytes != NULL)((outKeyBytes != ((void*)0)) ? ((void)0) : PR_Assert("outKeyBytes != NULL"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 8647
))
;
8648 PORT_Memcpymemcpy(outKeyBytes, okm, keySize);
8649 }
8650 PORT_Memsetmemset(keyBlockData, 0, genLen);
8651 PORT_Memsetmemset(hashbuf, 0, sizeof(hashbuf));
8652 PORT_FreePORT_Free_Util(keyBlockAlloc);
8653 return crv;
8654}
8655
8656/*
8657 * SSL Key generation given pre master secret
8658 */
8659#define NUM_MIXERS9 9
8660static const char *const mixers[NUM_MIXERS9] = {
8661 "A",
8662 "BB",
8663 "CCC",
8664 "DDDD",
8665 "EEEEE",
8666 "FFFFFF",
8667 "GGGGGGG",
8668 "HHHHHHHH",
8669 "IIIIIIIII"
8670};
8671#define SSL3_PMS_LENGTH48 48
8672#define SSL3_MASTER_SECRET_LENGTH48 48
8673#define SSL3_RANDOM_LENGTH32 32
8674
8675/* NSC_DeriveKey derives a key from a base key, creating a new key object. */
8676CK_RV
8677NSC_DeriveKey(CK_SESSION_HANDLE hSession,
8678 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
8679 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
8680 CK_OBJECT_HANDLE_PTR phKey)
8681{
8682 SFTKSession *session;
8683 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
8684 SFTKObject *key;
8685 SFTKObject *sourceKey;
8686 SFTKAttribute *att = NULL((void*)0);
8687 SFTKAttribute *att2 = NULL((void*)0);
8688 unsigned char *buf;
8689 SHA1Context *sha;
8690 MD5Context *md5;
8691 MD2Context *md2;
8692 CK_ULONG macSize;
8693 CK_ULONG tmpKeySize;
8694 CK_ULONG IVSize;
8695 CK_ULONG keySize = 0;
8696 CK_RV crv = CKR_OK0x00000000UL;
8697 CK_BBOOL cktrue = CK_TRUE1;
8698 CK_BBOOL ckfalse = CK_FALSE0;
8699 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET0x00000010UL;
8700 CK_OBJECT_CLASS classType = CKO_SECRET_KEY0x00000004UL;
8701 CK_KEY_DERIVATION_STRING_DATA *stringPtr;
8702 PRBool isTLS = PR_FALSE0;
8703 PRBool isDH = PR_FALSE0;
8704 HASH_HashType tlsPrfHash = HASH_AlgNULL;
8705 SECStatus rv;
8706 int i;
8707 unsigned int outLen;
8708 unsigned char sha_out[SHA1_LENGTH20];
8709 unsigned char key_block[NUM_MIXERS9 * SFTK_MAX_MAC_LENGTH64];
8710 PRBool isFIPS;
8711 HASH_HashType hashType;
8712 CK_MECHANISM_TYPE hashMech;
8713 PRBool extractValue = PR_TRUE1;
8714 CK_IKE1_EXTENDED_DERIVE_PARAMS ikeAppB;
8715 CK_IKE1_EXTENDED_DERIVE_PARAMS *pIkeAppB;
8716
8717 CHECK_FORK();
8718
8719 if (!slot) {
8720 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
8721 }
8722 if (!pMechanism) {
8723 return CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8724 }
8725 CK_MECHANISM_TYPE mechanism = pMechanism->mechanism;
8726
8727 /*
8728 * now lets create an object to hang the attributes off of
8729 */
8730 if (phKey) {
8731 *phKey = CK_INVALID_HANDLE0;
8732 }
8733
8734 key = sftk_NewObject(slot); /* fill in the handle later */
8735 if (key == NULL((void*)0)) {
8736 return CKR_HOST_MEMORY0x00000002UL;
8737 }
8738 isFIPS = sftk_isFIPS(slot->slotID)(((slot->slotID) == 3) || ((slot->slotID) >= 101));
8739
8740 /*
8741 * load the template values into the object
8742 */
8743 for (i = 0; i < (int)ulAttributeCount; i++) {
8744 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])(&pTemplate[i])->type, (&pTemplate[i])->pValue,
(&pTemplate[i])->ulValueLen
);
8745 if (crv != CKR_OK0x00000000UL)
8746 break;
8747
8748 if (pTemplate[i].type == CKA_KEY_TYPE0x00000100UL) {
8749 keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue;
8750 }
8751 if (pTemplate[i].type == CKA_VALUE_LEN0x00000161UL) {
8752 keySize = *(CK_ULONG *)pTemplate[i].pValue;
8753 }
8754 }
8755 if (crv != CKR_OK0x00000000UL) {
8756 sftk_FreeObject(key);
8757 return crv;
8758 }
8759
8760 if (keySize == 0) {
8761 keySize = sftk_MapKeySize(keyType);
8762 }
8763
8764 switch (mechanism) {
8765 case CKM_NSS_JPAKE_ROUND2_SHA1((0x80000000UL | 0x4E534350) + 11): /* fall through */
8766 case CKM_NSS_JPAKE_ROUND2_SHA256((0x80000000UL | 0x4E534350) + 12): /* fall through */
8767 case CKM_NSS_JPAKE_ROUND2_SHA384((0x80000000UL | 0x4E534350) + 13): /* fall through */
8768 case CKM_NSS_JPAKE_ROUND2_SHA512((0x80000000UL | 0x4E534350) + 14):
8769 extractValue = PR_FALSE0;
8770 classType = CKO_PRIVATE_KEY0x00000003UL;
8771 break;
8772 case CKM_NSS_PUB_FROM_PRIV((0x80000000UL | 0x4E534350) + 40):
8773 extractValue = PR_FALSE0;
8774 classType = CKO_PUBLIC_KEY0x00000002UL;
8775 break;
8776 case CKM_HKDF_DATA0x0000402bUL: /* fall through */
8777 case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 42): /* fall through */
8778 case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 43): /* fall through */
8779 case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 44):
8780 classType = CKO_DATA0x00000000UL;
8781 break;
8782 case CKM_NSS_JPAKE_FINAL_SHA1((0x80000000UL | 0x4E534350) + 15): /* fall through */
8783 case CKM_NSS_JPAKE_FINAL_SHA256((0x80000000UL | 0x4E534350) + 16): /* fall through */
8784 case CKM_NSS_JPAKE_FINAL_SHA384((0x80000000UL | 0x4E534350) + 17): /* fall through */
8785 case CKM_NSS_JPAKE_FINAL_SHA512((0x80000000UL | 0x4E534350) + 18):
8786 extractValue = PR_FALSE0;
8787 /* fall through */
8788 default:
8789 classType = CKO_SECRET_KEY0x00000004UL;
8790 }
8791
8792 crv = sftk_forceAttribute(key, CKA_CLASS0x00000000UL, &classType, sizeof(classType));
8793 if (crv != CKR_OK0x00000000UL) {
8794 sftk_FreeObject(key);
8795 return crv;
8796 }
8797
8798 /* look up the base key we're deriving with */
8799 session = sftk_SessionFromHandle(hSession);
8800 if (session == NULL((void*)0)) {
8801 sftk_FreeObject(key);
8802 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
8803 }
8804
8805 sourceKey = sftk_ObjectFromHandle(hBaseKey, session);
8806 /* is this eventually succeeds, lastOpWasFIPS will be set the resulting key's
8807 * FIPS state below. */
8808 session->lastOpWasFIPS = PR_FALSE0;
8809 sftk_FreeSession(session);
8810 if (sourceKey == NULL((void*)0)) {
8811 sftk_FreeObject(key);
8812 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8813 }
8814
8815 if (extractValue) {
8816 /* get the value of the base key */
8817 att = sftk_FindAttribute(sourceKey, CKA_VALUE0x00000011UL);
8818 if (att == NULL((void*)0)) {
8819 sftk_FreeObject(key);
8820 sftk_FreeObject(sourceKey);
8821 return CKR_KEY_HANDLE_INVALID0x00000060UL;
8822 }
8823 }
8824 sftk_setFIPS(key, sftk_operationIsFIPS(slot, pMechanism,
8825 CKA_DERIVE0x0000010CUL, sourceKey,
8826 keySize * PR_BITS_PER_BYTE8));
8827
8828 switch (mechanism) {
8829 /* get a public key from a private key. nsslowkey_ConvertToPublickey()
8830 * will generate the public portion if it doesn't already exist. */
8831 case CKM_NSS_PUB_FROM_PRIV((0x80000000UL | 0x4E534350) + 40): {
8832 NSSLOWKEYPrivateKey *privKey;
8833 NSSLOWKEYPublicKey *pubKey;
8834 int error;
8835
8836 crv = sftk_GetULongAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL, &keyType);
8837 if (crv != CKR_OK0x00000000UL) {
8838 break;
8839 }
8840
8841 /* privKey is stored in sourceKey and will be destroyed when
8842 * the sourceKey is freed. */
8843 privKey = sftk_GetPrivKey(sourceKey, keyType, &crv);
8844 if (privKey == NULL((void*)0)) {
8845 break;
8846 }
8847 pubKey = nsslowkey_ConvertToPublicKey(privKey);
8848 if (pubKey == NULL((void*)0)) {
8849 error = PORT_GetErrorPORT_GetError_Util();
8850 crv = sftk_MapCryptError(error);
8851 break;
8852 }
8853 crv = sftk_PutPubKey(key, sourceKey, keyType, pubKey);
8854 nsslowkey_DestroyPublicKey(pubKey);
8855 break;
8856 }
8857 case CKM_NSS_IKE_PRF_DERIVE((0x80000000UL | 0x4E534350) + 35):
8858 case CKM_IKE_PRF_DERIVE0x0000402fUL:
8859 if (pMechanism->ulParameterLen !=
8860 sizeof(CK_IKE_PRF_DERIVE_PARAMS)) {
8861 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8862 break;
8863 }
8864 crv = sftk_ike_prf(hSession, att,
8865 (CK_IKE_PRF_DERIVE_PARAMS *)pMechanism->pParameter, key);
8866 break;
8867 case CKM_NSS_IKE1_PRF_DERIVE((0x80000000UL | 0x4E534350) + 36):
8868 case CKM_IKE1_PRF_DERIVE0x00004030UL:
8869 if (pMechanism->ulParameterLen !=
8870 sizeof(CK_IKE1_PRF_DERIVE_PARAMS)) {
8871 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8872 break;
8873 }
8874 crv = sftk_ike1_prf(hSession, att,
8875 (CK_IKE1_PRF_DERIVE_PARAMS *)pMechanism->pParameter,
8876 key, keySize);
8877 break;
8878 case CKM_NSS_IKE1_APP_B_PRF_DERIVE((0x80000000UL | 0x4E534350) + 37):
8879 case CKM_IKE1_EXTENDED_DERIVE0x00004031UL:
8880 pIkeAppB = (CK_IKE1_EXTENDED_DERIVE_PARAMS *)pMechanism->pParameter;
8881 if (pMechanism->ulParameterLen ==
8882 sizeof(CK_MECHANISM_TYPE)) {
8883 ikeAppB.prfMechanism = *(CK_MECHANISM_TYPE *)pMechanism->pParameter;
8884 ikeAppB.bHasKeygxy = PR_FALSE0;
8885 ikeAppB.hKeygxy = CK_INVALID_HANDLE0;
8886 ikeAppB.pExtraData = NULL((void*)0);
8887 ikeAppB.ulExtraDataLen = 0;
8888 pIkeAppB = &ikeAppB;
8889 } else if (pMechanism->ulParameterLen !=
8890 sizeof(CK_IKE1_EXTENDED_DERIVE_PARAMS)) {
8891 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8892 break;
8893 }
8894 crv = sftk_ike1_appendix_b_prf(hSession, att, pIkeAppB, key,
8895 keySize);
8896 break;
8897 case CKM_NSS_IKE_PRF_PLUS_DERIVE((0x80000000UL | 0x4E534350) + 34):
8898 case CKM_IKE2_PRF_PLUS_DERIVE0x0000402eUL:
8899 if (pMechanism->ulParameterLen !=
8900 sizeof(CK_IKE2_PRF_PLUS_DERIVE_PARAMS)) {
8901 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8902 break;
8903 }
8904 crv = sftk_ike_prf_plus(hSession, att,
8905 (CK_IKE2_PRF_PLUS_DERIVE_PARAMS *)pMechanism->pParameter,
8906 key, keySize);
8907 break;
8908 /*
8909 * generate the master secret
8910 */
8911 case CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL:
8912 case CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL:
8913 case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 22):
8914 case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24):
8915 case CKM_TLS_MASTER_KEY_DERIVE0x00000375UL:
8916 case CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377UL:
8917 case CKM_SSL3_MASTER_KEY_DERIVE0x00000371UL:
8918 case CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL: {
8919 CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
8920 SSL3RSAPreMasterSecret *rsa_pms;
8921 unsigned char crsrdata[SSL3_RANDOM_LENGTH32 * 2];
8922
8923 if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE0x000003E0UL) ||
8924 (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL)) {
8925 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))
) {
8926 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8927 break;
8928 }
8929 CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master =
8930 (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter;
8931 tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_master->prfHashMechanism);
8932 if (tlsPrfHash == HASH_AlgNULL) {
8933 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8934 break;
8935 }
8936 } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 22)) ||
8937 (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24))) {
8938 tlsPrfHash = HASH_AlgSHA256;
8939 }
8940
8941 if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE0x00000371UL) &&
8942 (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL)) {
8943 isTLS = PR_TRUE1;
8944 }
8945 if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH0x00000373UL) ||
8946 (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH0x00000377UL) ||
8947 (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256((0x80000000UL | 0x4E534350) + 24)) ||
8948 (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH0x000003E2UL)) {
8949 isDH = PR_TRUE1;
8950 }
8951
8952 /* first do the consistency checks */
8953 if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH48)) {
8954 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
8955 break;
8956 }
8957 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL);
8958 if ((att2 == NULL((void*)0)) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
8959 CKK_GENERIC_SECRET0x00000010UL)) {
8960 if (att2)
8961 sftk_FreeAttribute(att2);
8962 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
8963 break;
8964 }
8965 sftk_FreeAttribute(att2);
8966 if (keyType != CKK_GENERIC_SECRET0x00000010UL) {
8967 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
8968 break;
8969 }
8970 if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH48)) {
8971 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
8972 break;
8973 }
8974
8975 /* finally do the key gen */
8976 ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
8977 pMechanism->pParameter;
8978
8979 if (ssl3_master->pVersion) {
8980 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
8981 rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue;
8982 /* don't leak more key material then necessary for SSL to work */
8983 if ((sessKey == NULL((void*)0)) || sessKey->wasDerived) {
8984 ssl3_master->pVersion->major = 0xff;
8985 ssl3_master->pVersion->minor = 0xff;
8986 } else {
8987 ssl3_master->pVersion->major = rsa_pms->client_version[0];
8988 ssl3_master->pVersion->minor = rsa_pms->client_version[1];
8989 }
8990 }
8991 if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH32) {
8992 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8993 break;
8994 }
8995 if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH32) {
8996 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
8997 break;
8998 }
8999 PORT_Memcpymemcpy(crsrdata,
9000 ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH32);
9001 PORT_Memcpymemcpy(crsrdata + SSL3_RANDOM_LENGTH32,
9002 ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH32);
9003
9004 if (isTLS) {
9005 SECStatus status;
9006 SECItem crsr = { siBuffer, NULL((void*)0), 0 };
9007 SECItem master = { siBuffer, NULL((void*)0), 0 };
9008 SECItem pms = { siBuffer, NULL((void*)0), 0 };
9009
9010 crsr.data = crsrdata;
9011 crsr.len = sizeof crsrdata;
9012 master.data = key_block;
9013 master.len = SSL3_MASTER_SECRET_LENGTH48;
9014 pms.data = (unsigned char *)att->attrib.pValue;
9015 pms.len = att->attrib.ulValueLen;
9016
9017 if (tlsPrfHash != HASH_AlgNULL) {
9018 status = TLS_P_hash(tlsPrfHash, &pms, "master secret",
9019 &crsr, &master, isFIPS);
9020 } else {
9021 status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
9022 }
9023 if (status != SECSuccess) {
9024 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9025 crv = CKR_FUNCTION_FAILED0x00000006UL;
9026 break;
9027 }
9028 } else {
9029 /* now allocate the hash contexts */
9030 md5 = MD5_NewContext();
9031 if (md5 == NULL((void*)0)) {
9032 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9033 crv = CKR_HOST_MEMORY0x00000002UL;
9034 break;
9035 }
9036 sha = SHA1_NewContext();
9037 if (sha == NULL((void*)0)) {
9038 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9039 PORT_FreePORT_Free_Util(md5);
9040 crv = CKR_HOST_MEMORY0x00000002UL;
9041 break;
9042 }
9043 for (i = 0; i < 3; i++) {
9044 SHA1_Begin(sha);
9045 SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i]));
9046 SHA1_Update(sha, (const unsigned char *)att->attrib.pValue,
9047 att->attrib.ulValueLen);
9048 SHA1_Update(sha, crsrdata, sizeof crsrdata);
9049 SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH20);
9050 PORT_Assert(outLen == SHA1_LENGTH)((outLen == 20) ? ((void)0) : PR_Assert("outLen == SHA1_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9050
))
;
9051
9052 MD5_Begin(md5);
9053 MD5_Update(md5, (const unsigned char *)att->attrib.pValue,
9054 att->attrib.ulValueLen);
9055 MD5_Update(md5, sha_out, outLen);
9056 MD5_End(md5, &key_block[i * MD5_LENGTH16], &outLen, MD5_LENGTH16);
9057 PORT_Assert(outLen == MD5_LENGTH)((outLen == 16) ? ((void)0) : PR_Assert("outLen == MD5_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9057
))
;
9058 }
9059 PORT_FreePORT_Free_Util(md5);
9060 PORT_FreePORT_Free_Util(sha);
9061 PORT_Memsetmemset(crsrdata, 0, sizeof crsrdata);
9062 PORT_Memsetmemset(sha_out, 0, sizeof sha_out);
9063 }
9064
9065 /* store the results */
9066 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, SSL3_MASTER_SECRET_LENGTH48);
9067 PORT_Memsetmemset(key_block, 0, sizeof key_block);
9068 if (crv != CKR_OK0x00000000UL)
9069 break;
9070 keyType = CKK_GENERIC_SECRET0x00000010UL;
9071 crv = sftk_forceAttribute(key, CKA_KEY_TYPE0x00000100UL, &keyType, sizeof(keyType));
9072 if (isTLS) {
9073 /* TLS's master secret is used to "sign" finished msgs with PRF. */
9074 /* XXX This seems like a hack. But SFTK_Derive only accepts
9075 * one "operation" argument. */
9076 crv = sftk_forceAttribute(key, CKA_SIGN0x00000108UL, &cktrue, sizeof(CK_BBOOL));
9077 if (crv != CKR_OK0x00000000UL)
9078 break;
9079 crv = sftk_forceAttribute(key, CKA_VERIFY0x0000010AUL, &cktrue, sizeof(CK_BBOOL));
9080 if (crv != CKR_OK0x00000000UL)
9081 break;
9082 /* While we're here, we might as well force this, too. */
9083 crv = sftk_forceAttribute(key, CKA_DERIVE0x0000010CUL, &cktrue, sizeof(CK_BBOOL));
9084 if (crv != CKR_OK0x00000000UL)
9085 break;
9086 }
9087 break;
9088 }
9089
9090 /* Extended master key derivation [draft-ietf-tls-session-hash] */
9091 case CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE0x00000056UL:
9092 case CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH0x00000057UL:
9093 case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE((0x80000000UL | 0x4E534350) + 25):
9094 case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH((0x80000000UL | 0x4E534350) + 26): {
9095 CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params;
9096 SSL3RSAPreMasterSecret *rsa_pms;
9097 SECStatus status;
9098 SECItem pms = { siBuffer, NULL((void*)0), 0 };
9099 SECItem seed = { siBuffer, NULL((void*)0), 0 };
9100 SECItem master = { siBuffer, NULL((void*)0), 0 };
9101
9102 ems_params = (CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS *)
9103 pMechanism->pParameter;
9104
9105 /* First do the consistency checks */
9106 if (((mechanism == CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE0x00000056UL) ||
9107 (mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE((0x80000000UL | 0x4E534350) + 25))) &&
9108 (att->attrib.ulValueLen != SSL3_PMS_LENGTH48)) {
9109 crv = CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
9110 break;
9111 }
9112 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL);
9113 if ((att2 == NULL((void*)0)) ||
9114 (*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET0x00000010UL)) {
9115 if (att2)
9116 sftk_FreeAttribute(att2);
9117 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9118 break;
9119 }
9120 sftk_FreeAttribute(att2);
9121 if (keyType != CKK_GENERIC_SECRET0x00000010UL) {
9122 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9123 break;
9124 }
9125 if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH48)) {
9126 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9127 break;
9128 }
9129
9130 /* Do the key derivation */
9131 pms.data = (unsigned char *)att->attrib.pValue;
9132 pms.len = att->attrib.ulValueLen;
9133 seed.data = ems_params->pSessionHash;
9134 seed.len = ems_params->ulSessionHashLen;
9135 master.data = key_block;
9136 master.len = SSL3_MASTER_SECRET_LENGTH48;
9137 if (ems_params->prfHashMechanism == CKM_TLS_PRF0x00000378UL) {
9138 /*
9139 * In this case, the session hash is the concatenation of SHA-1
9140 * and MD5, so it should be 36 bytes long.
9141 */
9142 if (seed.len != MD5_LENGTH16 + SHA1_LENGTH20) {
9143 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9144 break;
9145 }
9146
9147 status = TLS_PRF(&pms, "extended master secret",
9148 &seed, &master, isFIPS);
9149 } else {
9150 const SECHashObject *hashObj;
9151
9152 tlsPrfHash = sftk_GetHashTypeFromMechanism(ems_params->prfHashMechanism);
9153 if (tlsPrfHash == HASH_AlgNULL) {
9154 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9155 break;
9156 }
9157
9158 hashObj = HASH_GetRawHashObject(tlsPrfHash);
9159 if (seed.len != hashObj->length) {
9160 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9161 break;
9162 }
9163
9164 status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret",
9165 &seed, &master, isFIPS);
9166 }
9167 if (status != SECSuccess) {
9168 crv = CKR_FUNCTION_FAILED0x00000006UL;
9169 break;
9170 }
9171
9172 /* Reflect the version if required */
9173 if (ems_params->pVersion) {
9174 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
9175 rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue;
9176 /* don't leak more key material than necessary for SSL to work */
9177 if ((sessKey == NULL((void*)0)) || sessKey->wasDerived) {
9178 ems_params->pVersion->major = 0xff;
9179 ems_params->pVersion->minor = 0xff;
9180 } else {
9181 ems_params->pVersion->major = rsa_pms->client_version[0];
9182 ems_params->pVersion->minor = rsa_pms->client_version[1];
9183 }
9184 }
9185
9186 /* Store the results */
9187 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block,
9188 SSL3_MASTER_SECRET_LENGTH48);
9189 PORT_Memsetmemset(key_block, 0, sizeof key_block);
9190 break;
9191 }
9192
9193 case CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL:
9194 case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 23):
9195 case CKM_TLS_KEY_AND_MAC_DERIVE0x00000376UL:
9196 case CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372UL: {
9197 CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
9198 CK_SSL3_KEY_MAT_OUT *ssl3_keys_out;
9199 CK_ULONG effKeySize;
9200 unsigned int block_needed;
9201 unsigned char srcrdata[SSL3_RANDOM_LENGTH32 * 2];
9202
9203 if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE0x000003E1UL) {
9204 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_KEY_MAT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_TLS12_KEY_MAT_PARAMS))
) {
9205 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9206 break;
9207 }
9208 CK_TLS12_KEY_MAT_PARAMS *tls12_keys =
9209 (CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter;
9210 tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_keys->prfHashMechanism);
9211 if (tlsPrfHash == HASH_AlgNULL) {
9212 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9213 break;
9214 }
9215 } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256((0x80000000UL | 0x4E534350) + 23)) {
9216 tlsPrfHash = HASH_AlgSHA256;
9217 }
9218
9219 if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE0x00000372UL) {
9220 isTLS = PR_TRUE1;
9221 }
9222
9223 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9224 if (crv != CKR_OK0x00000000UL)
9225 break;
9226
9227 if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH48) {
9228 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9229 break;
9230 }
9231 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE0x00000100UL);
9232 if ((att2 == NULL((void*)0)) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
9233 CKK_GENERIC_SECRET0x00000010UL)) {
9234 if (att2)
9235 sftk_FreeAttribute(att2);
9236 crv = CKR_KEY_FUNCTION_NOT_PERMITTED0x00000068UL;
9237 break;
9238 }
9239 sftk_FreeAttribute(att2);
9240 md5 = MD5_NewContext();
9241 if (md5 == NULL((void*)0)) {
9242 crv = CKR_HOST_MEMORY0x00000002UL;
9243 break;
9244 }
9245 sha = SHA1_NewContext();
9246 if (sha == NULL((void*)0)) {
9247 MD5_DestroyContext(md5, PR_TRUE1);
9248 crv = CKR_HOST_MEMORY0x00000002UL;
9249 break;
9250 }
9251
9252 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_SSL3_KEY_MAT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_SSL3_KEY_MAT_PARAMS))
) {
9253 MD5_DestroyContext(md5, PR_TRUE1);
9254 SHA1_DestroyContext(sha, PR_TRUE1);
9255 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9256 break;
9257 }
9258 ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter;
9259
9260 PORT_Memcpymemcpy(srcrdata,
9261 ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH32);
9262 PORT_Memcpymemcpy(srcrdata + SSL3_RANDOM_LENGTH32,
9263 ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH32);
9264
9265 /*
9266 * clear out our returned keys so we can recover on failure
9267 */
9268 ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
9269 ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE0;
9270 ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE0;
9271 ssl3_keys_out->hClientKey = CK_INVALID_HANDLE0;
9272 ssl3_keys_out->hServerKey = CK_INVALID_HANDLE0;
9273
9274 /*
9275 * How much key material do we need?
9276 */
9277 macSize = ssl3_keys->ulMacSizeInBits / 8;
9278 effKeySize = ssl3_keys->ulKeySizeInBits / 8;
9279 IVSize = ssl3_keys->ulIVSizeInBits / 8;
9280 if (keySize == 0) {
9281 effKeySize = keySize;
9282 }
9283
9284 /* bIsExport must be false. */
9285 if (ssl3_keys->bIsExport) {
9286 MD5_DestroyContext(md5, PR_TRUE1);
9287 SHA1_DestroyContext(sha, PR_TRUE1);
9288 PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata);
9289 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9290 break;
9291 }
9292
9293 /* Compute the amount of key material consumed using keySize
9294 * (from CKA_VALUE_LEN, which is what actually indexes key_block
9295 * below), not effKeySize. Bound each term first to prevent
9296 * integer overflow in the sum, then reject if the total exceeds
9297 * the buffer -- clamping block_needed would not bound the later
9298 * indexing and would permit a stack OOB read. */
9299 (void)effKeySize;
9300 if (macSize > sizeof key_block || IVSize > sizeof key_block ||
9301 keySize > sizeof key_block ||
9302 2 * (macSize + keySize + IVSize) > sizeof key_block) {
9303 MD5_DestroyContext(md5, PR_TRUE1);
9304 SHA1_DestroyContext(sha, PR_TRUE1);
9305 PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata);
9306 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9307 break;
9308 }
9309 block_needed = 2 * (macSize + keySize + IVSize);
9310
9311 /*
9312 * generate the key material: This looks amazingly similar to the
9313 * PMS code, and is clearly crying out for a function to provide it.
9314 */
9315 if (isTLS) {
9316 SECStatus status;
9317 SECItem srcr = { siBuffer, NULL((void*)0), 0 };
9318 SECItem keyblk = { siBuffer, NULL((void*)0), 0 };
9319 SECItem master = { siBuffer, NULL((void*)0), 0 };
9320
9321 srcr.data = srcrdata;
9322 srcr.len = sizeof srcrdata;
9323 keyblk.data = key_block;
9324 keyblk.len = block_needed;
9325 master.data = (unsigned char *)att->attrib.pValue;
9326 master.len = att->attrib.ulValueLen;
9327
9328 if (tlsPrfHash != HASH_AlgNULL) {
9329 status = TLS_P_hash(tlsPrfHash, &master, "key expansion",
9330 &srcr, &keyblk, isFIPS);
9331 } else {
9332 status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
9333 isFIPS);
9334 }
9335 if (status != SECSuccess) {
9336 goto key_and_mac_derive_fail;
9337 }
9338 } else {
9339 unsigned int block_bytes = 0;
9340 /* key_block =
9341 * MD5(master_secret + SHA('A' + master_secret +
9342 * ServerHello.random + ClientHello.random)) +
9343 * MD5(master_secret + SHA('BB' + master_secret +
9344 * ServerHello.random + ClientHello.random)) +
9345 * MD5(master_secret + SHA('CCC' + master_secret +
9346 * ServerHello.random + ClientHello.random)) +
9347 * [...];
9348 */
9349 for (i = 0; i < NUM_MIXERS9 && block_bytes < block_needed; i++) {
9350 SHA1_Begin(sha);
9351 SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i]));
9352 SHA1_Update(sha, (const unsigned char *)att->attrib.pValue,
9353 att->attrib.ulValueLen);
9354 SHA1_Update(sha, srcrdata, sizeof srcrdata);
9355 SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH20);
9356 PORT_Assert(outLen == SHA1_LENGTH)((outLen == 20) ? ((void)0) : PR_Assert("outLen == SHA1_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9356
))
;
9357 MD5_Begin(md5);
9358 MD5_Update(md5, (const unsigned char *)att->attrib.pValue,
9359 att->attrib.ulValueLen);
9360 MD5_Update(md5, sha_out, outLen);
9361 MD5_End(md5, &key_block[i * MD5_LENGTH16], &outLen, MD5_LENGTH16);
9362 PORT_Assert(outLen == MD5_LENGTH)((outLen == 16) ? ((void)0) : PR_Assert("outLen == MD5_LENGTH"
, "/root/firefox-clang/security/nss/lib/softoken/pkcs11c.c", 9362
))
;
9363 block_bytes += outLen;
9364 }
9365 PORT_Memsetmemset(sha_out, 0, sizeof sha_out);
9366 }
9367
9368 /*
9369 * Put the key material where it goes.
9370 */
9371 i = 0; /* now shows how much consumed */
9372
9373 /*
9374 * The key_block is partitioned as follows:
9375 * client_write_MAC_secret[CipherSpec.hash_size]
9376 */
9377 crv = sftk_buildSSLKey(hSession, key, PR_TRUE1, &key_block[i], macSize,
9378 &ssl3_keys_out->hClientMacSecret);
9379 if (crv != CKR_OK0x00000000UL)
9380 goto key_and_mac_derive_fail;
9381
9382 i += macSize;
9383
9384 /*
9385 * server_write_MAC_secret[CipherSpec.hash_size]
9386 */
9387 crv = sftk_buildSSLKey(hSession, key, PR_TRUE1, &key_block[i], macSize,
9388 &ssl3_keys_out->hServerMacSecret);
9389 if (crv != CKR_OK0x00000000UL) {
9390 goto key_and_mac_derive_fail;
9391 }
9392 i += macSize;
9393
9394 if (keySize) {
9395 /*
9396 ** Generate Domestic write keys and IVs.
9397 ** client_write_key[CipherSpec.key_material]
9398 */
9399 crv = sftk_buildSSLKey(hSession, key, PR_FALSE0, &key_block[i],
9400 keySize, &ssl3_keys_out->hClientKey);
9401 if (crv != CKR_OK0x00000000UL) {
9402 goto key_and_mac_derive_fail;
9403 }
9404 i += keySize;
9405
9406 /*
9407 ** server_write_key[CipherSpec.key_material]
9408 */
9409 crv = sftk_buildSSLKey(hSession, key, PR_FALSE0, &key_block[i],
9410 keySize, &ssl3_keys_out->hServerKey);
9411 if (crv != CKR_OK0x00000000UL) {
9412 goto key_and_mac_derive_fail;
9413 }
9414 i += keySize;
9415
9416 /*
9417 ** client_write_IV[CipherSpec.IV_size]
9418 */
9419 if (IVSize > 0) {
9420 PORT_Memcpymemcpy(ssl3_keys_out->pIVClient,
9421 &key_block[i], IVSize);
9422 i += IVSize;
9423 }
9424
9425 /*
9426 ** server_write_IV[CipherSpec.IV_size]
9427 */
9428 if (IVSize > 0) {
9429 PORT_Memcpymemcpy(ssl3_keys_out->pIVServer,
9430 &key_block[i], IVSize);
9431 i += IVSize;
9432 }
9433 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", 9433
))
;
9434 }
9435
9436 crv = CKR_OK0x00000000UL;
9437
9438 if (0) {
9439 key_and_mac_derive_fail:
9440 if (crv == CKR_OK0x00000000UL)
9441 crv = CKR_FUNCTION_FAILED0x00000006UL;
9442 sftk_freeSSLKeys(hSession, ssl3_keys_out);
9443 }
9444 PORT_Memsetmemset(srcrdata, 0, sizeof srcrdata);
9445 PORT_Memsetmemset(key_block, 0, sizeof key_block);
9446 MD5_DestroyContext(md5, PR_TRUE1);
9447 SHA1_DestroyContext(sha, PR_TRUE1);
9448 sftk_FreeObject(key);
9449 key = NULL((void*)0);
9450 break;
9451 }
9452
9453 case CKM_DES3_ECB_ENCRYPT_DATA0x00001102UL:
9454 case CKM_DES3_CBC_ENCRYPT_DATA0x00001103UL: {
9455 void *cipherInfo;
9456 unsigned char des3key[MAX_DES3_KEY_SIZE24];
9457 CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr;
9458 int mode;
9459 unsigned char *iv;
9460 unsigned char *data;
9461 CK_ULONG len;
9462
9463 if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA0x00001102UL) {
9464 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9465 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9466 break;
9467 }
9468 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
9469 pMechanism->pParameter;
9470 mode = NSS_DES_EDE32;
9471 iv = NULL((void*)0);
9472 data = stringPtr->pData;
9473 len = stringPtr->ulLen;
9474 } else {
9475 mode = NSS_DES_EDE3_CBC3;
9476 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_DES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_DES_CBC_ENCRYPT_DATA_PARAMS))
) {
9477 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9478 break;
9479 }
9480 desEncryptPtr =
9481 (CK_DES_CBC_ENCRYPT_DATA_PARAMS *)
9482 pMechanism->pParameter;
9483 iv = desEncryptPtr->iv;
9484 data = desEncryptPtr->pData;
9485 len = desEncryptPtr->length;
9486 }
9487 if (att->attrib.ulValueLen == 16) {
9488 PORT_Memcpymemcpy(des3key, att->attrib.pValue, 16);
9489 PORT_Memcpymemcpy(des3key + 16, des3key, 8);
9490 } else if (att->attrib.ulValueLen == 24) {
9491 PORT_Memcpymemcpy(des3key, att->attrib.pValue, 24);
9492 } else {
9493 crv = CKR_KEY_SIZE_RANGE0x00000062UL;
9494 break;
9495 }
9496 cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE1);
9497 PORT_Memsetmemset(des3key, 0, 24);
9498 if (cipherInfo == NULL((void*)0)) {
9499 crv = CKR_HOST_MEMORY0x00000002UL;
9500 break;
9501 }
9502 crv = sftk_DeriveEncrypt(SFTKCipher_DES_Encrypt,
9503 cipherInfo, 8, key, keySize,
9504 data, len);
9505 DES_DestroyContext(cipherInfo, PR_TRUE1);
9506 break;
9507 }
9508
9509 case CKM_AES_ECB_ENCRYPT_DATA0x00001104UL:
9510 case CKM_AES_CBC_ENCRYPT_DATA0x00001105UL: {
9511 void *cipherInfo;
9512 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
9513 int mode;
9514 unsigned char *iv;
9515 unsigned char *data;
9516 CK_ULONG len;
9517
9518 if (mechanism == CKM_AES_ECB_ENCRYPT_DATA0x00001104UL) {
9519 mode = NSS_AES0;
9520 iv = NULL((void*)0);
9521 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9522 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9523 break;
9524 }
9525 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9526 data = stringPtr->pData;
9527 len = stringPtr->ulLen;
9528 } else {
9529 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))
) {
9530 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9531 break;
9532 }
9533 aesEncryptPtr =
9534 (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter;
9535 mode = NSS_AES_CBC1;
9536 iv = aesEncryptPtr->iv;
9537 data = aesEncryptPtr->pData;
9538 len = aesEncryptPtr->length;
9539 }
9540
9541 cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue,
9542 iv, mode, PR_TRUE1,
9543 att->attrib.ulValueLen, 16);
9544 if (cipherInfo == NULL((void*)0)) {
9545 crv = CKR_HOST_MEMORY0x00000002UL;
9546 break;
9547 }
9548 crv = sftk_DeriveEncrypt(SFTKCipher_AES_Encrypt,
9549 cipherInfo, 16, key, keySize,
9550 data, len);
9551 AES_DestroyContext(cipherInfo, PR_TRUE1);
9552 break;
9553 }
9554
9555 case CKM_CAMELLIA_ECB_ENCRYPT_DATA0x00000556UL:
9556 case CKM_CAMELLIA_CBC_ENCRYPT_DATA0x00000557UL: {
9557 void *cipherInfo;
9558 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
9559 int mode;
9560 unsigned char *iv;
9561 unsigned char *data;
9562 CK_ULONG len;
9563
9564 if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA0x00000556UL) {
9565 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9566 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9567 break;
9568 }
9569 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
9570 pMechanism->pParameter;
9571 aesEncryptPtr = NULL((void*)0);
9572 mode = NSS_CAMELLIA0;
9573 data = stringPtr->pData;
9574 len = stringPtr->ulLen;
9575 iv = NULL((void*)0);
9576 } else {
9577 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))
) {
9578 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9579 break;
9580 }
9581 stringPtr = NULL((void*)0);
9582 aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
9583 pMechanism->pParameter;
9584 mode = NSS_CAMELLIA_CBC1;
9585 iv = aesEncryptPtr->iv;
9586 data = aesEncryptPtr->pData;
9587 len = aesEncryptPtr->length;
9588 }
9589
9590 cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue,
9591 iv, mode, PR_TRUE1,
9592 att->attrib.ulValueLen);
9593 if (cipherInfo == NULL((void*)0)) {
9594 crv = CKR_HOST_MEMORY0x00000002UL;
9595 break;
9596 }
9597 crv = sftk_DeriveEncrypt(SFTKCipher_Camellia_Encrypt,
9598 cipherInfo, 16, key, keySize,
9599 data, len);
9600 Camellia_DestroyContext(cipherInfo, PR_TRUE1);
9601 break;
9602 }
9603
9604#ifndef NSS_DISABLE_DEPRECATED_SEED
9605 case CKM_SEED_ECB_ENCRYPT_DATA0x00000656UL:
9606 case CKM_SEED_CBC_ENCRYPT_DATA0x00000657UL: {
9607 void *cipherInfo;
9608 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr;
9609 int mode;
9610 unsigned char *iv;
9611 unsigned char *data;
9612 CK_ULONG len;
9613
9614 if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA0x00000656UL) {
9615 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9616 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9617 break;
9618 }
9619 mode = NSS_SEED0;
9620 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)
9621 pMechanism->pParameter;
9622 aesEncryptPtr = NULL((void*)0);
9623 data = stringPtr->pData;
9624 len = stringPtr->ulLen;
9625 iv = NULL((void*)0);
9626 } else {
9627 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))
) {
9628 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9629 break;
9630 }
9631 mode = NSS_SEED_CBC1;
9632 aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)
9633 pMechanism->pParameter;
9634 iv = aesEncryptPtr->iv;
9635 data = aesEncryptPtr->pData;
9636 len = aesEncryptPtr->length;
9637 }
9638
9639 cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue,
9640 iv, mode, PR_TRUE1);
9641 if (cipherInfo == NULL((void*)0)) {
9642 crv = CKR_HOST_MEMORY0x00000002UL;
9643 break;
9644 }
9645 crv = sftk_DeriveEncrypt(SFTKCipher_SEED_Encrypt,
9646 cipherInfo, 16, key, keySize,
9647 data, len);
9648 SEED_DestroyContext(cipherInfo, PR_TRUE1);
9649 break;
9650 }
9651#endif /* NSS_DISABLE_DEPRECATED_SEED */
9652
9653 case CKM_CONCATENATE_BASE_AND_KEY0x00000360UL: {
9654 SFTKObject *paramKey;
9655
9656 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9657 if (crv != CKR_OK0x00000000UL)
9658 break;
9659
9660 session = sftk_SessionFromHandle(hSession);
9661 if (session == NULL((void*)0)) {
9662 crv = CKR_SESSION_HANDLE_INVALID0x000000B3UL;
9663 break;
9664 }
9665
9666 paramKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *)
9667 pMechanism->pParameter,
9668 session);
9669 sftk_FreeSession(session);
9670 if (paramKey == NULL((void*)0)) {
9671 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
9672 break;
9673 }
9674
9675 if (sftk_isTrue(paramKey, CKA_SENSITIVE0x00000103UL)) {
9676 crv = sftk_forceAttribute(key, CKA_SENSITIVE0x00000103UL, &cktrue,
9677 sizeof(CK_BBOOL));
9678 if (crv != CKR_OK0x00000000UL) {
9679 sftk_FreeObject(paramKey);
9680 break;
9681 }
9682 }
9683
9684 if (sftk_hasAttribute(paramKey, CKA_EXTRACTABLE0x00000162UL) && !sftk_isTrue(paramKey, CKA_EXTRACTABLE0x00000162UL)) {
9685 crv = sftk_forceAttribute(key, CKA_EXTRACTABLE0x00000162UL, &ckfalse, sizeof(CK_BBOOL));
9686 if (crv != CKR_OK0x00000000UL) {
9687 sftk_FreeObject(paramKey);
9688 break;
9689 }
9690 }
9691
9692 att2 = sftk_FindAttribute(paramKey, CKA_VALUE0x00000011UL);
9693 if (att2 == NULL((void*)0)) {
9694 sftk_FreeObject(paramKey);
9695 crv = CKR_KEY_HANDLE_INVALID0x00000060UL;
9696 break;
9697 }
9698 tmpKeySize = att->attrib.ulValueLen + att2->attrib.ulValueLen;
9699 if (keySize == 0)
9700 keySize = tmpKeySize;
9701 if (keySize > tmpKeySize) {
9702 sftk_FreeAttribute(att2);
9703 sftk_FreeObject(paramKey);
9704 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9705 break;
9706 }
9707 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize);
9708 if (buf == NULL((void*)0)) {
9709 sftk_FreeAttribute(att2);
9710 sftk_FreeObject(paramKey);
9711 crv = CKR_HOST_MEMORY0x00000002UL;
9712 break;
9713 }
9714
9715 PORT_Memcpymemcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
9716 PORT_Memcpymemcpy(buf + att->attrib.ulValueLen,
9717 att2->attrib.pValue, att2->attrib.ulValueLen);
9718
9719 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9720 PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize);
9721 /* preserve the source of the original base key */
9722 key->source = sourceKey->source;
9723
9724 /* make sure this is fully fips approved, and mark it
9725 * unapproved if not */
9726 if (sftk_hasFIPS(key)) {
9727 sftk_setFIPS(key, sftk_hasFIPS(paramKey));
9728 }
9729 sftk_FreeAttribute(att2);
9730 sftk_FreeObject(paramKey);
9731 break;
9732 }
9733
9734 case CKM_CONCATENATE_BASE_AND_DATA0x00000362UL:
9735 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9736 if (crv != CKR_OK0x00000000UL)
9737 break;
9738
9739 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9740 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9741 break;
9742 }
9743 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9744 tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
9745 if (keySize == 0)
9746 keySize = tmpKeySize;
9747 if (keySize > tmpKeySize) {
9748 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9749 break;
9750 }
9751 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize);
9752 if (buf == NULL((void*)0)) {
9753 crv = CKR_HOST_MEMORY0x00000002UL;
9754 break;
9755 }
9756
9757 PORT_Memcpymemcpy(buf, att->attrib.pValue, att->attrib.ulValueLen);
9758 PORT_Memcpymemcpy(buf + att->attrib.ulValueLen, stringPtr->pData,
9759 stringPtr->ulLen);
9760
9761 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9762 PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize);
9763 break;
9764 case CKM_CONCATENATE_DATA_AND_BASE0x00000363UL:
9765 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9766 if (crv != CKR_OK0x00000000UL)
9767 break;
9768
9769 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9770 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9771 break;
9772 }
9773 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9774 tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen;
9775 if (keySize == 0)
9776 keySize = tmpKeySize;
9777 if (keySize > tmpKeySize) {
9778 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9779 break;
9780 }
9781 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(tmpKeySize);
9782 if (buf == NULL((void*)0)) {
9783 crv = CKR_HOST_MEMORY0x00000002UL;
9784 break;
9785 }
9786
9787 PORT_Memcpymemcpy(buf, stringPtr->pData, stringPtr->ulLen);
9788 PORT_Memcpymemcpy(buf + stringPtr->ulLen, att->attrib.pValue,
9789 att->attrib.ulValueLen);
9790
9791 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9792 PORT_ZFreePORT_ZFree_Util(buf, tmpKeySize);
9793 break;
9794 case CKM_XOR_BASE_AND_DATA0x00000364UL:
9795 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9796 if (crv != CKR_OK0x00000000UL)
9797 break;
9798
9799 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_KEY_DERIVATION_STRING_DATA))
) {
9800 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9801 break;
9802 }
9803 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
9804 tmpKeySize = PR_MIN(att->attrib.ulValueLen, stringPtr->ulLen)((att->attrib.ulValueLen) < (stringPtr->ulLen) ? (att
->attrib.ulValueLen) : (stringPtr->ulLen))
;
9805 if (keySize == 0)
9806 keySize = tmpKeySize;
9807 if (keySize > tmpKeySize) {
9808 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9809 break;
9810 }
9811 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(keySize);
9812 if (buf == NULL((void*)0)) {
9813 crv = CKR_HOST_MEMORY0x00000002UL;
9814 break;
9815 }
9816
9817 PORT_Memcpymemcpy(buf, att->attrib.pValue, keySize);
9818 for (i = 0; i < (int)keySize; i++) {
9819 buf[i] ^= stringPtr->pData[i];
9820 }
9821
9822 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9823 PORT_ZFreePORT_ZFree_Util(buf, keySize);
9824 break;
9825
9826 case CKM_EXTRACT_KEY_FROM_KEY0x00000365UL: {
9827 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_EXTRACT_PARAMS))(!pMechanism->pParameter || pMechanism->ulParameterLen <
sizeof(CK_EXTRACT_PARAMS))
) {
9828 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9829 break;
9830 }
9831 /* the following assumes 8 bits per byte */
9832 CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
9833 CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */
9834 CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */
9835
9836 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
9837 if (crv != CKR_OK0x00000000UL)
9838 break;
9839
9840 if (keySize == 0) {
9841 crv = CKR_TEMPLATE_INCOMPLETE0x000000D0UL;
9842 break;
9843 }
9844 /* make sure we have enough bits in the original key */
9845 if (att->attrib.ulValueLen <
9846 (offset + keySize + ((shift != 0) ? 1 : 0))) {
9847 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
9848 break;
9849 }
9850 buf = (unsigned char *)PORT_AllocPORT_Alloc_Util(keySize);
9851 if (buf == NULL((void*)0)) {
9852 crv = CKR_HOST_MEMORY0x00000002UL;
9853 break;
9854 }
9855
9856 /* copy the bits we need into the new key */
9857 for (i = 0; i < (int)keySize; i++) {
9858 unsigned char *value =
9859 ((unsigned char *)att->attrib.pValue) + offset + i;
9860 if (shift) {
9861 buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift));
9862 } else {
9863 buf[i] = value[0];
9864 }
9865 }
9866
9867 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, buf, keySize);
9868 PORT_ZFreePORT_ZFree_Util(buf, keySize);
9869 break;
9870 }
9871 case CKM_MD2_KEY_DERIVATION0x00000391UL:
9872 if (keySize == 0)
9873 keySize = MD2_LENGTH16;
9874 if (keySize > MD2_LENGTH16) {
9875 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
9876 break;
9877 }
9878 /* now allocate the hash contexts */
9879 md2 = MD2_NewContext();
9880 if (md2 == NULL((void*)0)) {
9881 crv = CKR_HOST_MEMORY0x00000002UL;
9882 break;
9883 }
9884 MD2_Begin(md2);
9885 MD2_Update(md2, (const unsigned char *)att->attrib.pValue,
9886 att->attrib.ulValueLen);
9887 MD2_End(md2, key_block, &outLen, MD2_LENGTH16);
9888 MD2_DestroyContext(md2, PR_TRUE1);
9889
9890 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, keySize);
9891 PORT_Memsetmemset(key_block, 0, MD2_LENGTH16);
9892 break;
9893#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;
\
9894 case CKM_##hash##_KEY_DERIVATION: \
9895 if (keySize == 0) \
9896 keySize = hash##_LENGTH; \
9897 if (keySize > hash##_LENGTH) { \
9898 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL; \
9899 break; \
9900 } \
9901 hash##_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, \
9902 att->attrib.ulValueLen); \
9903 crv = sftk_forceAttribute(key, CKA_VALUE0x00000011UL, key_block, keySize); \
9904 PORT_Memsetmemset(key_block, 0, hash##_LENGTH); \
9905 break;
9906 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;
9907 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;
9908 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;
9909 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;
9910 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;
9911 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;
9912 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;
9913 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;
9914 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;
9915 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;
9916
9917 case CKM_DH_PKCS_DERIVE0x00000021UL: {
9918 SECItem derived, dhPublic;
9919 SECItem dhPrime, dhValue;
9920 const SECItem *subPrime;
9921 /* sourceKey - values for the local existing low key */
9922 /* get prime and value attributes */
9923 crv = sftk_Attribute2SecItem(NULL((void*)0), &dhPrime, sourceKey, CKA_PRIME0x00000130UL);
9924 if (crv != CKR_OK0x00000000UL)
9925 break;
9926
9927 dhPublic.data = pMechanism->pParameter;
9928 dhPublic.len = pMechanism->ulParameterLen;
9929
9930 /* if the prime is an approved prime, we can skip all the other
9931 * checks. */
9932 subPrime = sftk_VerifyDH_Prime(&dhPrime, NULL((void*)0), isFIPS);
9933 if (subPrime == NULL((void*)0)) {
9934 SECItem dhSubPrime;
9935 /* If the caller set the subprime value, it means that
9936 * either the caller knows the subprime value and wants us
9937 * to validate the key against the subprime, or that the
9938 * caller wants us to verify that the prime is a safe prime
9939 * by passing in subprime = (prime-1)/2 */
9940 dhSubPrime.data = NULL((void*)0);
9941 dhSubPrime.len = 0;
9942 crv = sftk_Attribute2SecItem(NULL((void*)0), &dhSubPrime,
9943 sourceKey, CKA_SUBPRIME0x00000131UL);
9944 /* we ignore the value of crv here, We treat a valid
9945 * return of len = 0 and a failure to find a subrime the same
9946 * NOTE: we free the subprime in both cases depending on
9947 * PORT_Free of NULL to be a noop */
9948 if (dhSubPrime.len != 0) {
9949 PRBool isSafe = PR_FALSE0;
9950
9951 /* Callers can set dhSubPrime to q=(p-1)/2 to force
9952 * checks for safe primes. If so we only need to check
9953 * q and p for primality and skip the group test. */
9954 rv = sftk_IsSafePrime(&dhPrime, &dhSubPrime, &isSafe);
9955 if (rv != SECSuccess) {
9956 /* either p or q was even and therefore not prime,
9957 * we can stop processing here and fail now */
9958 crv = CKR_ARGUMENTS_BAD0x00000007UL;
9959 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
9960 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
9961 break;
9962 }
9963
9964 /* first make sure the primes are really prime */
9965 if (!KEA_PrimeCheck(&dhPrime)) {
9966 crv = CKR_ARGUMENTS_BAD0x00000007UL;
9967 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
9968 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
9969 break;
9970 }
9971 if (!KEA_PrimeCheck(&dhSubPrime)) {
9972 crv = CKR_ARGUMENTS_BAD0x00000007UL;
9973 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
9974 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
9975 break;
9976 }
9977 if (isFIPS || !isSafe) {
9978 /* With safe primes, there is only one other small
9979 * subgroup. As long as y isn't 0, 1, or -1 mod p,
9980 * any other y is safe. Only do the full check for
9981 * non-safe primes, except in FIPS mode we need
9982 * to do this check on all primes in which
9983 * we receive the subprime value */
9984 if (!KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime)) {
9985 crv = CKR_ARGUMENTS_BAD0x00000007UL;
9986 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
9987 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
9988 break;
9989 }
9990 }
9991 } else if (isFIPS) {
9992 /* In FIPS mode we only accept approved primes, or
9993 * primes with the full subprime value */
9994 crv = CKR_ARGUMENTS_BAD0x00000007UL;
9995 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
9996 break;
9997 }
9998 /* checks are complete, no need for the subPrime any longer */
9999 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhSubPrime, PR_FALSE0);
10000 }
10001
10002 /* now that the prime is validated, get the private value */
10003 crv = sftk_Attribute2SecItem(NULL((void*)0), &dhValue, sourceKey, CKA_VALUE0x00000011UL);
10004 if (crv != CKR_OK0x00000000UL) {
10005 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10006 break;
10007 }
10008
10009 /* calculate private value - oct */
10010 rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
10011
10012 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhPrime, PR_FALSE0);
10013 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&dhValue, PR_FALSE0);
10014
10015 if (rv == SECSuccess) {
10016 key->source = SFTK_SOURCE_KEA;
10017 sftk_forceAttribute(key, CKA_VALUE0x00000011UL, derived.data, derived.len);
10018 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&derived, PR_FALSE0);
10019 crv = CKR_OK0x00000000UL;
10020 } else
10021 crv = CKR_HOST_MEMORY0x00000002UL;
10022
10023 break;
10024 }
10025
10026 case CKM_ECDH1_DERIVE0x00001050UL:
10027 case CKM_ECDH1_COFACTOR_DERIVE0x00001051UL: {
10028 SECItem ecScalar, ecPoint;
10029 SECItem tmp;
10030 PRBool withCofactor = PR_FALSE0;
10031 unsigned char *secret;
10032 unsigned char *keyData = NULL((void*)0);
10033 unsigned int secretlen, pubKeyLen;
10034 CK_ECDH1_DERIVE_PARAMS *mechParams;
10035 NSSLOWKEYPrivateKey *privKey;
10036 PLArenaPool *arena = NULL((void*)0);
10037
10038 /* Check mechanism parameters */
10039 mechParams = (CK_ECDH1_DERIVE_PARAMS *)pMechanism->pParameter;
10040 if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) ||
10041 ((mechParams->kdf == CKD_NULL0x00000001UL) &&
10042 ((mechParams->ulSharedDataLen != 0) ||
10043 (mechParams->pSharedData != NULL((void*)0))))) {
10044 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10045 break;
10046 }
10047
10048 privKey = sftk_GetPrivKey(sourceKey, CKK_EC0x00000003UL, &crv);
10049 if (privKey == NULL((void*)0)) {
10050 break;
10051 }
10052
10053 /* Now we are working with a non-NULL private key */
10054 SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &ecScalar, &privKey->u.ec.privateValue);
10055
10056 ecPoint.data = mechParams->pPublicData;
10057 ecPoint.len = mechParams->ulPublicDataLen;
10058
10059 pubKeyLen = EC_GetPointSize(&privKey->u.ec.ecParams);
10060
10061 /* if the len is too large, might be an encoded point */
10062 if (ecPoint.len > pubKeyLen) {
10063 SECItem newPoint;
10064
10065 arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
10066 if (arena == NULL((void*)0)) {
10067 goto ec_loser;
10068 }
10069
10070 rv = SEC_QuickDERDecodeItemSEC_QuickDERDecodeItem_Util(arena, &newPoint,
10071 SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util,
10072 &ecPoint);
10073 if (rv != SECSuccess) {
10074 goto ec_loser;
10075 }
10076 ecPoint = newPoint;
10077 }
10078
10079 if (mechanism == CKM_ECDH1_COFACTOR_DERIVE0x00001051UL) {
10080 withCofactor = PR_TRUE1;
10081 }
10082
10083 rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar,
10084 withCofactor, &tmp);
10085 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecScalar, PR_FALSE0);
10086 ecScalar.data = NULL((void*)0);
10087 if (privKey != sourceKey->objectInfo) {
10088 nsslowkey_DestroyPrivateKey(privKey);
10089 privKey = NULL((void*)0);
10090 }
10091 if (arena) {
10092 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_FALSE0);
10093 arena = NULL((void*)0);
10094 }
10095
10096 if (rv != SECSuccess) {
10097 crv = sftk_MapCryptError(PORT_GetErrorPORT_GetError_Util());
10098 break;
10099 }
10100
10101 /*
10102 * apply the kdf function.
10103 */
10104 if (mechParams->kdf == CKD_NULL0x00000001UL) {
10105 /*
10106 * tmp is the raw data created by ECDH_Derive,
10107 * secret and secretlen are the values we will
10108 * eventually pass as our generated key.
10109 */
10110 secret = tmp.data;
10111 secretlen = tmp.len;
10112 } else {
10113 secretlen = keySize;
10114 sftk_setFIPS(key, PR_FALSE0);
10115 crv = sftk_ANSI_X9_63_kdf(&secret, keySize,
10116 &tmp, mechParams->pSharedData,
10117 mechParams->ulSharedDataLen, mechParams->kdf);
10118 PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len);
10119 if (crv != CKR_OK0x00000000UL) {
10120 break;
10121 }
10122 tmp.data = secret;
10123 tmp.len = secretlen;
10124 }
10125
10126 /*
10127 * if keySize is supplied, then we are generating a key of a specific
10128 * length. This is done by taking the least significant 'keySize'
10129 * bytes from the unsigned value calculated by ECDH. Note: this may
10130 * mean padding temp with extra leading zeros from what ECDH_Derive
10131 * already returned (which itself may contain leading zeros).
10132 */
10133 if (keySize) {
10134 if (secretlen < keySize) {
10135 keyData = PORT_ZAllocPORT_ZAlloc_Util(keySize);
10136 if (!keyData) {
10137 PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len);
10138 crv = CKR_HOST_MEMORY0x00000002UL;
10139 break;
10140 }
10141 PORT_Memcpymemcpy(&keyData[keySize - secretlen], secret, secretlen);
10142 secret = keyData;
10143 } else {
10144 secret += (secretlen - keySize);
10145 }
10146 secretlen = keySize;
10147 }
10148 key->source = SFTK_SOURCE_KEA;
10149
10150 sftk_forceAttribute(key, CKA_VALUE0x00000011UL, secret, secretlen);
10151 PORT_ZFreePORT_ZFree_Util(tmp.data, tmp.len);
10152 if (keyData) {
10153 PORT_ZFreePORT_ZFree_Util(keyData, keySize);
10154 }
10155 break;
10156
10157 ec_loser:
10158 crv = CKR_ARGUMENTS_BAD0x00000007UL;
10159 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&ecScalar, PR_FALSE0);
10160 if (privKey != sourceKey->objectInfo)
10161 nsslowkey_DestroyPrivateKey(privKey);
10162 if (arena) {
10163 PORT_FreeArenaPORT_FreeArena_Util(arena, PR_TRUE1);
10164 }
10165 break;
10166 }
10167 /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */
10168 case CKM_NSS_HKDF_SHA1((0x80000000UL | 0x4E534350) + 3):
10169 hashMech = CKM_SHA_10x00000220UL;
10170 goto hkdf;
10171 case CKM_NSS_HKDF_SHA256((0x80000000UL | 0x4E534350) + 4):
10172 hashMech = CKM_SHA2560x00000250UL;
10173 goto hkdf;
10174 case CKM_NSS_HKDF_SHA384((0x80000000UL | 0x4E534350) + 5):
10175 hashMech = CKM_SHA3840x00000260UL;
10176 goto hkdf;
10177 case CKM_NSS_HKDF_SHA512((0x80000000UL | 0x4E534350) + 6):
10178 hashMech = CKM_SHA5120x00000270UL;
10179 goto hkdf;
10180 hkdf: {
10181 const CK_NSS_HKDFParams *params =
10182 (const CK_NSS_HKDFParams *)pMechanism->pParameter;
10183 CK_HKDF_PARAMS hkdfParams;
10184
10185 if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams)) {
10186 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10187 break;
10188 }
10189 hkdfParams.bExtract = params->bExtract;
10190 hkdfParams.bExpand = params->bExpand;
10191 if (params->pSalt) {
10192 hkdfParams.ulSaltType = CKF_HKDF_SALT_DATA0x00000002UL;
10193 } else {
10194 hkdfParams.ulSaltType = CKF_HKDF_SALT_NULL0x00000001UL;
10195 }
10196 hkdfParams.pSalt = params->pSalt;
10197 hkdfParams.ulSaltLen = params->ulSaltLen;
10198 hkdfParams.hSaltKey = CK_INVALID_HANDLE0;
10199 hkdfParams.pInfo = params->pInfo;
10200 hkdfParams.ulInfoLen = params->ulInfoLen;
10201 hkdfParams.prfHashMechanism = hashMech;
10202
10203 crv = sftk_HKDF(&hkdfParams, hSession, sourceKey,
10204 att->attrib.pValue, att->attrib.ulValueLen,
10205 key, NULL((void*)0), keySize, PR_FALSE0, isFIPS);
10206 } break;
10207 case CKM_HKDF_DERIVE0x0000402aUL:
10208 case CKM_HKDF_DATA0x0000402bUL: /* only difference is the class of key */
10209 if ((pMechanism->pParameter == NULL((void*)0)) ||
10210 (pMechanism->ulParameterLen != sizeof(CK_HKDF_PARAMS))) {
10211 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10212 break;
10213 }
10214 crv = sftk_HKDF((CK_HKDF_PARAMS_PTR)pMechanism->pParameter,
10215 hSession, sourceKey, att->attrib.pValue,
10216 att->attrib.ulValueLen, key, NULL((void*)0), keySize, PR_TRUE1,
10217 isFIPS);
10218 break;
10219 case CKM_NSS_JPAKE_ROUND2_SHA1((0x80000000UL | 0x4E534350) + 11):
10220 hashType = HASH_AlgSHA1;
10221 goto jpake2;
10222 case CKM_NSS_JPAKE_ROUND2_SHA256((0x80000000UL | 0x4E534350) + 12):
10223 hashType = HASH_AlgSHA256;
10224 goto jpake2;
10225 case CKM_NSS_JPAKE_ROUND2_SHA384((0x80000000UL | 0x4E534350) + 13):
10226 hashType = HASH_AlgSHA384;
10227 goto jpake2;
10228 case CKM_NSS_JPAKE_ROUND2_SHA512((0x80000000UL | 0x4E534350) + 14):
10229 hashType = HASH_AlgSHA512;
10230 goto jpake2;
10231 jpake2:
10232 if (pMechanism->pParameter == NULL((void*)0) ||
10233 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params))
10234 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10235 if (crv == CKR_OK0x00000000UL && sftk_isTrue(key, CKA_TOKEN0x00000001UL))
10236 crv = CKR_TEMPLATE_INCONSISTENT0x000000D1UL;
10237 if (crv == CKR_OK0x00000000UL)
10238 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
10239 if (crv == CKR_OK0x00000000UL)
10240 crv = jpake_Round2(hashType,
10241 (CK_NSS_JPAKERound2Params *)pMechanism->pParameter,
10242 sourceKey, key);
10243 break;
10244
10245 case CKM_NSS_JPAKE_FINAL_SHA1((0x80000000UL | 0x4E534350) + 15):
10246 hashType = HASH_AlgSHA1;
10247 goto jpakeFinal;
10248 case CKM_NSS_JPAKE_FINAL_SHA256((0x80000000UL | 0x4E534350) + 16):
10249 hashType = HASH_AlgSHA256;
10250 goto jpakeFinal;
10251 case CKM_NSS_JPAKE_FINAL_SHA384((0x80000000UL | 0x4E534350) + 17):
10252 hashType = HASH_AlgSHA384;
10253 goto jpakeFinal;
10254 case CKM_NSS_JPAKE_FINAL_SHA512((0x80000000UL | 0x4E534350) + 18):
10255 hashType = HASH_AlgSHA512;
10256 goto jpakeFinal;
10257 jpakeFinal:
10258 if (pMechanism->pParameter == NULL((void*)0) ||
10259 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams))
10260 crv = CKR_MECHANISM_PARAM_INVALID0x00000071UL;
10261 /* We purposely do not do the derive sensitivity check; we want to be
10262 able to derive non-sensitive keys while allowing the ROUND1 and
10263 ROUND2 keys to be sensitive (which they always are, since they are
10264 in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE
10265 in the template in order for the resultant keyblock key to be
10266 sensitive.
10267 */
10268 if (crv == CKR_OK0x00000000UL)
10269 crv = jpake_Final(hashType,
10270 (CK_NSS_JPAKEFinalParams *)pMechanism->pParameter,
10271 sourceKey, key);
10272 break;
10273
10274 case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 42): /* fall through */
10275 case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 43): /* fall through */
10276 case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA((0x80000000UL | 0x4E534350) + 44): /* fall through */
10277 case CKM_SP800_108_COUNTER_KDF0x000003acUL: /* fall through */
10278 case CKM_SP800_108_FEEDBACK_KDF0x000003adUL: /* fall through */
10279 case CKM_SP800_108_DOUBLE_PIPELINE_KDF0x000003aeUL:
10280 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE0);
10281 if (crv != CKR_OK0x00000000UL) {
10282 break;
10283 }
10284
10285 crv = kbkdf_Dispatch(mechanism, hSession, pMechanism, sourceKey, key, keySize);
10286 break;
10287 default:
10288 crv = CKR_MECHANISM_INVALID0x00000070UL;
10289 }
10290 if (att) {
10291 sftk_FreeAttribute(att);
10292 }
10293 sftk_FreeObject(sourceKey);
10294 if (crv != CKR_OK0x00000000UL) {
10295 if (key)
10296 sftk_FreeObject(key);
10297 return crv;
10298 }
10299
10300 /* link the key object into the list */
10301 if (key) {
10302 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
10303 if (sessKey == NULL((void*)0)) {
10304 sftk_FreeObject(key);
10305 return CKR_DEVICE_ERROR0x00000030UL;
10306 }
10307 sessKey->wasDerived = PR_TRUE1;
10308 session = sftk_SessionFromHandle(hSession);
10309 if (session == NULL((void*)0)) {
10310 sftk_FreeObject(key);
10311 return CKR_HOST_MEMORY0x00000002UL;
10312 }
10313
10314 crv = sftk_handleObject(key, session);
10315 session->lastOpWasFIPS = sftk_hasFIPS(key);
10316 sftk_FreeSession(session);
10317 if (phKey) {
10318 *phKey = key->handle;
10319 }
10320 sftk_FreeObject(key);
10321 }
10322 return crv;
10323}
10324
10325/* NSC_GetFunctionStatus obtains an updated status of a function running
10326 * in parallel with an application. */
10327CK_RV
10328NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
10329{
10330 CHECK_FORK();
10331
10332 return CKR_FUNCTION_NOT_PARALLEL0x00000051UL;
10333}
10334
10335/* NSC_CancelFunction cancels a function running in parallel */
10336CK_RV
10337NSC_CancelFunction(CK_SESSION_HANDLE hSession)
10338{
10339 CHECK_FORK();
10340
10341 return CKR_FUNCTION_NOT_PARALLEL0x00000051UL;
10342}
10343
10344/* NSC_GetOperationState saves the state of the cryptographic
10345 * operation in a session.
10346 * NOTE: This code only works for digest functions for now. eventually need
10347 * to add full flatten/resurect to our state stuff so that all types of state
10348 * can be saved */
10349CK_RV
10350NSC_GetOperationState(CK_SESSION_HANDLE hSession,
10351 CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
10352{
10353 SFTKSessionContext *context;
10354 SFTKSession *session;
10355 CK_RV crv;
10356 CK_ULONG pOSLen = *pulOperationStateLen;
10357
10358 CHECK_FORK();
10359
10360 /* make sure we're legal */
10361 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE1, &session);
10362 if (crv != CKR_OK0x00000000UL)
10363 return crv;
10364
10365 /* a zero cipherInfoLen signals that this context cannot be serialized */
10366 if (context->cipherInfoLen == 0) {
10367 sftk_FreeSession(session);
10368 return CKR_STATE_UNSAVEABLE0x00000180UL;
10369 }
10370
10371 *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE) + sizeof(SFTKContextType);
10372 if (pOperationState == NULL((void*)0)) {
10373 sftk_FreeSession(session);
10374 return CKR_OK0x00000000UL;
10375 } else {
10376 if (pOSLen < *pulOperationStateLen) {
10377 sftk_FreeSession(session);
10378 return CKR_BUFFER_TOO_SMALL0x00000150UL;
10379 }
10380 }
10381 PORT_Memcpymemcpy(pOperationState, &context->type, sizeof(SFTKContextType));
10382 pOperationState += sizeof(SFTKContextType);
10383 PORT_Memcpymemcpy(pOperationState, &context->currentMech,
10384 sizeof(CK_MECHANISM_TYPE));
10385 pOperationState += sizeof(CK_MECHANISM_TYPE);
10386 PORT_Memcpymemcpy(pOperationState, context->cipherInfo, context->cipherInfoLen);
10387 sftk_FreeSession(session);
10388 return CKR_OK0x00000000UL;
10389}
10390
10391#define sftk_Decrement(stateSize, len)stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize)
- (CK_ULONG)(len)) : 0;
\
10392 stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize) - (CK_ULONG)(len)) : 0;
10393
10394/* NSC_SetOperationState restores the state of the cryptographic
10395 * operation in a session. This is coded like it can restore lots of
10396 * states, but it only works for truly flat cipher structures. */
10397CK_RV
10398NSC_SetOperationState(CK_SESSION_HANDLE hSession,
10399 CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
10400 CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
10401{
10402 SFTKSessionContext *context;
10403 SFTKSession *session;
10404 SFTKContextType type;
10405 CK_MECHANISM mech;
10406 CK_RV crv = CKR_OK0x00000000UL;
10407
10408 CHECK_FORK();
10409
10410 while (ulOperationStateLen != 0) {
10411 /* get what type of state we're dealing with... */
10412 PORT_Memcpymemcpy(&type, pOperationState, sizeof(SFTKContextType));
10413
10414 /* fix up session contexts based on type */
10415 session = sftk_SessionFromHandle(hSession);
10416 if (session == NULL((void*)0))
10417 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
10418 sftk_UninstallContext(session, type);
10419 pOperationState += sizeof(SFTKContextType);
10420 sftk_Decrement(ulOperationStateLen, sizeof(SFTKContextType))ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)(
sizeof(SFTKContextType))) ? ((ulOperationStateLen) - (CK_ULONG
)(sizeof(SFTKContextType))) : 0;
;
10421
10422 /* get the mechanism structure */
10423 PORT_Memcpymemcpy(&mech.mechanism, pOperationState, sizeof(CK_MECHANISM_TYPE));
10424 pOperationState += sizeof(CK_MECHANISM_TYPE);
10425 sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE))ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)(
sizeof(CK_MECHANISM_TYPE))) ? ((ulOperationStateLen) - (CK_ULONG
)(sizeof(CK_MECHANISM_TYPE))) : 0;
;
10426 /* should be filled in... but not necessary for hash */
10427 mech.pParameter = NULL((void*)0);
10428 mech.ulParameterLen = 0;
10429 switch (type) {
10430 case SFTK_HASH:
10431 crv = NSC_DigestInit(hSession, &mech);
10432 if (crv != CKR_OK0x00000000UL)
10433 break;
10434 /* NSC_DigestInit just installed a SFTK_HASH context on
10435 * this session; the outer session reference keeps it
10436 * alive across the load below. */
10437 context = sftk_ReturnContextByType(session, SFTK_HASH);
10438 if (context == NULL((void*)0) || context->type != SFTK_HASH) {
10439 crv = CKR_OPERATION_NOT_INITIALIZED0x00000091UL;
10440 break;
10441 }
10442 if (context->cipherInfoLen == 0) {
10443 crv = CKR_SAVED_STATE_INVALID0x00000160UL;
10444 break;
10445 }
10446 PORT_Memcpymemcpy(context->cipherInfo, pOperationState,
10447 context->cipherInfoLen);
10448 pOperationState += context->cipherInfoLen;
10449 sftk_Decrement(ulOperationStateLen, context->cipherInfoLen)ulOperationStateLen = ((ulOperationStateLen) > (CK_ULONG)(
context->cipherInfoLen)) ? ((ulOperationStateLen) - (CK_ULONG
)(context->cipherInfoLen)) : 0;
;
10450 break;
10451 default:
10452 /* do sign/encrypt/decrypt later */
10453 crv = CKR_SAVED_STATE_INVALID0x00000160UL;
10454 }
10455 sftk_FreeSession(session);
10456 if (crv != CKR_OK0x00000000UL)
10457 break;
10458 }
10459 return crv;
10460}
10461
10462/* Dual-function cryptographic operations */
10463
10464/* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption
10465 * operation. */
10466CK_RV
10467NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
10468 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
10469 CK_ULONG_PTR pulEncryptedPartLen)
10470{
10471 CK_RV crv;
10472
10473 CHECK_FORK();
10474
10475 crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
10476 pulEncryptedPartLen);
10477 if (crv != CKR_OK0x00000000UL)
10478 return crv;
10479 crv = NSC_DigestUpdate(hSession, pPart, ulPartLen);
10480
10481 return crv;
10482}
10483
10484/* NSC_DecryptDigestUpdate continues a multiple-part decryption and
10485 * digesting operation. */
10486CK_RV
10487NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
10488 CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
10489 CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
10490{
10491 CK_RV crv;
10492
10493 CHECK_FORK();
10494
10495 crv = NSC_DecryptUpdate(hSession, pEncryptedPart, ulEncryptedPartLen,
10496 pPart, pulPartLen);
10497 if (crv != CKR_OK0x00000000UL)
10498 return crv;
10499 crv = NSC_DigestUpdate(hSession, pPart, *pulPartLen);
10500
10501 return crv;
10502}
10503
10504/* NSC_SignEncryptUpdate continues a multiple-part signing and
10505 * encryption operation. */
10506CK_RV
10507NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
10508 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
10509 CK_ULONG_PTR pulEncryptedPartLen)
10510{
10511 CK_RV crv;
10512
10513 CHECK_FORK();
10514
10515 crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart,
10516 pulEncryptedPartLen);
10517 if (crv != CKR_OK0x00000000UL)
10518 return crv;
10519 crv = NSC_SignUpdate(hSession, pPart, ulPartLen);
10520
10521 return crv;
10522}
10523
10524/* NSC_DecryptVerifyUpdate continues a multiple-part decryption
10525 * and verify operation. */
10526CK_RV
10527NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
10528 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
10529 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
10530{
10531 CK_RV crv;
10532
10533 CHECK_FORK();
10534
10535 crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
10536 pData, pulDataLen);
10537 if (crv != CKR_OK0x00000000UL)
10538 return crv;
10539 crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);
10540
10541 return crv;
10542}
10543
10544/* NSC_DigestKey continues a multi-part message-digesting operation,
10545 * by digesting the value of a secret key as part of the data already digested.
10546 */
10547CK_RV
10548NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
10549{
10550 SFTKSession *session = NULL((void*)0);
10551 SFTKObject *key = NULL((void*)0);
10552 SFTKAttribute *att;
10553 CK_RV crv;
10554
10555 CHECK_FORK();
10556
10557 session = sftk_SessionFromHandle(hSession);
10558 if (session == NULL((void*)0))
10559 return CKR_SESSION_HANDLE_INVALID0x000000B3UL;
10560
10561 key = sftk_ObjectFromHandle(hKey, session);
10562 sftk_FreeSession(session);
10563 if (key == NULL((void*)0))
10564 return CKR_KEY_HANDLE_INVALID0x00000060UL;
10565
10566 /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */
10567
10568 /* make sure it's a valid key for this operation */
10569 if (key->objclass != CKO_SECRET_KEY0x00000004UL) {
10570 sftk_FreeObject(key);
10571 return CKR_KEY_TYPE_INCONSISTENT0x00000063UL;
10572 }
10573 /* get the key value */
10574 att = sftk_FindAttribute(key, CKA_VALUE0x00000011UL);
10575 if (!att) {
10576 sftk_FreeObject(key);
10577 return CKR_KEY_HANDLE_INVALID0x00000060UL;
10578 }
10579 crv = NSC_DigestUpdate(hSession, (CK_BYTE_PTR)att->attrib.pValue,
10580 att->attrib.ulValueLen);
10581 sftk_FreeAttribute(att);
10582 sftk_FreeObject(key);
10583 return crv;
10584}