00001
00029
00030
00031
00032
00033
00034
00035
00036 #include "polarssl/config.h"
00037
00038 #if defined(POLARSSL_PKCS5_C)
00039
00040 #include "polarssl/pkcs5.h"
00041 #include "polarssl/asn1.h"
00042 #include "polarssl/cipher.h"
00043 #include "polarssl/oid.h"
00044
00045 static int pkcs5_parse_pbkdf2_params( asn1_buf *params,
00046 asn1_buf *salt, int *iterations,
00047 int *keylen, md_type_t *md_type )
00048 {
00049 int ret;
00050 asn1_buf prf_alg_oid;
00051 unsigned char **p = ¶ms->p;
00052 const unsigned char *end = params->p + params->len;
00053
00054 if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
00055 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT +
00056 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
00067 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
00068
00069 salt->p = *p;
00070 *p += salt->len;
00071
00072 if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 )
00073 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
00074
00075 if( *p == end )
00076 return( 0 );
00077
00078 if( ( ret = asn1_get_int( p, end, keylen ) ) != 0 )
00079 {
00080 if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00081 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
00082 }
00083
00084 if( *p == end )
00085 return( 0 );
00086
00087 if( ( ret = asn1_get_alg_null( p, end, &prf_alg_oid ) ) != 0 )
00088 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
00089
00090 if( !OID_CMP( OID_HMAC_SHA1, &prf_alg_oid ) )
00091 return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
00092
00093 *md_type = POLARSSL_MD_SHA1;
00094
00095 if( *p != end )
00096 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT +
00097 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00098
00099 return( 0 );
00100 }
00101
00102 int pkcs5_pbes2( asn1_buf *pbe_params, int mode,
00103 const unsigned char *pwd, size_t pwdlen,
00104 const unsigned char *data, size_t datalen,
00105 unsigned char *output )
00106 {
00107 int ret, iterations = 0, keylen = 0;
00108 unsigned char *p, *end;
00109 asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
00110 asn1_buf salt;
00111 md_type_t md_type = POLARSSL_MD_SHA1;
00112 unsigned char key[32], iv[32];
00113 size_t olen = 0;
00114 const md_info_t *md_info;
00115 const cipher_info_t *cipher_info;
00116 md_context_t md_ctx;
00117 cipher_type_t cipher_alg;
00118 cipher_context_t cipher_ctx;
00119
00120 p = pbe_params->p;
00121 end = p + pbe_params->len;
00122
00123 memset( &md_ctx, 0, sizeof(md_context_t) );
00124 memset( &cipher_ctx, 0, sizeof(cipher_context_t) );
00125
00126
00127
00128
00129
00130
00131
00132 if( pbe_params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
00133 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT +
00134 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00135
00136 if( ( ret = asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
00137 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
00138
00139
00140
00141 if( !OID_CMP( OID_PKCS5_PBKDF2, &kdf_alg_oid ) )
00142 return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
00143
00144 if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params,
00145 &salt, &iterations, &keylen,
00146 &md_type ) ) != 0 )
00147 {
00148 return( ret );
00149 }
00150
00151 md_info = md_info_from_type( md_type );
00152 if( md_info == NULL )
00153 return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
00154
00155 if( ( ret = asn1_get_alg( &p, end, &enc_scheme_oid, &enc_scheme_params ) ) != 0 )
00156 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
00157
00158 if ( oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
00159 return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
00160
00161 cipher_info = cipher_info_from_type( cipher_alg );
00162 if( cipher_info == NULL )
00163 return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );
00164
00165 keylen = cipher_info->key_length / 8;
00166
00167 if( enc_scheme_params.tag != ASN1_OCTET_STRING ||
00168 enc_scheme_params.len != cipher_info->iv_size )
00169 {
00170 return( POLARSSL_ERR_PKCS5_INVALID_FORMAT );
00171 }
00172
00173 memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
00174
00175 if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
00176 goto exit;
00177
00178 if ( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
00179 iterations, keylen, key ) ) != 0 )
00180 {
00181 goto exit;
00182 }
00183
00184 if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 )
00185 goto exit;
00186
00187 if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 )
00188 goto exit;
00189
00190 if( ( ret = cipher_set_iv( &cipher_ctx, iv, enc_scheme_params.len ) ) != 0 )
00191 goto exit;
00192
00193 if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 )
00194 goto exit;
00195
00196 if( ( ret = cipher_update( &cipher_ctx, data, datalen,
00197 output, &olen ) ) != 0 )
00198 {
00199 goto exit;
00200 }
00201
00202 if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
00203 ret = POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH;
00204
00205 exit:
00206 md_free_ctx( &md_ctx );
00207 cipher_free_ctx( &cipher_ctx );
00208
00209 return( ret );
00210 }
00211
00212 int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password,
00213 size_t plen, const unsigned char *salt, size_t slen,
00214 unsigned int iteration_count,
00215 uint32_t key_length, unsigned char *output )
00216 {
00217 int ret, j;
00218 unsigned int i;
00219 unsigned char md1[POLARSSL_MD_MAX_SIZE];
00220 unsigned char work[POLARSSL_MD_MAX_SIZE];
00221 unsigned char md_size = md_get_size( ctx->md_info );
00222 size_t use_len;
00223 unsigned char *out_p = output;
00224 unsigned char counter[4];
00225
00226 memset( counter, 0, 4 );
00227 counter[3] = 1;
00228
00229 if( iteration_count > 0xFFFFFFFF )
00230 return( POLARSSL_ERR_PKCS5_BAD_INPUT_DATA );
00231
00232 while( key_length )
00233 {
00234
00235
00236 if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 )
00237 return( ret );
00238
00239 if( ( ret = md_hmac_update( ctx, salt, slen ) ) != 0 )
00240 return( ret );
00241
00242 if( ( ret = md_hmac_update( ctx, counter, 4 ) ) != 0 )
00243 return( ret );
00244
00245 if( ( ret = md_hmac_finish( ctx, work ) ) != 0 )
00246 return( ret );
00247
00248 memcpy( md1, work, md_size );
00249
00250 for ( i = 1; i < iteration_count; i++ )
00251 {
00252
00253
00254 if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 )
00255 return( ret );
00256
00257 if( ( ret = md_hmac_update( ctx, md1, md_size ) ) != 0 )
00258 return( ret );
00259
00260 if( ( ret = md_hmac_finish( ctx, md1 ) ) != 0 )
00261 return( ret );
00262
00263
00264
00265 for( j = 0; j < md_size; j++ )
00266 work[j] ^= md1[j];
00267 }
00268
00269 use_len = ( key_length < md_size ) ? key_length : md_size;
00270 memcpy( out_p, work, use_len );
00271
00272 key_length -= (uint32_t) use_len;
00273 out_p += use_len;
00274
00275 for( i = 4; i > 0; i-- )
00276 if( ++counter[i - 1] != 0 )
00277 break;
00278 }
00279
00280 return( 0 );
00281 }
00282
00283 #if defined(POLARSSL_SELF_TEST)
00284
00285 #include <stdio.h>
00286
00287 #define MAX_TESTS 6
00288
00289 size_t plen[MAX_TESTS] =
00290 { 8, 8, 8, 8, 24, 9 };
00291
00292 unsigned char password[MAX_TESTS][32] =
00293 {
00294 "password",
00295 "password",
00296 "password",
00297 "password",
00298 "passwordPASSWORDpassword",
00299 "pass\0word",
00300 };
00301
00302 size_t slen[MAX_TESTS] =
00303 { 4, 4, 4, 4, 36, 5 };
00304
00305 unsigned char salt[MAX_TESTS][40] =
00306 {
00307 "salt",
00308 "salt",
00309 "salt",
00310 "salt",
00311 "saltSALTsaltSALTsaltSALTsaltSALTsalt",
00312 "sa\0lt",
00313 };
00314
00315 uint32_t it_cnt[MAX_TESTS] =
00316 { 1, 2, 4096, 16777216, 4096, 4096 };
00317
00318 uint32_t key_len[MAX_TESTS] =
00319 { 20, 20, 20, 20, 25, 16 };
00320
00321
00322 unsigned char result_key[MAX_TESTS][32] =
00323 {
00324 { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
00325 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
00326 0x2f, 0xe0, 0x37, 0xa6 },
00327 { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
00328 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
00329 0xd8, 0xde, 0x89, 0x57 },
00330 { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
00331 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
00332 0x65, 0xa4, 0x29, 0xc1 },
00333 { 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
00334 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
00335 0x26, 0x34, 0xe9, 0x84 },
00336 { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
00337 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
00338 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
00339 0x38 },
00340 { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
00341 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
00342 };
00343
00344 int pkcs5_self_test( int verbose )
00345 {
00346 md_context_t sha1_ctx;
00347 const md_info_t *info_sha1;
00348 int ret, i;
00349 unsigned char key[64];
00350
00351 info_sha1 = md_info_from_type( POLARSSL_MD_SHA1 );
00352 if( info_sha1 == NULL )
00353 return( 1 );
00354
00355 if( ( ret = md_init_ctx( &sha1_ctx, info_sha1 ) ) != 0 )
00356 return( 1 );
00357
00358 for( i = 0; i < MAX_TESTS; i++ )
00359 {
00360 printf( " PBKDF2 (SHA1) #%d: ", i );
00361
00362 ret = pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
00363 slen[i], it_cnt[i], key_len[i], key );
00364 if( ret != 0 ||
00365 memcmp( result_key[i], key, key_len[i] ) != 0 )
00366 {
00367 if( verbose != 0 )
00368 printf( "failed\n" );
00369
00370 return( 1 );
00371 }
00372
00373 if( verbose != 0 )
00374 printf( "passed\n" );
00375 }
00376
00377 printf( "\n" );
00378
00379 if( ( ret = md_free_ctx( &sha1_ctx ) ) != 0 )
00380 return( 1 );
00381
00382 return( 0 );
00383 }
00384
00385 #endif
00386
00387 #endif