Coverage Report

Created: 2025-07-04 06:19

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