00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <gpxe/crypto.h>
00022 #include <gpxe/sha1.h>
00023 #include <gpxe/hmac.h>
00024 #include <stdint.h>
00025 #include <byteswap.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 void prf_sha1 ( const void *key, size_t key_len, const char *label,
00043 const void *data, size_t data_len, void *prf, size_t prf_len )
00044 {
00045 u32 blk;
00046 u8 keym[key_len];
00047 u8 in[strlen ( label ) + 1 + data_len + 1];
00048 u8 *in_blknr;
00049 u8 out[SHA1_SIZE];
00050 u8 sha1_ctx[SHA1_CTX_SIZE];
00051 const size_t label_len = strlen ( label );
00052
00053
00054
00055
00056
00057 memcpy ( keym, key, key_len );
00058
00059 memcpy ( in, label, strlen ( label ) + 1 );
00060 memcpy ( in + label_len + 1, data, data_len );
00061 in_blknr = in + label_len + 1 + data_len;
00062
00063 for ( blk = 0 ;; blk++ ) {
00064 *in_blknr = blk;
00065
00066 hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len );
00067 hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) );
00068 hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out );
00069
00070 if ( prf_len <= SHA1_SIZE ) {
00071 memcpy ( prf, out, prf_len );
00072 break;
00073 }
00074
00075 memcpy ( prf, out, SHA1_SIZE );
00076 prf_len -= SHA1_SIZE;
00077 prf += SHA1_SIZE;
00078 }
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
00095 const void *salt, size_t salt_len,
00096 int iterations, u32 blocknr, u8 *block )
00097 {
00098 u8 pass[pass_len];
00099 u8 in[salt_len + 4];
00100 u8 last[SHA1_SIZE];
00101 u8 sha1_ctx[SHA1_CTX_SIZE];
00102 u8 *next_in = in;
00103 int next_size = sizeof ( in );
00104 int i, j;
00105
00106 blocknr = htonl ( blocknr );
00107
00108 memcpy ( pass, passphrase, pass_len );
00109 memcpy ( in, salt, salt_len );
00110 memcpy ( in + salt_len, &blocknr, 4 );
00111 memset ( block, 0, SHA1_SIZE );
00112
00113 for ( i = 0; i < iterations; i++ ) {
00114 hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len );
00115 hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size );
00116 hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last );
00117
00118 for ( j = 0; j < SHA1_SIZE; j++ ) {
00119 block[j] ^= last[j];
00120 }
00121
00122 next_in = last;
00123 next_size = SHA1_SIZE;
00124 }
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 void pbkdf2_sha1 ( const void *passphrase, size_t pass_len,
00146 const void *salt, size_t salt_len,
00147 int iterations, void *key, size_t key_len )
00148 {
00149 u32 blocks = ( key_len + SHA1_SIZE - 1 ) / SHA1_SIZE;
00150 u32 blk;
00151 u8 buf[SHA1_SIZE];
00152
00153 for ( blk = 1; blk <= blocks; blk++ ) {
00154 pbkdf2_sha1_f ( passphrase, pass_len, salt, salt_len,
00155 iterations, blk, buf );
00156 if ( key_len <= SHA1_SIZE ) {
00157 memcpy ( key, buf, key_len );
00158 break;
00159 }
00160
00161 memcpy ( key, buf, SHA1_SIZE );
00162 key_len -= SHA1_SIZE;
00163 key += SHA1_SIZE;
00164 }
00165 }