Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/nss/lib/pk11wrap/pk11mech.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 maps various PKCS #11 Mechanisms to related mechanisms, key
6
 * types, and ASN.1 encodings.
7
 */
8
#include "seccomon.h"
9
#include "secmod.h"
10
#include "secmodi.h"
11
#include "pkcs11t.h"
12
#include "pk11func.h"
13
#include "secitem.h"
14
#include "secder.h"
15
#include "secasn1.h"
16
#include "secoid.h"
17
#include "secerr.h"
18
19
/*************************************************************
20
 * local static and global data
21
 *************************************************************/
22
23
/*
24
 * Tables used for Extended mechanism mapping (currently not used)
25
 */
26
typedef struct {
27
    CK_MECHANISM_TYPE keyGen;
28
    CK_KEY_TYPE keyType;
29
    CK_MECHANISM_TYPE type;
30
    CK_MECHANISM_TYPE padType;
31
    int blockSize;
32
    int iv;
33
} pk11MechanismData;
34
35
static pk11MechanismData pk11_default =
36
    { CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET,
37
      CKM_FAKE_RANDOM, CKM_FAKE_RANDOM, 8, 8 };
38
static pk11MechanismData *pk11_MechanismTable = NULL;
39
static int pk11_MechTableSize = 0;
40
static int pk11_MechEntrySize = 0;
41
42
/*
43
 * list of mechanisms we're willing to wrap secret keys with.
44
 * This list is ordered by preference.
45
 */
46
CK_MECHANISM_TYPE wrapMechanismList[] = {
47
    CKM_DES3_ECB,
48
    CKM_CAST5_ECB,
49
    CKM_AES_ECB,
50
    CKM_CAMELLIA_ECB,
51
    CKM_SEED_ECB,
52
    CKM_CAST5_ECB,
53
    CKM_DES_ECB,
54
    CKM_KEY_WRAP_LYNKS,
55
    CKM_IDEA_ECB,
56
    CKM_CAST3_ECB,
57
    CKM_CAST_ECB,
58
    CKM_RC5_ECB,
59
    CKM_RC2_ECB,
60
    CKM_CDMF_ECB,
61
    CKM_SKIPJACK_WRAP,
62
};
63
64
int wrapMechanismCount = sizeof(wrapMechanismList) / sizeof(wrapMechanismList[0]);
65
66
/*********************************************************************
67
 *       Mechanism Mapping functions
68
 *********************************************************************/
69
70
/*
71
 * lookup an entry in the mechanism table. If none found, return the
72
 * default structure.
73
 */
74
static pk11MechanismData *
75
pk11_lookup(CK_MECHANISM_TYPE type)
76
0
{
77
0
    int i;
78
0
    for (i = 0; i < pk11_MechEntrySize; i++) {
79
0
        if (pk11_MechanismTable[i].type == type) {
80
0
            return (&pk11_MechanismTable[i]);
81
0
        }
82
0
    }
83
0
    return &pk11_default;
84
0
}
85
86
/*
87
 * find the best key wrap mechanism for this slot.
88
 */
89
CK_MECHANISM_TYPE
90
PK11_GetBestWrapMechanism(PK11SlotInfo *slot)
91
0
{
92
0
    int i;
93
0
    for (i = 0; i < wrapMechanismCount; i++) {
94
0
        if (PK11_DoesMechanism(slot, wrapMechanismList[i])) {
95
0
            return wrapMechanismList[i];
96
0
        }
97
0
    }
98
0
    return CKM_INVALID_MECHANISM;
99
0
}
100
101
/*
102
 * NOTE: This is not thread safe. Called at init time, and when loading
103
 * a new Entry. It is reasonably safe as long as it is not re-entered
104
 * (readers will always see a consistant table)
105
 *
106
 * This routine is called to add entries to the mechanism table, once there,
107
 * they can not be removed.
108
 */
109
void
110
PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
111
                       CK_MECHANISM_TYPE keyGen,
112
                       CK_MECHANISM_TYPE padType,
113
                       int ivLen, int blockSize)
114
0
{
115
0
    int tableSize = pk11_MechTableSize;
116
0
    int size = pk11_MechEntrySize;
117
0
    int entry = size++;
118
0
    pk11MechanismData *old = pk11_MechanismTable;
119
0
    pk11MechanismData *newt = pk11_MechanismTable;
120
0
121
0
    if (size > tableSize) {
122
0
        int oldTableSize = tableSize;
123
0
        tableSize += 10;
124
0
        newt = PORT_NewArray(pk11MechanismData, tableSize);
125
0
        if (newt == NULL)
126
0
            return;
127
0
128
0
        if (old)
129
0
            PORT_Memcpy(newt, old, oldTableSize * sizeof(*newt));
130
0
    } else
131
0
        old = NULL;
132
0
133
0
    newt[entry].type = type;
134
0
    newt[entry].keyType = key;
135
0
    newt[entry].keyGen = keyGen;
136
0
    newt[entry].padType = padType;
137
0
    newt[entry].iv = ivLen;
138
0
    newt[entry].blockSize = blockSize;
139
0
140
0
    pk11_MechanismTable = newt;
141
0
    pk11_MechTableSize = tableSize;
142
0
    pk11_MechEntrySize = size;
143
0
    if (old)
144
0
        PORT_Free(old);
145
0
}
146
147
/*
148
 * Get the mechanism needed for the given key type
149
 */
150
CK_MECHANISM_TYPE
151
PK11_GetKeyMechanism(CK_KEY_TYPE type)
152
0
{
153
0
    switch (type) {
154
0
        case CKK_SEED:
155
0
            return CKM_SEED_CBC;
156
0
        case CKK_CAMELLIA:
157
0
            return CKM_CAMELLIA_CBC;
158
0
        case CKK_NSS_CHACHA20:
159
0
            return CKM_NSS_CHACHA20_POLY1305;
160
0
        case CKK_AES:
161
0
            return CKM_AES_CBC;
162
0
        case CKK_DES:
163
0
            return CKM_DES_CBC;
164
0
        case CKK_DES3:
165
0
            return CKM_DES3_KEY_GEN;
166
0
        case CKK_DES2:
167
0
            return CKM_DES2_KEY_GEN;
168
0
        case CKK_CDMF:
169
0
            return CKM_CDMF_CBC;
170
0
        case CKK_RC2:
171
0
            return CKM_RC2_CBC;
172
0
        case CKK_RC4:
173
0
            return CKM_RC4;
174
0
        case CKK_RC5:
175
0
            return CKM_RC5_CBC;
176
0
        case CKK_SKIPJACK:
177
0
            return CKM_SKIPJACK_CBC64;
178
0
        case CKK_BATON:
179
0
            return CKM_BATON_CBC128;
180
0
        case CKK_JUNIPER:
181
0
            return CKM_JUNIPER_CBC128;
182
0
        case CKK_IDEA:
183
0
            return CKM_IDEA_CBC;
184
0
        case CKK_CAST:
185
0
            return CKM_CAST_CBC;
186
0
        case CKK_CAST3:
187
0
            return CKM_CAST3_CBC;
188
0
        case CKK_CAST5:
189
0
            return CKM_CAST5_CBC;
190
0
        case CKK_RSA:
191
0
            return CKM_RSA_PKCS;
192
0
        case CKK_DSA:
193
0
            return CKM_DSA;
194
0
        case CKK_DH:
195
0
            return CKM_DH_PKCS_DERIVE;
196
0
        case CKK_KEA:
197
0
            return CKM_KEA_KEY_DERIVE;
198
0
        case CKK_EC: /* CKK_ECDSA is deprecated */
199
0
            return CKM_ECDSA;
200
0
        case CKK_GENERIC_SECRET:
201
0
        default:
202
0
            return CKM_SHA_1_HMAC;
203
0
    }
204
0
}
205
206
/*
207
 * Get the key type needed for the given mechanism
208
 */
