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
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.
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 ***** */
59 typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter
;
60 struct SEC_PKCS5PBEParameterStr
{
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
[] =
74 0, NULL
, sizeof(SEC_PKCS5PBEParameter
) },
75 { SEC_ASN1_OCTET_STRING
,
76 offsetof(SEC_PKCS5PBEParameter
, salt
) },
78 offsetof(SEC_PKCS5PBEParameter
, iteration
) },
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
) },
90 /* maps crypto algorithm from PBE algorithm.
93 SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID
*algid
)
99 return SEC_OID_UNKNOWN
;
101 algorithm
= SECOID_GetAlgorithmTag(algid
);
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
:
126 return SEC_OID_UNKNOWN
;
129 /* check to see if an oid is a pbe algorithm
132 SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID
*algid
)
134 return (PRBool
)(SEC_PKCS5GetCryptoAlgorithm(algid
) != SEC_OID_UNKNOWN
);
137 /* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
140 SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag
, int keyLen
)
144 case SEC_OID_DES_EDE3_CBC
:
148 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
;
151 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC
;
156 case SEC_OID_DES_CBC
:
157 return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC
;
158 case SEC_OID_RC2_CBC
:
161 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
;
163 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC
;
171 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4
;
173 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4
;
182 return SEC_OID_UNKNOWN
;
186 /* get the key length needed for the PBE algorithm
190 SEC_PKCS5GetKeyLength(SECAlgorithmID
*algid
)
196 return SEC_OID_UNKNOWN
;
198 algorithm
= SECOID_GetAlgorithmTag(algid
);
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
:
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
:
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
:
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
:
227 /* the V2 algorithms only encode the salt, there is no iteration
228 * count so we need a check for V2 algorithm parameters.
231 sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag 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
:
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.
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
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
,
278 PRArenaPool
*poolp
= NULL
;
279 SEC_PKCS5PBEParameter
*pbe_param
= NULL
;
280 SECStatus rv
= SECSuccess
;
287 poolp
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
291 pbe_param
= (SEC_PKCS5PBEParameter
*)PORT_ArenaZAlloc(poolp
,
292 sizeof(SEC_PKCS5PBEParameter
));
294 PORT_FreeArena(poolp
, PR_TRUE
);
298 pbe_param
->poolp
= poolp
;
301 if (salt
&& salt
->data
) {
302 rv
= SECITEM_CopyItem(poolp
, &pbe_param
->salt
, salt
);
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
);
318 /* encode the integer */
319 dummy
= SEC_ASN1EncodeInteger(poolp
, &pbe_param
->iteration
,
321 rv
= (dummy
) ? SECSuccess
: SECFailure
;
323 if(rv
!= SECSuccess
) {
324 PORT_FreeArena(poolp
, PR_FALSE
);
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
340 SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm
,
344 PRArenaPool
*poolp
= NULL
;
345 SECAlgorithmID
*algid
, *ret_algid
;
347 SECStatus rv
= SECFailure
;
348 SEC_PKCS5PBEParameter
*pbe_param
;
354 der_param
.data
= NULL
;
357 /* generate the parameter */
358 pbe_param
= sec_pkcs5_create_pbe_parameter(algorithm
, salt
, iteration
);
363 poolp
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
365 sec_pkcs5_destroy_pbe_param(pbe_param
);
369 /* generate the algorithm id */
370 algid
= (SECAlgorithmID
*)PORT_ArenaZAlloc(poolp
, sizeof(SECAlgorithmID
));
373 if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm
)) {
374 dummy
= SEC_ASN1EncodeItem(poolp
, &der_param
, pbe_param
,
375 SEC_PKCS5PBEParameterTemplate
);
377 dummy
= SEC_ASN1EncodeItem(poolp
, &der_param
, pbe_param
,
378 SEC_V2PKCS12PBEParameterTemplate
);
382 rv
= SECOID_SetAlgorithmID(poolp
, algid
, algorithm
, &der_param
);
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
);
399 PORT_FreeArena(poolp
, PR_TRUE
);
403 sec_pkcs5_destroy_pbe_param(pbe_param
);
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
;
420 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
424 iv_len
= PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm
));
429 if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm
)) {
430 rv
= SEC_ASN1DecodeItem(arena
, &p5_param
,
431 SEC_V2PKCS12PBEParameterTemplate
, &algid
->parameters
);
433 rv
= SEC_ASN1DecodeItem(arena
,&p5_param
,SEC_PKCS5PBEParameterTemplate
,
437 if (rv
!= SECSuccess
) {
441 salt
= &p5_param
.salt
;
443 pbe_params
= (CK_PBE_PARAMS
*)PORT_ZAlloc(sizeof(CK_PBE_PARAMS
)+
445 if (pbe_params
== NULL
) {
450 pbe_params
->pSalt
= ((CK_CHAR_PTR
) pbe_params
)+sizeof(CK_PBE_PARAMS
);
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
);
465 PORT_FreeArena(arena
,PR_TRUE
);
471 PORT_Free(pbe_params
);
474 PORT_FreeArena(arena
,PR_TRUE
);
480 PBE_PK11ParamToAlgid(SECOidTag algTag
, SECItem
*param
, PRArenaPool
*arena
,
481 SECAlgorithmID
*algId
)
483 CK_PBE_PARAMS
*pbe_param
;
485 SECAlgorithmID
*pbeAlgID
= NULL
;
488 if(!param
|| !algId
) {
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
);
501 rv
= SECOID_CopyAlgorithmID(arena
, algId
, pbeAlgID
);
502 SECOID_DestroyAlgorithmID(pbeAlgID
, PR_TRUE
);
507 PBE_CreateContext(SECOidTag hashAlgorithm
, PBEBitGenID bitGenPurpose
,
508 SECItem
*pwitem
, SECItem
*salt
, unsigned int bitsNeeded
,
509 unsigned int iterations
)
511 SECItem
*context
= NULL
;
513 CK_PBE_PARAMS pbe_params
;
514 CK_MECHANISM_TYPE mechanism
= CKM_INVALID_MECHANISM
;
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
) {
525 mechanism
= CKM_PBA_SHA1_WITH_SHA1_HMAC
;
528 mechanism
= CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN
;
531 mechanism
= CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN
;
537 case pbeBitGenCipherIV
:
538 if (bitsNeeded
> 64) {
541 if (hashAlgorithm
!= SEC_OID_SHA1
) {
544 mechanism
= CKM_PBE_SHA1_DES3_EDE_CBC
;
546 case pbeBitGenCipherKey
:
547 if (hashAlgorithm
!= SEC_OID_SHA1
) {
550 switch (bitsNeeded
) {
552 mechanism
= CKM_PBE_SHA1_RC4_40
;
555 mechanism
= CKM_PBE_SHA1_RC4_128
;
560 case pbeBitGenIDNull
:
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;)... */
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
);
584 if (symKey
!= NULL
) {
585 if (bitGenPurpose
== pbeBitGenCipherIV
) {
586 /* NOTE: this assumes that bitsNeeded is a multiple of 8! */
589 ivItem
.data
= ivData
;
590 ivItem
.len
= bitsNeeded
/8;
591 context
= SECITEM_DupItem(&ivItem
);
594 PK11_ExtractKeyValue(symKey
);
595 keyData
= PK11_GetKeyData(symKey
);
597 /* assert bitsNeeded with length? */
599 context
= SECITEM_DupItem(keyData
);
602 PK11_FreeSymKey(symKey
);
605 return (PBEBitGenContext
*)context
;
609 PBE_GenerateBits(PBEBitGenContext
*context
)
611 return (SECItem
*)context
;
615 PBE_DestroyContext(PBEBitGenContext
*context
)
617 SECITEM_FreeItem((SECItem
*)context
,PR_TRUE
);
621 SEC_PKCS5GetIV(SECAlgorithmID
*algid
, SECItem
*pwitem
, PRBool faulty3DES
)
624 SECOidTag algorithm
= SECOID_GetAlgorithmTag(algid
);
625 CK_PBE_PARAMS
*pbe_params
;
626 CK_MECHANISM_TYPE mechanism
;
633 rv
= pbe_PK11AlgidToParam(algid
,&mechItem
);
634 if (rv
!= SECSuccess
) {
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
);
650 tmp
.data
= pbe_params
->pInitVector
;
652 iv
= SECITEM_DupItem(&tmp
);
653 PK11_FreeSymKey(symKey
);
657 PORT_ZFree(mechItem
.data
,mechItem
.len
);
664 * Subs from nss 3.x that are depricated
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
);
676 __PBE_GenerateBits(PBEBitGenContext
*context
)
678 PORT_Assert("__PBE_GenerateBits is Depricated" == NULL
);
683 __PBE_DestroyContext(PBEBitGenContext
*context
)
685 PORT_Assert("__PBE_DestroyContext is Depricated" == NULL
);
689 RSA_FormatBlock(SECItem
*result
, unsigned modulusLen
,
690 int blockType
, SECItem
*data
)
692 PORT_Assert("RSA_FormatBlock is Depricated" == NULL
);
696 /****************************************************************************
698 * Now Do The PBE Functions Here...
700 ****************************************************************************/
703 pk11_destroy_ck_pbe_params(CK_PBE_PARAMS
*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
));
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
));
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
) {
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
) {
739 PORT_Memcpy(pbe_params
->pSalt
, salt
->data
, salt
->len
);
740 pbe_params
->ulSaltLen
= salt
->len
;
742 pbe_params
->ulIteration
= (CK_ULONG
)iterations
;
747 pk11_destroy_ck_pbe_params(pbe_params
);
749 PORT_ZFree(paramRV
, sizeof(SECItem
));
754 PK11_DestroyPBEParams(SECItem
*pItem
)
757 CK_PBE_PARAMS
* params
= (CK_PBE_PARAMS
*)(pItem
->data
);
759 pk11_destroy_ck_pbe_params(params
);
760 PORT_ZFree(pItem
, sizeof(SECItem
));
765 PK11_CreatePBEAlgorithmID(SECOidTag algorithm
, int iteration
, SECItem
*salt
)
767 SECAlgorithmID
*algid
= NULL
;
768 algid
= SEC_PKCS5CreateAlgorithmID(algorithm
, salt
, iteration
);
773 PK11_RawPBEKeyGen(PK11SlotInfo
*slot
, CK_MECHANISM_TYPE type
, SECItem
*mech
,
774 SECItem
*pwitem
, PRBool faulty3DES
, void *wincx
)
777 CK_PBE_PARAMS
*pbe_params
;
780 if(faulty3DES
&& (type
== CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC
)) {
781 type
= CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC
;
787 pbe_params
= (CK_PBE_PARAMS
*)mech
->data
;
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
;
796 SECITEM_ZfreeItem(mech
, PR_TRUE
);
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;
810 PK11_PBEKeyGen(PK11SlotInfo
*slot
, SECAlgorithmID
*algid
, SECItem
*pwitem
,
811 PRBool faulty3DES
, void *wincx
)
814 CK_MECHANISM_TYPE type
;
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
;
826 symKey
= PK11_RawPBEKeyGen(slot
, type
, mech
, pwitem
, faulty3DES
, wincx
);
828 SECITEM_ZfreeItem(mech
, PR_TRUE
);
833 PK11_GetPBEIV(SECAlgorithmID
*algid
, SECItem
*pwitem
)
836 CK_MECHANISM_TYPE type
;
839 PK11SlotInfo
*slot
= PK11_GetInternalSlot();
841 CK_PBE_PARAMS_PTR pPBEparams
;
846 mech
= PK11_ParamFromAlgid(algid
);
847 type
= PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid
->algorithm
));
851 symKey
= PK11_RawPBEKeyGen(slot
, type
, mech
, pwitem
, PR_FALSE
, NULL
);
853 if (symKey
== NULL
) {
854 SECITEM_ZfreeItem(mech
, PR_TRUE
);
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
;
863 iv
= SECITEM_DupItem(&src
);
865 SECITEM_ZfreeItem(mech
, PR_TRUE
);