Coverage Report

Created: 2024-05-20 06:23

/src/nss/lib/softoken/sftkmessage.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
 * Implement the PKCS #11 v3.0 Message interfaces
8
 */
9
#include "seccomon.h"
10
#include "pkcs11.h"
11
#include "pkcs11i.h"
12
#include "blapi.h"
13
#include "prenv.h"
14
#include "softoken.h"
15
16
static SECStatus
17
sftk_ChaCha20_Poly1305_Message_Encrypt(ChaCha20Poly1305Context *ctx,
18
                                       unsigned char *cipherText, unsigned int *cipherTextLen,
19
                                       unsigned int maxOutLen, const unsigned char *plainText,
20
                                       unsigned int plainTextLen,
21
                                       CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *params,
22
                                       unsigned int paramsLen, const unsigned char *aad,
23
                                       unsigned int aadLen)
24
0
{
25
0
    return ChaCha20Poly1305_Encrypt(ctx, cipherText, cipherTextLen, maxOutLen,
26
0
                                    plainText, plainTextLen, params->pNonce, params->ulNonceLen,
27
0
                                    aad, aadLen, params->pTag);
28
0
}
29
static SECStatus
30
sftk_ChaCha20_Poly1305_Message_Decrypt(ChaCha20Poly1305Context *ctx,
31
                                       unsigned char *plainText, unsigned int *plainTextLen,
32
                                       unsigned int maxOutLen, const unsigned char *cipherText,
33
                                       unsigned int cipherTextLen,
34
                                       CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *params,
35
                                       unsigned int paramsLen, const unsigned char *aad,
36
                                       unsigned int aadLen)
37
0
{
38
0
    return ChaCha20Poly1305_Decrypt(ctx, plainText, plainTextLen, maxOutLen,
39
0
                                    cipherText, cipherTextLen, params->pNonce, params->ulNonceLen,
40
0
                                    aad, aadLen, params->pTag);
41
0
}
42
43
/*
44
 * Handle AEAD Encryption operation
45
 *
46
 * The setup is similiar to sftk_CryptInit except we set the aeadUpdate
47
 * function instead of the normal update function. This function handles
48
 * both the Encrypt case and the Decrypt case.
49
 */
50
static CK_RV
51
sftk_MessageCryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
52
                      CK_OBJECT_HANDLE hKey, SFTKContextType contextType,
53
                      CK_ATTRIBUTE_TYPE operation, PRBool encrypt)
54
16
{
55
16
    SFTKSession *session;
56
16
    SFTKObject *key;
57
16
    SFTKSessionContext *context;
58
16
    SFTKAttribute *att;
59
16
    CK_KEY_TYPE key_type;
60
16
    CK_RV crv = CKR_OK;
61
62
16
    if (!pMechanism) {
63
0
        return CKR_MECHANISM_PARAM_INVALID;
64
0
    }
65
66
16
    crv = sftk_MechAllowsOperation(pMechanism->mechanism,
67
16
                                   CKA_NSS_MESSAGE | operation);
68
16
    if (crv != CKR_OK)
69
0
        return crv;
70
71
16
    session = sftk_SessionFromHandle(hSession);
72
16
    if (session == NULL)
73
0
        return CKR_SESSION_HANDLE_INVALID;
74
75
16
    crv = sftk_InitGeneric(session, pMechanism, &context, contextType, &key,
76
16
                           hKey, &key_type, CKO_SECRET_KEY, operation);
77
16
    if (crv != CKR_OK) {
78
0
        sftk_FreeSession(session);
79
0
        return crv;
80
0
    }
81
82
16
    att = sftk_FindAttribute(key, CKA_VALUE);
83
16
    if (att == NULL) {
84
0
        sftk_FreeSession(session);
85
0
        sftk_FreeContext(context);
86
0
        return CKR_KEY_HANDLE_INVALID;
87
0
    }
88
89
16
    context->doPad = PR_FALSE;
90
16
    context->multi = PR_TRUE; /* All message are 'multi' operations */
91
92
16
    switch (pMechanism->mechanism) {
93
14
        case CKM_AES_GCM:
94
14
            context->cipherInfo = AES_CreateContext(
95
14
                (unsigned char *)att->attrib.pValue,
96
14
                NULL, NSS_AES_GCM, encrypt, att->attrib.ulValueLen,
97
14
                AES_BLOCK_SIZE);
98
14
            context->aeadUpdate = (SFTKAEADCipher)AES_AEAD;
99
14
            context->destroy = (SFTKDestroy)AES_DestroyContext;
100
14
            break;
101
2
        case CKM_CHACHA20_POLY1305:
102
2
            context->cipherInfo = ChaCha20Poly1305_CreateContext(
103
2
                (unsigned char *)att->attrib.pValue, att->attrib.ulValueLen,
104
2
                16);
105
2
            context->aeadUpdate = (SFTKAEADCipher)(encrypt ? sftk_ChaCha20_Poly1305_Message_Encrypt : sftk_ChaCha20_Poly1305_Message_Decrypt);
106
2
            context->destroy = (SFTKDestroy)ChaCha20Poly1305_DestroyContext;
107
2
            break;
108
0
        default:
109
0
            crv = CKR_MECHANISM_INVALID;
110
0
            break;
111
16
    }
112
16
    if (context->cipherInfo == NULL) {
113
0
        crv = sftk_MapCryptError(PORT_GetError());
114
0
        if (crv == CKR_OK) {
115
0
            crv = CKR_GENERAL_ERROR;
116
0
        }
117
0
    }
118
16
    if (crv != CKR_OK) {
119
0
        sftk_FreeContext(context);
120
0
        sftk_FreeSession(session);
121
0
        return crv;
122
0
    }
123
16
    sftk_SetContextByType(session, contextType, context);
124
16
    sftk_FreeSession(session);
125
16
    return CKR_OK;
126
16
}
127
128
/*
129
 * Generic handler for the actual encryption/decryption. Each call handles
130
 * The authentication data for the entire block. Multiple calls using
131
 * BeginMessage and NextMessage are not supported and CKF_MESSSAGE_MULTI is
132
 * not set on the supported algorithms
133
 */