209
CK_KEY_TYPE
210
PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
211
0
{
212
0
    switch (type) {
213
0
        case CKM_SEED_ECB:
214
0
        case CKM_SEED_CBC:
215
0
        case CKM_SEED_MAC:
216
0
        case CKM_SEED_MAC_GENERAL:
217
0
        case CKM_SEED_CBC_PAD:
218
0
        case CKM_SEED_KEY_GEN:
219
0
            return CKK_SEED;
220
0
        case CKM_CAMELLIA_ECB:
221
0
        case CKM_CAMELLIA_CBC:
222
0
        case CKM_CAMELLIA_MAC:
223
0
        case CKM_CAMELLIA_MAC_GENERAL:
224
0
        case CKM_CAMELLIA_CBC_PAD:
225
0
        case CKM_CAMELLIA_KEY_GEN:
226
0
            return CKK_CAMELLIA;
227
0
        case CKM_NSS_CHACHA20_POLY1305:
228
0
        case CKM_NSS_CHACHA20_KEY_GEN:
229
0
            return CKK_NSS_CHACHA20;
230
0
        case CKM_AES_ECB:
231
0
        case CKM_AES_CBC:
232
0
        case CKM_AES_CCM:
233
0
        case CKM_AES_CTR:
234
0
        case CKM_AES_CTS:
235
0
        case CKM_AES_GCM:
236
0
        case CKM_AES_MAC:
237
0
        case CKM_AES_MAC_GENERAL:
238
0
        case CKM_AES_CBC_PAD:
239
0
        case CKM_AES_KEY_GEN:
240
0
        case CKM_NETSCAPE_AES_KEY_WRAP:
241
0
        case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
242
0
            return CKK_AES;
243
0
        case CKM_DES_ECB:
244
0
        case CKM_DES_CBC:
245
0
        case CKM_DES_MAC:
246
0
        case CKM_DES_MAC_GENERAL:
247
0
        case CKM_DES_CBC_PAD:
248
0
        case CKM_DES_KEY_GEN:
249
0
        case CKM_KEY_WRAP_LYNKS:
250
0
        case CKM_PBE_MD2_DES_CBC:
251
0
        case CKM_PBE_MD5_DES_CBC:
252
0
            return CKK_DES;
253
0
        case CKM_DES3_ECB:
254
0
        case CKM_DES3_CBC:
255
0
        case CKM_DES3_MAC:
256
0
        case CKM_DES3_MAC_GENERAL:
257
0
        case CKM_DES3_CBC_PAD:
258
0
            return (len == 16) ? CKK_DES2 : CKK_DES3;
259
0
        case CKM_DES2_KEY_GEN:
260
0
        case CKM_PBE_SHA1_DES2_EDE_CBC:
261
0
            return CKK_DES2;
262
0
        case CKM_PBE_SHA1_DES3_EDE_CBC:
263
0
        case CKM_DES3_KEY_GEN:
264
0
            return CKK_DES3;
265
0
        case CKM_CDMF_ECB:
266
0
        case CKM_CDMF_CBC:
267
0
        case CKM_CDMF_MAC:
268
0
        case CKM_CDMF_MAC_GENERAL:
269
0
        case CKM_CDMF_CBC_PAD:
270
0
        case CKM_CDMF_KEY_GEN:
271
0
            return CKK_CDMF;
272
0
        case CKM_RC2_ECB:
273
0
        case CKM_RC2_CBC:
274
0
        case CKM_RC2_MAC:
275
0
        case CKM_RC2_MAC_GENERAL:
276
0
        case CKM_RC2_CBC_PAD:
277
0
        case CKM_RC2_KEY_GEN:
278
0
        case CKM_PBE_SHA1_RC2_128_CBC:
279
0
        case CKM_PBE_SHA1_RC2_40_CBC:
280
0
            return CKK_RC2;
281
0
        case CKM_RC4:
282
0
        case CKM_RC4_KEY_GEN:
283
0
            return CKK_RC4;
284
0
        case CKM_RC5_ECB:
285
0
        case CKM_RC5_CBC:
286
0
        case CKM_RC5_MAC:
287
0
        case CKM_RC5_MAC_GENERAL:
288
0
        case CKM_RC5_CBC_PAD:
289
0
        case CKM_RC5_KEY_GEN:
290
0
            return CKK_RC5;
291
0
        case CKM_SKIPJACK_CBC64:
292
0
        case CKM_SKIPJACK_ECB64:
293
0
        case CKM_SKIPJACK_OFB64:
294
0
        case CKM_SKIPJACK_CFB64:
295
0
        case CKM_SKIPJACK_CFB32:
296
0
        case CKM_SKIPJACK_CFB16:
297
0
        case CKM_SKIPJACK_CFB8:
298
0
        case CKM_SKIPJACK_KEY_GEN:
299
0
        case CKM_SKIPJACK_WRAP:
300
0
        case CKM_SKIPJACK_PRIVATE_WRAP:
301
0
            return CKK_SKIPJACK;
302
0
        case CKM_BATON_ECB128:
303
0
        case CKM_BATON_ECB96:
304
0
        case CKM_BATON_CBC128:
305
0
        case CKM_BATON_COUNTER:
306
0
        case CKM_BATON_SHUFFLE:
307
0
        case CKM_BATON_WRAP:
308
0
        case CKM_BATON_KEY_GEN:
309
0
            return CKK_BATON;
310
0
        case CKM_JUNIPER_ECB128:
311
0
        case CKM_JUNIPER_CBC128:
312
0
        case CKM_JUNIPER_COUNTER:
313
0
        case CKM_JUNIPER_SHUFFLE:
314
0
        case CKM_JUNIPER_WRAP:
315
0
        case CKM_JUNIPER_KEY_GEN:
316
0
            return CKK_JUNIPER;
317
0
        case CKM_IDEA_CBC:
318
0
        case CKM_IDEA_ECB:
319
0
        case CKM_IDEA_MAC:
320
0
        case CKM_IDEA_MAC_GENERAL:
321
0
        case CKM_IDEA_CBC_PAD:
322
0
        case CKM_IDEA_KEY_GEN:
323
0
            return CKK_IDEA;
324
0
        case CKM_CAST_ECB:
325
0
        case CKM_CAST_CBC:
326
0
        case CKM_CAST_MAC:
327
0
        case CKM_CAST_MAC_GENERAL:
328
0
        case CKM_CAST_CBC_PAD:
329
0
        case CKM_CAST_KEY_GEN:
330
0
        case CKM_PBE_MD5_CAST_CBC:
331
0
            return CKK_CAST;
332
0
        case CKM_CAST3_ECB:
333
0
        case CKM_CAST3_CBC:
334
0
        case CKM_CAST3_MAC:
335
0
        case CKM_CAST3_MAC_GENERAL:
336
0
        case CKM_CAST3_CBC_PAD:
337
0
        case CKM_CAST3_KEY_GEN:
338
0
        case CKM_PBE_MD5_CAST3_CBC:
339
0
            return CKK_CAST3;
340
0
        case CKM_CAST5_ECB:
341
0
        case CKM_CAST5_CBC:
342
0
        case CKM_CAST5_MAC:
343
0
        case CKM_CAST5_MAC_GENERAL:
344
0
        case CKM_CAST5_CBC_PAD:
345
0
        case CKM_CAST5_KEY_GEN:
346
0
        case CKM_PBE_MD5_CAST5_CBC:
347
0
            return CKK_CAST5;
348
0
        case CKM_RSA_PKCS:
349
0
        case CKM_RSA_9796:
350
0
        case CKM_RSA_X_509:
351
0
        case CKM_MD2_RSA_PKCS:
352
0
        case CKM_MD5_RSA_PKCS:
353
0
        case CKM_SHA1_RSA_PKCS:
354
0
        case CKM_SHA224_RSA_PKCS:
355
0
        case CKM_SHA256_RSA_PKCS:
356
0
        case CKM_SHA384_RSA_PKCS:
357
0
        case CKM_SHA512_RSA_PKCS:
358
0
        case CKM_KEY_WRAP_SET_OAEP:
359
0
        case CKM_RSA_PKCS_KEY_PAIR_GEN:
360
0
        case CKM_RSA_X9_31_KEY_PAIR_GEN:
361
0
            return CKK_RSA;
362
0
        case CKM_DSA:
363
0
        case CKM_DSA_SHA1:
364
0
        case CKM_DSA_KEY_PAIR_GEN:
365
0
            return CKK_DSA;
366
0
        case CKM_DH_PKCS_DERIVE:
367
0
        case CKM_DH_PKCS_KEY_PAIR_GEN:
368
0
            return CKK_DH;
369
0
        case CKM_KEA_KEY_DERIVE:
370
0
        case CKM_KEA_KEY_PAIR_GEN:
371
0
            return CKK_KEA;
372
0
        case CKM_ECDSA:
373
0
        case CKM_ECDSA_SHA1:
374
0
        case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
375
0
        case CKM_ECDH1_DERIVE:
376
0
            return CKK_EC; /* CKK_ECDSA is deprecated */
377
0
        case CKM_SSL3_PRE_MASTER_KEY_GEN:
378
0
        case CKM_GENERIC_SECRET_KEY_GEN:
379
0
        case CKM_SSL3_MASTER_KEY_DERIVE:
380
0
        case CKM_SSL3_MASTER_KEY_DERIVE_DH:
381
0
        case CKM_SSL3_KEY_AND_MAC_DERIVE:
382
0
        case CKM_SSL3_SHA1_MAC:
383
0
        case CKM_SSL3_MD5_MAC:
384
0
        case CKM_TLS_MASTER_KEY_DERIVE:
385
0
        case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256:
386
0
        case CKM_TLS_MASTER_KEY_DERIVE_DH:
387
0
        case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256:
388
0
        case CKM_TLS_KEY_AND_MAC_DERIVE:
389
0
        case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
390
0
        case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
391
0
        case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
392
0
        case CKM_SHA_1_HMAC:
393
0
        case CKM_SHA_1_HMAC_GENERAL:
394
0
        case CKM_SHA224_HMAC:
395
0
        case CKM_SHA224_HMAC_GENERAL:
396
0
        case CKM_SHA256_HMAC:
397
0
        case CKM_SHA256_HMAC_GENERAL:
398
0
        case CKM_SHA384_HMAC:
399
0
        case CKM_SHA384_HMAC_GENERAL:
400
0
        case CKM_SHA512_HMAC:
401
0
        case CKM_SHA512_HMAC_GENERAL:
402
0
        case CKM_MD2_HMAC:
403
0
        case CKM_MD2_HMAC_GENERAL:
404
0
        case CKM_MD5_HMAC:
405
0
        case CKM_MD5_HMAC_GENERAL:
406
0
        case CKM_TLS_PRF_GENERAL:
407
0
        case CKM_NSS_TLS_PRF_GENERAL_SHA256:
408
0
            return CKK_GENERIC_SECRET;
409
0
        default:
410
0
            return pk11_lookup(type)->keyType;
411
0
    }
412
0
}
413
414
/*
415
 * Get the Key Gen Mechanism needed for the given
416
 * crypto mechanism
417
 */
