Annotation of qemu/roms/ipxe/src/crypto/sha1extra.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2009 Joshua Oreman <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: #include <ipxe/crypto.h>
                     22: #include <ipxe/sha1.h>
                     23: #include <ipxe/hmac.h>
                     24: #include <stdint.h>
                     25: #include <byteswap.h>
                     26: 
                     27: /**
                     28:  * SHA1 pseudorandom function for creating derived keys
                     29:  *
                     30:  * @v key      Master key with which this call is associated
                     31:  * @v key_len  Length of key
                     32:  * @v label    NUL-terminated ASCII string describing purpose of PRF data
                     33:  * @v data     Further data that should be included in the PRF
                     34:  * @v data_len Length of further PRF data
                     35:  * @v prf_len  Bytes of PRF to generate
                     36:  * @ret prf    Pseudorandom function bytes
                     37:  *
                     38:  * This is the PRF variant used by 802.11, defined in IEEE 802.11-2007
                     39:  * 8.5.5.1. EAP-FAST uses a different SHA1-based PRF, and TLS uses an
                     40:  * MD5-based PRF.
                     41:  */
                     42: void prf_sha1 ( const void *key, size_t key_len, const char *label,
                     43:                const void *data, size_t data_len, void *prf, size_t prf_len )
                     44: {
                     45:        u32 blk;
                     46:        u8 keym[key_len];       /* modifiable copy of key */
                     47:        u8 in[strlen ( label ) + 1 + data_len + 1]; /* message to HMAC */
                     48:        u8 *in_blknr;           /* pointer to last byte of in, block number */
                     49:        u8 out[SHA1_SIZE];      /* HMAC-SHA1 result */
                     50:        u8 sha1_ctx[SHA1_CTX_SIZE]; /* SHA1 context */
                     51:        const size_t label_len = strlen ( label );
                     52: 
                     53:        /* The HMAC-SHA-1 is calculated using the given key on the
                     54:           message text `label', followed by a NUL, followed by one
                     55:           byte indicating the block number (0 for first). */
                     56: 
                     57:        memcpy ( keym, key, key_len );
                     58: 
                     59:        memcpy ( in, label, strlen ( label ) + 1 );
                     60:        memcpy ( in + label_len + 1, data, data_len );
                     61:        in_blknr = in + label_len + 1 + data_len;
                     62: 
                     63:        for ( blk = 0 ;; blk++ ) {
                     64:                *in_blknr = blk;
                     65: 
                     66:                hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len );
                     67:                hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) );
                     68:                hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out );
                     69: 
                     70:                if ( prf_len <= SHA1_SIZE ) {
                     71:                        memcpy ( prf, out, prf_len );
                     72:                        break;
                     73:                }
                     74: 
                     75:                memcpy ( prf, out, SHA1_SIZE );
                     76:                prf_len -= SHA1_SIZE;
                     77:                prf += SHA1_SIZE;
                     78:        }
                     79: }
                     80: 
                     81: /**
                     82:  * PBKDF2 key derivation function inner block operation
                     83:  *
                     84:  * @v passphrase       Passphrase from which to derive key
                     85:  * @v pass_len         Length of passphrase
                     86:  * @v salt             Salt to include in key
                     87:  * @v salt_len         Length of salt
                     88:  * @v iterations       Number of iterations of SHA1 to perform
                     89:  * @v blocknr          Index of this block, starting at 1
                     90:  * @ret block          SHA1_SIZE bytes of PBKDF2 data
                     91:  *
                     92:  * The operation of this function is described in RFC 2898.
                     93:  */
                     94: static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
                     95:                            const void *salt, size_t salt_len,
                     96:                            int iterations, u32 blocknr, u8 *block )
                     97: {
                     98:        u8 pass[pass_len];      /* modifiable passphrase */
                     99:        u8 in[salt_len + 4];    /* input buffer to first round */
                    100:        u8 last[SHA1_SIZE];     /* output of round N, input of N+1 */
                    101:        u8 sha1_ctx[SHA1_CTX_SIZE];
                    102:        u8 *next_in = in;       /* changed to `last' after first round */
                    103:        int next_size = sizeof ( in );
                    104:        int i, j;
                    105: 
                    106:        blocknr = htonl ( blocknr );
                    107: 
                    108:        memcpy ( pass, passphrase, pass_len );
                    109:        memcpy ( in, salt, salt_len );
                    110:        memcpy ( in + salt_len, &blocknr, 4 );
                    111:        memset ( block, 0, SHA1_SIZE );
                    112: 
                    113:        for ( i = 0; i < iterations; i++ ) {
                    114:                hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len );
                    115:                hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size );
                    116:                hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last );
                    117: 
                    118:                for ( j = 0; j < SHA1_SIZE; j++ ) {
                    119:                        block[j] ^= last[j];
                    120:                }
                    121: 
                    122:                next_in = last;
                    123:                next_size = SHA1_SIZE;
                    124:        }
                    125: }
                    126: 
                    127: /**
                    128:  * PBKDF2 key derivation function using SHA1
                    129:  *
                    130:  * @v passphrase       Passphrase from which to derive key
                    131:  * @v pass_len         Length of passphrase
                    132:  * @v salt             Salt to include in key
                    133:  * @v salt_len         Length of salt
                    134:  * @v iterations       Number of iterations of SHA1 to perform
                    135:  * @v key_len          Length of key to generate
                    136:  * @ret key            Generated key bytes
                    137:  *
                    138:  * This is used most notably in 802.11 WPA passphrase hashing, in
                    139:  * which case the salt is the SSID, 4096 iterations are used, and a
                    140:  * 32-byte key is generated that serves as the Pairwise Master Key for
                    141:  * EAPOL authentication.
                    142:  *
                    143:  * The operation of this function is further described in RFC 2898.
                    144:  */
                    145: void pbkdf2_sha1 ( const void *passphrase, size_t pass_len,
                    146:                   const void *salt, size_t salt_len,
                    147:                   int iterations, void *key, size_t key_len )
                    148: {
                    149:        u32 blocks = ( key_len + SHA1_SIZE - 1 ) / SHA1_SIZE;
                    150:        u32 blk;
                    151:        u8 buf[SHA1_SIZE];
                    152: 
                    153:        for ( blk = 1; blk <= blocks; blk++ ) {
                    154:                pbkdf2_sha1_f ( passphrase, pass_len, salt, salt_len,
                    155:                                iterations, blk, buf );
                    156:                if ( key_len <= SHA1_SIZE ) {
                    157:                        memcpy ( key, buf, key_len );
                    158:                        break;
                    159:                }
                    160: 
                    161:                memcpy ( key, buf, SHA1_SIZE );
                    162:                key_len -= SHA1_SIZE;
                    163:                key += SHA1_SIZE;
                    164:        }
                    165: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.