134
static CK_RV
135
sftk_CryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
136
                  CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
137
                  CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pIntext,
138
                  CK_ULONG ulIntextLen, CK_BYTE_PTR pOuttext,
139
                  CK_ULONG_PTR pulOuttextLen, SFTKContextType contextType)
140
0
{
141
0
    SFTKSessionContext *context;
142
0
    unsigned int outlen;
143
0
    unsigned int maxout = *pulOuttextLen;
144
0
    CK_RV crv;
145
0
    SECStatus rv;
146
147
0
    CHECK_FORK();
148
149
    /* make sure we're legal */
150
0
    crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL);
151
0
    if (crv != CKR_OK)
152
0
        return crv;
153
154
0
    if (!pOuttext) {
155
0
        *pulOuttextLen = ulIntextLen;
156
0
        return CKR_OK;
157
0
    }
158
0
    rv = (*context->aeadUpdate)(context->cipherInfo, pOuttext, &outlen,
159
0
                                maxout, pIntext, ulIntextLen,
160
0
                                pParameter, ulParameterLen,
161
0
                                pAssociatedData, ulAssociatedDataLen);
162
163
0
    if (rv != SECSuccess) {
164
0
        if (contextType == SFTK_MESSAGE_ENCRYPT) {
165
0
            return sftk_MapCryptError(PORT_GetError());
166
0
        } else {
167
0
            return sftk_MapDecryptError(PORT_GetError());
168
0
        }
169
0
    }
170
0
    *pulOuttextLen = (CK_ULONG)(outlen);
171
0
    return CKR_OK;
172
0
}
173
174
/*
175
 * Common message cleanup rountine
176
 */
177
static CK_RV
178
sftk_MessageCryptFinal(CK_SESSION_HANDLE hSession,
179
                       SFTKContextType contextType)
180
0
{
181
0
    SFTKSession *session;
182
0
    SFTKSessionContext *context;
183
0
    CK_RV crv;
184
185
0
    CHECK_FORK();
186
187
    /* make sure we're legal */
188
0
    crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, &session);
189
0
    if (crv != CKR_OK)
190
0
        return crv;
191
0
    sftk_TerminateOp(session, contextType, context);
192
0
    sftk_FreeSession(session);
193
0
    return CKR_OK;
194
0
}
195
196
/* MessageEncrypt and EncryptMessage functions just use the helper functions
197
 * above */
198
CK_RV
199
NSC_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
200
                       CK_OBJECT_HANDLE hKey)
201
8
{
202
8
    return sftk_MessageCryptInit(hSession, pMechanism, hKey,
203
8
                                 SFTK_MESSAGE_ENCRYPT, CKA_ENCRYPT, PR_TRUE);
204
8
}
205
206
CK_RV
207
NSC_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
208
                   CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
209
                   CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext,
210
                   CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext,
211
                   CK_ULONG_PTR pulCiphertextLen)
212
0
{
213
0
    return sftk_CryptMessage(hSession, pParameter, ulParameterLen,
214
0
                             pAssociatedData, ulAssociatedDataLen, pPlaintext,
215
0
                             ulPlaintextLen, pCiphertext, pulCiphertextLen,
216
0
                             SFTK_MESSAGE_ENCRYPT);
217
0
}
218
219
/*
220
 * We only support the single shot function. The Begin/Next version can be
221
 * dealt with if we need to support S/MIME or something. It would probably
222
 * just buffer rather then returning intermediate results.
223
 */
224
CK_RV
225
NSC_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
226
                        CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
227
                        CK_ULONG ulAssociatedDataLen)
