Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / lib / pk11wrap / pk11pbe.c
blob07ac7dff499a9f9a52321e7b4c7271262018c503
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #include "plarena.h"
39 #include "seccomon.h"
40 #include "secitem.h"
41 #include "secport.h"
42 #include "hasht.h"
43 #include "pkcs11t.h"
44 #include "sechash.h"
45 #include "secasn1.h"
46 #include "secder.h"
47 #include "secoid.h"
48 #include "secerr.h"
49 #include "secmod.h"
50 #include "pk11func.h"
51 #include "secpkcs5.h"
52 #include "secmodi.h"
53 #include "secmodti.h"
54 #include "pkcs11.h"
55 #include "pk11func.h"
56 #include "secitem.h"
57 #include "key.h"
59 typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
60 struct SEC_PKCS5PBEParameterStr {
61 PRArenaPool *poolp;
62 SECItem salt; /* octet string */
63 SECItem iteration; /* integer */
67 /* template for PKCS 5 PBE Parameter. This template has been expanded
68 * based upon the additions in PKCS 12. This should eventually be moved
69 * if RSA updates PKCS 5.
71 const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
73 { SEC_ASN1_SEQUENCE,
74 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
75 { SEC_ASN1_OCTET_STRING,
76 offsetof(SEC_PKCS5PBEParameter, salt) },
77 { SEC_ASN1_INTEGER,
78 offsetof(SEC_PKCS5PBEParameter, iteration) },
79 { 0 }
82 const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
84 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
85 { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
86 { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
87 { 0 }
90 /* maps crypto algorithm from PBE algorithm.
92 SECOidTag
93 SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
96 SECOidTag algorithm;
98 if(algid == NULL)
99 return SEC_OID_UNKNOWN;
101 algorithm = SECOID_GetAlgorithmTag(algid);
102 switch(algorithm)
104 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
105 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
106 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
107 return SEC_OID_DES_EDE3_CBC;
108 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
109 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
110 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
111 return SEC_OID_DES_CBC;
112 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
113 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
114 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
115 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
116 return SEC_OID_RC2_CBC;
117 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
118 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
119 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
120 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
121 return SEC_OID_RC4;
122 default:
123 break;
126 return SEC_OID_UNKNOWN;
129 /* check to see if an oid is a pbe algorithm
131 PRBool
132 SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
134 return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN);
137 /* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
139 SECOidTag
140 SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
142 switch(algTag)
144 case SEC_OID_DES_EDE3_CBC:
145 switch(keyLen) {
146 case 168:
147 case 192:
148 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
149 case 128:
150 case 92:
151 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
152 default:
153 break;
155 break;
156 case SEC_OID_DES_CBC:
157 return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
158 case SEC_OID_RC2_CBC:
159 switch(keyLen) {
160 case 40:
161 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
162 case 128:
163 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
164 default:
165 break;
167 break;
168 case SEC_OID_RC4:
169 switch(keyLen) {
170 case 40:
171 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
172 case 128:
173 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
174 default:
175 break;
177 break;
178 default:
179 break;
182 return SEC_OID_UNKNOWN;
186 /* get the key length needed for the PBE algorithm
189 int
190 SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
193 SECOidTag algorithm;
195 if(algid == NULL)
196 return SEC_OID_UNKNOWN;
198 algorithm = SECOID_GetAlgorithmTag(algid);
200 switch(algorithm)
202 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
203 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
204 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
205 return 24;
206 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
207 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
208 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
209 return 8;
210 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
211 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
212 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
213 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
214 return 5;
215 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
216 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
217 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
218 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
219 return 16;
220 default:
221 break;
223 return -1;
227 /* the V2 algorithms only encode the salt, there is no iteration
228 * count so we need a check for V2 algorithm parameters.
230 static PRBool
231 sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
233 switch(algorithm)
235 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
236 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
237 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
238 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
239 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
240 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
241 return PR_TRUE;
242 default:
243 break;
246 return PR_FALSE;
248 /* destroy a pbe parameter. it assumes that the parameter was
249 * generated using the appropriate create function and therefor
250 * contains an arena pool.
252 static void
253 sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
255 if(pbe_param != NULL)
256 PORT_FreeArena(pbe_param->poolp, PR_TRUE);
259 /* creates a PBE parameter based on the PBE algorithm. the only required
260 * parameters are algorithm and interation. the return is a PBE parameter
261 * which conforms to PKCS 5 parameter unless an extended parameter is needed.
262 * this is primarily if keyLen and a variable key length algorithm are
263 * specified.
264 * salt - if null, a salt will be generated from random bytes.
265 * iteration - number of iterations to perform hashing.
266 * keyLen - only used in variable key length algorithms
267 * iv - if null, the IV will be generated based on PKCS 5 when needed.
268 * params - optional, currently unsupported additional parameters.
269 * once a parameter is allocated, it should be destroyed calling
270 * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
272 #define DEFAULT_SALT_LENGTH 16
273 static SEC_PKCS5PBEParameter *
274 sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
275 SECItem *salt,
276 int iteration)
278 PRArenaPool *poolp = NULL;
279 SEC_PKCS5PBEParameter *pbe_param = NULL;
280 SECStatus rv= SECSuccess;
281 void *dummy = NULL;
283 if(iteration < 0) {
284 return NULL;
287 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
288 if(poolp == NULL)
289 return NULL;
291 pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
292 sizeof(SEC_PKCS5PBEParameter));
293 if(!pbe_param) {
294 PORT_FreeArena(poolp, PR_TRUE);
295 return NULL;
298 pbe_param->poolp = poolp;
300 rv = SECFailure;
301 if (salt && salt->data) {
302 rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt);
303 } else {
304 /* sigh, the old interface generated salt on the fly, so we have to
305 * preserve the semantics */
306 pbe_param->salt.len = DEFAULT_SALT_LENGTH;
307 pbe_param->salt.data = PORT_ArenaZAlloc(poolp,DEFAULT_SALT_LENGTH);
308 if (pbe_param->salt.data) {
309 rv = PK11_GenerateRandom(pbe_param->salt.data,DEFAULT_SALT_LENGTH);
313 if(rv != SECSuccess) {
314 PORT_FreeArena(poolp, PR_TRUE);
315 return NULL;
318 /* encode the integer */
319 dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
320 iteration);
321 rv = (dummy) ? SECSuccess : SECFailure;
323 if(rv != SECSuccess) {
324 PORT_FreeArena(poolp, PR_FALSE);
325 return NULL;
328 return pbe_param;
331 /* creates a algorithm ID containing the PBE algorithm and appropriate
332 * parameters. the required parameter is the algorithm. if salt is
333 * not specified, it is generated randomly. if IV is specified, it overrides
334 * the PKCS 5 generation of the IV.
336 * the returned SECAlgorithmID should be destroyed using
337 * SECOID_DestroyAlgorithmID
339 SECAlgorithmID *
340 SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
341 SECItem *salt,
342 int iteration)
344 PRArenaPool *poolp = NULL;
345 SECAlgorithmID *algid, *ret_algid;
346 SECItem der_param;
347 SECStatus rv = SECFailure;
348 SEC_PKCS5PBEParameter *pbe_param;
350 if(iteration <= 0) {
351 return NULL;
354 der_param.data = NULL;
355 der_param.len = 0;
357 /* generate the parameter */
358 pbe_param = sec_pkcs5_create_pbe_parameter(algorithm, salt, iteration);
359 if(!pbe_param) {
360 return NULL;
363 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
364 if(!poolp) {
365 sec_pkcs5_destroy_pbe_param(pbe_param);
366 return NULL;
369 /* generate the algorithm id */
370 algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
371 if(algid != NULL) {
372 void *dummy;
373 if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
374 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
375 SEC_PKCS5PBEParameterTemplate);
376 } else {
377 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
378 SEC_V2PKCS12PBEParameterTemplate);
381 if(dummy) {
382 rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
386 ret_algid = NULL;
387 if(algid != NULL) {
388 ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
389 if(ret_algid != NULL) {
390 rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
391 if(rv != SECSuccess) {
392 SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
393 ret_algid = NULL;
398 if(poolp != NULL) {
399 PORT_FreeArena(poolp, PR_TRUE);
400 algid = NULL;
403 sec_pkcs5_destroy_pbe_param(pbe_param);
405 return ret_algid;
408 SECStatus
409 pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech)
411 CK_PBE_PARAMS *pbe_params = NULL;
412 SEC_PKCS5PBEParameter p5_param;
413 SECItem *salt = NULL;
414 SECOidTag algorithm = SECOID_GetAlgorithmTag(algid);
415 PRArenaPool *arena = NULL;
416 SECStatus rv = SECFailure;
417 int iv_len;
420 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
421 if (arena == NULL) {
422 goto loser;
424 iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm));
425 if (iv_len < 0) {
426 goto loser;
429 if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
430 rv = SEC_ASN1DecodeItem(arena, &p5_param,
431 SEC_V2PKCS12PBEParameterTemplate, &algid->parameters);
432 } else {
433 rv = SEC_ASN1DecodeItem(arena,&p5_param,SEC_PKCS5PBEParameterTemplate,
434 &algid->parameters);
437 if (rv != SECSuccess) {
438 goto loser;
441 salt = &p5_param.salt;
443 pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)+
444 salt->len+iv_len);
445 if (pbe_params == NULL) {
446 goto loser;
449 /* get salt */
450 pbe_params->pSalt = ((CK_CHAR_PTR) pbe_params)+sizeof(CK_PBE_PARAMS);
451 if (iv_len) {
452 pbe_params->pInitVector = ((CK_CHAR_PTR) pbe_params)+
453 sizeof(CK_PBE_PARAMS)+salt->len;
455 PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
456 pbe_params->ulSaltLen = (CK_ULONG) salt->len;
458 /* get iteration count */
459 pbe_params->ulIteration = (CK_ULONG) DER_GetInteger(&p5_param.iteration);
461 /* copy into the mechanism sec item */
462 mech->data = (unsigned char *)pbe_params;
463 mech->len = sizeof(*pbe_params);
464 if (arena) {
465 PORT_FreeArena(arena,PR_TRUE);
467 return SECSuccess;
469 loser:
470 if (pbe_params) {
471 PORT_Free(pbe_params);
473 if (arena) {
474 PORT_FreeArena(arena,PR_TRUE);
476 return SECFailure;
479 SECStatus
480 PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena,
481 SECAlgorithmID *algId)
483 CK_PBE_PARAMS *pbe_param;
484 SECItem pbeSalt;
485 SECAlgorithmID *pbeAlgID = NULL;
486 SECStatus rv;
488 if(!param || !algId) {
489 return SECFailure;
492 pbe_param = (CK_PBE_PARAMS *)param->data;
493 pbeSalt.data = (unsigned char *)pbe_param->pSalt;
494 pbeSalt.len = pbe_param->ulSaltLen;
495 pbeAlgID = SEC_PKCS5CreateAlgorithmID(algTag, &pbeSalt,
496 (int)pbe_param->ulIteration);
497 if(!pbeAlgID) {
498 return SECFailure;
501 rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID);
502 SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE);
503 return rv;
506 PBEBitGenContext *
507 PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
508 SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
509 unsigned int iterations)
511 SECItem *context = NULL;
512 SECItem mechItem;
513 CK_PBE_PARAMS pbe_params;
514 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
515 PK11SlotInfo *slot;
516 PK11SymKey *symKey = NULL;
517 unsigned char ivData[8];
520 /* use the purpose to select the low level keygen algorithm */
521 switch (bitGenPurpose) {
522 case pbeBitGenIntegrityKey:
523 switch (hashAlgorithm) {
524 case SEC_OID_SHA1:
525 mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC;
526 break;
527 case SEC_OID_MD2:
528 mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
529 break;
530 case SEC_OID_MD5:
531 mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
532 break;
533 default:
534 break;
536 break;
537 case pbeBitGenCipherIV:
538 if (bitsNeeded > 64) {
539 break;
541 if (hashAlgorithm != SEC_OID_SHA1) {
542 break;
544 mechanism = CKM_PBE_SHA1_DES3_EDE_CBC;
545 break;
546 case pbeBitGenCipherKey:
547 if (hashAlgorithm != SEC_OID_SHA1) {
548 break;
550 switch (bitsNeeded) {
551 case 40:
552 mechanism = CKM_PBE_SHA1_RC4_40;
553 break;
554 case 128:
555 mechanism = CKM_PBE_SHA1_RC4_128;
556 break;
557 default:
558 break;
560 case pbeBitGenIDNull:
561 break;
564 if (mechanism == CKM_INVALID_MECHANISM) {
565 /* we should set an error, but this is a depricated function, and
566 * we are keeping bug for bug compatibility;)... */
567 return NULL;
570 pbe_params.pInitVector = ivData;
571 pbe_params.pPassword = pwitem->data;
572 pbe_params.ulPasswordLen = pwitem->len;
573 pbe_params.pSalt = salt->data;
574 pbe_params.ulSaltLen = salt->len;
575 pbe_params.ulIteration = iterations;
576 mechItem.data = (unsigned char *) &pbe_params;
577 mechItem.len = sizeof(pbe_params);
580 slot = PK11_GetInternalSlot();
581 symKey = PK11_RawPBEKeyGen(slot,mechanism,
582 &mechItem, pwitem, PR_FALSE, NULL);
583 PK11_FreeSlot(slot);
584 if (symKey != NULL) {
585 if (bitGenPurpose == pbeBitGenCipherIV) {
586 /* NOTE: this assumes that bitsNeeded is a multiple of 8! */
587 SECItem ivItem;
589 ivItem.data = ivData;
590 ivItem.len = bitsNeeded/8;
591 context = SECITEM_DupItem(&ivItem);
592 } else {
593 SECItem *keyData;
594 PK11_ExtractKeyValue(symKey);
595 keyData = PK11_GetKeyData(symKey);
597 /* assert bitsNeeded with length? */
598 if (keyData) {
599 context = SECITEM_DupItem(keyData);
602 PK11_FreeSymKey(symKey);
605 return (PBEBitGenContext *)context;
608 SECItem *
609 PBE_GenerateBits(PBEBitGenContext *context)
611 return (SECItem *)context;
614 void
615 PBE_DestroyContext(PBEBitGenContext *context)
617 SECITEM_FreeItem((SECItem *)context,PR_TRUE);
620 SECItem *
621 SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
623 SECItem mechItem;
624 SECOidTag algorithm = SECOID_GetAlgorithmTag(algid);
625 CK_PBE_PARAMS *pbe_params;
626 CK_MECHANISM_TYPE mechanism;
627 SECItem *iv = NULL;
628 SECStatus rv;
629 int iv_len;
630 PK11SlotInfo *slot;
631 PK11SymKey *symKey;
633 rv = pbe_PK11AlgidToParam(algid,&mechItem);
634 if (rv != SECSuccess) {
635 return NULL;
638 mechanism = PK11_AlgtagToMechanism(algorithm);
639 iv_len = PK11_GetIVLength(mechanism);
640 pbe_params = (CK_PBE_PARAMS_PTR)mechItem.data;
642 slot = PK11_GetInternalSlot();
643 symKey = PK11_RawPBEKeyGen(slot,mechanism,
644 &mechItem, pwitem, faulty3DES,NULL);
645 PK11_FreeSlot(slot);
647 if (symKey) {
648 SECItem tmp;
650 tmp.data = pbe_params->pInitVector;
651 tmp.len = iv_len;
652 iv = SECITEM_DupItem(&tmp);
653 PK11_FreeSymKey(symKey);
656 if (mechItem.data) {
657 PORT_ZFree(mechItem.data,mechItem.len);
660 return iv;
664 * Subs from nss 3.x that are depricated
666 PBEBitGenContext *
667 __PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
668 SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
669 unsigned int iterations)
671 PORT_Assert("__PBE_CreateContext is Depricated" == NULL);
672 return NULL;
675 SECItem *
676 __PBE_GenerateBits(PBEBitGenContext *context)
678 PORT_Assert("__PBE_GenerateBits is Depricated" == NULL);
679 return NULL;
682 void
683 __PBE_DestroyContext(PBEBitGenContext *context)
685 PORT_Assert("__PBE_DestroyContext is Depricated" == NULL);
688 SECStatus
689 RSA_FormatBlock(SECItem *result, unsigned modulusLen,
690 int blockType, SECItem *data)
692 PORT_Assert("RSA_FormatBlock is Depricated" == NULL);
693 return SECFailure;
696 /****************************************************************************
698 * Now Do The PBE Functions Here...
700 ****************************************************************************/
702 static void
703 pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params)
705 if (pbe_params) {
706 if (pbe_params->pPassword)
707 PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen);
708 if (pbe_params->pSalt)
709 PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen);
710 PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS));
714 SECItem *
715 PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
717 CK_PBE_PARAMS *pbe_params = NULL;
718 SECItem *paramRV = NULL;
720 paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS));
721 if (!paramRV ) {
722 goto loser;
724 /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */
725 PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS));
727 pbe_params = (CK_PBE_PARAMS *)paramRV->data;
728 pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len);
729 if (!pbe_params->pPassword) {
730 goto loser;
732 PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
733 pbe_params->ulPasswordLen = pwd->len;
735 pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
736 if (!pbe_params->pSalt) {
737 goto loser;
739 PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
740 pbe_params->ulSaltLen = salt->len;
742 pbe_params->ulIteration = (CK_ULONG)iterations;
743 return paramRV;
745 loser:
746 if (pbe_params)
747 pk11_destroy_ck_pbe_params(pbe_params);
748 if (paramRV)
749 PORT_ZFree(paramRV, sizeof(SECItem));
750 return NULL;
753 void
754 PK11_DestroyPBEParams(SECItem *pItem)
756 if (pItem) {
757 CK_PBE_PARAMS * params = (CK_PBE_PARAMS *)(pItem->data);
758 if (params)
759 pk11_destroy_ck_pbe_params(params);
760 PORT_ZFree(pItem, sizeof(SECItem));
764 SECAlgorithmID *
765 PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
767 SECAlgorithmID *algid = NULL;
768 algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, iteration);
769 return algid;
772 PK11SymKey *
773 PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech,
774 SECItem *pwitem, PRBool faulty3DES, void *wincx)
776 /* pbe stuff */
777 CK_PBE_PARAMS *pbe_params;
778 PK11SymKey *symKey;
780 if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
781 type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
783 if(mech == NULL) {
784 return NULL;
787 pbe_params = (CK_PBE_PARAMS *)mech->data;
788 if (!pbe_params) {
789 return NULL;
791 pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwitem->len);
792 if(pbe_params->pPassword != NULL) {
793 PORT_Memcpy(pbe_params->pPassword, pwitem->data, pwitem->len);
794 pbe_params->ulPasswordLen = pwitem->len;
795 } else {
796 SECITEM_ZfreeItem(mech, PR_TRUE);
797 return NULL;
800 symKey = PK11_TokenKeyGenWithFlags(slot, type, mech, 0, NULL,
801 CKF_SIGN|CKF_ENCRYPT|CKF_DECRYPT|CKF_UNWRAP|CKF_WRAP, 0, wincx);
803 PORT_ZFree(pbe_params->pPassword, pwitem->len);
804 pbe_params->pPassword = NULL;
805 pbe_params->ulPasswordLen = 0;
806 return symKey;
809 PK11SymKey *
810 PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
811 PRBool faulty3DES, void *wincx)
813 /* pbe stuff */
814 CK_MECHANISM_TYPE type;
815 SECItem *mech;
816 PK11SymKey *symKey;
818 mech = PK11_ParamFromAlgid(algid);
819 type = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm));
820 if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
821 type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
823 if(mech == NULL) {
824 return NULL;
826 symKey = PK11_RawPBEKeyGen(slot, type, mech, pwitem, faulty3DES, wincx);
828 SECITEM_ZfreeItem(mech, PR_TRUE);
829 return symKey;
832 SECItem *
833 PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem)
835 /* pbe stuff */
836 CK_MECHANISM_TYPE type;
837 SECItem *mech;
838 PK11SymKey *symKey;
839 PK11SlotInfo *slot = PK11_GetInternalSlot();
840 int iv_len = 0;
841 CK_PBE_PARAMS_PTR pPBEparams;
842 SECItem src;
843 SECItem *iv;
846 mech = PK11_ParamFromAlgid(algid);
847 type = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm));
848 if(mech == NULL) {
849 return NULL;
851 symKey = PK11_RawPBEKeyGen(slot, type, mech, pwitem, PR_FALSE, NULL);
852 PK11_FreeSlot(slot);
853 if (symKey == NULL) {
854 SECITEM_ZfreeItem(mech, PR_TRUE);
855 return NULL;
857 PK11_FreeSymKey(symKey);
858 pPBEparams = (CK_PBE_PARAMS_PTR)mech->data;
859 iv_len = PK11_GetIVLength(type);
861 src.data = (unsigned char *)pPBEparams->pInitVector;
862 src.len = iv_len;
863 iv = SECITEM_DupItem(&src);
865 SECITEM_ZfreeItem(mech, PR_TRUE);
866 return iv;