418
CK_MECHANISM_TYPE
419
PK11_GetKeyGen(CK_MECHANISM_TYPE type)
420
0
{
421
0
    return PK11_GetKeyGenWithSize(type, 0);
422
0
}
423
424
CK_MECHANISM_TYPE
425
PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
426
0
{
427
0
    switch (type) {
428
0
        case CKM_SEED_ECB:
429
0
        case CKM_SEED_CBC:
430
0
        case CKM_SEED_MAC:
431
0
        case CKM_SEED_MAC_GENERAL:
432
0
        case CKM_SEED_CBC_PAD:
433
0
        case CKM_SEED_KEY_GEN:
434
0
            return CKM_SEED_KEY_GEN;
435
0
        case CKM_CAMELLIA_ECB:
436
0
        case CKM_CAMELLIA_CBC:
437
0
        case CKM_CAMELLIA_MAC:
438
0
        case CKM_CAMELLIA_MAC_GENERAL:
439
0
        case CKM_CAMELLIA_CBC_PAD:
440
0
        case CKM_CAMELLIA_KEY_GEN:
441
0
            return CKM_CAMELLIA_KEY_GEN;
442
0
        case CKM_NSS_CHACHA20_POLY1305:
443
0
            return CKM_NSS_CHACHA20_KEY_GEN;
444
0
        case CKM_AES_ECB:
445
0
        case CKM_AES_CBC:
446
0
        case CKM_AES_CCM:
447
0
        case CKM_AES_CTR:
448
0
        case CKM_AES_CTS:
449
0
        case CKM_AES_GCM:
450
0
        case CKM_AES_MAC:
451
0
        case CKM_AES_MAC_GENERAL:
452
0
        case CKM_AES_CBC_PAD:
453
0
        case CKM_AES_KEY_GEN:
454
0
            return CKM_AES_KEY_GEN;
455
0
        case CKM_DES_ECB:
456
0
        case CKM_DES_CBC:
457
0
        case CKM_DES_MAC:
458
0
        case CKM_DES_MAC_GENERAL:
459
0
        case CKM_KEY_WRAP_LYNKS:
460
0
        case CKM_DES_CBC_PAD:
461
0
        case CKM_DES_KEY_GEN:
462
0
            return CKM_DES_KEY_GEN;
463
0
        case CKM_DES3_ECB:
464
0
        case CKM_DES3_CBC:
465
0
        case CKM_DES3_MAC:
466
0
        case CKM_DES3_MAC_GENERAL:
467
0
        case CKM_DES3_CBC_PAD:
468
0
            return (size == 16) ? CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN;
469
0
        case CKM_DES3_KEY_GEN:
470
0
            return CKM_DES3_KEY_GEN;
471
0
        case CKM_DES2_KEY_GEN:
472
0
            return CKM_DES2_KEY_GEN;
473
0
        case CKM_CDMF_ECB:
474
0
        case CKM_CDMF_CBC:
475
0
        case CKM_CDMF_MAC:
476
0
        case CKM_CDMF_MAC_GENERAL:
477
0
        case CKM_CDMF_CBC_PAD:
478
0
        case CKM_CDMF_KEY_GEN:
479
0
            return CKM_CDMF_KEY_GEN;
480
0
        case CKM_RC2_ECB:
481
0
        case CKM_RC2_CBC:
482
0
        case CKM_RC2_MAC:
483
0
        case CKM_RC2_MAC_GENERAL:
484
0
        case CKM_RC2_CBC_PAD:
485
0
        case CKM_RC2_KEY_GEN:
486
0
            return CKM_RC2_KEY_GEN;
487
0
        case CKM_RC4:
488
0
        case CKM_RC4_KEY_GEN:
489
0
            return CKM_RC4_KEY_GEN;
490
0
        case CKM_RC5_ECB:
491
0
        case CKM_RC5_CBC:
492
0
        case CKM_RC5_MAC:
493
0
        case CKM_RC5_MAC_GENERAL:
494
0
        case CKM_RC5_CBC_PAD:
495
0
        case CKM_RC5_KEY_GEN:
496
0
            return CKM_RC5_KEY_GEN;
497
0
        case CKM_SKIPJACK_CBC64:
498
0
        case CKM_SKIPJACK_ECB64:
499
0
        case CKM_SKIPJACK_OFB64:
500
0
        case CKM_SKIPJACK_CFB64:
501
0
        case CKM_SKIPJACK_CFB32:
502
0
        case CKM_SKIPJACK_CFB16:
503
0
        case CKM_SKIPJACK_CFB8:
504
0
        case CKM_SKIPJACK_WRAP:
505
0
        case CKM_SKIPJACK_KEY_GEN:
506
0
            return CKM_SKIPJACK_KEY_GEN;
507
0
        case CKM_BATON_ECB128:
508
0
        case CKM_BATON_ECB96:
509
0
        case CKM_BATON_CBC128:
510
0
        case CKM_BATON_COUNTER:
511
0
        case CKM_BATON_SHUFFLE:
512
0
        case CKM_BATON_WRAP:
513
0
        case CKM_BATON_KEY_GEN:
514
0
            return CKM_BATON_KEY_GEN;
515
0
        case CKM_JUNIPER_ECB128:
516
0
        case CKM_JUNIPER_CBC128:
517
0
        case CKM_JUNIPER_COUNTER:
518
0
        case CKM_JUNIPER_SHUFFLE:
519
0
        case CKM_JUNIPER_WRAP:
520
0
        case CKM_JUNIPER_KEY_GEN:
521
0
            return CKM_JUNIPER_KEY_GEN;
522
0
        case CKM_IDEA_CBC:
523
0
        case CKM_IDEA_ECB:
524
0
        case CKM_IDEA_MAC:
525
0
        case CKM_IDEA_MAC_GENERAL:
526
0
        case CKM_IDEA_CBC_PAD:
527
0
        case CKM_IDEA_KEY_GEN:
528
0
            return CKM_IDEA_KEY_GEN;
529
0
        case CKM_CAST_ECB:
530
0
        case CKM_CAST_CBC:
531
0
        case CKM_CAST_MAC:
532
0
        case CKM_CAST_MAC_GENERAL:
533
0
        case CKM_CAST_CBC_PAD:
534
0
        case CKM_CAST_KEY_GEN:
535
0
            return CKM_CAST_KEY_GEN;
536
0
        case CKM_CAST3_ECB:
537
0
        case CKM_CAST3_CBC:
538
0
        case CKM_CAST3_MAC:
539
0
        case CKM_CAST3_MAC_GENERAL:
540
0
        case CKM_CAST3_CBC_PAD:
541
0
        case CKM_CAST3_KEY_GEN:
542
0
            return CKM_CAST3_KEY_GEN;
543
0
        case CKM_CAST5_ECB:
544
0
        case CKM_CAST5_CBC:
545
0
        case CKM_CAST5_MAC:
546
0
        case CKM_CAST5_MAC_GENERAL:
547
0
        case CKM_CAST5_CBC_PAD:
548
0
        case CKM_CAST5_KEY_GEN:
549
0
            return CKM_CAST5_KEY_GEN;
550
0
        case CKM_RSA_PKCS:
551
0
        case CKM_RSA_9796:
552
0
        case CKM_RSA_X_509:
553
0
        case CKM_MD2_RSA_PKCS:
554
0
        case CKM_MD5_RSA_PKCS:
555
0
        case CKM_SHA1_RSA_PKCS:
556
0
        case CKM_SHA224_RSA_PKCS:
557
0
        case CKM_SHA256_RSA_PKCS:
558
0
        case CKM_SHA384_RSA_PKCS:
559
0
        case CKM_SHA512_RSA_PKCS:
560
0
        case CKM_KEY_WRAP_SET_OAEP:
561
0
        case CKM_RSA_PKCS_KEY_PAIR_GEN:
562
0
            return CKM_RSA_PKCS_KEY_PAIR_GEN;
563
0
        case CKM_RSA_X9_31_KEY_PAIR_GEN:
564
0
            return CKM_RSA_X9_31_KEY_PAIR_GEN;
565
0
        case CKM_DSA:
566
0
        case CKM_DSA_SHA1:
567
0
        case CKM_DSA_KEY_PAIR_GEN:
568
0
            return CKM_DSA_KEY_PAIR_GEN;
569
0
        case CKM_DH_PKCS_DERIVE:
570
0
        case CKM_DH_PKCS_KEY_PAIR_GEN:
571
0
            return CKM_DH_PKCS_KEY_PAIR_GEN;
572
0
        case CKM_KEA_KEY_DERIVE:
573
0
        case CKM_KEA_KEY_PAIR_GEN:
574
0
            return CKM_KEA_KEY_PAIR_GEN;
575
0
        case CKM_ECDSA:
576
0
        case CKM_ECDSA_SHA1:
577
0
        case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
578
0
        case CKM_ECDH1_DERIVE:
579
0
            return CKM_EC_KEY_PAIR_GEN;
580
0
        case CKM_SSL3_PRE_MASTER_KEY_GEN:
581
0
        case CKM_SSL3_MASTER_KEY_DERIVE:
582
0
        case CKM_SSL3_KEY_AND_MAC_DERIVE:
583
0
        case CKM_SSL3_SHA1_MAC:
584
0
        case CKM_SSL3_MD5_MAC:
585
0
        case CKM_TLS_MASTER_KEY_DERIVE:
586
0
        case CKM_TLS_KEY_AND_MAC_DERIVE:
587
0
        case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256:
588
0
        case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE:
589
0
        case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH:
590
0
            return CKM_SSL3_PRE_MASTER_KEY_GEN;
591
0
        case CKM_SHA_1_HMAC:
592
0
        case CKM_SHA_1_HMAC_GENERAL:
593
0
        case CKM_SHA224_HMAC:
594
0
        case CKM_SHA224_HMAC_GENERAL:
595
0
        case CKM_SHA256_HMAC:
596
0
        case CKM_SHA256_HMAC_GENERAL:
597
0
        case CKM_SHA384_HMAC:
598
0
        case CKM_SHA384_HMAC_GENERAL:
599
0
        case CKM_SHA512_HMAC:
600
0
        case CKM_SHA512_HMAC_GENERAL:
601
0
        case CKM_MD2_HMAC:
602
0
        case CKM_MD2_HMAC_GENERAL:
603
0
        case CKM_MD5_HMAC:
604
0
        case CKM_MD5_HMAC_GENERAL:
605
0
        case CKM_TLS_PRF_GENERAL:
606
0
        case CKM_NSS_TLS_PRF_GENERAL_SHA256:
607
0
        case CKM_GENERIC_SECRET_KEY_GEN:
608
0
            return CKM_GENERIC_SECRET_KEY_GEN;
609
0
        case CKM_PBE_MD2_DES_CBC:
610
0
        case CKM_PBE_MD5_DES_CBC:
611
0
        case CKM_PBA_SHA1_WITH_SHA1_HMAC:
612
0
        case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
613
0
        case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
614
0
        case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
615
0
        case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
616
0
        case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
617
0
        case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
618
0
        case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
619
0
        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
620
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
621
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
622
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
623
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
624
0
        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
625
0
        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
626
0
        case CKM_PBE_SHA1_RC2_40_CBC:
627
0
        case CKM_PBE_SHA1_RC2_128_CBC:
628
0
        case CKM_PBE_SHA1_RC4_40:
629
0
        case CKM_PBE_SHA1_RC4_128:
630
0
        case CKM_PBE_SHA1_DES3_EDE_CBC:
631
0
        case CKM_PBE_SHA1_DES2_EDE_CBC:
632
0
        case CKM_PKCS5_PBKD2:
633
0
            return type;
634
0
        default:
635
0
            return pk11_lookup(type)->keyGen;
636
0
    }
637
0
}
638
639
/*
640
 * get the mechanism block size
641
 */
642
int
643
PK11_GetBlockSize(CK_MECHANISM_TYPE type, SECItem *params)
644
0
{
645
0
    CK_RC5_PARAMS *rc5_params;
646
0
    CK_RC5_CBC_PARAMS *rc5_cbc_params;
647
0
    switch (type) {
648
0
        case CKM_RC5_ECB:
649
0
            if ((params) && (params->data)) {
650
0
                rc5_params = (CK_RC5_PARAMS *)params->data;
651
0
                return (rc5_params->ulWordsize) * 2;
652
0
            }
653
0
            return 8;
654
0
        case CKM_RC5_CBC:
655
0
        case CKM_RC5_CBC_PAD:
656
0
            if ((params) && (params->data)) {
657
0
                rc5_cbc_params = (CK_RC5_CBC_PARAMS *)params->data;
658
0
                return (rc5_cbc_params->ulWordsize) * 2;
659
0
            }
660
0
            return 8;
661
0
        case CKM_DES_ECB:
662
0
        case CKM_DES3_ECB:
663
0
        case CKM_RC2_ECB:
664
0
        case CKM_IDEA_ECB:
665
0
        case CKM_CAST_ECB:
666
0
        case CKM_CAST3_ECB:
667
0
        case CKM_CAST5_ECB:
668
0
        case CKM_RC2_CBC:
669
0
        case CKM_SKIPJACK_CBC64:
670
0
        case CKM_SKIPJACK_ECB64:
671
0
        case CKM_SKIPJACK_OFB64:
672
0
        case CKM_SKIPJACK_CFB64:
673
0
        case CKM_DES_CBC:
674
0
        case CKM_DES3_CBC:
675
0
        case CKM_IDEA_CBC:
676
0
        case CKM_CAST_CBC:
677
0
        case CKM_CAST3_CBC:
678
0
        case CKM_CAST5_CBC:
679
0
        case CKM_DES_CBC_PAD:
680
0
        case CKM_DES3_CBC_PAD:
681
0
        case CKM_RC2_CBC_PAD:
682
0
        case CKM_IDEA_CBC_PAD:
683
0
        case CKM_CAST_CBC_PAD:
684
0
        case CKM_CAST3_CBC_PAD:
685
0
        case CKM_CAST5_CBC_PAD:
686
0
        case CKM_PBE_MD2_DES_CBC:
687
0
        case CKM_PBE_MD5_DES_CBC:
688
0
        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
689
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
690
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
691
0
        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
692
0
        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
693
0
        case CKM_PBE_SHA1_RC2_40_CBC:
694
0
        case CKM_PBE_SHA1_RC2_128_CBC:
695
0
        case CKM_PBE_SHA1_DES3_EDE_CBC:
696
0
        case CKM_PBE_SHA1_DES2_EDE_CBC:
697
0
            return 8;
698
0
        case CKM_SKIPJACK_CFB32:
699
0
        case CKM_SKIPJACK_CFB16:
700
0
        case CKM_SKIPJACK_CFB8:
701
0
            return 4;
702
0
        case CKM_SEED_ECB:
703
0
        case CKM_SEED_CBC:
704
0
        case CKM_SEED_CBC_PAD:
705
0
        case CKM_CAMELLIA_ECB:
706
0
        case CKM_CAMELLIA_CBC:
707
0
        case CKM_CAMELLIA_CBC_PAD:
708
0
        case CKM_AES_ECB:
709
0
        case CKM_AES_CBC:
710
0
        case CKM_AES_CBC_PAD:
711
0
        case CKM_BATON_ECB128:
712
0
        case CKM_BATON_CBC128:
713
0
        case CKM_BATON_COUNTER:
714
0
        case CKM_BATON_SHUFFLE:
715
0
        case CKM_JUNIPER_ECB128:
716
0
        case CKM_JUNIPER_CBC128:
717
0
        case CKM_JUNIPER_COUNTER:
718
0
        case CKM_JUNIPER_SHUFFLE:
719
0
            return 16;
720
0
        case CKM_BATON_ECB96:
721
0
            return 12;
722
0
        case CKM_RC4:
723
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
724
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
725
0
        case CKM_PBE_SHA1_RC4_40:
726
0
        case CKM_PBE_SHA1_RC4_128:
727
0
            return 0;
728
0
        case CKM_RSA_PKCS:
729
0
        case CKM_RSA_9796:
730
0
        case CKM_RSA_X_509:
731
0
            /*actually it's the modulus length of the key!*/
732
0
            return -1; /* failure */
733
0
        default:
734
0
            return pk11_lookup(type)->blockSize;
735
0
    }
736
0
}
737
738
/*
739
 * get the iv length
740
 */