228
0
{
229
0
    return CKR_FUNCTION_NOT_SUPPORTED;
230
0
}
231
232
CK_RV
233
NSC_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
234
                       CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart,
235
                       CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart,
236
                       CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags)
237
0
{
238
0
    return CKR_FUNCTION_NOT_SUPPORTED;
239
0
}
240
241
CK_RV
242
NSC_MessageEncryptFinal(CK_SESSION_HANDLE hSession)
243
0
{
244
0
    return sftk_MessageCryptFinal(hSession, SFTK_MESSAGE_ENCRYPT);
245
0
}
246
247
/* MessageDecrypt and DecryptMessage functions just use the helper functions
248
 * above */
249
CK_RV
250
NSC_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
251
                       CK_OBJECT_HANDLE hKey)
252
8
{
253
8
    return sftk_MessageCryptInit(hSession, pMechanism, hKey,
254
8
                                 SFTK_MESSAGE_DECRYPT, CKA_DECRYPT, PR_FALSE);
255
8
}
256
257
CK_RV
258
NSC_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
259
                   CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
260
                   CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext,
261
                   CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext,
262
                   CK_ULONG_PTR pulPlaintextLen)
263
0
{
264
0
    return sftk_CryptMessage(hSession, pParameter, ulParameterLen,
265
0
                             pAssociatedData, ulAssociatedDataLen, pCiphertext,
266
0
                             ulCiphertextLen, pPlaintext, pulPlaintextLen,
267
0
                             SFTK_MESSAGE_DECRYPT);
268
0
}
269
270
/*
271
 * We only support the single shot function. The Begin/Next version can be
272
 * dealt with if we need to support S/MIME or something. It would probably
273
 * just buffer rather then returning intermediate results. This is expecially
274
 * true for decrypt, which isn't supposed to return any data unless it's been
275
 * authenticated (which can't happen until the last block is processed).
276
 */
277
CK_RV
278
NSC_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
279
                        CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
280
                        CK_ULONG ulAssociatedDataLen)
281
0
{
282
0
    return CKR_FUNCTION_NOT_SUPPORTED;
283
0
}
284
285
CK_RV
286
NSC_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
287
                       CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart,
288
                       CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart,
289
                       CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags)
290
0
{
291
0
    return CKR_FUNCTION_NOT_SUPPORTED;
292
0
}
293
294
CK_RV
295
NSC_MessageDecryptFinal(CK_SESSION_HANDLE hSession)
296
0
{
297
0
    return sftk_MessageCryptFinal(hSession, SFTK_MESSAGE_DECRYPT);
298
0
}
299
300
/*
301
 * There are no mechanisms defined to use the MessageSign and MessageVerify
302
 * interfaces yet, so we don't need to implement anything.
303
 */
304
CK_RV
305
NSC_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
306
                    CK_OBJECT_HANDLE hKey)
307
0
{
308
0
    return CKR_FUNCTION_NOT_SUPPORTED;
309
0
}
310
311
CK_RV
312
NSC_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
313
                CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
314
                CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
315
0
{
316
0
    return CKR_FUNCTION_NOT_SUPPORTED;
317
0
}
318
319
CK_RV
320
NSC_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
321
                     CK_ULONG ulParameterLen)
322
0
{
323
0
    return CKR_FUNCTION_NOT_SUPPORTED;
324
0
}
325
326
CK_RV
327
NSC_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
328
                    CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
329
                    CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
330
                    CK_ULONG_PTR pulSignatureLen)
331
0
{
332
0
    return CKR_FUNCTION_NOT_SUPPORTED;
333
0
}
334
335
CK_RV
336
NSC_MessageSignFinal(CK_SESSION_HANDLE hSession)
337
0
{
338
0
    return CKR_FUNCTION_NOT_SUPPORTED;
339
0
}
340
341
CK_RV
342
NSC_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
343
                      CK_OBJECT_HANDLE hKey)
344
0
{
345
0
    return CKR_FUNCTION_NOT_SUPPORTED;
346
0
}
347
348
CK_RV
349
NSC_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
350
                  CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
351
                  CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
352
                  CK_ULONG ulSignatureLen)
353
0
{
354
0
    return CKR_FUNCTION_NOT_SUPPORTED;
355
0
}
356
357
CK_RV
358
NSC_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
359
                       CK_ULONG ulParameterLen)
360
0
{
361
0
    return CKR_FUNCTION_NOT_SUPPORTED;
362
0
}
363
364
CK_RV
365
NSC_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
366
                      CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
367
                      CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
368
                      CK_ULONG ulSignatureLen)
369
0
{
370
0
    return CKR_FUNCTION_NOT_SUPPORTED;
371
0
}
372
373
CK_RV
374
NSC_MessageVerifyFinal(CK_SESSION_HANDLE hSession)
375
0
{
376
0
    return CKR_FUNCTION_NOT_SUPPORTED;
377
0
}