Hannes Tschofenig
/
aes-gcm-test-program
Example program to test AES-GCM functionality. Used for a workshop
Embed:
(wiki syntax)
Show/hide line numbers
pkcs12.c
00001 /* 00002 * PKCS#12 Personal Information Exchange Syntax 00003 * 00004 * Copyright (C) 2006-2014, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 /* 00026 * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 00027 * 00028 * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf 00029 * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn 00030 */ 00031 00032 #if !defined(POLARSSL_CONFIG_FILE) 00033 #include "polarssl/config.h" 00034 #else 00035 #include POLARSSL_CONFIG_FILE 00036 #endif 00037 00038 #if defined(POLARSSL_PKCS12_C) 00039 00040 #include "polarssl/pkcs12.h" 00041 #include "polarssl/asn1.h" 00042 #include "polarssl/cipher.h" 00043 00044 #if defined(POLARSSL_ARC4_C) 00045 #include "polarssl/arc4.h" 00046 #endif 00047 00048 #if defined(POLARSSL_DES_C) 00049 #include "polarssl/des.h" 00050 #endif 00051 00052 static int pkcs12_parse_pbe_params( asn1_buf *params, 00053 asn1_buf *salt, int *iterations ) 00054 { 00055 int ret; 00056 unsigned char **p = ¶ms->p; 00057 const unsigned char *end = params->p + params->len; 00058 00059 /* 00060 * pkcs-12PbeParams ::= SEQUENCE { 00061 * salt OCTET STRING, 00062 * iterations INTEGER 00063 * } 00064 * 00065 */ 00066 if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) 00067 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + 00068 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); 00069 00070 if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 ) 00071 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00072 00073 salt->p = *p; 00074 *p += salt->len; 00075 00076 if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 ) 00077 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); 00078 00079 if( *p != end ) 00080 return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + 00081 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00082 00083 return( 0 ); 00084 } 00085 00086 static int pkcs12_pbe_derive_key_iv( asn1_buf *pbe_params, md_type_t md_type, 00087 const unsigned char *pwd, size_t pwdlen, 00088 unsigned char *key, size_t keylen, 00089 unsigned char *iv, size_t ivlen ) 00090 { 00091 int ret, iterations; 00092 asn1_buf salt; 00093 size_t i; 00094 unsigned char unipwd[258]; 00095 00096 memset(&salt, 0, sizeof(asn1_buf)); 00097 memset(&unipwd, 0, sizeof(unipwd)); 00098 00099 if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, 00100 &iterations ) ) != 0 ) 00101 return( ret ); 00102 00103 for(i = 0; i < pwdlen; i++) 00104 unipwd[i * 2 + 1] = pwd[i]; 00105 00106 if( ( ret = pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, 00107 salt.p, salt.len, md_type, 00108 PKCS12_DERIVE_KEY, iterations ) ) != 0 ) 00109 { 00110 return( ret ); 00111 } 00112 00113 if( iv == NULL || ivlen == 0 ) 00114 return( 0 ); 00115 00116 if( ( ret = pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, 00117 salt.p, salt.len, md_type, 00118 PKCS12_DERIVE_IV, iterations ) ) != 0 ) 00119 { 00120 return( ret ); 00121 } 00122 return( 0 ); 00123 } 00124 00125 int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode, 00126 const unsigned char *pwd, size_t pwdlen, 00127 const unsigned char *data, size_t len, 00128 unsigned char *output ) 00129 { 00130 #if !defined(POLARSSL_ARC4_C) 00131 ((void) pbe_params); 00132 ((void) mode); 00133 ((void) pwd); 00134 ((void) pwdlen); 00135 ((void) data); 00136 ((void) len); 00137 ((void) output); 00138 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00139 #else 00140 int ret; 00141 unsigned char key[16]; 00142 arc4_context ctx; 00143 ((void) mode); 00144 00145 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, POLARSSL_MD_SHA1, 00146 pwd, pwdlen, 00147 key, 16, NULL, 0 ) ) != 0 ) 00148 { 00149 return( ret ); 00150 } 00151 00152 arc4_setup( &ctx, key, 16 ); 00153 if( ( ret = arc4_crypt( &ctx, len, data, output ) ) != 0 ) 00154 return( ret ); 00155 00156 return( 0 ); 00157 #endif /* POLARSSL_ARC4_C */ 00158 } 00159 00160 int pkcs12_pbe( asn1_buf *pbe_params, int mode, 00161 cipher_type_t cipher_type, md_type_t md_type, 00162 const unsigned char *pwd, size_t pwdlen, 00163 const unsigned char *data, size_t len, 00164 unsigned char *output ) 00165 { 00166 int ret, keylen = 0; 00167 unsigned char key[32]; 00168 unsigned char iv[16]; 00169 const cipher_info_t *cipher_info; 00170 cipher_context_t cipher_ctx; 00171 size_t olen = 0; 00172 00173 cipher_info = cipher_info_from_type( cipher_type ); 00174 if( cipher_info == NULL ) 00175 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00176 00177 keylen = cipher_info->key_length / 8; 00178 00179 if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, 00180 key, keylen, 00181 iv, cipher_info->iv_size ) ) != 0 ) 00182 { 00183 return( ret ); 00184 } 00185 00186 if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 ) 00187 goto exit; 00188 00189 if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 ) 00190 goto exit; 00191 00192 if( ( ret = cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) 00193 goto exit; 00194 00195 if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 ) 00196 goto exit; 00197 00198 if( ( ret = cipher_update( &cipher_ctx, data, len, 00199 output, &olen ) ) != 0 ) 00200 { 00201 goto exit; 00202 } 00203 00204 if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) 00205 ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH; 00206 00207 exit: 00208 cipher_free_ctx( &cipher_ctx ); 00209 00210 return( ret ); 00211 } 00212 00213 static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, 00214 const unsigned char *filler, size_t fill_len ) 00215 { 00216 unsigned char *p = data; 00217 size_t use_len; 00218 00219 while( data_len > 0 ) 00220 { 00221 use_len = ( data_len > fill_len ) ? fill_len : data_len; 00222 memcpy( p, filler, use_len ); 00223 p += use_len; 00224 data_len -= use_len; 00225 } 00226 } 00227 00228 int pkcs12_derivation( unsigned char *data, size_t datalen, 00229 const unsigned char *pwd, size_t pwdlen, 00230 const unsigned char *salt, size_t saltlen, 00231 md_type_t md_type, int id, int iterations ) 00232 { 00233 int ret; 00234 unsigned int j; 00235 00236 unsigned char diversifier[128]; 00237 unsigned char salt_block[128], pwd_block[128], hash_block[128]; 00238 unsigned char hash_output[POLARSSL_MD_MAX_SIZE]; 00239 unsigned char *p; 00240 unsigned char c; 00241 00242 size_t hlen, use_len, v, i; 00243 00244 const md_info_t *md_info; 00245 md_context_t md_ctx; 00246 00247 // This version only allows max of 64 bytes of password or salt 00248 if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) 00249 return( POLARSSL_ERR_PKCS12_BAD_INPUT_DATA ); 00250 00251 md_info = md_info_from_type( md_type ); 00252 if( md_info == NULL ) 00253 return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); 00254 00255 if ( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) 00256 return( ret ); 00257 hlen = md_get_size( md_info ); 00258 00259 if( hlen <= 32 ) 00260 v = 64; 00261 else 00262 v = 128; 00263 00264 memset( diversifier, (unsigned char) id, v ); 00265 00266 pkcs12_fill_buffer( salt_block, v, salt, saltlen ); 00267 pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); 00268 00269 p = data; 00270 while( datalen > 0 ) 00271 { 00272 // Calculate hash( diversifier || salt_block || pwd_block ) 00273 if( ( ret = md_starts( &md_ctx ) ) != 0 ) 00274 goto exit; 00275 00276 if( ( ret = md_update( &md_ctx, diversifier, v ) ) != 0 ) 00277 goto exit; 00278 00279 if( ( ret = md_update( &md_ctx, salt_block, v ) ) != 0 ) 00280 goto exit; 00281 00282 if( ( ret = md_update( &md_ctx, pwd_block, v ) ) != 0 ) 00283 goto exit; 00284 00285 if( ( ret = md_finish( &md_ctx, hash_output ) ) != 0 ) 00286 goto exit; 00287 00288 // Perform remaining ( iterations - 1 ) recursive hash calculations 00289 for( i = 1; i < (size_t) iterations; i++ ) 00290 { 00291 if( ( ret = md( md_info, hash_output, hlen, hash_output ) ) != 0 ) 00292 goto exit; 00293 } 00294 00295 use_len = ( datalen > hlen ) ? hlen : datalen; 00296 memcpy( p, hash_output, use_len ); 00297 datalen -= use_len; 00298 p += use_len; 00299 00300 if( datalen == 0 ) 00301 break; 00302 00303 // Concatenating copies of hash_output into hash_block (B) 00304 pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); 00305 00306 // B += 1 00307 for( i = v; i > 0; i-- ) 00308 if( ++hash_block[i - 1] != 0 ) 00309 break; 00310 00311 // salt_block += B 00312 c = 0; 00313 for( i = v; i > 0; i-- ) 00314 { 00315 j = salt_block[i - 1] + hash_block[i - 1] + c; 00316 c = (unsigned char) (j >> 8); 00317 salt_block[i - 1] = j & 0xFF; 00318 } 00319 00320 // pwd_block += B 00321 c = 0; 00322 for( i = v; i > 0; i-- ) 00323 { 00324 j = pwd_block[i - 1] + hash_block[i - 1] + c; 00325 c = (unsigned char) (j >> 8); 00326 pwd_block[i - 1] = j & 0xFF; 00327 } 00328 } 00329 00330 ret = 0; 00331 00332 exit: 00333 md_free_ctx( &md_ctx ); 00334 00335 return( ret ); 00336 } 00337 00338 #endif /* POLARSSL_PKCS12_C */ 00339 00340
Generated on Tue Jul 12 2022 19:40:20 by 1.7.2