741
int
742
PK11_GetIVLength(CK_MECHANISM_TYPE type)
743
0
{
744
0
    switch (type) {
745
0
        case CKM_SEED_ECB:
746
0
        case CKM_CAMELLIA_ECB:
747
0
        case CKM_AES_ECB:
748
0
        case CKM_DES_ECB:
749
0
        case CKM_DES3_ECB:
750
0
        case CKM_RC2_ECB:
751
0
        case CKM_IDEA_ECB:
752
0
        case CKM_SKIPJACK_WRAP:
753
0
        case CKM_BATON_WRAP:
754
0
        case CKM_RC5_ECB:
755
0
        case CKM_CAST_ECB:
756
0
        case CKM_CAST3_ECB:
757
0
        case CKM_CAST5_ECB:
758
0
            return 0;
759
0
        case CKM_RC2_CBC:
760
0
        case CKM_DES_CBC:
761
0
        case CKM_DES3_CBC:
762
0
        case CKM_IDEA_CBC:
763
0
        case CKM_PBE_MD2_DES_CBC:
764
0
        case CKM_PBE_MD5_DES_CBC:
765
0
        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
766
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
767
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
768
0
        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
769
0
        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
770
0
        case CKM_PBE_SHA1_RC2_40_CBC:
771
0
        case CKM_PBE_SHA1_RC2_128_CBC:
772
0
        case CKM_PBE_SHA1_DES3_EDE_CBC:
773
0
        case CKM_PBE_SHA1_DES2_EDE_CBC:
774
0
        case CKM_RC5_CBC:
775
0
        case CKM_CAST_CBC:
776
0
        case CKM_CAST3_CBC:
777
0
        case CKM_CAST5_CBC:
778
0
        case CKM_RC2_CBC_PAD:
779
0
        case CKM_DES_CBC_PAD:
780
0
        case CKM_DES3_CBC_PAD:
781
0
        case CKM_IDEA_CBC_PAD:
782
0
        case CKM_RC5_CBC_PAD:
783
0
        case CKM_CAST_CBC_PAD:
784
0
        case CKM_CAST3_CBC_PAD:
785
0
        case CKM_CAST5_CBC_PAD:
786
0
            return 8;
787
0
        case CKM_SEED_CBC:
788
0
        case CKM_SEED_CBC_PAD:
789
0
        case CKM_CAMELLIA_CBC:
790
0
        case CKM_CAMELLIA_CBC_PAD:
791
0
        case CKM_AES_CBC:
792
0
        case CKM_AES_CBC_PAD:
793
0
            return 16;
794
0
        case CKM_SKIPJACK_CBC64:
795
0
        case CKM_SKIPJACK_ECB64:
796
0
        case CKM_SKIPJACK_OFB64:
797
0
        case CKM_SKIPJACK_CFB64:
798
0
        case CKM_SKIPJACK_CFB32:
799
0
        case CKM_SKIPJACK_CFB16:
800
0
        case CKM_SKIPJACK_CFB8:
801
0
        case CKM_BATON_ECB128:
802
0
        case CKM_BATON_ECB96:
803
0
        case CKM_BATON_CBC128:
804
0
        case CKM_BATON_COUNTER:
805
0
        case CKM_BATON_SHUFFLE:
806
0
        case CKM_JUNIPER_ECB128:
807
0
        case CKM_JUNIPER_CBC128:
808
0
        case CKM_JUNIPER_COUNTER:
809
0
        case CKM_JUNIPER_SHUFFLE:
810
0
            return 24;
811
0
        case CKM_RC4:
812
0
        case CKM_RSA_PKCS:
813
0
        case CKM_RSA_9796:
814
0
        case CKM_RSA_X_509:
815
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
816
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
817
0
        case CKM_PBE_SHA1_RC4_40:
818
0
        case CKM_PBE_SHA1_RC4_128:
819
0
            return 0;
820
0
        default:
821
0
            return pk11_lookup(type)->iv;
822
0
    }
823
0
}
824
825
/* These next two utilities are here to help facilitate future
826
 * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions
827
 * like SSL and S-MIME to automatically add them.
828
 */
829
SECItem *
830
pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen)
831
0
{
832
0
    CK_RC2_CBC_PARAMS *rc2_params = NULL;
833
0
    CK_RC2_PARAMS *rc2_ecb_params = NULL;
834
0
    CK_RC5_PARAMS *rc5_params = NULL;
835
0
    CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL;
836
0
    SECItem *param;
837
0
838
0
    param = (SECItem *)PORT_Alloc(sizeof(SECItem));
839
0
    if (param == NULL)
840
0
        return NULL;
841
0
    param->data = NULL;
842
0
    param->len = 0;
843
0
    param->type = 0;
844
0
    switch (type) {
845
0
        case CKM_SEED_ECB:
846
0
        case CKM_CAMELLIA_ECB:
847
0
        case CKM_AES_ECB:
848
0
        case CKM_DES_ECB:
849
0
        case CKM_DES3_ECB:
850
0
        case CKM_RSA_PKCS:
851
0
        case CKM_RSA_X_509:
852
0
        case CKM_RSA_9796:
853
0
        case CKM_IDEA_ECB:
854
0
        case CKM_CDMF_ECB:
855
0
        case CKM_CAST_ECB:
856
0
        case CKM_CAST3_ECB:
857
0
        case CKM_CAST5_ECB:
858
0
        case CKM_RC4:
859
0
            break;
860
0
        case CKM_RC2_ECB:
861
0
            rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
862
0
            if (rc2_ecb_params == NULL)
863
0
                break;
864
0
            /*  Maybe we should pass the key size in too to get this value? */
865
0
            *rc2_ecb_params = keyLen ? keyLen * 8 : 128;
866
0
            param->data = (unsigned char *)rc2_ecb_params;
867
0
            param->len = sizeof(CK_RC2_PARAMS);
868
0
            break;
869
0
        case CKM_RC2_CBC:
870
0
        case CKM_RC2_CBC_PAD:
871
0
            rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
872
0
            if (rc2_params == NULL)
873
0
                break;
874
0
            /* Maybe we should pass the key size in too to get this value? */
875
0
            rc2_params->ulEffectiveBits = keyLen ? keyLen * 8 : 128;
876
0
            if (iv && iv->data)
877
0
                PORT_Memcpy(rc2_params->iv, iv->data, sizeof(rc2_params->iv));
878
0
            param->data = (unsigned char *)rc2_params;
879
0
            param->len = sizeof(CK_RC2_CBC_PARAMS);
880
0
            break;
881
0
        case CKM_RC5_CBC:
882
0
        case CKM_RC5_CBC_PAD:
883
0
            rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
884
0
                PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0));
885
0
            if (rc5_cbc_params == NULL)
886
0
                break;
887
0
            if (iv && iv->data && iv->len) {
888
0
                rc5_cbc_params->pIv = ((CK_BYTE_PTR)rc5_cbc_params) + sizeof(CK_RC5_CBC_PARAMS);
889
0
                PORT_Memcpy(rc5_cbc_params->pIv, iv->data, iv->len);
890
0
                rc5_cbc_params->ulIvLen = iv->len;
891
0
                rc5_cbc_params->ulWordsize = iv->len / 2;
892
0
            } else {
893
0
                rc5_cbc_params->ulWordsize = 4;
894
0
                rc5_cbc_params->pIv = NULL;
895
0
                rc5_cbc_params->ulIvLen = 0;
896
0
            }
897
0
            rc5_cbc_params->ulRounds = 16;
898
0
            param->data = (unsigned char *)rc5_cbc_params;
899
0
            param->len = sizeof(CK_RC5_CBC_PARAMS);
900
0
            break;
901
0
        case CKM_RC5_ECB:
902
0
            rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS));
903
0
            if (rc5_params == NULL)
904
0
                break;
905
0
            if (iv && iv->data && iv->len) {
906
0
                rc5_params->ulWordsize = iv->len / 2;
907
0
            } else {
908
0
                rc5_params->ulWordsize = 4;
909
0
            }
910
0
            rc5_params->ulRounds = 16;
911
0
            param->data = (unsigned char *)rc5_params;
912
0
            param->len = sizeof(CK_RC5_PARAMS);
913
0
            break;
914
0
915
0
        case CKM_SEED_CBC:
916
0
        case CKM_CAMELLIA_CBC:
917
0
        case CKM_AES_CBC:
918
0
        case CKM_DES_CBC:
919
0
        case CKM_DES3_CBC:
920
0
        case CKM_IDEA_CBC:
921
0
        case CKM_CDMF_CBC:
922
0
        case CKM_CAST_CBC:
923
0
        case CKM_CAST3_CBC:
924
0
        case CKM_CAST5_CBC:
925
0
        case CKM_CAMELLIA_CBC_PAD:
926
0
        case CKM_AES_CBC_PAD:
927
0
        case CKM_DES_CBC_PAD:
928
0
        case CKM_DES3_CBC_PAD:
929
0
        case CKM_IDEA_CBC_PAD:
930
0
        case CKM_CDMF_CBC_PAD:
931
0
        case CKM_CAST_CBC_PAD:
932
0
        case CKM_CAST3_CBC_PAD:
933
0
        case CKM_CAST5_CBC_PAD:
934
0
        case CKM_SKIPJACK_CBC64:
935
0
        case CKM_SKIPJACK_ECB64:
936
0
        case CKM_SKIPJACK_OFB64:
937
0
        case CKM_SKIPJACK_CFB64:
938
0
        case CKM_SKIPJACK_CFB32:
939
0
        case CKM_SKIPJACK_CFB16:
940
0
        case CKM_SKIPJACK_CFB8:
941
0
        case CKM_BATON_ECB128:
942
0
        case CKM_BATON_ECB96:
943
0
        case CKM_BATON_CBC128:
944
0
        case CKM_BATON_COUNTER:
945
0
        case CKM_BATON_SHUFFLE:
946
0
        case CKM_JUNIPER_ECB128:
947
0
        case CKM_JUNIPER_CBC128:
948
0
        case CKM_JUNIPER_COUNTER:
949
0
        case CKM_JUNIPER_SHUFFLE:
