Bug Summary

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