Coverage Report

Created: 2025-04-22 06:18

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