950
0
            if ((iv == NULL) || (iv->data == NULL))
951
0
                break;
952
0
            param->data = (unsigned char *)PORT_Alloc(iv->len);
953
0
            if (param->data != NULL) {
954
0
                PORT_Memcpy(param->data, iv->data, iv->len);
955
0
                param->len = iv->len;
956
0
            }
957
0
            break;
958
0
        /* unknown mechanism, pass IV in if it's there */
959
0
        default:
960
0
            if (pk11_lookup(type)->iv == 0) {
961
0
                break;
962
0
            }
963
0
            if ((iv == NULL) || (iv->data == NULL)) {
964
0
                break;
965
0
            }
966
0
            param->data = (unsigned char *)PORT_Alloc(iv->len);
967
0
            if (param->data != NULL) {
968
0
                PORT_Memcpy(param->data, iv->data, iv->len);
969
0
                param->len = iv->len;
970
0
            }
971
0
            break;
972
0
    }
973
0
    return param;
974
0
}
975
976
/* These next two utilities are here to help facilitate future
977
 * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions
978
 * like SSL and S-MIME to automatically add them.
979
 */
980
SECItem *
981
PK11_ParamFromIV(CK_MECHANISM_TYPE type, SECItem *iv)
982
0
{
983
0
    return pk11_ParamFromIVWithLen(type, iv, 0);
984
0
}
985
986
unsigned char *
987
PK11_IVFromParam(CK_MECHANISM_TYPE type, SECItem *param, int *len)
988
0
{
989
0
    CK_RC2_CBC_PARAMS *rc2_params;
990
0
    CK_RC5_CBC_PARAMS *rc5_cbc_params;
991
0
992
0
    *len = 0;
993
0
    switch (type) {
994
0
        case CKM_SEED_ECB:
995
0
        case CKM_CAMELLIA_ECB:
996
0
        case CKM_AES_ECB:
997
0
        case CKM_DES_ECB:
998
0
        case CKM_DES3_ECB:
999
0
        case CKM_RSA_PKCS:
1000
0
        case CKM_RSA_X_509:
1001
0
        case CKM_RSA_9796:
1002
0
        case CKM_IDEA_ECB:
1003
0
        case CKM_CDMF_ECB:
1004
0
        case CKM_CAST_ECB:
1005
0
        case CKM_CAST3_ECB:
1006
0
        case CKM_CAST5_ECB:
1007
0
        case CKM_RC4:
1008
0
            return NULL;
1009
0
        case CKM_RC2_ECB:
1010
0
            return NULL;
1011
0
        case CKM_RC2_CBC:
1012
0
        case CKM_RC2_CBC_PAD:
1013
0
            rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
1014
0
            *len = sizeof(rc2_params->iv);
1015
0
            return &rc2_params->iv[0];
1016
0
        case CKM_RC5_CBC:
1017
0
        case CKM_RC5_CBC_PAD:
1018
0
            rc5_cbc_params = (CK_RC5_CBC_PARAMS *)param->data;
1019
0
            *len = rc5_cbc_params->ulIvLen;
1020
0
            return rc5_cbc_params->pIv;
1021
0
        case CKM_SEED_CBC:
1022
0
        case CKM_CAMELLIA_CBC:
1023
0
        case CKM_AES_CBC:
1024
0
        case CKM_DES_CBC:
1025
0
        case CKM_DES3_CBC:
1026
0
        case CKM_IDEA_CBC:
1027
0
        case CKM_CDMF_CBC:
1028
0
        case CKM_CAST_CBC:
1029
0
        case CKM_CAST3_CBC:
1030
0
        case CKM_CAST5_CBC:
1031
0
        case CKM_CAMELLIA_CBC_PAD:
1032
0
        case CKM_AES_CBC_PAD:
1033
0
        case CKM_DES_CBC_PAD:
1034
0
        case CKM_DES3_CBC_PAD:
1035
0
        case CKM_IDEA_CBC_PAD:
1036
0
        case CKM_CDMF_CBC_PAD:
1037
0
        case CKM_CAST_CBC_PAD:
1038
0
        case CKM_CAST3_CBC_PAD:
1039
0
        case CKM_CAST5_CBC_PAD:
1040
0
        case CKM_SKIPJACK_CBC64:
1041
0
        case CKM_SKIPJACK_ECB64:
1042
0
        case CKM_SKIPJACK_OFB64:
1043
0
        case CKM_SKIPJACK_CFB64:
1044
0
        case CKM_SKIPJACK_CFB32:
1045
0
        case CKM_SKIPJACK_CFB16:
1046
0
        case CKM_SKIPJACK_CFB8:
1047
0
        case CKM_BATON_ECB128:
1048
0
        case CKM_BATON_ECB96:
1049
0
        case CKM_BATON_CBC128:
1050
0
        case CKM_BATON_COUNTER:
1051
0
        case CKM_BATON_SHUFFLE:
1052
0
        case CKM_JUNIPER_ECB128:
1053
0
        case CKM_JUNIPER_CBC128:
1054
0
        case CKM_JUNIPER_COUNTER:
1055
0
        case CKM_JUNIPER_SHUFFLE:
1056
0
            break;
1057
0
        /* unknown mechanism, pass IV in if it's there */
1058
0
        default:
1059
0
            break;
1060
0
    }
1061
0
    if (param->data) {
1062
0
        *len = param->len;
1063
0
    }
1064
0
    return param->data;
1065
0
}
1066
1067
typedef struct sec_rc5cbcParameterStr {
1068
    SECItem version;
1069
    SECItem rounds;
1070
    SECItem blockSizeInBits;
1071
    SECItem iv;
1072
} sec_rc5cbcParameter;
1073
1074
static const SEC_ASN1Template sec_rc5ecb_parameter_template[] = {
1075
    { SEC_ASN1_SEQUENCE,
1076
      0, NULL, sizeof(sec_rc5cbcParameter) },
1077
    { SEC_ASN1_INTEGER,
1078
      offsetof(sec_rc5cbcParameter, version) },
1079
    { SEC_ASN1_INTEGER,
1080
      offsetof(sec_rc5cbcParameter, rounds) },
1081
    { SEC_ASN1_INTEGER,
1082
      offsetof(sec_rc5cbcParameter, blockSizeInBits) },
1083
    { 0 }
1084
};
1085
1086
static const SEC_ASN1Template sec_rc5cbc_parameter_template[] = {
1087
    { SEC_ASN1_SEQUENCE,
1088
      0, NULL, sizeof(sec_rc5cbcParameter) },
1089
    { SEC_ASN1_INTEGER,
1090
      offsetof(sec_rc5cbcParameter, version) },
1091
    { SEC_ASN1_INTEGER,
1092
      offsetof(sec_rc5cbcParameter, rounds) },
1093
    { SEC_ASN1_INTEGER,
1094
      offsetof(sec_rc5cbcParameter, blockSizeInBits) },
1095
    { SEC_ASN1_OCTET_STRING,
1096
      offsetof(sec_rc5cbcParameter, iv) },
1097
    { 0 }
1098
};
1099
1100
typedef struct sec_rc2cbcParameterStr {
1101
    SECItem rc2ParameterVersion;
1102
    SECItem iv;
1103
} sec_rc2cbcParameter;
1104
1105
static const SEC_ASN1Template sec_rc2cbc_parameter_template[] = {
1106
    { SEC_ASN1_SEQUENCE,
1107
      0, NULL, sizeof(sec_rc2cbcParameter) },
1108
    { SEC_ASN1_INTEGER,
1109
      offsetof(sec_rc2cbcParameter, rc2ParameterVersion) },
1110
    { SEC_ASN1_OCTET_STRING,
1111
      offsetof(sec_rc2cbcParameter, iv) },
1112
    { 0 }
1113
};
1114
1115
static const SEC_ASN1Template sec_rc2ecb_parameter_template[] = {
1116
    { SEC_ASN1_SEQUENCE,
1117
      0, NULL, sizeof(sec_rc2cbcParameter) },
1118
    { SEC_ASN1_INTEGER,
1119
      offsetof(sec_rc2cbcParameter, rc2ParameterVersion) },
1120
    { 0 }
1121
};
1122
1123
/* S/MIME picked id values to represent differnt keysizes */
1124
/* I do have a formula, but it ain't pretty, and it only works because you
1125
 * can always match three points to a parabola:) */
1126
static unsigned char
1127
rc2_map(SECItem *version)
1128
0
{
1129
0
    long x;
1130
0
1131
0
    x = DER_GetInteger(version);
1132
0
1133
0
    switch (x) {
1134
0
        case 58:
1135
0
            return 128;
1136
0
        case 120:
1137
0
            return 64;
1138
0
        case 160:
1139
0
            return 40;
1140
0
    }
1141
0
    return 128;
1142
0
}
1143
1144
static unsigned long
1145
rc2_unmap(unsigned long x)
1146
0
{
1147
0
    switch (x) {
1148
0
        case 128:
1149
0
            return 58;
1150
0
        case 64:
1151
0
            return 120;
1152
0
        case 40:
1153
0
            return 160;
1154
0
    }
1155
0
    return 58;
1156
0
}
1157
1158
/* Generate a mechaism param from a type, and iv. */
1159
SECItem *
1160
PK11_ParamFromAlgid(SECAlgorithmID *algid)
1161
0
{
1162
0
    CK_RC2_CBC_PARAMS *rc2_cbc_params = NULL;
1163
0
    CK_RC2_PARAMS *rc2_ecb_params = NULL;
1164
0
    CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL;
1165
0
    CK_RC5_PARAMS *rc5_ecb_params = NULL;
1166
0
    PLArenaPool *arena = NULL;
1167
0
    SECItem *mech = NULL;
1168
0
    SECOidTag algtag;
1169
0
    SECStatus rv;
1170
0
    CK_MECHANISM_TYPE type;
1171
0
    /* initialize these to prevent UMRs in the ASN1 decoder. */
1172
0
    SECItem iv = { siBuffer, NULL, 0 };
1173
0
    sec_rc2cbcParameter rc2 = { { siBuffer, NULL, 0 }, { siBuffer, NULL, 0 } };
1174
0
    sec_rc5cbcParameter rc5 = { { siBuffer, NULL, 0 }, { siBuffer, NULL, 0 }, { siBuffer, NULL, 0 }, { siBuffer, NULL, 0 } };
1175
0
1176
0
    algtag = SECOID_GetAlgorithmTag(algid);
1177
0
    type = PK11_AlgtagToMechanism(algtag);
1178
0
1179
0
    mech = PORT_New(SECItem);
1180
0
    if (mech == NULL) {
1181
0
        return NULL;
1182
0
    }
1183
0
    mech->type = siBuffer;
1184
0
    mech->data = NULL;
1185
0
    mech->len = 0;
1186
0
1187
0
    arena = PORT_NewArena(1024);
1188
0
    if (!arena) {
1189
0
        goto loser;
1190
0
    }
1191
0
1192
0
    /* handle the complicated cases */
1193
0
    switch (type) {
1194
0
        case CKM_RC2_ECB:
1195
0
            rv = SEC_ASN1DecodeItem(arena, &rc2, sec_rc2ecb_parameter_template,
1196
0
                                    &(algid->parameters));
1197
0
            if (rv != SECSuccess) {
1198
0
                goto loser;
1199
0
            }
1200
0
            rc2_ecb_params = PORT_New(CK_RC2_PARAMS);
1201
0
            if (rc2_ecb_params == NULL) {
1202
0
                goto loser;
1203
0
            }
1204
0
            *rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion);
1205
0
            mech->data = (unsigned char *)rc2_ecb_params;
1206
0
            mech->len = sizeof *rc2_ecb_params;
1207
0
            break;
1208
0
        case CKM_RC2_CBC:
1209
0
        case CKM_RC2_CBC_PAD:
1210
0
            rv = SEC_ASN1DecodeItem(arena, &rc2, sec_rc2cbc_parameter_template,
1211
0
                                    &(algid->parameters));
1212
0
            if (rv != SECSuccess) {
1213
0
                goto loser;
1214
0
            }
1215
0
            rc2_cbc_params = PORT_New(CK_RC2_CBC_PARAMS);
1216
0
            if (rc2_cbc_params == NULL) {
1217
0
                goto loser;
1218
0
            }
1219
0
            mech->data = (unsigned char *)rc2_cbc_params;
1220
0
            mech->len = sizeof *rc2_cbc_params;
1221
0
            rc2_cbc_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion);
