2 * PKCS#12 Personal Information Exchange Syntax
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
17 * http://www.apache.org/licenses/LICENSE-2.0
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
28 * GNU General Public License v2.0 or later:
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
47 * The PKCS #12 Personal Information Exchange Syntax Standard v1.1
49 * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
50 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
53 #if !defined(MBEDTLS_CONFIG_FILE)
54 #include "mbedtls/config.h"
56 #include MBEDTLS_CONFIG_FILE
59 #if defined(MBEDTLS_PKCS12_C)
61 #include "mbedtls/pkcs12.h"
62 #include "mbedtls/asn1.h"
63 #include "mbedtls/cipher.h"
64 #include "mbedtls/platform_util.h"
68 #if defined(MBEDTLS_ARC4_C)
69 #include "mbedtls/arc4.h"
72 #if defined(MBEDTLS_DES_C)
73 #include "mbedtls/des.h"
76 #if defined(MBEDTLS_ASN1_PARSE_C)
78 static int pkcs12_parse_pbe_params( mbedtls_asn1_buf
*params
,
79 mbedtls_asn1_buf
*salt
, int *iterations
)
82 unsigned char **p
= ¶ms
->p
;
83 const unsigned char *end
= params
->p
+ params
->len
;
86 * pkcs-12PbeParams ::= SEQUENCE {
92 if( params
->tag
!= ( MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) )
93 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+
94 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
96 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &salt
->len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
97 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+ ret
);
102 if( ( ret
= mbedtls_asn1_get_int( p
, end
, iterations
) ) != 0 )
103 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+ ret
);
106 return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+
107 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
112 #define PKCS12_MAX_PWDLEN 128
114 static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf
*pbe_params
, mbedtls_md_type_t md_type
,
115 const unsigned char *pwd
, size_t pwdlen
,
116 unsigned char *key
, size_t keylen
,
117 unsigned char *iv
, size_t ivlen
)
119 int ret
, iterations
= 0;
120 mbedtls_asn1_buf salt
;
122 unsigned char unipwd
[PKCS12_MAX_PWDLEN
* 2 + 2];
124 if( pwdlen
> PKCS12_MAX_PWDLEN
)
125 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA
);
127 memset( &salt
, 0, sizeof(mbedtls_asn1_buf
) );
128 memset( &unipwd
, 0, sizeof(unipwd
) );
130 if( ( ret
= pkcs12_parse_pbe_params( pbe_params
, &salt
,
131 &iterations
) ) != 0 )
134 for( i
= 0; i
< pwdlen
; i
++ )
135 unipwd
[i
* 2 + 1] = pwd
[i
];
137 if( ( ret
= mbedtls_pkcs12_derivation( key
, keylen
, unipwd
, pwdlen
* 2 + 2,
138 salt
.p
, salt
.len
, md_type
,
139 MBEDTLS_PKCS12_DERIVE_KEY
, iterations
) ) != 0 )
144 if( iv
== NULL
|| ivlen
== 0 )
147 if( ( ret
= mbedtls_pkcs12_derivation( iv
, ivlen
, unipwd
, pwdlen
* 2 + 2,
148 salt
.p
, salt
.len
, md_type
,
149 MBEDTLS_PKCS12_DERIVE_IV
, iterations
) ) != 0 )
156 #undef PKCS12_MAX_PWDLEN
158 int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf
*pbe_params
, int mode
,
159 const unsigned char *pwd
, size_t pwdlen
,
160 const unsigned char *data
, size_t len
,
161 unsigned char *output
)
163 #if !defined(MBEDTLS_ARC4_C)
171 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE
);
174 unsigned char key
[16];
175 mbedtls_arc4_context ctx
;
178 mbedtls_arc4_init( &ctx
);
180 if( ( ret
= pkcs12_pbe_derive_key_iv( pbe_params
, MBEDTLS_MD_SHA1
,
182 key
, 16, NULL
, 0 ) ) != 0 )
187 mbedtls_arc4_setup( &ctx
, key
, 16 );
188 if( ( ret
= mbedtls_arc4_crypt( &ctx
, len
, data
, output
) ) != 0 )
192 mbedtls_platform_zeroize( key
, sizeof( key
) );
193 mbedtls_arc4_free( &ctx
);
196 #endif /* MBEDTLS_ARC4_C */
199 int mbedtls_pkcs12_pbe( mbedtls_asn1_buf
*pbe_params
, int mode
,
200 mbedtls_cipher_type_t cipher_type
, mbedtls_md_type_t md_type
,
201 const unsigned char *pwd
, size_t pwdlen
,
202 const unsigned char *data
, size_t len
,
203 unsigned char *output
)
206 unsigned char key
[32];
207 unsigned char iv
[16];
208 const mbedtls_cipher_info_t
*cipher_info
;
209 mbedtls_cipher_context_t cipher_ctx
;
212 cipher_info
= mbedtls_cipher_info_from_type( cipher_type
);
213 if( cipher_info
== NULL
)
214 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE
);
216 keylen
= cipher_info
->key_bitlen
/ 8;
218 if( ( ret
= pkcs12_pbe_derive_key_iv( pbe_params
, md_type
, pwd
, pwdlen
,
220 iv
, cipher_info
->iv_size
) ) != 0 )
225 mbedtls_cipher_init( &cipher_ctx
);
227 if( ( ret
= mbedtls_cipher_setup( &cipher_ctx
, cipher_info
) ) != 0 )
230 if( ( ret
= mbedtls_cipher_setkey( &cipher_ctx
, key
, 8 * keylen
, (mbedtls_operation_t
) mode
) ) != 0 )
233 if( ( ret
= mbedtls_cipher_set_iv( &cipher_ctx
, iv
, cipher_info
->iv_size
) ) != 0 )
236 if( ( ret
= mbedtls_cipher_reset( &cipher_ctx
) ) != 0 )
239 if( ( ret
= mbedtls_cipher_update( &cipher_ctx
, data
, len
,
240 output
, &olen
) ) != 0 )
245 if( ( ret
= mbedtls_cipher_finish( &cipher_ctx
, output
+ olen
, &olen
) ) != 0 )
246 ret
= MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH
;
249 mbedtls_platform_zeroize( key
, sizeof( key
) );
250 mbedtls_platform_zeroize( iv
, sizeof( iv
) );
251 mbedtls_cipher_free( &cipher_ctx
);
256 #endif /* MBEDTLS_ASN1_PARSE_C */
258 static void pkcs12_fill_buffer( unsigned char *data
, size_t data_len
,
259 const unsigned char *filler
, size_t fill_len
)
261 unsigned char *p
= data
;
264 while( data_len
> 0 )
266 use_len
= ( data_len
> fill_len
) ? fill_len
: data_len
;
267 memcpy( p
, filler
, use_len
);
273 int mbedtls_pkcs12_derivation( unsigned char *data
, size_t datalen
,
274 const unsigned char *pwd
, size_t pwdlen
,
275 const unsigned char *salt
, size_t saltlen
,
276 mbedtls_md_type_t md_type
, int id
, int iterations
)
281 unsigned char diversifier
[128];
282 unsigned char salt_block
[128], pwd_block
[128], hash_block
[128];
283 unsigned char hash_output
[MBEDTLS_MD_MAX_SIZE
];
287 size_t hlen
, use_len
, v
, i
;
289 const mbedtls_md_info_t
*md_info
;
290 mbedtls_md_context_t md_ctx
;
292 // This version only allows max of 64 bytes of password or salt
293 if( datalen
> 128 || pwdlen
> 64 || saltlen
> 64 )
294 return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA
);
296 md_info
= mbedtls_md_info_from_type( md_type
);
297 if( md_info
== NULL
)
298 return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE
);
300 mbedtls_md_init( &md_ctx
);
302 if( ( ret
= mbedtls_md_setup( &md_ctx
, md_info
, 0 ) ) != 0 )
304 hlen
= mbedtls_md_get_size( md_info
);
311 memset( diversifier
, (unsigned char) id
, v
);
313 pkcs12_fill_buffer( salt_block
, v
, salt
, saltlen
);
314 pkcs12_fill_buffer( pwd_block
, v
, pwd
, pwdlen
);
319 // Calculate hash( diversifier || salt_block || pwd_block )
320 if( ( ret
= mbedtls_md_starts( &md_ctx
) ) != 0 )
323 if( ( ret
= mbedtls_md_update( &md_ctx
, diversifier
, v
) ) != 0 )
326 if( ( ret
= mbedtls_md_update( &md_ctx
, salt_block
, v
) ) != 0 )
329 if( ( ret
= mbedtls_md_update( &md_ctx
, pwd_block
, v
) ) != 0 )
332 if( ( ret
= mbedtls_md_finish( &md_ctx
, hash_output
) ) != 0 )
335 // Perform remaining ( iterations - 1 ) recursive hash calculations
336 for( i
= 1; i
< (size_t) iterations
; i
++ )
338 if( ( ret
= mbedtls_md( md_info
, hash_output
, hlen
, hash_output
) ) != 0 )
342 use_len
= ( datalen
> hlen
) ? hlen
: datalen
;
343 memcpy( p
, hash_output
, use_len
);
350 // Concatenating copies of hash_output into hash_block (B)
351 pkcs12_fill_buffer( hash_block
, v
, hash_output
, hlen
);
354 for( i
= v
; i
> 0; i
-- )
355 if( ++hash_block
[i
- 1] != 0 )
360 for( i
= v
; i
> 0; i
-- )
362 j
= salt_block
[i
- 1] + hash_block
[i
- 1] + c
;
363 c
= (unsigned char) (j
>> 8);
364 salt_block
[i
- 1] = j
& 0xFF;
369 for( i
= v
; i
> 0; i
-- )
371 j
= pwd_block
[i
- 1] + hash_block
[i
- 1] + c
;
372 c
= (unsigned char) (j
>> 8);
373 pwd_block
[i
- 1] = j
& 0xFF;
380 mbedtls_platform_zeroize( salt_block
, sizeof( salt_block
) );
381 mbedtls_platform_zeroize( pwd_block
, sizeof( pwd_block
) );
382 mbedtls_platform_zeroize( hash_block
, sizeof( hash_block
) );
383 mbedtls_platform_zeroize( hash_output
, sizeof( hash_output
) );
385 mbedtls_md_free( &md_ctx
);
390 #endif /* MBEDTLS_PKCS12_C */