blob: 39ab10fa9538b3ea17b094563f61ca74183d5fe6 [file] [log] [blame]
Paul Bakkerf1f21fe2013-06-24 19:17:19 +02001/*
2 * PKCS#12 Personal Information Exchange Syntax
3 *
4 * Copyright (C) 2006-2013, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The PKCS #12 Personal Information Exchange Syntax Standard v1.1
27 *
28 * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
29 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
30 */
31
32#include "polarssl/config.h"
33
34#if defined(POLARSSL_PKCS12_C)
35
36#include "polarssl/pkcs12.h"
37#include "polarssl/asn1.h"
38
39#if defined(POLARSSL_ARC4_C)
40#include "polarssl/arc4.h"
41#endif
42
43#if defined(POLARSSL_DES_C)
44#include "polarssl/des.h"
45#endif
46
47static int pkcs12_parse_pbe_params( unsigned char **p,
48 const unsigned char *end,
49 asn1_buf *salt, int *iterations )
50{
51 int ret;
52 size_t len = 0;
53
54 /*
55 * pkcs-12PbeParams ::= SEQUENCE {
56 * salt OCTET STRING,
57 * iterations INTEGER
58 * }
59 *
60 */
61 if( ( ret = asn1_get_tag( p, end, &len,
62 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
63 {
64 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
65 }
66
67 end = *p + len;
68
69 if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
70 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
71
72 salt->p = *p;
73 *p += salt->len;
74
75 if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 )
76 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
77
78 if( *p != end )
79 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT +
80 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
81
82 return( 0 );
83}
84
85static int pkcs12_pbe_derive_key_iv( asn1_buf *pbe_params,
86 const unsigned char *pwd, size_t pwdlen,
87 unsigned char *key, size_t keylen,
88 unsigned char *iv, size_t ivlen )
89{
90 int ret, iterations;
91 asn1_buf salt;
92 size_t i;
93 unsigned char *p, *end;
94 unsigned char unipwd[258];
95
96 memset(&salt, 0, sizeof(asn1_buf));
97 memset(&unipwd, 0, sizeof(unipwd));
98
99 p = pbe_params->p;
100 end = p + pbe_params->len;
101
102 if( ( ret = pkcs12_parse_pbe_params( &p, end, &salt, &iterations ) ) != 0 )
103 return( ret );
104
105 for(i = 0; i < pwdlen; i++)
106 unipwd[i * 2 + 1] = pwd[i];
107
108 if( ( ret = pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2,
109 salt.p, salt.len, POLARSSL_MD_SHA1,
110 PKCS12_DERIVE_KEY, iterations ) ) != 0 )
111 {
112 return( ret );
113 }
114
115 if( iv == NULL || ivlen == 0 )
116 return( 0 );
117
118 if( ( ret = pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2,
119 salt.p, salt.len, POLARSSL_MD_SHA1,
120 PKCS12_DERIVE_IV, iterations ) ) != 0 )
121 {
122 return( ret );
123 }
124 return( 0 );
125}
126
127int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode,
128 const unsigned char *pwd, size_t pwdlen,
129 const unsigned char *data, size_t len,
130 unsigned char *output )
131{
132#if !defined(POLARSSL_ARC4_C)
133 ((void) pbe_params);
134 ((void) mode);
135 ((void) pwd);
136 ((void) pwdlen);
137 ((void) data);
138 ((void) len);
139 ((void) output);
140 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
141#else
142 int ret;
143 unsigned char key[16];
144 arc4_context ctx;
145 ((void) mode);
146
147 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, pwd, pwdlen,
148 key, 16, NULL, 0 ) ) != 0 )
149 {
150 return( ret );
151 }
152
153 arc4_setup( &ctx, key, 16 );
154 if( ( ret = arc4_crypt( &ctx, len, data, output ) ) != 0 )
155 return( ret );
156
157 return( 0 );
158}
159#endif /* POLARSSL_ARC4_C */
160
161int pkcs12_pbe_sha1_des2_ede_cbc( asn1_buf *pbe_params, int mode,
162 const unsigned char *pwd, size_t pwdlen,
163 const unsigned char *data, size_t len,
164 unsigned char *output )
165{
166#if !defined(POLARSSL_DES_C)
167 ((void) pbe_params);
168 ((void) mode);
169 ((void) pwd);
170 ((void) pwdlen);
171 ((void) data);
172 ((void) len);
173 ((void) output);
174 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
175#else
176 int ret;
177 unsigned char key[16];
178 unsigned char iv[8];
179 des3_context ctx;
180
181 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, pwd, pwdlen,
182 key, 16, iv, 8 ) ) != 0 )
183 {
184 return( ret );
185 }
186
187 if( mode == PKCS12_PBE_ENCRYPT )
188 {
189 des3_set2key_enc( &ctx, key );
190 des3_crypt_cbc( &ctx, DES_ENCRYPT, len, iv, data, output );
191 }
192 else
193 {
194 des3_set2key_dec( &ctx, key );
195 des3_crypt_cbc( &ctx, DES_DECRYPT, len, iv, data, output );
196 }
197
198 return( 0 );
199}
200#endif /* POLARSSL_DES_C */
201
202int pkcs12_pbe_sha1_des3_ede_cbc( asn1_buf *pbe_params, int mode,
203 const unsigned char *pwd, size_t pwdlen,
204 const unsigned char *data, size_t len,
205 unsigned char *output )
206{
207#if !defined(POLARSSL_DES_C)
208 ((void) pbe_params);
209 ((void) mode);
210 ((void) pwd);
211 ((void) pwdlen);
212 ((void) data);
213 ((void) len);
214 ((void) output);
215 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
216#else
217 int ret;
218 unsigned char key[24];
219 unsigned char iv[8];
220 des3_context ctx;
221
222 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, pwd, pwdlen,
223 key, 24, iv, 8 ) ) != 0 )
224 {
225 return( ret );
226 }
227
228 if( mode == PKCS12_PBE_ENCRYPT )
229 {
230 des3_set3key_enc( &ctx, key );
231 des3_crypt_cbc( &ctx, DES_ENCRYPT, len, iv, data, output );
232 }
233 else
234 {
235 des3_set3key_dec( &ctx, key );
236 des3_crypt_cbc( &ctx, DES_DECRYPT, len, iv, data, output );
237 }
238
239 return( 0 );
240}
241#endif /* POLARSSL_DES_C */
242
243static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
244 const unsigned char *filler, size_t fill_len )
245{
246 unsigned char *p = data;
247 size_t use_len;
248
249 while( data_len > 0 )
250 {
251 use_len = ( data_len > fill_len ) ? fill_len : data_len;
252 memcpy( p, filler, use_len );
253 p += use_len;
254 data_len -= use_len;
255 }
256}
257
258int pkcs12_derivation( unsigned char *data, size_t datalen,
259 const unsigned char *pwd, size_t pwdlen,
260 const unsigned char *salt, size_t saltlen,
261 md_type_t md_type, int id, int iterations )
262{
263 int ret, i;
264 unsigned int j;
265
266 unsigned char diversifier[128];
267 unsigned char salt_block[128], pwd_block[128], hash_block[128];
268 unsigned char hash_output[POLARSSL_MD_MAX_SIZE];
269 unsigned char *p;
270 unsigned char c;
271
272 size_t hlen, use_len, v;
273
274 const md_info_t *md_info;
275 md_context_t md_ctx;
276
277 // This version only allows max of 64 bytes of password or salt
278 if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
279 return( POLARSSL_ERR_PKCS12_BAD_INPUT_DATA );
280
281 md_info = md_info_from_type( md_type );
282 if( md_info == NULL )
283 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
284
285 if ( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
286 return( ret );
287 hlen = md_get_size( md_info );
288
289 if( hlen <= 32 )
290 v = 64;
291 else
292 v = 128;
293
294 memset( diversifier, (unsigned char) id, v );
295
296 pkcs12_fill_buffer( salt_block, v, salt, saltlen );
297 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen );
298
299 p = data;
300 while( datalen > 0 )
301 {
302 // Calculate hash( diversifier || salt_block || pwd_block )
303 if( ( ret = md_starts( &md_ctx ) ) != 0 )
304 return( ret );
305
306 if( ( ret = md_update( &md_ctx, diversifier, v ) ) != 0 )
307 return( ret );
308
309 if( ( ret = md_update( &md_ctx, salt_block, v ) ) != 0 )
310 return( ret );
311
312 if( ( ret = md_update( &md_ctx, pwd_block, v ) ) != 0 )
313 return( ret );
314
315 if( ( ret = md_finish( &md_ctx, hash_output ) ) != 0 )
316 return( ret );
317
318 // Perform remaining ( iterations - 1 ) recursive hash calculations
319 for( i = 1; i < iterations; i++ )
320 {
321 if( ( ret = md( md_info, hash_output, hlen, hash_output ) ) != 0 )
322 return( ret );
323 }
324
325 use_len = ( datalen > hlen ) ? hlen : datalen;
326 memcpy( p, hash_output, use_len );
327 datalen -= use_len;
328 p += use_len;
329
330 if( datalen == 0 )
331 break;
332
333 // Concatenating copies of hash_output into hash_block (B)
334 pkcs12_fill_buffer( hash_block, v, hash_output, hlen );
335
336 // B += 1
337 for( i = v; i > 0; i-- )
338 if( ++hash_block[i - 1] != 0 )
339 break;
340
341 // salt_block += B
342 c = 0;
343 for( i = v; i > 0; i-- )
344 {
345 j = salt_block[i - 1] + hash_block[i - 1] + c;
346 c = (unsigned char) (j >> 8);
347 salt_block[i - 1] = j & 0xFF;
348 }
349
350 // pwd_block += B
351 c = 0;
352 for( i = v; i > 0; i-- )
353 {
354 j = pwd_block[i - 1] + hash_block[i - 1] + c;
355 c = (unsigned char) (j >> 8);
356 pwd_block[i - 1] = j & 0xFF;
357 }
358 }
359
360 return( 0 );
361}
362
363#endif /* POLARSSL_PKCS12_C */