1222
0
            if (rc2.iv.len != sizeof rc2_cbc_params->iv) {
1223
0
                PORT_SetError(SEC_ERROR_INPUT_LEN);
1224
0
                goto loser;
1225
0
            }
1226
0
            PORT_Memcpy(rc2_cbc_params->iv, rc2.iv.data, rc2.iv.len);
1227
0
            break;
1228
0
        case CKM_RC5_ECB:
1229
0
            rv = SEC_ASN1DecodeItem(arena, &rc5, sec_rc5ecb_parameter_template,
1230
0
                                    &(algid->parameters));
1231
0
            if (rv != SECSuccess) {
1232
0
                goto loser;
1233
0
            }
1234
0
            rc5_ecb_params = PORT_New(CK_RC5_PARAMS);
1235
0
            if (rc5_ecb_params == NULL) {
1236
0
                goto loser;
1237
0
            }
1238
0
            rc5_ecb_params->ulRounds = DER_GetInteger(&rc5.rounds);
1239
0
            rc5_ecb_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits) / 8;
1240
0
            mech->data = (unsigned char *)rc5_ecb_params;
1241
0
            mech->len = sizeof *rc5_ecb_params;
1242
0
            break;
1243
0
        case CKM_RC5_CBC:
1244
0
        case CKM_RC5_CBC_PAD:
1245
0
            rv = SEC_ASN1DecodeItem(arena, &rc5, sec_rc5cbc_parameter_template,
1246
0
                                    &(algid->parameters));
1247
0
            if (rv != SECSuccess) {
1248
0
                goto loser;
1249
0
            }
1250
0
            rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
1251
0
                PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len);
1252
0
            if (rc5_cbc_params == NULL) {
1253
0
                goto loser;
1254
0
            }
1255
0
            mech->data = (unsigned char *)rc5_cbc_params;
1256
0
            mech->len = sizeof *rc5_cbc_params;
1257
0
            rc5_cbc_params->ulRounds = DER_GetInteger(&rc5.rounds);
1258
0
            rc5_cbc_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits) / 8;
1259
0
            rc5_cbc_params->pIv = ((CK_BYTE_PTR)rc5_cbc_params) + sizeof(CK_RC5_CBC_PARAMS);
1260
0
            rc5_cbc_params->ulIvLen = rc5.iv.len;
1261
0
            PORT_Memcpy(rc5_cbc_params->pIv, rc5.iv.data, rc5.iv.len);
1262
0
            break;
1263
0
        case CKM_PBE_MD2_DES_CBC:
1264
0
        case CKM_PBE_MD5_DES_CBC:
1265
0
        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
1266
0
        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
1267
0
        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
1268
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
1269
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
1270
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
1271
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
1272
0
        case CKM_PBE_SHA1_DES2_EDE_CBC:
1273
0
        case CKM_PBE_SHA1_DES3_EDE_CBC:
1274
0
        case CKM_PBE_SHA1_RC2_40_CBC:
1275
0
        case CKM_PBE_SHA1_RC2_128_CBC:
1276
0
        case CKM_PBE_SHA1_RC4_40:
1277
0
        case CKM_PBE_SHA1_RC4_128:
1278
0
        case CKM_PKCS5_PBKD2:
1279
0
            rv = pbe_PK11AlgidToParam(algid, mech);
1280
0
            if (rv != SECSuccess) {
1281
0
                goto loser;
1282
0
            }
1283
0
            break;
1284
0
        case CKM_RC4:
1285
0
        case CKM_SEED_ECB:
1286
0
        case CKM_CAMELLIA_ECB:
1287
0
        case CKM_AES_ECB:
1288
0
        case CKM_DES_ECB:
1289
0
        case CKM_DES3_ECB:
1290
0
        case CKM_IDEA_ECB:
1291
0
        case CKM_CDMF_ECB:
1292
0
        case CKM_CAST_ECB:
1293
0
        case CKM_CAST3_ECB:
1294
0
        case CKM_CAST5_ECB:
1295
0
            break;
1296
0
1297
0
        default:
1298
0
            if (pk11_lookup(type)->iv == 0) {
1299
0
                break;
1300
0
            }
1301
0
        /* FALL THROUGH */
1302
0
        case CKM_SEED_CBC:
1303
0
        case CKM_CAMELLIA_CBC:
1304
0
        case CKM_AES_CBC:
1305
0
        case CKM_DES_CBC:
1306
0
        case CKM_DES3_CBC:
1307
0
        case CKM_IDEA_CBC:
1308
0
        case CKM_CDMF_CBC:
1309
0
        case CKM_CAST_CBC:
1310
0
        case CKM_CAST3_CBC:
1311
0
        case CKM_CAST5_CBC:
1312
0
        case CKM_SEED_CBC_PAD:
1313
0
        case CKM_CAMELLIA_CBC_PAD:
1314
0
        case CKM_AES_CBC_PAD:
1315
0
        case CKM_DES_CBC_PAD:
1316
0
        case CKM_DES3_CBC_PAD:
1317
0
        case CKM_IDEA_CBC_PAD:
1318
0
        case CKM_CDMF_CBC_PAD:
1319
0
        case CKM_CAST_CBC_PAD:
1320
0
        case CKM_CAST3_CBC_PAD:
1321
0
        case CKM_CAST5_CBC_PAD:
1322
0
        case CKM_SKIPJACK_CBC64:
1323
0
        case CKM_SKIPJACK_ECB64:
1324
0
        case CKM_SKIPJACK_OFB64:
1325
0
        case CKM_SKIPJACK_CFB64:
1326
0
        case CKM_SKIPJACK_CFB32:
1327
0
        case CKM_SKIPJACK_CFB16:
1328
0
        case CKM_SKIPJACK_CFB8:
1329
0
        case CKM_BATON_ECB128:
1330
0
        case CKM_BATON_ECB96:
1331
0
        case CKM_BATON_CBC128:
1332
0
        case CKM_BATON_COUNTER:
1333
0
        case CKM_BATON_SHUFFLE:
1334
0
        case CKM_JUNIPER_ECB128:
1335
0
        case CKM_JUNIPER_CBC128:
1336
0
        case CKM_JUNIPER_COUNTER:
1337
0
        case CKM_JUNIPER_SHUFFLE:
1338
0
            /* simple cases are simply octet string encoded IVs */
1339
0
            rv = SEC_ASN1DecodeItem(arena, &iv,
1340
0
                                    SEC_ASN1_GET(SEC_OctetStringTemplate),
1341
0
                                    &(algid->parameters));
1342
0
            if (rv != SECSuccess || iv.data == NULL) {
1343
0
                goto loser;
1344
0
            }
1345
0
            /* XXX Should be some IV length sanity check here. */
1346
0
            mech->data = (unsigned char *)PORT_Alloc(iv.len);
1347
0
            if (mech->data == NULL) {
1348
0
                goto loser;
1349
0
            }
1350
0
            PORT_Memcpy(mech->data, iv.data, iv.len);
1351
0
            mech->len = iv.len;
1352
0
            break;
1353
0
    }
1354
0
    PORT_FreeArena(arena, PR_FALSE);
1355
0
    return mech;
1356
0
1357
0
loser:
1358
0
    if (arena)
1359
0
        PORT_FreeArena(arena, PR_FALSE);
1360
0
    SECITEM_FreeItem(mech, PR_TRUE);
1361
0
    return NULL;
1362
0
}
1363
1364
/*
1365
 * Generate an IV for the given mechanism
1366
 */
1367
static SECStatus
1368
pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv)
1369
0
{
1370
0
    int iv_size = PK11_GetIVLength(type);
1371
0
    SECStatus rv;
1372
0
1373
0
    iv->len = iv_size;
1374
0
    if (iv_size == 0) {
1375
0
        iv->data = NULL;
1376
0
        return SECSuccess;
1377
0
    }
1378
0
1379
0
    iv->data = (unsigned char *)PORT_Alloc(iv_size);
1380
0
    if (iv->data == NULL) {
1381
0
        iv->len = 0;
1382
0
        return SECFailure;
1383
0
    }
1384
0
1385
0
    rv = PK11_GenerateRandom(iv->data, iv->len);
1386
0
    if (rv != SECSuccess) {
1387
0
        PORT_Free(iv->data);
1388
0
        iv->data = NULL;
1389
0
        iv->len = 0;
1390
0
        return SECFailure;
1391
0
    }
1392
0
    return SECSuccess;
1393
0
}
1394
1395
/*
1396
 * create a new parameter block from the passed in MECHANISM and the
1397
 * key. Use Netscape's S/MIME Rules for the New param block.
1398
 */
