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