Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Committer:
HannesTschofenig
Date:
Thu Sep 27 06:34:22 2018 +0000
Revision:
0:796d0f61a05b
Example AES-GCM test program

Who changed what in which revision?

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