1399
SECItem *
1400
pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen)
1401
0
{
1402
0
    CK_RC2_CBC_PARAMS *rc2_params;
1403
0
    CK_RC2_PARAMS *rc2_ecb_params;
1404
0
    SECItem *mech;
1405
0
    SECItem iv;
1406
0
    SECStatus rv;
1407
0
1408
0
    mech = (SECItem *)PORT_Alloc(sizeof(SECItem));
1409
0
    if (mech == NULL)
1410
0
        return NULL;
1411
0
1412
0
    rv = SECSuccess;
1413
0
    mech->type = siBuffer;
1414
0
    mech->data = NULL;
1415
0
    mech->len = 0;
1416
0
    switch (type) {
1417
0
        case CKM_RC4:
1418
0
        case CKM_SEED_ECB:
1419
0
        case CKM_CAMELLIA_ECB:
1420
0
        case CKM_AES_ECB:
1421
0
        case CKM_DES_ECB:
1422
0
        case CKM_DES3_ECB:
1423
0
        case CKM_IDEA_ECB:
1424
0
        case CKM_CDMF_ECB:
1425
0
        case CKM_CAST_ECB:
1426
0
        case CKM_CAST3_ECB:
1427
0
        case CKM_CAST5_ECB:
1428
0
            break;
1429
0
        case CKM_RC2_ECB:
1430
0
            rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
1431
0
            if (rc2_ecb_params == NULL) {
1432
0
                rv = SECFailure;
1433
0
                break;
1434
0
            }
1435
0
            /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
1436
0
             *   or RC4 key. Of course that wouldn't happen here doing RC2:).*/
1437
0
            *rc2_ecb_params = keyLen ? keyLen * 8 : 128;
1438
0
            mech->data = (unsigned char *)rc2_ecb_params;
1439
0
            mech->len = sizeof(CK_RC2_PARAMS);
1440
0
            break;
1441
0
        case CKM_RC2_CBC:
1442
0
        case CKM_RC2_CBC_PAD:
1443
0
            rv = pk11_GenIV(type, &iv);
1444
0
            if (rv != SECSuccess) {
1445
0
                break;
1446
0
            }
1447
0
            rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
1448
0
            if (rc2_params == NULL) {
1449
0
                PORT_Free(iv.data);
1450
0
                rv = SECFailure;
1451
0
                break;
1452
0
            }
1453
0
            /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
1454
0
             *   or RC4 key. Of course that wouldn't happen here doing RC2:).*/
1455
0
            rc2_params->ulEffectiveBits = keyLen ? keyLen * 8 : 128;
1456
0
            if (iv.data)
1457
0
                PORT_Memcpy(rc2_params->iv, iv.data, sizeof(rc2_params->iv));
1458
0
            mech->data = (unsigned char *)rc2_params;
1459
0
            mech->len = sizeof(CK_RC2_CBC_PARAMS);
1460
0
            PORT_Free(iv.data);
1461
0
            break;
1462
0
        case CKM_RC5_ECB:
1463
0
            PORT_Free(mech);
1464
0
            return PK11_ParamFromIV(type, NULL);
1465
0
        case CKM_RC5_CBC:
1466
0
        case CKM_RC5_CBC_PAD:
1467
0
            rv = pk11_GenIV(type, &iv);
1468
0
            if (rv != SECSuccess) {
1469
0
                break;
1470
0
            }
1471
0
            PORT_Free(mech);
1472
0
            return PK11_ParamFromIV(type, &iv);
1473
0
        default:
1474
0
            if (pk11_lookup(type)->iv == 0) {
1475
0
                break;
1476
0
            }
1477
0
        case CKM_SEED_CBC:
1478
0
        case CKM_CAMELLIA_CBC:
1479
0
        case CKM_AES_CBC:
1480
0
        case CKM_DES_CBC:
1481
0
        case CKM_DES3_CBC:
1482
0
        case CKM_IDEA_CBC:
1483
0
        case CKM_CDMF_CBC:
1484
0
        case CKM_CAST_CBC:
1485
0
        case CKM_CAST3_CBC:
1486
0
        case CKM_CAST5_CBC:
1487
0
        case CKM_DES_CBC_PAD:
1488
0
        case CKM_DES3_CBC_PAD:
1489
0
        case CKM_IDEA_CBC_PAD:
1490
0
        case CKM_CDMF_CBC_PAD:
1491
0
        case CKM_CAST_CBC_PAD:
1492
0
        case CKM_CAST3_CBC_PAD:
1493
0
        case CKM_CAST5_CBC_PAD:
1494
0
        case CKM_SKIPJACK_CBC64:
1495
0
        case CKM_SKIPJACK_ECB64:
1496
0
        case CKM_SKIPJACK_OFB64:
1497
0
        case CKM_SKIPJACK_CFB64:
1498
0
        case CKM_SKIPJACK_CFB32:
1499
0
        case CKM_SKIPJACK_CFB16:
1500
0
        case CKM_SKIPJACK_CFB8:
1501
0
        case CKM_BATON_ECB128:
1502
0
        case CKM_BATON_ECB96:
1503
0
        case CKM_BATON_CBC128:
1504
0
        case CKM_BATON_COUNTER:
1505
0
        case CKM_BATON_SHUFFLE:
1506
0
        case CKM_JUNIPER_ECB128:
1507
0
        case CKM_JUNIPER_CBC128:
1508
0
        case CKM_JUNIPER_COUNTER:
1509
0
        case CKM_JUNIPER_SHUFFLE:
1510
0
            rv = pk11_GenIV(type, &iv);
1511
0
            if (rv != SECSuccess) {
1512
0
                break;
1513
0
            }
1514
0
            mech->data = (unsigned char *)PORT_Alloc(iv.len);
1515
0
            if (mech->data == NULL) {
1516
0
                PORT_Free(iv.data);
1517
0
                rv = SECFailure;
1518
0
                break;
1519
0
            }
1520
0
            PORT_Memcpy(mech->data, iv.data, iv.len);
1521
0
            mech->len = iv.len;
1522
0
            PORT_Free(iv.data);
1523
0
            break;
1524
0
    }
1525
0
    if (rv != SECSuccess) {
1526
0
        SECITEM_FreeItem(mech, PR_TRUE);
1527
0
        return NULL;
1528
0
    }
1529
0
    return mech;
1530
0
}
1531
1532
SECItem *
1533
PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key)
1534
0
{
1535
0
    int keyLen = key ? PK11_GetKeyLength(key) : 0;
1536
0
1537
0
    return pk11_GenerateNewParamWithKeyLen(type, keyLen);
1538
0
}
1539
1540
0
#define RC5_V10 0x10
1541
1542
/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */
1543
SECStatus
1544
PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
1545
                  PLArenaPool *arena, SECAlgorithmID *algid)
1546
0
{
1547
0
    CK_RC2_CBC_PARAMS *rc2_params;
1548
0
    sec_rc2cbcParameter rc2;
1549
0
    CK_RC5_CBC_PARAMS *rc5_params;
1550
0
    sec_rc5cbcParameter rc5;
1551
0
    CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag);
1552
0
    SECItem *newParams = NULL;
1553
0
    SECStatus rv = SECFailure;
1554
0
    unsigned long rc2version;
1555
0
1556
0
    switch (type) {
1557
0
        case CKM_RC4:
1558
0
        case CKM_SEED_ECB:
1559
0
        case CKM_CAMELLIA_ECB:
1560
0
        case CKM_AES_ECB:
1561
0
        case CKM_DES_ECB:
1562
0
        case CKM_DES3_ECB:
1563
0
        case CKM_IDEA_ECB:
1564
0
        case CKM_CDMF_ECB:
1565
0
        case CKM_CAST_ECB:
1566
0
        case CKM_CAST3_ECB:
1567
0
        case CKM_CAST5_ECB:
1568
0
            newParams = NULL;
1569
0
            rv = SECSuccess;
1570
0
            break;
1571
0
        case CKM_RC2_ECB:
1572
0
            break;
1573
0
        case CKM_RC2_CBC:
1574
0
        case CKM_RC2_CBC_PAD:
1575
0
            rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
1576
0
            rc2version = rc2_unmap(rc2_params->ulEffectiveBits);
1577
0
            if (SEC_ASN1EncodeUnsignedInteger(NULL, &(rc2.rc2ParameterVersion),
1578
0
                                              rc2version) == NULL)
1579
0
                break;
1580
0
            rc2.iv.data = rc2_params->iv;
1581
0
            rc2.iv.len = sizeof(rc2_params->iv);
1582
0
            newParams = SEC_ASN1EncodeItem(NULL, NULL, &rc2,
1583
0
                                           sec_rc2cbc_parameter_template);
1584
0
            PORT_Free(rc2.rc2ParameterVersion.data);
1585
0
            if (newParams == NULL)
1586
0
                break;
1587
0
            rv = SECSuccess;
1588
0
            break;
1589
0
1590
0
        case CKM_RC5_ECB: /* well not really... */
1591
0
            break;
1592
0
        case CKM_RC5_CBC:
1593
0
        case CKM_RC5_CBC_PAD:
1594
0
            rc5_params = (CK_RC5_CBC_PARAMS *)param->data;
1595
0
            if (SEC_ASN1EncodeUnsignedInteger(NULL, &rc5.version, RC5_V10) == NULL)
1596
0
                break;
1597
0
            if (SEC_ASN1EncodeUnsignedInteger(NULL, &rc5.blockSizeInBits,
1598
0
                                              rc5_params->ulWordsize * 8) == NULL) {
1599
0
                PORT_Free(rc5.version.data);
1600
0
                break;
1601
0
            }
1602
0
            if (SEC_ASN1EncodeUnsignedInteger(NULL, &rc5.rounds,
1603
0
                                              rc5_params->ulWordsize * 8) == NULL) {
1604
0
                PORT_Free(rc5.blockSizeInBits.data);
1605
0
                PORT_Free(rc5.version.data);
1606
0
                break;
1607
0
            }
1608
0
            rc5.iv.data = rc5_params->pIv;
1609
0
            rc5.iv.len = rc5_params->ulIvLen;
1610
0
            newParams = SEC_ASN1EncodeItem(NULL, NULL, &rc5,
1611
0
                                           sec_rc5cbc_parameter_template);
1612
0
            PORT_Free(rc5.version.data);
1613
0
            PORT_Free(rc5.blockSizeInBits.data);
1614
0
            PORT_Free(rc5.rounds.data);
1615
0
            if (newParams == NULL)
1616
0
                break;
1617
0
            rv = SECSuccess;
1618
0
            break;
1619
0
        case CKM_PBE_MD2_DES_CBC:
1620
0
        case CKM_PBE_MD5_DES_CBC:
1621
0
        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
1622
0
        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
1623
0
        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
1624
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
1625
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
1626
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
1627
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
1628
0
        case CKM_PBE_SHA1_DES3_EDE_CBC:
1629
0
        case CKM_PBE_SHA1_DES2_EDE_CBC:
1630
0
        case CKM_PBE_SHA1_RC2_40_CBC:
1631
0
        case CKM_PBE_SHA1_RC2_128_CBC:
1632
0
        case CKM_PBE_SHA1_RC4_40:
1633
0
        case CKM_PBE_SHA1_RC4_128:
1634
0
            return PBE_PK11ParamToAlgid(algTag, param, arena, algid);
1635
0
        default:
1636
0
            if (pk11_lookup(type)->iv == 0) {
1637
0
                rv = SECSuccess;
1638
0
                newParams = NULL;
1639
0
                break;
1640
0
            }
1641
0
        case CKM_SEED_CBC:
1642
0
        case CKM_CAMELLIA_CBC:
1643
0
        case CKM_AES_CBC:
1644
0
        case CKM_DES_CBC:
1645
0
        case CKM_DES3_CBC:
1646
0
        case CKM_IDEA_CBC:
1647
0
        case CKM_CDMF_CBC:
1648
0
        case CKM_CAST_CBC:
1649
0
        case CKM_CAST3_CBC:
1650
0
        case CKM_CAST5_CBC:
1651
0
        case CKM_DES_CBC_PAD:
1652
0
        case CKM_DES3_CBC_PAD:
1653
0
        case CKM_IDEA_CBC_PAD:
1654
0
        case CKM_CDMF_CBC_PAD:
1655
0
        case CKM_CAST_CBC_PAD:
1656
0
        case CKM_CAST3_CBC_PAD:
1657
0
        case CKM_CAST5_CBC_PAD:
1658
0
        case CKM_SKIPJACK_CBC64:
1659
0
        case CKM_SKIPJACK_ECB64:
1660
0
        case CKM_SKIPJACK_OFB64:
1661
0
        case CKM_SKIPJACK_CFB64:
1662
0
        case CKM_SKIPJACK_CFB32:
1663
0
        case CKM_SKIPJACK_CFB16:
1664
0
        case CKM_SKIPJACK_CFB8:
1665
0
        case CKM_BATON_ECB128:
1666
0
        case CKM_BATON_ECB96:
1667
0
        case CKM_BATON_CBC128:
1668
0
        case CKM_BATON_COUNTER:
1669
0
        case CKM_BATON_SHUFFLE:
1670
0
        case CKM_JUNIPER_ECB128:
1671
0
        case CKM_JUNIPER_CBC128:
1672
0
        case CKM_JUNIPER_COUNTER:
1673
0
        case CKM_JUNIPER_SHUFFLE:
1674
0
            newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
1675
0
                                           SEC_ASN1_GET(SEC_OctetStringTemplate));
