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 */
64 SECItem keyLength
; /* PKCS5v2 only */
65 SECAlgorithmID
*pPrfAlgId
; /* PKCS5v2 only */
66 SECAlgorithmID prfAlgId
; /* PKCS5v2 only */
69 /* PKCS5 V2 has an algorithm ID for the encryption and for
70 * the key generation. This is valid for SEC_OID_PKCS5_PBES2
71 * and SEC_OID_PKCS5_PBMAC1
73 struct sec_pkcs5V2ParameterStr
{
75 SECAlgorithmID pbeAlgId
; /* real pbe algorithms */
76 SECAlgorithmID cipherAlgId
; /* encryption/mac */
79 typedef struct sec_pkcs5V2ParameterStr sec_pkcs5V2Parameter
;
82 /* template for PKCS 5 PBE Parameter. This template has been expanded
83 * based upon the additions in PKCS 12. This should eventually be moved
84 * if RSA updates PKCS 5.
86 const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate
[] =
89 0, NULL
, sizeof(SEC_PKCS5PBEParameter
) },
90 { SEC_ASN1_OCTET_STRING
,
91 offsetof(SEC_PKCS5PBEParameter
, salt
) },
93 offsetof(SEC_PKCS5PBEParameter
, iteration
) },
97 const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate
[] =
99 { SEC_ASN1_SEQUENCE
, 0, NULL
, sizeof(SEC_PKCS5PBEParameter
) },
100 { SEC_ASN1_OCTET_STRING
, offsetof(SEC_PKCS5PBEParameter
, salt
) },
101 { SEC_ASN1_INTEGER
, offsetof(SEC_PKCS5PBEParameter
, iteration
) },
105 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate
)
107 /* SECOID_PKCS5_PBKDF2 */
108 const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate
[] =
110 { SEC_ASN1_SEQUENCE
, 0, NULL
, sizeof(SEC_PKCS5PBEParameter
) },
111 /* This is really a choice, but since we only understand this
112 * choice, just inline it */
113 { SEC_ASN1_OCTET_STRING
, offsetof(SEC_PKCS5PBEParameter
, salt
) },
114 { SEC_ASN1_INTEGER
, offsetof(SEC_PKCS5PBEParameter
, iteration
) },
115 { SEC_ASN1_INTEGER
|SEC_ASN1_OPTIONAL
,
116 offsetof(SEC_PKCS5PBEParameter
, keyLength
) },
117 { SEC_ASN1_POINTER
| SEC_ASN1_XTRN
| SEC_ASN1_OPTIONAL
,
118 offsetof(SEC_PKCS5PBEParameter
, pPrfAlgId
),
119 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate
) },
123 /* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
124 const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate
[] =
126 { SEC_ASN1_SEQUENCE
, 0, NULL
, sizeof(SEC_PKCS5PBEParameter
) },
127 { SEC_ASN1_INLINE
| SEC_ASN1_XTRN
, offsetof(sec_pkcs5V2Parameter
, pbeAlgId
),
128 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate
) },
129 { SEC_ASN1_INLINE
| SEC_ASN1_XTRN
,
130 offsetof(sec_pkcs5V2Parameter
, cipherAlgId
),
131 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate
) },
137 * maps a PBE algorithm to a crypto algorithm. for PKCS12 and PKCS5v1
138 * for PKCS5v2 it returns SEC_OID_PKCS5_PBKDF2.
141 sec_pkcs5GetCryptoFromAlgTag(SECOidTag algorithm
)
145 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
:
146 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC
:
147 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC
:
148 return SEC_OID_DES_EDE3_CBC
;
149 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC
:
150 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC
:
151 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC
:
152 return SEC_OID_DES_CBC
;
153 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
:
154 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC
:
155 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC
:
156 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
:
157 return SEC_OID_RC2_CBC
;
158 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4
:
159 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4
:
160 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4
:
161 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4
:
163 case SEC_OID_PKCS5_PBKDF2
:
164 case SEC_OID_PKCS5_PBES2
:
165 case SEC_OID_PKCS5_PBMAC1
:
166 return SEC_OID_PKCS5_PBKDF2
;
171 return SEC_OID_UNKNOWN
;
175 * get a new PKCS5 V2 Parameter from the algorithm id.
176 * if arena is passed in, use it, otherwise create a new arena.
178 sec_pkcs5V2Parameter
*
179 sec_pkcs5_v2_get_v2_param(PRArenaPool
*arena
, SECAlgorithmID
*algid
)
181 PRArenaPool
*localArena
= NULL
;
182 sec_pkcs5V2Parameter
*pbeV2_param
;
186 localArena
= arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
191 pbeV2_param
= PORT_ArenaZNew(arena
, sec_pkcs5V2Parameter
);
192 if (pbeV2_param
== NULL
) {
196 rv
= SEC_ASN1DecodeItem(arena
, pbeV2_param
,
197 SEC_PKCS5V2ParameterTemplate
, &algid
->parameters
);
198 if (rv
== SECFailure
) {
202 pbeV2_param
->poolp
= arena
;
206 PORT_FreeArena(arena
, PR_FALSE
);
212 sec_pkcs5_v2_destroy_v2_param(sec_pkcs5V2Parameter
*param
)
214 if (param
&& param
->poolp
) {
215 PORT_FreeArena(param
->poolp
, PR_TRUE
);
220 /* maps crypto algorithm from PBE algorithm.
223 SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID
*algid
)
230 return SEC_OID_UNKNOWN
;
232 pbeAlg
= SECOID_GetAlgorithmTag(algid
);
233 cipherAlg
= sec_pkcs5GetCryptoFromAlgTag(pbeAlg
);
234 if ((cipherAlg
== SEC_OID_PKCS5_PBKDF2
) &&
235 (pbeAlg
!= SEC_OID_PKCS5_PBKDF2
)) {
236 sec_pkcs5V2Parameter
*pbeV2_param
;
237 cipherAlg
= SEC_OID_UNKNOWN
;
239 pbeV2_param
= sec_pkcs5_v2_get_v2_param(NULL
, algid
);
240 if (pbeV2_param
!= NULL
) {
241 cipherAlg
= SECOID_GetAlgorithmTag(&pbeV2_param
->cipherAlgId
);
242 sec_pkcs5_v2_destroy_v2_param(pbeV2_param
);
249 /* check to see if an oid is a pbe algorithm
252 SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID
*algid
)
254 return (PRBool
)(SEC_PKCS5GetCryptoAlgorithm(algid
) != SEC_OID_UNKNOWN
);
258 SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algtag
)
260 return (PRBool
)(sec_pkcs5GetCryptoFromAlgTag(algtag
) != SEC_OID_UNKNOWN
);
264 * find the most appropriate PKCS5v2 overall oid tag from a regular
265 * cipher/hash algorithm tag.
268 sec_pkcs5v2_get_pbe(SECOidTag algTag
)
270 /* if it's a valid hash oid... */
271 if (HASH_GetHashOidTagByHMACOidTag(algTag
) != SEC_OID_UNKNOWN
) {
272 /* use the MAC tag */
273 return SEC_OID_PKCS5_PBMAC1
;
275 if (HASH_GetHashTypeByOidTag(algTag
) != HASH_AlgNULL
) {
276 /* eliminate Hash algorithms */
277 return SEC_OID_UNKNOWN
;
279 if (PK11_AlgtagToMechanism(algTag
) != CKM_INVALID_MECHANISM
) {
280 /* it's not a hash, if it has a PKCS #11 mechanism associated
281 * with it, assume it's a cipher. (NOTE this will generate
282 * some false positives). */
283 return SEC_OID_PKCS5_PBES2
;
285 return SEC_OID_UNKNOWN
;
289 * maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
290 * input keyLen in bits.
293 SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag
, int keyLen
)
297 case SEC_OID_DES_EDE3_CBC
:
302 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
;
305 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC
;
310 case SEC_OID_DES_CBC
:
311 return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC
;
312 case SEC_OID_RC2_CBC
:
315 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
;
318 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC
;
326 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4
;
329 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4
;
335 return sec_pkcs5v2_get_pbe(algTag
);
338 return SEC_OID_UNKNOWN
;
342 * get the key length in bytes from a PKCS5 PBE
345 sec_pkcs5v2_key_length(SECAlgorithmID
*algid
)
348 PRArenaPool
*arena
= NULL
;
349 SEC_PKCS5PBEParameter p5_param
;
353 algorithm
= SECOID_GetAlgorithmTag(algid
);
354 /* sanity check, they should all be PBKDF2 here */
355 if (algorithm
!= SEC_OID_PKCS5_PBKDF2
) {
359 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
363 PORT_Memset(&p5_param
, 0, sizeof(p5_param
));
364 rv
= SEC_ASN1DecodeItem(arena
,&p5_param
,
365 SEC_PKCS5V2PBEParameterTemplate
, &algid
->parameters
);
366 if (rv
!= SECSuccess
) {
370 if (p5_param
.keyLength
.data
!= NULL
) {
371 length
= DER_GetInteger(&p5_param
.keyLength
);
376 PORT_FreeArena(arena
, PR_FALSE
);
382 * get the key length in bytes needed for the PBE algorithm
385 SEC_PKCS5GetKeyLength(SECAlgorithmID
*algid
)
391 return SEC_OID_UNKNOWN
;
393 algorithm
= SECOID_GetAlgorithmTag(algid
);
397 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
:
398 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC
:
399 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC
:
401 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC
:
402 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC
:
403 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC
:
405 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
:
406 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4
:
407 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4
:
408 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
:
410 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC
:
411 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4
:
412 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC
:
413 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4
:
415 case SEC_OID_PKCS5_PBKDF2
:
416 return sec_pkcs5v2_key_length(algid
);
417 case SEC_OID_PKCS5_PBES2
:
418 case SEC_OID_PKCS5_PBMAC1
:
420 sec_pkcs5V2Parameter
*pbeV2_param
;
422 pbeV2_param
= sec_pkcs5_v2_get_v2_param(NULL
, algid
);
423 if (pbeV2_param
!= NULL
) {
424 length
= sec_pkcs5v2_key_length(&pbeV2_param
->pbeAlgId
);
425 sec_pkcs5_v2_destroy_v2_param(pbeV2_param
);
437 /* the PKCS12 V2 algorithms only encode the salt, there is no iteration
438 * count so we need a check for V2 algorithm parameters.
441 sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm
)
445 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4
:
446 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4
:
447 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
:
448 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC
:
449 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC
:
450 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
:
460 sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(SECOidTag algorithm
)
464 case SEC_OID_PKCS5_PBES2
:
465 case SEC_OID_PKCS5_PBMAC1
:
466 case SEC_OID_PKCS5_PBKDF2
:
475 /* destroy a pbe parameter. it assumes that the parameter was
476 * generated using the appropriate create function and therefor
477 * contains an arena pool.
480 sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter
*pbe_param
)
482 if(pbe_param
!= NULL
)
483 PORT_FreeArena(pbe_param
->poolp
, PR_TRUE
);
486 /* creates a PBE parameter based on the PBE algorithm. the only required
487 * parameters are algorithm and interation. the return is a PBE parameter
488 * which conforms to PKCS 5 parameter unless an extended parameter is needed.
489 * this is primarily if keyLength and a variable key length algorithm are
491 * salt - if null, a salt will be generated from random bytes.
492 * iteration - number of iterations to perform hashing.
493 * keyLength - only used in variable key length algorithms. if specified,
494 * should be in bytes.
495 * once a parameter is allocated, it should be destroyed calling
496 * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
498 #define DEFAULT_SALT_LENGTH 16
499 static SEC_PKCS5PBEParameter
*
500 sec_pkcs5_create_pbe_parameter(SECOidTag algorithm
,
506 PRArenaPool
*poolp
= NULL
;
507 SEC_PKCS5PBEParameter
*pbe_param
= NULL
;
508 SECStatus rv
= SECSuccess
;
515 poolp
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
519 pbe_param
= (SEC_PKCS5PBEParameter
*)PORT_ArenaZAlloc(poolp
,
520 sizeof(SEC_PKCS5PBEParameter
));
522 PORT_FreeArena(poolp
, PR_TRUE
);
526 pbe_param
->poolp
= poolp
;
529 if (salt
&& salt
->data
) {
530 rv
= SECITEM_CopyItem(poolp
, &pbe_param
->salt
, salt
);
532 /* sigh, the old interface generated salt on the fly, so we have to
533 * preserve the semantics */
534 pbe_param
->salt
.len
= DEFAULT_SALT_LENGTH
;
535 pbe_param
->salt
.data
= PORT_ArenaZAlloc(poolp
,DEFAULT_SALT_LENGTH
);
536 if (pbe_param
->salt
.data
) {
537 rv
= PK11_GenerateRandom(pbe_param
->salt
.data
,DEFAULT_SALT_LENGTH
);
541 if(rv
!= SECSuccess
) {
542 PORT_FreeArena(poolp
, PR_TRUE
);
546 /* encode the integer */
547 dummy
= SEC_ASN1EncodeInteger(poolp
, &pbe_param
->iteration
,
549 rv
= (dummy
) ? SECSuccess
: SECFailure
;
551 if(rv
!= SECSuccess
) {
552 PORT_FreeArena(poolp
, PR_FALSE
);
557 * for PKCS5 v2 Add the keylength and the prf
559 if (algorithm
== SEC_OID_PKCS5_PBKDF2
) {
560 dummy
= SEC_ASN1EncodeInteger(poolp
, &pbe_param
->keyLength
,
562 rv
= (dummy
) ? SECSuccess
: SECFailure
;
563 if (rv
!= SECSuccess
) {
564 PORT_FreeArena(poolp
, PR_FALSE
);
567 rv
= SECOID_SetAlgorithmID(poolp
, &pbe_param
->prfAlgId
, prfAlg
, NULL
);
568 if (rv
!= SECSuccess
) {
569 PORT_FreeArena(poolp
, PR_FALSE
);
572 pbe_param
->pPrfAlgId
= &pbe_param
->prfAlgId
;
578 /* creates a algorithm ID containing the PBE algorithm and appropriate
579 * parameters. the required parameter is the algorithm. if salt is
580 * not specified, it is generated randomly.
582 * the returned SECAlgorithmID should be destroyed using
583 * SECOID_DestroyAlgorithmID
586 sec_pkcs5CreateAlgorithmID(SECOidTag algorithm
,
587 SECOidTag cipherAlgorithm
,
589 SECOidTag
*pPbeAlgorithm
,
594 PRArenaPool
*poolp
= NULL
;
595 SECAlgorithmID
*algid
, *ret_algid
= NULL
;
596 SECOidTag pbeAlgorithm
= algorithm
;
599 SECStatus rv
= SECFailure
;
600 SEC_PKCS5PBEParameter
*pbe_param
= NULL
;
601 sec_pkcs5V2Parameter pbeV2_param
;
607 poolp
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
612 if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm
) ||
613 sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm
)) {
615 SECItem
*cipherParams
;
618 * if we ask for pkcs5 Algorithms directly, then the
619 * application needs to supply the cipher algorithm,
620 * otherwise we are implicitly using pkcs5 v2 and the
621 * passed in algorithm is the encryption algorithm.
623 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm
)) {
624 if (cipherAlgorithm
== SEC_OID_UNKNOWN
) {
628 cipherAlgorithm
= algorithm
;
629 /* force algorithm to be chosen below */
630 algorithm
= SEC_OID_PKCS5_PBKDF2
;
633 pbeAlgorithm
= SEC_OID_PKCS5_PBKDF2
;
635 * 'algorithm' is the overall algorithm oid tag used to wrap the
636 * entire algoithm ID block. For PKCS5v1 and PKCS12, this
637 * algorithm OID has encoded in it both the PBE KDF function
638 * and the encryption algorithm. For PKCS 5v2, PBE KDF and
639 * encryption/macing oids are encoded as parameters in
640 * the algorithm ID block.
642 * Thus in PKCS5 v1 and PKCS12, this algorithm maps to a pkcs #11
643 * mechanism, where as in PKCS 5v2, this alogithm tag does not map
644 * directly to a PKCS #11 mechanim, instead the 2 oids in the
645 * algorithm ID block map the the actual PKCS #11 mechanism.
646 * gorithm is). We use choose this algorithm oid based on the
647 * cipherAlgorithm to determine what this should be (MAC1 or PBES2).
649 if (algorithm
== SEC_OID_PKCS5_PBKDF2
) {
650 /* choose mac or pbes */
651 algorithm
= sec_pkcs5v2_get_pbe(cipherAlgorithm
);
654 /* set the PKCS5v2 specific parameters */
655 if (keyLength
== 0) {
656 SECOidTag hashAlg
= HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm
);
657 if (hashAlg
!= SEC_OID_UNKNOWN
) {
658 keyLength
= HASH_ResultLenByOidTag(hashAlg
);
660 CK_MECHANISM_TYPE cryptoMech
;
661 cryptoMech
= PK11_AlgtagToMechanism(cipherAlgorithm
);
662 if (cryptoMech
== CKM_INVALID_MECHANISM
) {
665 keyLength
= PK11_GetMaxKeyLength(cryptoMech
);
667 if (keyLength
== 0) {
671 /* currently only SEC_OID_HMAC_SHA1 is defined */
672 if (prfAlg
== SEC_OID_UNKNOWN
) {
673 prfAlg
= SEC_OID_HMAC_SHA1
;
676 /* build the PKCS5v2 cipher algorithm id */
677 cipherParams
= pk11_GenerateNewParamWithKeyLen(
678 PK11_AlgtagToMechanism(cipherAlgorithm
), keyLength
);
683 PORT_Memset(&pbeV2_param
, 0, sizeof (pbeV2_param
));
685 rv
= PK11_ParamToAlgid(cipherAlgorithm
, cipherParams
,
686 poolp
, &pbeV2_param
.cipherAlgId
);
687 SECITEM_FreeItem(cipherParams
, PR_TRUE
);
688 if (rv
!= SECSuccess
) {
694 /* generate the parameter */
695 pbe_param
= sec_pkcs5_create_pbe_parameter(pbeAlgorithm
, salt
, iteration
,
701 /* generate the algorithm id */
702 algid
= (SECAlgorithmID
*)PORT_ArenaZAlloc(poolp
, sizeof(SECAlgorithmID
));
707 der_param
.data
= NULL
;
709 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm
)) {
710 /* first encode the PBE algorithm ID */
711 dummy
= SEC_ASN1EncodeItem(poolp
, &der_param
, pbe_param
,
712 SEC_PKCS5V2PBEParameterTemplate
);
716 rv
= SECOID_SetAlgorithmID(poolp
, &pbeV2_param
.pbeAlgId
,
717 pbeAlgorithm
, &der_param
);
718 if (rv
!= SECSuccess
) {
722 /* now encode the Full PKCS 5 parameter */
723 der_param
.data
= NULL
;
725 dummy
= SEC_ASN1EncodeItem(poolp
, &der_param
, &pbeV2_param
,
726 SEC_PKCS5V2ParameterTemplate
);
727 } else if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm
)) {
728 dummy
= SEC_ASN1EncodeItem(poolp
, &der_param
, pbe_param
,
729 SEC_PKCS5PBEParameterTemplate
);
731 dummy
= SEC_ASN1EncodeItem(poolp
, &der_param
, pbe_param
,
732 SEC_V2PKCS12PBEParameterTemplate
);
738 rv
= SECOID_SetAlgorithmID(poolp
, algid
, algorithm
, &der_param
);
739 if (rv
!= SECSuccess
) {
743 ret_algid
= (SECAlgorithmID
*)PORT_ZAlloc(sizeof(SECAlgorithmID
));
744 if (ret_algid
== NULL
) {
748 rv
= SECOID_CopyAlgorithmID(NULL
, ret_algid
, algid
);
749 if (rv
!= SECSuccess
) {
750 SECOID_DestroyAlgorithmID(ret_algid
, PR_TRUE
);
752 } else if (pPbeAlgorithm
) {
753 *pPbeAlgorithm
= pbeAlgorithm
;
758 PORT_FreeArena(poolp
, PR_TRUE
);
763 sec_pkcs5_destroy_pbe_param(pbe_param
);
770 pbe_PK11AlgidToParam(SECAlgorithmID
*algid
,SECItem
*mech
)
772 SEC_PKCS5PBEParameter p5_param
;
773 SECItem
*salt
= NULL
;
774 SECOidTag algorithm
= SECOID_GetAlgorithmTag(algid
);
775 PRArenaPool
*arena
= NULL
;
776 SECStatus rv
= SECFailure
;
777 unsigned char *paramData
= NULL
;
778 unsigned char *pSalt
= NULL
;
784 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
791 * decode the algid based on the pbe type
793 if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm
)) {
794 iv_len
= PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm
));
795 rv
= SEC_ASN1DecodeItem(arena
, &p5_param
,
796 SEC_V2PKCS12PBEParameterTemplate
, &algid
->parameters
);
797 } else if (algorithm
== SEC_OID_PKCS5_PBKDF2
) {
799 PORT_Memset(&p5_param
, 0, sizeof(p5_param
));
800 rv
= SEC_ASN1DecodeItem(arena
,&p5_param
,
801 SEC_PKCS5V2PBEParameterTemplate
, &algid
->parameters
);
803 iv_len
= PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm
));
804 rv
= SEC_ASN1DecodeItem(arena
,&p5_param
,SEC_PKCS5PBEParameterTemplate
,
812 if (rv
!= SECSuccess
) {
817 salt
= &p5_param
.salt
;
818 iterations
= (CK_ULONG
) DER_GetInteger(&p5_param
.iteration
);
820 /* allocate and fill in the PKCS #11 parameters
821 * based on the algorithm. */
822 if (algorithm
== SEC_OID_PKCS5_PBKDF2
) {
824 CK_PKCS5_PBKD2_PARAMS
*pbeV2_params
=
825 (CK_PKCS5_PBKD2_PARAMS
*)PORT_ZAlloc(
826 sizeof(CK_PKCS5_PBKD2_PARAMS
)+ salt
->len
);
828 if (pbeV2_params
== NULL
) {
831 paramData
= (unsigned char *)pbeV2_params
;
832 paramLen
= sizeof(CK_PKCS5_PBKD2_PARAMS
);
835 prfAlgTag
= SEC_OID_HMAC_SHA1
;
836 if (p5_param
.pPrfAlgId
&&
837 p5_param
.pPrfAlgId
->algorithm
.data
!= 0) {
838 prfAlgTag
= SECOID_GetAlgorithmTag(p5_param
.pPrfAlgId
);
840 if (prfAlgTag
== SEC_OID_HMAC_SHA1
) {
841 pbeV2_params
->prf
= CKP_PKCS5_PBKD2_HMAC_SHA1
;
843 /* only SHA1_HMAC is currently supported by PKCS #11 */
844 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM
);
848 /* probably should fetch these from the prfAlgid */
849 pbeV2_params
->pPrfData
= NULL
;
850 pbeV2_params
->ulPrfDataLen
= 0;
851 pbeV2_params
->saltSource
= CKZ_SALT_SPECIFIED
;
852 pSalt
= ((CK_CHAR_PTR
) pbeV2_params
)+sizeof(CK_PKCS5_PBKD2_PARAMS
);
853 PORT_Memcpy(pSalt
, salt
->data
, salt
->len
);
854 pbeV2_params
->pSaltSourceData
= pSalt
;
855 pbeV2_params
->ulSaltSourceDataLen
= salt
->len
;
856 pbeV2_params
->iterations
= iterations
;
858 CK_PBE_PARAMS
*pbe_params
= NULL
;
859 pbe_params
= (CK_PBE_PARAMS
*)PORT_ZAlloc(sizeof(CK_PBE_PARAMS
)+
861 if (pbe_params
== NULL
) {
864 paramData
= (unsigned char *)pbe_params
;
865 paramLen
= sizeof(CK_PBE_PARAMS
);
867 pSalt
= ((CK_CHAR_PTR
) pbe_params
)+sizeof(CK_PBE_PARAMS
);
868 pbe_params
->pSalt
= pSalt
;
869 PORT_Memcpy(pSalt
, salt
->data
, salt
->len
);
870 pbe_params
->ulSaltLen
= salt
->len
;
872 pbe_params
->pInitVector
=
873 ((CK_CHAR_PTR
) pbe_params
)+ sizeof(CK_PBE_PARAMS
)+salt
->len
;
875 pbe_params
->ulIteration
= iterations
;
878 /* copy into the mechanism sec item */
879 mech
->data
= paramData
;
880 mech
->len
= paramLen
;
882 PORT_FreeArena(arena
,PR_TRUE
);
888 PORT_Free(paramData
);
891 PORT_FreeArena(arena
,PR_TRUE
);
897 * public, deprecated, not valid for pkcs5 v2
899 * use PK11_CreatePBEV2AlgorithmID or PK11_CreatePBEAlgorithmID to create
900 * PBE algorithmID's directly.
903 PBE_PK11ParamToAlgid(SECOidTag algTag
, SECItem
*param
, PRArenaPool
*arena
,
904 SECAlgorithmID
*algId
)
906 CK_PBE_PARAMS
*pbe_param
;
908 SECAlgorithmID
*pbeAlgID
= NULL
;
911 if(!param
|| !algId
) {
915 pbe_param
= (CK_PBE_PARAMS
*)param
->data
;
916 pbeSalt
.data
= (unsigned char *)pbe_param
->pSalt
;
917 pbeSalt
.len
= pbe_param
->ulSaltLen
;
918 pbeAlgID
= sec_pkcs5CreateAlgorithmID(algTag
, SEC_OID_UNKNOWN
,
919 SEC_OID_UNKNOWN
, NULL
, 0, &pbeSalt
, (int)pbe_param
->ulIteration
);
924 rv
= SECOID_CopyAlgorithmID(arena
, algId
, pbeAlgID
);
925 SECOID_DestroyAlgorithmID(pbeAlgID
, PR_TRUE
);
930 * public, Deprecated, This function is only for binary compatibility with
931 * older applications. Does not support PKCS5v2.
933 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for
934 * iv values rather than generating PBE bits directly.
937 PBE_CreateContext(SECOidTag hashAlgorithm
, PBEBitGenID bitGenPurpose
,
938 SECItem
*pwitem
, SECItem
*salt
, unsigned int bitsNeeded
,
939 unsigned int iterations
)
941 SECItem
*context
= NULL
;
943 CK_PBE_PARAMS pbe_params
;
944 CK_MECHANISM_TYPE mechanism
= CKM_INVALID_MECHANISM
;
946 PK11SymKey
*symKey
= NULL
;
947 unsigned char ivData
[8];
950 /* use the purpose to select the low level keygen algorithm */
951 switch (bitGenPurpose
) {
952 case pbeBitGenIntegrityKey
:
953 switch (hashAlgorithm
) {
955 mechanism
= CKM_PBA_SHA1_WITH_SHA1_HMAC
;
958 mechanism
= CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN
;
961 mechanism
= CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN
;
967 case pbeBitGenCipherIV
:
968 if (bitsNeeded
> 64) {
971 if (hashAlgorithm
!= SEC_OID_SHA1
) {
974 mechanism
= CKM_PBE_SHA1_DES3_EDE_CBC
;
976 case pbeBitGenCipherKey
:
977 if (hashAlgorithm
!= SEC_OID_SHA1
) {
980 switch (bitsNeeded
) {
982 mechanism
= CKM_PBE_SHA1_RC4_40
;
985 mechanism
= CKM_PBE_SHA1_RC4_128
;
990 case pbeBitGenIDNull
:
994 if (mechanism
== CKM_INVALID_MECHANISM
) {
995 /* we should set an error, but this is a deprecated function, and
996 * we are keeping bug for bug compatibility;)... */
1000 pbe_params
.pInitVector
= ivData
;
1001 pbe_params
.pPassword
= pwitem
->data
;
1002 pbe_params
.ulPasswordLen
= pwitem
->len
;
1003 pbe_params
.pSalt
= salt
->data
;
1004 pbe_params
.ulSaltLen
= salt
->len
;
1005 pbe_params
.ulIteration
= iterations
;
1006 mechItem
.data
= (unsigned char *) &pbe_params
;
1007 mechItem
.len
= sizeof(pbe_params
);
1010 slot
= PK11_GetInternalSlot();
1011 symKey
= PK11_RawPBEKeyGen(slot
,mechanism
,
1012 &mechItem
, pwitem
, PR_FALSE
, NULL
);
1013 PK11_FreeSlot(slot
);
1014 if (symKey
!= NULL
) {
1015 if (bitGenPurpose
== pbeBitGenCipherIV
) {
1016 /* NOTE: this assumes that bitsNeeded is a multiple of 8! */
1019 ivItem
.data
= ivData
;
1020 ivItem
.len
= bitsNeeded
/8;
1021 context
= SECITEM_DupItem(&ivItem
);
1024 PK11_ExtractKeyValue(symKey
);
1025 keyData
= PK11_GetKeyData(symKey
);
1027 /* assert bitsNeeded with length? */
1029 context
= SECITEM_DupItem(keyData
);
1032 PK11_FreeSymKey(symKey
);
1035 return (PBEBitGenContext
*)context
;
1039 * public, Deprecated, This function is only for binary compatibility with
1040 * older applications. Does not support PKCS5v2.
1042 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetIV() for
1043 * iv values rather than generating PBE bits directly.
1046 PBE_GenerateBits(PBEBitGenContext
*context
)
1048 return (SECItem
*)context
;
1052 * public, Deprecated, This function is only for binary compatibility with
1053 * older applications. Does not support PKCS5v2.
1055 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for
1056 * iv values rather than generating PBE bits directly.
1059 PBE_DestroyContext(PBEBitGenContext
*context
)
1061 SECITEM_FreeItem((SECItem
*)context
,PR_TRUE
);
1065 * public, deprecated. Replaced with PK11_GetPBEIV().
1068 SEC_PKCS5GetIV(SECAlgorithmID
*algid
, SECItem
*pwitem
, PRBool faulty3DES
)
1071 CK_MECHANISM_TYPE type
;
1072 SECItem
*param
= NULL
;
1078 CK_PBE_PARAMS_PTR pPBEparams
;
1081 pbeAlg
= SECOID_GetAlgorithmTag(algid
);
1082 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg
)) {
1083 unsigned char *ivData
;
1084 sec_pkcs5V2Parameter
*pbeV2_param
= NULL
;
1086 /* can only return the IV if the crypto Algorithm exists */
1087 if (pbeAlg
== SEC_OID_PKCS5_PBKDF2
) {
1088 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM
);
1091 pbeV2_param
= sec_pkcs5_v2_get_v2_param(NULL
, algid
);
1092 if (pbeV2_param
== NULL
) {
1095 /* extract the IV from the cipher algid portion of our pkcs 5 v2
1097 type
= PK11_AlgtagToMechanism(
1098 SECOID_GetAlgorithmTag(&pbeV2_param
->cipherAlgId
));
1099 param
= PK11_ParamFromAlgid(&pbeV2_param
->cipherAlgId
);
1100 sec_pkcs5_v2_destroy_v2_param(pbeV2_param
);
1104 /* NOTE: NULL is a permissible return here */
1105 ivData
= PK11_IVFromParam(type
, param
, &iv_len
);
1111 type
= PK11_AlgtagToMechanism(pbeAlg
);
1112 param
= PK11_ParamFromAlgid(algid
);
1113 if (param
== NULL
) {
1116 slot
= PK11_GetInternalSlot();
1117 symKey
= PK11_RawPBEKeyGen(slot
, type
, param
, pwitem
, faulty3DES
, NULL
);
1118 PK11_FreeSlot(slot
);
1119 if (symKey
== NULL
) {
1122 PK11_FreeSymKey(symKey
);
1123 pPBEparams
= (CK_PBE_PARAMS_PTR
)param
->data
;
1124 iv_len
= PK11_GetIVLength(type
);
1126 src
.data
= (unsigned char *)pPBEparams
->pInitVector
;
1130 iv
= SECITEM_DupItem(&src
);
1134 SECITEM_ZfreeItem(param
, PR_TRUE
);
1140 * Subs from nss 3.x that are deprecated
1143 __PBE_CreateContext(SECOidTag hashAlgorithm
, PBEBitGenID bitGenPurpose
,
1144 SECItem
*pwitem
, SECItem
*salt
, unsigned int bitsNeeded
,
1145 unsigned int iterations
)
1147 PORT_Assert("__PBE_CreateContext is Deprecated" == NULL
);
1152 __PBE_GenerateBits(PBEBitGenContext
*context
)
1154 PORT_Assert("__PBE_GenerateBits is Deprecated" == NULL
);
1159 __PBE_DestroyContext(PBEBitGenContext
*context
)
1161 PORT_Assert("__PBE_DestroyContext is Deprecated" == NULL
);
1165 RSA_FormatBlock(SECItem
*result
, unsigned modulusLen
,
1166 int blockType
, SECItem
*data
)
1168 PORT_Assert("RSA_FormatBlock is Deprecated" == NULL
);
1172 /****************************************************************************
1174 * Now Do The PBE Functions Here...
1176 ****************************************************************************/
1179 pk11_destroy_ck_pbe_params(CK_PBE_PARAMS
*pbe_params
)
1182 if (pbe_params
->pPassword
)
1183 PORT_ZFree(pbe_params
->pPassword
, pbe_params
->ulPasswordLen
);
1184 if (pbe_params
->pSalt
)
1185 PORT_ZFree(pbe_params
->pSalt
, pbe_params
->ulSaltLen
);
1186 PORT_ZFree(pbe_params
, sizeof(CK_PBE_PARAMS
));
1191 * public, deprecated. use PK11_CreatePBEAlgorithmID or
1192 * PK11_CreatePBEV2AlgorithmID instead. If you needthe pkcs #11 parameters,
1193 * use PK11_ParamFromAlgid from the algorithm id you created using
1194 * PK11_CreatePBEAlgorithmID or PK11_CreatePBEV2AlgorithmID.
1197 PK11_CreatePBEParams(SECItem
*salt
, SECItem
*pwd
, unsigned int iterations
)
1199 CK_PBE_PARAMS
*pbe_params
= NULL
;
1200 SECItem
*paramRV
= NULL
;
1202 paramRV
= SECITEM_AllocItem(NULL
, NULL
, sizeof(CK_PBE_PARAMS
));
1206 /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */
1207 PORT_Memset(paramRV
->data
, 0, sizeof(CK_PBE_PARAMS
));
1209 pbe_params
= (CK_PBE_PARAMS
*)paramRV
->data
;
1210 pbe_params
->pPassword
= (CK_CHAR_PTR
)PORT_ZAlloc(pwd
->len
);
1211 if (!pbe_params
->pPassword
) {
1214 PORT_Memcpy(pbe_params
->pPassword
, pwd
->data
, pwd
->len
);
1215 pbe_params
->ulPasswordLen
= pwd
->len
;
1217 pbe_params
->pSalt
= (CK_CHAR_PTR
)PORT_ZAlloc(salt
->len
);
1218 if (!pbe_params
->pSalt
) {
1221 PORT_Memcpy(pbe_params
->pSalt
, salt
->data
, salt
->len
);
1222 pbe_params
->ulSaltLen
= salt
->len
;
1224 pbe_params
->ulIteration
= (CK_ULONG
)iterations
;
1229 pk11_destroy_ck_pbe_params(pbe_params
);
1231 PORT_ZFree(paramRV
, sizeof(SECItem
));
1236 * public, deprecated.
1239 PK11_DestroyPBEParams(SECItem
*pItem
)
1242 CK_PBE_PARAMS
* params
= (CK_PBE_PARAMS
*)(pItem
->data
);
1244 pk11_destroy_ck_pbe_params(params
);
1245 PORT_ZFree(pItem
, sizeof(SECItem
));
1250 * public, Partially supports PKCS5 V2 (some parameters are not controllable
1251 * through this interface). Use PK11_CreatePBEV2AlgorithmID() if you need
1252 * finer control these.
1255 PK11_CreatePBEAlgorithmID(SECOidTag algorithm
, int iteration
, SECItem
*salt
)
1257 SECAlgorithmID
*algid
= NULL
;
1258 algid
= sec_pkcs5CreateAlgorithmID(algorithm
,
1259 SEC_OID_UNKNOWN
, SEC_OID_UNKNOWN
, NULL
, 0, salt
, iteration
);
1264 * public, fully support pkcs5v2.
1267 PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag
, SECOidTag cipherAlgTag
,
1268 SECOidTag prfAlgTag
, int keyLength
, int iteration
,
1271 SECAlgorithmID
*algid
= NULL
;
1272 algid
= sec_pkcs5CreateAlgorithmID(pbeAlgTag
, cipherAlgTag
, prfAlgTag
,
1273 NULL
, keyLength
, salt
, iteration
);
1281 pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo
*slot
, CK_MECHANISM_TYPE type
,
1282 SECItem
*params
, CK_KEY_TYPE keyType
, int keyLen
,
1283 SECItem
*pwitem
, void *wincx
)
1286 /* do some sanity checks */
1287 if ((params
== NULL
) || (params
->data
== NULL
)) {
1288 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1292 if (type
== CKM_INVALID_MECHANISM
) {
1293 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM
);
1297 /* set the password pointer in the parameters... */
1298 if (type
== CKM_PKCS5_PBKD2
) {
1299 CK_PKCS5_PBKD2_PARAMS
*pbev2_params
;
1300 if (params
->len
< sizeof(CK_PKCS5_PBKD2_PARAMS
)) {
1301 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1304 pbev2_params
= (CK_PKCS5_PBKD2_PARAMS
*)params
->data
;
1305 pbev2_params
->pPassword
= pwitem
->data
;
1306 pwLen
= pwitem
->len
;
1307 pbev2_params
->ulPasswordLen
= &pwLen
;
1309 CK_PBE_PARAMS
*pbe_params
;
1310 if (params
->len
< sizeof(CK_PBE_PARAMS
)) {
1311 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1314 pbe_params
= (CK_PBE_PARAMS
*)params
->data
;
1315 pbe_params
->pPassword
= pwitem
->data
;
1316 pbe_params
->ulPasswordLen
= pwitem
->len
;
1319 /* generate the key (and sometimes the IV as a side effect...) */
1320 return pk11_TokenKeyGenWithFlagsAndKeyType(slot
, type
, params
, keyType
,
1321 keyLen
, NULL
, CKF_SIGN
|CKF_ENCRYPT
|CKF_DECRYPT
|CKF_UNWRAP
|CKF_WRAP
,
1326 * public, deprecated. use PK11_PBEKeyGen instead.
1329 PK11_RawPBEKeyGen(PK11SlotInfo
*slot
, CK_MECHANISM_TYPE type
, SECItem
*mech
,
1330 SECItem
*pwitem
, PRBool faulty3DES
, void *wincx
)
1332 if(faulty3DES
&& (type
== CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC
)) {
1333 type
= CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC
;
1335 return pk11_RawPBEKeyGenWithKeyType(slot
, type
, mech
, -1, 0, pwitem
, wincx
);
1339 * pubic, supports pkcs5 v2.
1341 * Create symkey from a PBE key. The algid can be created with
1342 * PK11_CreatePBEV2AlgorithmID and PK11_CreatePBEAlgorithmID, or by
1343 * extraction of der data.
1346 PK11_PBEKeyGen(PK11SlotInfo
*slot
, SECAlgorithmID
*algid
, SECItem
*pwitem
,
1347 PRBool faulty3DES
, void *wincx
)
1349 CK_MECHANISM_TYPE type
;
1350 SECItem
*param
= NULL
;
1353 CK_KEY_TYPE keyType
= -1;
1356 pbeAlg
= SECOID_GetAlgorithmTag(algid
);
1357 /* if we're using PKCS5v2, extract the additional information we need
1358 * (key length, key type, and pbeAlg). */
1359 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg
)) {
1360 CK_MECHANISM_TYPE cipherMech
;
1361 sec_pkcs5V2Parameter
*pbeV2_param
;
1363 pbeV2_param
= sec_pkcs5_v2_get_v2_param(NULL
, algid
);
1364 if (pbeV2_param
== NULL
) {
1367 cipherMech
= PK11_AlgtagToMechanism(
1368 SECOID_GetAlgorithmTag(&pbeV2_param
->cipherAlgId
));
1369 pbeAlg
= SECOID_GetAlgorithmTag(&pbeV2_param
->pbeAlgId
);
1370 param
= PK11_ParamFromAlgid(&pbeV2_param
->pbeAlgId
);
1371 sec_pkcs5_v2_destroy_v2_param(pbeV2_param
);
1372 keyLen
= SEC_PKCS5GetKeyLength(algid
);
1376 keyType
= PK11_GetKeyType(cipherMech
, keyLen
);
1378 param
= PK11_ParamFromAlgid(algid
);
1384 type
= PK11_AlgtagToMechanism(pbeAlg
);
1385 if (type
== CKM_INVALID_MECHANISM
) {
1386 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM
);
1389 if(faulty3DES
&& (type
== CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC
)) {
1390 type
= CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC
;
1392 symKey
= pk11_RawPBEKeyGenWithKeyType(slot
, type
, param
, keyType
, keyLen
,
1395 SECITEM_ZfreeItem(param
, PR_TRUE
);
1400 * public, supports pkcs5v2
1403 PK11_GetPBEIV(SECAlgorithmID
*algid
, SECItem
*pwitem
)
1405 return SEC_PKCS5GetIV(algid
, pwitem
, PR_FALSE
);
1409 pk11_GetPBECryptoMechanism(SECAlgorithmID
*algid
, SECItem
**param
,
1410 SECItem
*pbe_pwd
, PRBool faulty3DES
)
1413 SECOidTag algTag
= SEC_PKCS5GetCryptoAlgorithm(algid
);
1414 CK_MECHANISM_TYPE mech
= PK11_AlgtagToMechanism(algTag
);
1415 CK_MECHANISM_TYPE returnedMechanism
= CKM_INVALID_MECHANISM
;
1418 if (mech
== CKM_INVALID_MECHANISM
) {
1419 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM
);
1422 if (PK11_GetIVLength(mech
)) {
1423 iv
= SEC_PKCS5GetIV(algid
, pbe_pwd
, faulty3DES
);
1429 keyLen
= SEC_PKCS5GetKeyLength(algid
);
1431 *param
= pk11_ParamFromIVWithLen(mech
, iv
, keyLen
);
1432 if (*param
== NULL
) {
1435 returnedMechanism
= mech
;
1439 SECITEM_FreeItem(iv
,PR_TRUE
);
1441 return returnedMechanism
;
1445 * public, supports pkcs5 v2
1447 * get a the crypto mechanism directly from the pbe algorithmid.
1449 * it's important to go directly from the algorithm id so that we can
1450 * handle both the PKCS #5 v1, PKCS #12, and PKCS #5 v2 cases.
1452 * This function returns both the mechanism an the paramter for the mechanism.
1453 * The caller is responsible for freeing the parameter.
1456 PK11_GetPBECryptoMechanism(SECAlgorithmID
*algid
, SECItem
**param
,
1459 return pk11_GetPBECryptoMechanism(algid
, param
, pbe_pwd
, PR_FALSE
);