2 * PKCS#12 Personal Information Exchange Syntax
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 * The PKCS #12 Personal Information Exchange Syntax Standard v1.1
26 * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
27 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
30 #if !defined(MBEDTLS_CONFIG_FILE)
31 #include "mbedtls/config.h"
33 #include MBEDTLS_CONFIG_FILE
36 #if defined(MBEDTLS_PKCS12_C)
38 #include "mbedtls/pkcs12.h"
39 #include "mbedtls/asn1.h"
40 #include "mbedtls/cipher.h"
41 #include "mbedtls/platform_util.h"
45 #if defined(MBEDTLS_ARC4_C)
46 #include "mbedtls/arc4.h"
49 #if defined(MBEDTLS_DES_C)
50 #include "mbedtls/des.h"
53 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf
*params
,
54 mbedtls_asn1_buf
*salt
, int *iterations
)
57 unsigned char **p
= ¶ms
->p
;
58 const unsigned char *end
= params
->p
+ params
->len
;
61 * pkcs-12PbeParams ::= SEQUENCE {
67 if( params
->tag
!= ( MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) )
68 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+
69 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
71 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &salt
->len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
72 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+ ret
);
77 if( ( ret
= mbedtls_asn1_get_int( p
, end
, iterations
) ) != 0 )
78 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+ ret
);
81 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+
82 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
87 #define PKCS12_MAX_PWDLEN 128
89 static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf
*pbe_params
, mbedtls_md_type_t md_type
,
90 const unsigned char *pwd
, size_t pwdlen
,
91 unsigned char *key
, size_t keylen
,
92 unsigned char *iv
, size_t ivlen
)
94 int ret
, iterations
= 0;
95 mbedtls_asn1_buf salt
;
97 unsigned char unipwd
[PKCS12_MAX_PWDLEN
* 2 + 2];
99 if( pwdlen
> PKCS12_MAX_PWDLEN
)
100 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA
);
102 memset( &salt
, 0, sizeof(mbedtls_asn1_buf
) );
103 memset( &unipwd
, 0, sizeof(unipwd
) );
105 if( ( ret
= pkcs12_parse_pbe_params( pbe_params
, &salt
,
106 &iterations
) ) != 0 )
109 for( i
= 0; i
< pwdlen
; i
++ )
110 unipwd
[i
* 2 + 1] = pwd
[i
];
112 if( ( ret
= mbedtls_pkcs12_derivation( key
, keylen
, unipwd
, pwdlen
* 2 + 2,
113 salt
.p
, salt
.len
, md_type
,
114 MBEDTLS_PKCS12_DERIVE_KEY
, iterations
) ) != 0 )
119 if( iv
== NULL
|| ivlen
== 0 )
122 if( ( ret
= mbedtls_pkcs12_derivation( iv
, ivlen
, unipwd
, pwdlen
* 2 + 2,
123 salt
.p
, salt
.len
, md_type
,
124 MBEDTLS_PKCS12_DERIVE_IV
, iterations
) ) != 0 )
131 #undef PKCS12_MAX_PWDLEN
133 int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf
*pbe_params
, int mode
,
134 const unsigned char *pwd
, size_t pwdlen
,
135 const unsigned char *data
, size_t len
,
136 unsigned char *output
)
138 #if !defined(MBEDTLS_ARC4_C)
146 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE
);
149 unsigned char key
[16];
150 mbedtls_arc4_context ctx
;
153 mbedtls_arc4_init( &ctx
);
155 if( ( ret
= pkcs12_pbe_derive_key_iv( pbe_params
, MBEDTLS_MD_SHA1
,
157 key
, 16, NULL
, 0 ) ) != 0 )
162 mbedtls_arc4_setup( &ctx
, key
, 16 );
163 if( ( ret
= mbedtls_arc4_crypt( &ctx
, len
, data
, output
) ) != 0 )
167 mbedtls_platform_zeroize( key
, sizeof( key
) );
168 mbedtls_arc4_free( &ctx
);
171 #endif /* MBEDTLS_ARC4_C */
174 int mbedtls_pkcs12_pbe( mbedtls_asn1_buf
*pbe_params
, int mode
,
175 mbedtls_cipher_type_t cipher_type
, mbedtls_md_type_t md_type
,
176 const unsigned char *pwd
, size_t pwdlen
,
177 const unsigned char *data
, size_t len
,
178 unsigned char *output
)
181 unsigned char key
[32];
182 unsigned char iv
[16];
183 const mbedtls_cipher_info_t
*cipher_info
;
184 mbedtls_cipher_context_t cipher_ctx
;
187 cipher_info
= mbedtls_cipher_info_from_type( cipher_type
);
188 if( cipher_info
== NULL
)
189 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE
);
191 keylen
= cipher_info
->key_bitlen
/ 8;
193 if( ( ret
= pkcs12_pbe_derive_key_iv( pbe_params
, md_type
, pwd
, pwdlen
,
195 iv
, cipher_info
->iv_size
) ) != 0 )
200 mbedtls_cipher_init( &cipher_ctx
);
202 if( ( ret
= mbedtls_cipher_setup( &cipher_ctx
, cipher_info
) ) != 0 )
205 if( ( ret
= mbedtls_cipher_setkey( &cipher_ctx
, key
, 8 * keylen
, (mbedtls_operation_t
) mode
) ) != 0 )
208 if( ( ret
= mbedtls_cipher_set_iv( &cipher_ctx
, iv
, cipher_info
->iv_size
) ) != 0 )
211 if( ( ret
= mbedtls_cipher_reset( &cipher_ctx
) ) != 0 )
214 if( ( ret
= mbedtls_cipher_update( &cipher_ctx
, data
, len
,
215 output
, &olen
) ) != 0 )
220 if( ( ret
= mbedtls_cipher_finish( &cipher_ctx
, output
+ olen
, &olen
) ) != 0 )
221 ret
= MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH
;
224 mbedtls_platform_zeroize( key
, sizeof( key
) );
225 mbedtls_platform_zeroize( iv
, sizeof( iv
) );
226 mbedtls_cipher_free( &cipher_ctx
);
231 static void pkcs12_fill_buffer( unsigned char *data
, size_t data_len
,
232 const unsigned char *filler
, size_t fill_len
)
234 unsigned char *p
= data
;
237 while( data_len
> 0 )
239 use_len
= ( data_len
> fill_len
) ? fill_len
: data_len
;
240 memcpy( p
, filler
, use_len
);
246 int mbedtls_pkcs12_derivation( unsigned char *data
, size_t datalen
,
247 const unsigned char *pwd
, size_t pwdlen
,
248 const unsigned char *salt
, size_t saltlen
,
249 mbedtls_md_type_t md_type
, int id
, int iterations
)
254 unsigned char diversifier
[128];
255 unsigned char salt_block
[128], pwd_block
[128], hash_block
[128];
256 unsigned char hash_output
[MBEDTLS_MD_MAX_SIZE
];
260 size_t hlen
, use_len
, v
, i
;
262 const mbedtls_md_info_t
*md_info
;
263 mbedtls_md_context_t md_ctx
;
265 // This version only allows max of 64 bytes of password or salt
266 if( datalen
> 128 || pwdlen
> 64 || saltlen
> 64 )
267 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA
);
269 md_info
= mbedtls_md_info_from_type( md_type
);
270 if( md_info
== NULL
)
271 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE
);
273 mbedtls_md_init( &md_ctx
);
275 if( ( ret
= mbedtls_md_setup( &md_ctx
, md_info
, 0 ) ) != 0 )
277 hlen
= mbedtls_md_get_size( md_info
);
284 memset( diversifier
, (unsigned char) id
, v
);
286 pkcs12_fill_buffer( salt_block
, v
, salt
, saltlen
);
287 pkcs12_fill_buffer( pwd_block
, v
, pwd
, pwdlen
);
292 // Calculate hash( diversifier || salt_block || pwd_block )
293 if( ( ret
= mbedtls_md_starts( &md_ctx
) ) != 0 )
296 if( ( ret
= mbedtls_md_update( &md_ctx
, diversifier
, v
) ) != 0 )
299 if( ( ret
= mbedtls_md_update( &md_ctx
, salt_block
, v
) ) != 0 )
302 if( ( ret
= mbedtls_md_update( &md_ctx
, pwd_block
, v
) ) != 0 )
305 if( ( ret
= mbedtls_md_finish( &md_ctx
, hash_output
) ) != 0 )
308 // Perform remaining ( iterations - 1 ) recursive hash calculations
309 for( i
= 1; i
< (size_t) iterations
; i
++ )
311 if( ( ret
= mbedtls_md( md_info
, hash_output
, hlen
, hash_output
) ) != 0 )
315 use_len
= ( datalen
> hlen
) ? hlen
: datalen
;
316 memcpy( p
, hash_output
, use_len
);
323 // Concatenating copies of hash_output into hash_block (B)
324 pkcs12_fill_buffer( hash_block
, v
, hash_output
, hlen
);
327 for( i
= v
; i
> 0; i
-- )
328 if( ++hash_block
[i
- 1] != 0 )
333 for( i
= v
; i
> 0; i
-- )
335 j
= salt_block
[i
- 1] + hash_block
[i
- 1] + c
;
336 c
= (unsigned char) (j
>> 8);
337 salt_block
[i
- 1] = j
& 0xFF;
342 for( i
= v
; i
> 0; i
-- )
344 j
= pwd_block
[i
- 1] + hash_block
[i
- 1] + c
;
345 c
= (unsigned char) (j
>> 8);
346 pwd_block
[i
- 1] = j
& 0xFF;
353 mbedtls_platform_zeroize( salt_block
, sizeof( salt_block
) );
354 mbedtls_platform_zeroize( pwd_block
, sizeof( pwd_block
) );
355 mbedtls_platform_zeroize( hash_block
, sizeof( hash_block
) );
356 mbedtls_platform_zeroize( hash_output
, sizeof( hash_output
) );
358 mbedtls_md_free( &md_ctx
);
363 #endif /* MBEDTLS_PKCS12_C */