1676
0
            if (newParams == NULL)
1677
0
                break;
1678
0
            rv = SECSuccess;
1679
0
            break;
1680
0
    }
1681
0
1682
0
    if (rv != SECSuccess) {
1683
0
        if (newParams)
1684
0
            SECITEM_FreeItem(newParams, PR_TRUE);
1685
0
        return rv;
1686
0
    }
1687
0
1688
0
    rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams);
1689
0
    SECITEM_FreeItem(newParams, PR_TRUE);
1690
0
    return rv;
1691
0
}
1692
1693
/* turn an OID algorithm tag into a PKCS #11 mechanism. This allows us to
1694
 * map OID's directly into the PKCS #11 mechanism we want to call. We find
1695
 * this mapping in our standard OID table */
1696
CK_MECHANISM_TYPE
1697
PK11_AlgtagToMechanism(SECOidTag algTag)
1698
0
{
1699
0
    SECOidData *oid = SECOID_FindOIDByTag(algTag);
1700
0
1701
0
    if (oid)
1702
0
        return (CK_MECHANISM_TYPE)oid->mechanism;
1703
0
    return CKM_INVALID_MECHANISM;
1704
0
}
1705
1706
/* turn a mechanism into an oid. */
1707
SECOidTag
1708
PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type)
1709
0
{
1710
0
    SECOidData *oid = SECOID_FindOIDByMechanism((unsigned long)type);
1711
0
1712
0
    if (oid)
1713
0
        return oid->offset;
1714
0
    return SEC_OID_UNKNOWN;
1715
0
}
1716
1717
/* Determine appropriate blocking mechanism, used when wrapping private keys
1718
 * which require PKCS padding.  If the mechanism does not map to a padding
1719
 * mechanism, we simply return the mechanism.
1720
 */
1721
CK_MECHANISM_TYPE
1722
PK11_GetPadMechanism(CK_MECHANISM_TYPE type)
1723
0
{
1724
0
    switch (type) {
1725
0
        case CKM_SEED_CBC:
1726
0
            return CKM_SEED_CBC_PAD;
1727
0
        case CKM_CAMELLIA_CBC:
1728
0
            return CKM_CAMELLIA_CBC_PAD;
1729
0
        case CKM_AES_CBC:
1730
0
            return CKM_AES_CBC_PAD;
1731
0
        case CKM_DES_CBC:
1732
0
            return CKM_DES_CBC_PAD;
1733
0
        case CKM_DES3_CBC:
1734
0
            return CKM_DES3_CBC_PAD;
1735
0
        case CKM_RC2_CBC:
1736
0
            return CKM_RC2_CBC_PAD;
1737
0
        case CKM_CDMF_CBC:
1738
0
            return CKM_CDMF_CBC_PAD;
1739
0
        case CKM_CAST_CBC:
1740
0
            return CKM_CAST_CBC_PAD;
1741
0
        case CKM_CAST3_CBC:
1742
0
            return CKM_CAST3_CBC_PAD;
1743
0
        case CKM_CAST5_CBC:
1744
0
            return CKM_CAST5_CBC_PAD;
1745
0
        case CKM_RC5_CBC:
1746
0
            return CKM_RC5_CBC_PAD;
1747
0
        case CKM_IDEA_CBC:
1748
0
            return CKM_IDEA_CBC_PAD;
1749
0
        default:
1750
0
            break;
1751
0
    }
1752
0
1753
0
    return type;
1754
0
}
1755
1756
static PRBool
1757
pk11_isAllZero(unsigned char *data, int len)
1758
0
{
1759
0
    while (len--) {
1760
0
        if (*data++) {
1761
0
            return PR_FALSE;
1762
0
        }
1763
0
    }
1764
0
    return PR_TRUE;
1765
0
}
1766
1767
CK_RV
1768
PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
1769
                                      CK_MECHANISM_PTR pCryptoMechanism,
1770
                                      SECItem *pbe_pwd, PRBool faulty3DES)
1771
0
{
1772
0
    int iv_len = 0;
1773
0
    CK_PBE_PARAMS_PTR pPBEparams;
1774
0
    CK_RC2_CBC_PARAMS_PTR rc2_params;
1775
0
    CK_ULONG rc2_key_len;
1776
0
1777
0
    if ((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) {
1778
0
        return CKR_HOST_MEMORY;
1779
0
    }
1780
0
1781
0
    /* pkcs5 v2 cannot be supported by this interface.
1782
0
     * use PK11_GetPBECryptoMechanism instead.
1783
0
     */
1784
0
    if ((pPBEMechanism->mechanism == CKM_INVALID_MECHANISM) ||
1785
0
        (pPBEMechanism->mechanism == CKM_PKCS5_PBKD2)) {
1786
0
        return CKR_MECHANISM_INVALID;
1787
0
    }
1788
0
1789
0
    pPBEparams = (CK_PBE_PARAMS_PTR)pPBEMechanism->pParameter;
1790
0
    iv_len = PK11_GetIVLength(pPBEMechanism->mechanism);
1791
0
1792
0
    if (iv_len) {
1793
0
        if (pk11_isAllZero(pPBEparams->pInitVector, iv_len)) {
1794
0
            SECItem param;
1795
0
            PK11SymKey *symKey;
1796
0
            PK11SlotInfo *intSlot = PK11_GetInternalSlot();
1797
0
1798
0
            if (intSlot == NULL) {
1799
0
                return CKR_DEVICE_ERROR;
1800
0
            }
1801
0
1802
0
            param.data = pPBEMechanism->pParameter;
1803
0
            param.len = pPBEMechanism->ulParameterLen;
1804
0
1805
0
            symKey = PK11_RawPBEKeyGen(intSlot,
1806
0
                                       pPBEMechanism->mechanism, &param, pbe_pwd, faulty3DES, NULL);
1807
0
            PK11_FreeSlot(intSlot);
1808
0
            if (symKey == NULL) {
1809
0
                return CKR_DEVICE_ERROR; /* sigh */
1810
0
            }
1811
0
            PK11_FreeSymKey(symKey);
1812
0
        }
1813
0
    }
1814
0
1815
0
    switch (pPBEMechanism->mechanism) {
1816
0
        case CKM_PBE_MD2_DES_CBC:
1817
0
        case CKM_PBE_MD5_DES_CBC:
1818
0
        case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
1819
0
            pCryptoMechanism->mechanism = CKM_DES_CBC;
1820
0
            goto have_crypto_mechanism;
1821
0
        case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
1822
0
        case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
1823
0
        case CKM_PBE_SHA1_DES3_EDE_CBC:
1824
0
        case CKM_PBE_SHA1_DES2_EDE_CBC:
1825
0
            pCryptoMechanism->mechanism = CKM_DES3_CBC;
1826
0
        have_crypto_mechanism:
1827
0
            pCryptoMechanism->pParameter = PORT_Alloc(iv_len);
1828
0
            pCryptoMechanism->ulParameterLen = (CK_ULONG)iv_len;
1829
0
            if (pCryptoMechanism->pParameter == NULL) {
1830
0
                return CKR_HOST_MEMORY;
1831
0
            }
1832
0
            PORT_Memcpy((unsigned char *)(pCryptoMechanism->pParameter),
1833
0
                        (unsigned char *)(pPBEparams->pInitVector),
1834
0
                        iv_len);
1835
0
            break;
1836
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
1837
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
1838
0
        case CKM_PBE_SHA1_RC4_40:
1839
0
        case CKM_PBE_SHA1_RC4_128:
1840
0
            pCryptoMechanism->mechanism = CKM_RC4;
1841
0
            pCryptoMechanism->ulParameterLen = 0;
1842
0
            pCryptoMechanism->pParameter = CK_NULL_PTR;
1843
0
            break;
1844
0
        case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
1845
0
        case CKM_PBE_SHA1_RC2_40_CBC:
1846
0
            rc2_key_len = 40;
1847
0
            goto have_key_len;
1848
0
        case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
1849
0
            rc2_key_len = 128;
1850
0
        have_key_len:
1851
0
            pCryptoMechanism->mechanism = CKM_RC2_CBC;
1852
0
            pCryptoMechanism->ulParameterLen = (CK_ULONG)sizeof(CK_RC2_CBC_PARAMS);
1853
0
            pCryptoMechanism->pParameter = (CK_RC2_CBC_PARAMS_PTR)
1854
0
                PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS));
1855
0
            if (pCryptoMechanism->pParameter == NULL) {
1856
0
                return CKR_HOST_MEMORY;
1857
0
            }
1858
0
            rc2_params = (CK_RC2_CBC_PARAMS_PTR)pCryptoMechanism->pParameter;
1859
0
            PORT_Memcpy((unsigned char *)rc2_params->iv,
1860
0
                        (unsigned char *)pPBEparams->pInitVector,
1861
0
                        iv_len);
1862
0
            rc2_params->ulEffectiveBits = rc2_key_len;
1863
0
            break;
1864
0
        default:
1865
0
            return CKR_MECHANISM_INVALID;
1866
0
    }
1867
0
1868
0
    return CKR_OK;
1869
0
}
1870
1871
/* Make a Key type to an appropriate signing/verification mechanism */
1872
CK_MECHANISM_TYPE
1873
PK11_MapSignKeyType(KeyType keyType)
1874
0
{
1875
0
    switch (keyType) {
1876
0
        case rsaKey:
1877
0
            return CKM_RSA_PKCS;
1878
0
        case fortezzaKey:
1879
0
        case dsaKey:
1880
0
            return CKM_DSA;
1881
0
        case ecKey:
1882
0
            return CKM_ECDSA;
1883
0
        case dhKey:
1884
0
        default:
1885
0
            break;
1886
0
    }
1887
0
    return CKM_INVALID_MECHANISM;
1888
0
}
1889
1890
CK_MECHANISM_TYPE
1891
pk11_mapWrapKeyType(KeyType keyType)
1892
0
{
1893
0
    switch (keyType) {
1894
0
        case rsaKey:
1895
0
            return CKM_RSA_PKCS;
1896
0
        /* Add fortezza?? */
1897
0
        default:
1898
0
            break;
1899
0
    }
1900
0
    return CKM_INVALID_MECHANISM;
1901
0
}
1902
1903
SECOidTag
1904
PK11_FortezzaMapSig(SECOidTag algTag)
1905
0
{
1906
0
    switch (algTag) {
1907
0
        case SEC_OID_MISSI_KEA_DSS:
1908
0
        case SEC_OID_MISSI_DSS:
1909
0
        case SEC_OID_MISSI_DSS_OLD:
1910
0
        case SEC_OID_MISSI_KEA_DSS_OLD:
1911
0
        case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
1912
0
            return SEC_OID_ANSIX9_DSA_SIGNATURE;
1913
0
        default:
1914
0
            break;
1915
0
    }
1916
0
    return algTag;
1917
0
}