00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "polarssl/config.h"
00033
00034 #if defined(POLARSSL_PKCS12_C)
00035
00036 #include "polarssl/pkcs12.h"
00037 #include "polarssl/asn1.h"
00038 #include "polarssl/cipher.h"
00039
00040 #if defined(POLARSSL_ARC4_C)
00041 #include "polarssl/arc4.h"
00042 #endif
00043
00044 #if defined(POLARSSL_DES_C)
00045 #include "polarssl/des.h"
00046 #endif
00047
00048 static int pkcs12_parse_pbe_params( asn1_buf *params,
00049 asn1_buf *salt, int *iterations )
00050 {
00051 int ret;
00052 unsigned char **p = ¶ms->p;
00053 const unsigned char *end = params->p + params->len;
00054
00055
00056
00057
00058
00059
00060
00061
00062 if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
00063 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT +
00064 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00065
00066 if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 )
00067 return( POLARSSL_ERR_PKCS12_PBE_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_PKCS12_PBE_INVALID_FORMAT + ret );
00074
00075 if( *p != end )
00076 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT +
00077 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00078
00079 return( 0 );
00080 }
00081
00082 static int pkcs12_pbe_derive_key_iv( asn1_buf *pbe_params, md_type_t md_type,
00083 const unsigned char *pwd, size_t pwdlen,
00084 unsigned char *key, size_t keylen,
00085 unsigned char *iv, size_t ivlen )
00086 {
00087 int ret, iterations;
00088 asn1_buf salt;
00089 size_t i;
00090 unsigned char unipwd[258];
00091
00092 memset(&salt, 0, sizeof(asn1_buf));
00093 memset(&unipwd, 0, sizeof(unipwd));
00094
00095 if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, &iterations ) ) != 0 )
00096 return( ret );
00097
00098 for(i = 0; i < pwdlen; i++)
00099 unipwd[i * 2 + 1] = pwd[i];
00100
00101 if( ( ret = pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2,
00102 salt.p, salt.len, md_type,
00103 PKCS12_DERIVE_KEY, iterations ) ) != 0 )
00104 {
00105 return( ret );
00106 }
00107
00108 if( iv == NULL || ivlen == 0 )
00109 return( 0 );
00110
00111 if( ( ret = pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2,
00112 salt.p, salt.len, md_type,
00113 PKCS12_DERIVE_IV, iterations ) ) != 0 )
00114 {
00115 return( ret );
00116 }
00117 return( 0 );
00118 }
00119
00120 int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode,
00121 const unsigned char *pwd, size_t pwdlen,
00122 const unsigned char *data, size_t len,
00123 unsigned char *output )
00124 {
00125 #if !defined(POLARSSL_ARC4_C)
00126 ((void) pbe_params);
00127 ((void) mode);
00128 ((void) pwd);
00129 ((void) pwdlen);
00130 ((void) data);
00131 ((void) len);
00132 ((void) output);
00133 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
00134 #else
00135 int ret;
00136 unsigned char key[16];
00137 arc4_context ctx;
00138 ((void) mode);
00139
00140 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, POLARSSL_MD_SHA1,
00141 pwd, pwdlen,
00142 key, 16, NULL, 0 ) ) != 0 )
00143 {
00144 return( ret );
00145 }
00146
00147 arc4_setup( &ctx, key, 16 );
00148 if( ( ret = arc4_crypt( &ctx, len, data, output ) ) != 0 )
00149 return( ret );
00150
00151 return( 0 );
00152 #endif
00153 }
00154
00155 int pkcs12_pbe( asn1_buf *pbe_params, int mode,
00156 cipher_type_t cipher_type, md_type_t md_type,
00157 const unsigned char *pwd, size_t pwdlen,
00158 const unsigned char *data, size_t len,
00159 unsigned char *output )
00160 {
00161 int ret, keylen = 0;
00162 unsigned char key[32];
00163 unsigned char iv[16];
00164 const cipher_info_t *cipher_info;
00165 cipher_context_t cipher_ctx;
00166 size_t olen = 0;
00167
00168 cipher_info = cipher_info_from_type( cipher_type );
00169 if( cipher_info == NULL )
00170 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
00171
00172 keylen = cipher_info->key_length / 8;
00173
00174 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen,
00175 key, keylen,
00176 iv, cipher_info->iv_size ) ) != 0 )
00177 {
00178 return( ret );
00179 }
00180
00181 if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 )
00182 goto exit;
00183
00184 if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 )
00185 goto exit;
00186
00187 if( ( ret = cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 )
00188 goto exit;
00189
00190 if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 )
00191 goto exit;
00192
00193 if( ( ret = cipher_update( &cipher_ctx, data, len,
00194 output, &olen ) ) != 0 )
00195 {
00196 goto exit;
00197 }
00198
00199 if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
00200 ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH;
00201
00202 exit:
00203 cipher_free_ctx( &cipher_ctx );
00204
00205 return( ret );
00206 }
00207
00208 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
00209 const unsigned char *filler, size_t fill_len )
00210 {
00211 unsigned char *p = data;
00212 size_t use_len;
00213
00214 while( data_len > 0 )
00215 {
00216 use_len = ( data_len > fill_len ) ? fill_len : data_len;
00217 memcpy( p, filler, use_len );
00218 p += use_len;
00219 data_len -= use_len;
00220 }
00221 }
00222
00223 int pkcs12_derivation( unsigned char *data, size_t datalen,
00224 const unsigned char *pwd, size_t pwdlen,
00225 const unsigned char *salt, size_t saltlen,
00226 md_type_t md_type, int id, int iterations )
00227 {
00228 int ret;
00229 unsigned int j;
00230
00231 unsigned char diversifier[128];
00232 unsigned char salt_block[128], pwd_block[128], hash_block[128];
00233 unsigned char hash_output[POLARSSL_MD_MAX_SIZE];
00234 unsigned char *p;
00235 unsigned char c;
00236
00237 size_t hlen, use_len, v, i;
00238
00239 const md_info_t *md_info;
00240 md_context_t md_ctx;
00241
00242
00243 if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
00244 return( POLARSSL_ERR_PKCS12_BAD_INPUT_DATA );
00245
00246 md_info = md_info_from_type( md_type );
00247 if( md_info == NULL )
00248 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE );
00249
00250 if ( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
00251 return( ret );
00252 hlen = md_get_size( md_info );
00253
00254 if( hlen <= 32 )
00255 v = 64;
00256 else
00257 v = 128;
00258
00259 memset( diversifier, (unsigned char) id, v );
00260
00261 pkcs12_fill_buffer( salt_block, v, salt, saltlen );
00262 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen );
00263
00264 p = data;
00265 while( datalen > 0 )
00266 {
00267
00268 if( ( ret = md_starts( &md_ctx ) ) != 0 )
00269 goto exit;
00270
00271 if( ( ret = md_update( &md_ctx, diversifier, v ) ) != 0 )
00272 goto exit;
00273
00274 if( ( ret = md_update( &md_ctx, salt_block, v ) ) != 0 )
00275 goto exit;
00276
00277 if( ( ret = md_update( &md_ctx, pwd_block, v ) ) != 0 )
00278 goto exit;
00279
00280 if( ( ret = md_finish( &md_ctx, hash_output ) ) != 0 )
00281 goto exit;
00282
00283
00284 for( i = 1; i < (size_t) iterations; i++ )
00285 {
00286 if( ( ret = md( md_info, hash_output, hlen, hash_output ) ) != 0 )
00287 goto exit;
00288 }
00289
00290 use_len = ( datalen > hlen ) ? hlen : datalen;
00291 memcpy( p, hash_output, use_len );
00292 datalen -= use_len;
00293 p += use_len;
00294
00295 if( datalen == 0 )
00296 break;
00297
00298
00299 pkcs12_fill_buffer( hash_block, v, hash_output, hlen );
00300
00301
00302 for( i = v; i > 0; i-- )
00303 if( ++hash_block[i - 1] != 0 )
00304 break;
00305
00306
00307 c = 0;
00308 for( i = v; i > 0; i-- )
00309 {
00310 j = salt_block[i - 1] + hash_block[i - 1] + c;
00311 c = (unsigned char) (j >> 8);
00312 salt_block[i - 1] = j & 0xFF;
00313 }
00314
00315
00316 c = 0;
00317 for( i = v; i > 0; i-- )
00318 {
00319 j = pwd_block[i - 1] + hash_block[i - 1] + c;
00320 c = (unsigned char) (j >> 8);
00321 pwd_block[i - 1] = j & 0xFF;
00322 }
00323 }
00324
00325 ret = 0;
00326
00327 exit:
00328 md_free_ctx( &md_ctx );
00329
00330 return( ret );
00331 }
00332
00333 #endif