PolarSSL v1.3.8
pkcs5.c
Go to the documentation of this file.
1 
29 /*
30  * PKCS#5 includes PBKDF2 and more
31  *
32  * http://tools.ietf.org/html/rfc2898 (Specification)
33  * http://tools.ietf.org/html/rfc6070 (Test vectors)
34  */
35 
36 #if !defined(POLARSSL_CONFIG_FILE)
37 #include "polarssl/config.h"
38 #else
39 #include POLARSSL_CONFIG_FILE
40 #endif
41 
42 #if defined(POLARSSL_PKCS5_C)
43 
44 #include "polarssl/pkcs5.h"
45 #include "polarssl/asn1.h"
46 #include "polarssl/cipher.h"
47 #include "polarssl/oid.h"
48 
49 #if defined(POLARSSL_PLATFORM_C)
50 #include "polarssl/platform.h"
51 #else
52 #define polarssl_printf printf
53 #endif
54 
55 static int pkcs5_parse_pbkdf2_params( const asn1_buf *params,
56  asn1_buf *salt, int *iterations,
57  int *keylen, md_type_t *md_type )
58 {
59  int ret;
60  asn1_buf prf_alg_oid;
61  unsigned char *p = params->p;
62  const unsigned char *end = params->p + params->len;
63 
64  if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
67  /*
68  * PBKDF2-params ::= SEQUENCE {
69  * salt OCTET STRING,
70  * iterationCount INTEGER,
71  * keyLength INTEGER OPTIONAL
72  * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
73  * }
74  *
75  */
76  if( ( ret = asn1_get_tag( &p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
77  return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
78 
79  salt->p = p;
80  p += salt->len;
81 
82  if( ( ret = asn1_get_int( &p, end, iterations ) ) != 0 )
83  return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
84 
85  if( p == end )
86  return( 0 );
87 
88  if( ( ret = asn1_get_int( &p, end, keylen ) ) != 0 )
89  {
91  return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
92  }
93 
94  if( p == end )
95  return( 0 );
96 
97  if( ( ret = asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
98  return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
99 
100  if( !OID_CMP( OID_HMAC_SHA1, &prf_alg_oid ) )
102 
103  *md_type = POLARSSL_MD_SHA1;
104 
105  if( p != end )
108 
109  return( 0 );
110 }
111 
112 int pkcs5_pbes2( asn1_buf *pbe_params, int mode,
113  const unsigned char *pwd, size_t pwdlen,
114  const unsigned char *data, size_t datalen,
115  unsigned char *output )
116 {
117  int ret, iterations = 0, keylen = 0;
118  unsigned char *p, *end;
119  asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
120  asn1_buf salt;
121  md_type_t md_type = POLARSSL_MD_SHA1;
122  unsigned char key[32], iv[32];
123  size_t olen = 0;
124  const md_info_t *md_info;
125  const cipher_info_t *cipher_info;
126  md_context_t md_ctx;
127  cipher_type_t cipher_alg;
128  cipher_context_t cipher_ctx;
129 
130  p = pbe_params->p;
131  end = p + pbe_params->len;
132 
133  /*
134  * PBES2-params ::= SEQUENCE {
135  * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
136  * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
137  * }
138  */
139  if( pbe_params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
142 
143  if( ( ret = asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
144  return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
145 
146  // Only PBKDF2 supported at the moment
147  //
148  if( !OID_CMP( OID_PKCS5_PBKDF2, &kdf_alg_oid ) )
150 
151  if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params,
152  &salt, &iterations, &keylen,
153  &md_type ) ) != 0 )
154  {
155  return( ret );
156  }
157 
158  md_info = md_info_from_type( md_type );
159  if( md_info == NULL )
161 
162  if( ( ret = asn1_get_alg( &p, end, &enc_scheme_oid,
163  &enc_scheme_params ) ) != 0 )
164  {
165  return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
166  }
167 
168  if( oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
170 
171  cipher_info = cipher_info_from_type( cipher_alg );
172  if( cipher_info == NULL )
174 
175  /*
176  * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
177  * since it is optional and we don't know if it was set or not
178  */
179  keylen = cipher_info->key_length / 8;
180 
181  if( enc_scheme_params.tag != ASN1_OCTET_STRING ||
182  enc_scheme_params.len != cipher_info->iv_size )
183  {
185  }
186 
187  md_init( &md_ctx );
188  cipher_init( &cipher_ctx );
189 
190  memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
191 
192  if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
193  goto exit;
194 
195  if( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
196  iterations, keylen, key ) ) != 0 )
197  {
198  goto exit;
199  }
200 
201  if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 )
202  goto exit;
203 
204  if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 )
205  goto exit;
206 
207  if( ( ret = cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
208  data, datalen, output, &olen ) ) != 0 )
210 
211 exit:
212  md_free( &md_ctx );
213  cipher_free( &cipher_ctx );
214 
215  return( ret );
216 }
217 
218 int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password,
219  size_t plen, const unsigned char *salt, size_t slen,
220  unsigned int iteration_count,
221  uint32_t key_length, unsigned char *output )
222 {
223  int ret, j;
224  unsigned int i;
225  unsigned char md1[POLARSSL_MD_MAX_SIZE];
226  unsigned char work[POLARSSL_MD_MAX_SIZE];
227  unsigned char md_size = md_get_size( ctx->md_info );
228  size_t use_len;
229  unsigned char *out_p = output;
230  unsigned char counter[4];
231 
232  memset( counter, 0, 4 );
233  counter[3] = 1;
234 
235  if( iteration_count > 0xFFFFFFFF )
237 
238  while( key_length )
239  {
240  // U1 ends up in work
241  //
242  if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 )
243  return( ret );
244 
245  if( ( ret = md_hmac_update( ctx, salt, slen ) ) != 0 )
246  return( ret );
247 
248  if( ( ret = md_hmac_update( ctx, counter, 4 ) ) != 0 )
249  return( ret );
250 
251  if( ( ret = md_hmac_finish( ctx, work ) ) != 0 )
252  return( ret );
253 
254  memcpy( md1, work, md_size );
255 
256  for( i = 1; i < iteration_count; i++ )
257  {
258  // U2 ends up in md1
259  //
260  if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 )
261  return( ret );
262 
263  if( ( ret = md_hmac_update( ctx, md1, md_size ) ) != 0 )
264  return( ret );
265 
266  if( ( ret = md_hmac_finish( ctx, md1 ) ) != 0 )
267  return( ret );
268 
269  // U1 xor U2
270  //
271  for( j = 0; j < md_size; j++ )
272  work[j] ^= md1[j];
273  }
274 
275  use_len = ( key_length < md_size ) ? key_length : md_size;
276  memcpy( out_p, work, use_len );
277 
278  key_length -= (uint32_t) use_len;
279  out_p += use_len;
280 
281  for( i = 4; i > 0; i-- )
282  if( ++counter[i - 1] != 0 )
283  break;
284  }
285 
286  return( 0 );
287 }
288 
289 #if defined(POLARSSL_SELF_TEST)
290 
291 #if !defined(POLARSSL_SHA1_C)
292 int pkcs5_self_test( int verbose )
293 {
294  if( verbose != 0 )
295  polarssl_printf( " PBKDF2 (SHA1): skipped\n\n" );
296 
297  return( 0 );
298 }
299 #else
300 
301 #include <stdio.h>
302 
303 #define MAX_TESTS 6
304 
305 size_t plen[MAX_TESTS] =
306  { 8, 8, 8, 8, 24, 9 };
307 
308 unsigned char password[MAX_TESTS][32] =
309 {
310  "password",
311  "password",
312  "password",
313  "password",
314  "passwordPASSWORDpassword",
315  "pass\0word",
316 };
317 
318 size_t slen[MAX_TESTS] =
319  { 4, 4, 4, 4, 36, 5 };
320 
321 unsigned char salt[MAX_TESTS][40] =
322 {
323  "salt",
324  "salt",
325  "salt",
326  "salt",
327  "saltSALTsaltSALTsaltSALTsaltSALTsalt",
328  "sa\0lt",
329 };
330 
331 uint32_t it_cnt[MAX_TESTS] =
332  { 1, 2, 4096, 16777216, 4096, 4096 };
333 
334 uint32_t key_len[MAX_TESTS] =
335  { 20, 20, 20, 20, 25, 16 };
336 
337 
338 unsigned char result_key[MAX_TESTS][32] =
339 {
340  { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
341  0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
342  0x2f, 0xe0, 0x37, 0xa6 },
343  { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
344  0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
345  0xd8, 0xde, 0x89, 0x57 },
346  { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
347  0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
348  0x65, 0xa4, 0x29, 0xc1 },
349  { 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
350  0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
351  0x26, 0x34, 0xe9, 0x84 },
352  { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
353  0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
354  0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
355  0x38 },
356  { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
357  0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
358 };
359 
360 int pkcs5_self_test( int verbose )
361 {
362  md_context_t sha1_ctx;
363  const md_info_t *info_sha1;
364  int ret, i;
365  unsigned char key[64];
366 
367  md_init( &sha1_ctx );
368 
369  info_sha1 = md_info_from_type( POLARSSL_MD_SHA1 );
370  if( info_sha1 == NULL )
371  {
372  ret = 1;
373  goto exit;
374  }
375 
376  if( ( ret = md_init_ctx( &sha1_ctx, info_sha1 ) ) != 0 )
377  {
378  ret = 1;
379  goto exit;
380  }
381 
382  if( verbose != 0 )
383  polarssl_printf( " PBKDF2 note: test #3 may be slow!\n" );
384 
385  for( i = 0; i < MAX_TESTS; i++ )
386  {
387  if( verbose != 0 )
388  polarssl_printf( " PBKDF2 (SHA1) #%d: ", i );
389 
390  ret = pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
391  slen[i], it_cnt[i], key_len[i], key );
392  if( ret != 0 ||
393  memcmp( result_key[i], key, key_len[i] ) != 0 )
394  {
395  if( verbose != 0 )
396  polarssl_printf( "failed\n" );
397 
398  ret = 1;
399  goto exit;
400  }
401 
402  if( verbose != 0 )
403  polarssl_printf( "passed\n" );
404  }
405 
406  polarssl_printf( "\n" );
407 
408 exit:
409  md_free( &sha1_ctx );
410 
411  return( 0 );
412 }
413 #endif /* POLARSSL_SHA1_C */
414 
415 #endif /* POLARSSL_SELF_TEST */
416 
417 #endif /* POLARSSL_PKCS5_C */