Coverage Report

Created: 2025-09-17 07:05

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