diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-03 16:06:41 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-03 16:06:41 -0800 |
commit | addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa (patch) | |
tree | 2ffea726dc494e87ecc9f506bc6a2bc9242730e3 /gpxe/src/crypto | |
parent | 5c0f48e49f8d7d084810ecf0b98a76aaebb44835 (diff) | |
parent | e7a5f95432132c8fc8f8ede39fda1d368002ddd8 (diff) | |
download | syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.tar.gz syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.tar.xz syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.zip |
Merge branch 'master' into i915res
Diffstat (limited to 'gpxe/src/crypto')
-rw-r--r-- | gpxe/src/crypto/aes_wrap.c | 123 | ||||
-rw-r--r-- | gpxe/src/crypto/arc4.c | 131 | ||||
-rw-r--r-- | gpxe/src/crypto/asn1.c | 2 | ||||
-rw-r--r-- | gpxe/src/crypto/axtls_aes.c | 15 | ||||
-rw-r--r-- | gpxe/src/crypto/cbc.c | 2 | ||||
-rw-r--r-- | gpxe/src/crypto/chap.c | 2 | ||||
-rw-r--r-- | gpxe/src/crypto/crandom.c | 55 | ||||
-rw-r--r-- | gpxe/src/crypto/crc32.c | 54 | ||||
-rw-r--r-- | gpxe/src/crypto/crypto_null.c | 2 | ||||
-rw-r--r-- | gpxe/src/crypto/hmac.c | 2 | ||||
-rw-r--r-- | gpxe/src/crypto/md5.c | 14 | ||||
-rw-r--r-- | gpxe/src/crypto/sha1extra.c | 165 | ||||
-rw-r--r-- | gpxe/src/crypto/x509.c | 2 |
13 files changed, 550 insertions, 19 deletions
diff --git a/gpxe/src/crypto/aes_wrap.c b/gpxe/src/crypto/aes_wrap.c new file mode 100644 index 00000000..d7f94af0 --- /dev/null +++ b/gpxe/src/crypto/aes_wrap.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdlib.h> +#include <string.h> +#include <gpxe/crypto.h> +#include <gpxe/aes.h> + +/** + * Wrap a key or other data using AES Key Wrap (RFC 3394) + * + * @v kek Key Encryption Key, 16 bytes + * @v src Data to encrypt + * @v nblk Number of 8-byte blocks in @a data + * @ret dest Encrypted data (8 bytes longer than input) + * + * The algorithm is implemented such that @a src and @a dest may point + * to the same buffer. + */ +int aes_wrap ( const void *kek, const void *src, void *dest, int nblk ) +{ + u8 *A = dest; + u8 B[16]; + u8 *R; + int i, j; + void *aes_ctx = malloc ( AES_CTX_SIZE ); + + if ( ! aes_ctx ) + return -1; + + cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 ); + + /* Set up */ + memset ( A, 0xA6, sizeof ( A ) ); + memmove ( dest + 8, src, nblk * 8 ); + + /* Wrap */ + for ( j = 0; j < 6; j++ ) { + R = dest + 8; + for ( i = 1; i <= nblk; i++ ) { + memcpy ( B, A, 8 ); + memcpy ( B + 8, R, 8 ); + cipher_encrypt ( &aes_algorithm, aes_ctx, B, B, 16 ); + memcpy ( A, B, 8 ); + A[7] ^= ( nblk * j ) + i; + memcpy ( R, B + 8, 8 ); + R += 8; + } + } + + free ( aes_ctx ); + return 0; +} + +/** + * Unwrap a key or other data using AES Key Wrap (RFC 3394) + * + * @v kek Key Encryption Key, 16 bytes + * @v src Data to decrypt + * @v nblk Number of 8-byte blocks in @e plaintext key + * @ret dest Decrypted data (8 bytes shorter than input) + * @ret rc Zero on success, nonzero on IV mismatch + * + * The algorithm is implemented such that @a src and @a dest may point + * to the same buffer. + */ +int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk ) +{ + u8 A[8], B[16]; + u8 *R; + int i, j; + void *aes_ctx = malloc ( AES_CTX_SIZE ); + + if ( ! aes_ctx ) + return -1; + + cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 ); + + /* Set up */ + memcpy ( A, src, 8 ); + memmove ( dest, src + 8, nblk * 8 ); + + /* Unwrap */ + for ( j = 5; j >= 0; j-- ) { + R = dest + ( nblk - 1 ) * 8; + for ( i = nblk; i >= 1; i-- ) { + memcpy ( B, A, 8 ); + memcpy ( B + 8, R, 8 ); + B[7] ^= ( nblk * j ) + i; + cipher_decrypt ( &aes_algorithm, aes_ctx, B, B, 16 ); + memcpy ( A, B, 8 ); + memcpy ( R, B + 8, 8 ); + R -= 8; + } + } + + free ( aes_ctx ); + + /* Check IV */ + for ( i = 0; i < 8; i++ ) { + if ( A[i] != 0xA6 ) + return -1; + } + + return 0; +} diff --git a/gpxe/src/crypto/arc4.c b/gpxe/src/crypto/arc4.c new file mode 100644 index 00000000..e58fba7c --- /dev/null +++ b/gpxe/src/crypto/arc4.c @@ -0,0 +1,131 @@ +/* + * The ARC4 stream cipher. + * + * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <gpxe/crypto.h> +#include <gpxe/arc4.h> + +#define SWAP( ary, i, j ) \ + ({ u8 temp = ary[i]; ary[i] = ary[j]; ary[j] = temp; }) + +/** + * Set ARC4 key + * + * @v ctxv ARC4 encryption context + * @v keyv Key to set + * @v keylen Length of key + * + * If an initialisation vector is to be used, it should be prepended + * to the key; ARC4 does not implement the @c setiv function because + * there is no standard length for an initialisation vector in the + * cipher. + */ +static int arc4_setkey ( void *ctxv, const void *keyv, size_t keylen ) +{ + struct arc4_ctx *ctx = ctxv; + const u8 *key = keyv; + u8 *S = ctx->state; + int i, j; + + for ( i = 0; i < 256; i++ ) { + S[i] = i; + } + + for ( i = j = 0; i < 256; i++ ) { + j = ( j + S[i] + key[i % keylen] ) & 0xff; + SWAP ( S, i, j ); + } + + ctx->i = ctx->j = 0; + return 0; +} + +/** + * Perform ARC4 encryption or decryption + * + * @v ctxv ARC4 encryption context + * @v srcv Data to encrypt or decrypt + * @v dstv Location to store encrypted or decrypted data + * @v len Length of data to operate on + * + * ARC4 is a stream cipher that works by generating a stream of PRNG + * data based on the key, and XOR'ing it with the data to be + * encrypted. Since XOR is symmetric, encryption and decryption in + * ARC4 are the same operation. + * + * If you pass a @c NULL source or destination pointer, @a len + * keystream bytes will be consumed without encrypting any data. + */ +static void arc4_xor ( void *ctxv, const void *srcv, void *dstv, + size_t len ) +{ + struct arc4_ctx *ctx = ctxv; + const u8 *src = srcv; + u8 *dst = dstv; + u8 *S = ctx->state; + int i = ctx->i, j = ctx->j; + + while ( len-- ) { + i = ( i + 1 ) & 0xff; + j = ( j + S[i] ) & 0xff; + SWAP ( S, i, j ); + if ( srcv && dstv ) + *dst++ = *src++ ^ S[(S[i] + S[j]) & 0xff]; + } + + ctx->i = i; + ctx->j = j; +} + +static void arc4_setiv ( void *ctx __unused, const void *iv __unused ) +{ + /* ARC4 does not use a fixed-length IV */ +} + + +/** + * Perform ARC4 encryption or decryption, skipping initial keystream bytes + * + * @v key ARC4 encryption key + * @v keylen Key length + * @v skip Number of bytes of keystream to skip + * @v src Message to encrypt or decrypt + * @v msglen Length of message + * @ret dst Encrypted or decrypted message + */ +void arc4_skip ( const void *key, size_t keylen, size_t skip, + const void *src, void *dst, size_t msglen ) +{ + struct arc4_ctx ctx; + arc4_setkey ( &ctx, key, keylen ); + arc4_xor ( &ctx, NULL, NULL, skip ); + arc4_xor ( &ctx, src, dst, msglen ); +} + +struct cipher_algorithm arc4_algorithm = { + .name = "ARC4", + .ctxsize = ARC4_CTX_SIZE, + .blocksize = 1, + .setkey = arc4_setkey, + .setiv = arc4_setiv, + .encrypt = arc4_xor, + .decrypt = arc4_xor, +}; diff --git a/gpxe/src/crypto/asn1.c b/gpxe/src/crypto/asn1.c index 25e7495b..154a8a84 100644 --- a/gpxe/src/crypto/asn1.c +++ b/gpxe/src/crypto/asn1.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + #include <stdint.h> #include <stddef.h> #include <errno.h> diff --git a/gpxe/src/crypto/axtls_aes.c b/gpxe/src/crypto/axtls_aes.c index 51e1924e..8bd37586 100644 --- a/gpxe/src/crypto/axtls_aes.c +++ b/gpxe/src/crypto/axtls_aes.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + #include <string.h> #include <errno.h> #include <byteswap.h> @@ -30,17 +32,6 @@ * */ -/** Basic AES blocksize */ -#define AES_BLOCKSIZE 16 - -/** AES context */ -struct aes_context { - /** AES context for AXTLS */ - AES_CTX axtls_ctx; - /** Cipher is being used for decrypting */ - int decrypting; -}; - /** * Set key * @@ -152,7 +143,7 @@ static void aes_decrypt ( void *ctx, const void *src, void *dst, } /** Basic AES algorithm */ -static struct cipher_algorithm aes_algorithm = { +struct cipher_algorithm aes_algorithm = { .name = "aes", .ctxsize = sizeof ( struct aes_context ), .blocksize = AES_BLOCKSIZE, diff --git a/gpxe/src/crypto/cbc.c b/gpxe/src/crypto/cbc.c index c7116ea9..1710203c 100644 --- a/gpxe/src/crypto/cbc.c +++ b/gpxe/src/crypto/cbc.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + #include <string.h> #include <assert.h> #include <gpxe/crypto.h> diff --git a/gpxe/src/crypto/chap.c b/gpxe/src/crypto/chap.c index d0784d25..8aa224c4 100644 --- a/gpxe/src/crypto/chap.c +++ b/gpxe/src/crypto/chap.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + #include <stddef.h> #include <stdlib.h> #include <string.h> diff --git a/gpxe/src/crypto/crandom.c b/gpxe/src/crypto/crandom.c new file mode 100644 index 00000000..9828482e --- /dev/null +++ b/gpxe/src/crypto/crandom.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +/** @file + * + * Cryptographically strong random number generator + * + * Currently the cryptographic part is not implemented, and this just + * uses random(). + */ + +#include <gpxe/crypto.h> +#include <stdlib.h> + +/** + * Get cryptographically strong random bytes + * + * @v buf Buffer in which to store random bytes + * @v len Number of random bytes to generate + * + * @b WARNING: This function is currently underimplemented, and does + * not give numbers any stronger than random()! + */ +void get_random_bytes ( void *buf, size_t len ) +{ + u8 *bufp = buf; + + /* + * Somewhat arbitrarily, choose the 0x00FF0000-masked byte + * returned by random() as having good entropy. PRNGs often + * don't provide good entropy in lower bits, and the top byte + * might show a pattern because of sign issues. + */ + + while ( len-- ) { + *bufp++ = ( random() >> 16 ) & 0xFF; + } +} diff --git a/gpxe/src/crypto/crc32.c b/gpxe/src/crypto/crc32.c new file mode 100644 index 00000000..0cc314e8 --- /dev/null +++ b/gpxe/src/crypto/crc32.c @@ -0,0 +1,54 @@ +/* + * Little-endian CRC32 implementation. + * + * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <gpxe/crc32.h> + +#define CRCPOLY 0xedb88320 + +/** + * Calculate 32-bit little-endian CRC checksum + * + * @v seed Initial value + * @v data Data to checksum + * @v len Length of data + * + * Usually @a seed is initially zero or all one bits, depending on the + * protocol. To continue a CRC checksum over multiple calls, pass the + * return value from one call as the @a seed parameter to the next. + */ +u32 crc32_le ( u32 seed, const void *data, size_t len ) +{ + u32 crc = seed; + const u8 *src = data; + u32 mult; + int i; + + while ( len-- ) { + crc ^= *src++; + for ( i = 0; i < 8; i++ ) { + mult = ( crc & 1 ) ? CRCPOLY : 0; + crc = ( crc >> 1 ) ^ mult; + } + } + + return crc; +} diff --git a/gpxe/src/crypto/crypto_null.c b/gpxe/src/crypto/crypto_null.c index 8cc9217a..61efb34e 100644 --- a/gpxe/src/crypto/crypto_null.c +++ b/gpxe/src/crypto/crypto_null.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + /** * @file * diff --git a/gpxe/src/crypto/hmac.c b/gpxe/src/crypto/hmac.c index be0298a7..d64730c0 100644 --- a/gpxe/src/crypto/hmac.c +++ b/gpxe/src/crypto/hmac.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + /** * @file * diff --git a/gpxe/src/crypto/md5.c b/gpxe/src/crypto/md5.c index 76fb8a69..8c606398 100644 --- a/gpxe/src/crypto/md5.c +++ b/gpxe/src/crypto/md5.c @@ -20,36 +20,36 @@ * */ +FILE_LICENCE ( GPL2_OR_LATER ); + #include <stdint.h> #include <string.h> #include <byteswap.h> #include <gpxe/crypto.h> #include <gpxe/md5.h> -#define __md5step __attribute__ (( regparm ( 3 ) )) - struct md5_step { - u32 __md5step ( * f ) ( u32 b, u32 c, u32 d ); + u32 ( * f ) ( u32 b, u32 c, u32 d ); u8 coefficient; u8 constant; }; -static u32 __md5step f1(u32 b, u32 c, u32 d) +static u32 f1(u32 b, u32 c, u32 d) { return ( d ^ ( b & ( c ^ d ) ) ); } -static u32 __md5step f2(u32 b, u32 c, u32 d) +static u32 f2(u32 b, u32 c, u32 d) { return ( c ^ ( d & ( b ^ c ) ) ); } -static u32 __md5step f3(u32 b, u32 c, u32 d) +static u32 f3(u32 b, u32 c, u32 d) { return ( b ^ c ^ d ); } -static u32 __md5step f4(u32 b, u32 c, u32 d) +static u32 f4(u32 b, u32 c, u32 d) { return ( c ^ ( b | ~d ) ); } diff --git a/gpxe/src/crypto/sha1extra.c b/gpxe/src/crypto/sha1extra.c new file mode 100644 index 00000000..c144a0f6 --- /dev/null +++ b/gpxe/src/crypto/sha1extra.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <gpxe/crypto.h> +#include <gpxe/sha1.h> +#include <gpxe/hmac.h> +#include <stdint.h> +#include <byteswap.h> + +/** + * SHA1 pseudorandom function for creating derived keys + * + * @v key Master key with which this call is associated + * @v key_len Length of key + * @v label NUL-terminated ASCII string describing purpose of PRF data + * @v data Further data that should be included in the PRF + * @v data_len Length of further PRF data + * @v prf_len Bytes of PRF to generate + * @ret prf Pseudorandom function bytes + * + * This is the PRF variant used by 802.11, defined in IEEE 802.11-2007 + * 8.5.5.1. EAP-FAST uses a different SHA1-based PRF, and TLS uses an + * MD5-based PRF. + */ +void prf_sha1 ( const void *key, size_t key_len, const char *label, + const void *data, size_t data_len, void *prf, size_t prf_len ) +{ + u32 blk; + u8 keym[key_len]; /* modifiable copy of key */ + u8 in[strlen ( label ) + 1 + data_len + 1]; /* message to HMAC */ + u8 *in_blknr; /* pointer to last byte of in, block number */ + u8 out[SHA1_SIZE]; /* HMAC-SHA1 result */ + u8 sha1_ctx[SHA1_CTX_SIZE]; /* SHA1 context */ + const size_t label_len = strlen ( label ); + + /* The HMAC-SHA-1 is calculated using the given key on the + message text `label', followed by a NUL, followed by one + byte indicating the block number (0 for first). */ + + memcpy ( keym, key, key_len ); + + memcpy ( in, label, strlen ( label ) + 1 ); + memcpy ( in + label_len + 1, data, data_len ); + in_blknr = in + label_len + 1 + data_len; + + for ( blk = 0 ;; blk++ ) { + *in_blknr = blk; + + hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len ); + hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) ); + hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out ); + + if ( prf_len <= SHA1_SIZE ) { + memcpy ( prf, out, prf_len ); + break; + } + + memcpy ( prf, out, SHA1_SIZE ); + prf_len -= SHA1_SIZE; + prf += SHA1_SIZE; + } +} + +/** + * PBKDF2 key derivation function inner block operation + * + * @v passphrase Passphrase from which to derive key + * @v pass_len Length of passphrase + * @v salt Salt to include in key + * @v salt_len Length of salt + * @v iterations Number of iterations of SHA1 to perform + * @v blocknr Index of this block, starting at 1 + * @ret block SHA1_SIZE bytes of PBKDF2 data + * + * The operation of this function is described in RFC 2898. + */ +static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len, + const void *salt, size_t salt_len, + int iterations, u32 blocknr, u8 *block ) +{ + u8 pass[pass_len]; /* modifiable passphrase */ + u8 in[salt_len + 4]; /* input buffer to first round */ + u8 last[SHA1_SIZE]; /* output of round N, input of N+1 */ + u8 sha1_ctx[SHA1_CTX_SIZE]; + u8 *next_in = in; /* changed to `last' after first round */ + int next_size = sizeof ( in ); + int i, j; + + blocknr = htonl ( blocknr ); + + memcpy ( pass, passphrase, pass_len ); + memcpy ( in, salt, salt_len ); + memcpy ( in + salt_len, &blocknr, 4 ); + memset ( block, 0, SHA1_SIZE ); + + for ( i = 0; i < iterations; i++ ) { + hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len ); + hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size ); + hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last ); + + for ( j = 0; j < SHA1_SIZE; j++ ) { + block[j] ^= last[j]; + } + + next_in = last; + next_size = SHA1_SIZE; + } +} + +/** + * PBKDF2 key derivation function using SHA1 + * + * @v passphrase Passphrase from which to derive key + * @v pass_len Length of passphrase + * @v salt Salt to include in key + * @v salt_len Length of salt + * @v iterations Number of iterations of SHA1 to perform + * @v key_len Length of key to generate + * @ret key Generated key bytes + * + * This is used most notably in 802.11 WPA passphrase hashing, in + * which case the salt is the SSID, 4096 iterations are used, and a + * 32-byte key is generated that serves as the Pairwise Master Key for + * EAPOL authentication. + * + * The operation of this function is further described in RFC 2898. + */ +void pbkdf2_sha1 ( const void *passphrase, size_t pass_len, + const void *salt, size_t salt_len, + int iterations, void *key, size_t key_len ) +{ + u32 blocks = ( key_len + SHA1_SIZE - 1 ) / SHA1_SIZE; + u32 blk; + u8 buf[SHA1_SIZE]; + + for ( blk = 1; blk <= blocks; blk++ ) { + pbkdf2_sha1_f ( passphrase, pass_len, salt, salt_len, + iterations, blk, buf ); + if ( key_len <= SHA1_SIZE ) { + memcpy ( key, buf, key_len ); + break; + } + + memcpy ( key, buf, SHA1_SIZE ); + key_len -= SHA1_SIZE; + key += SHA1_SIZE; + } +} diff --git a/gpxe/src/crypto/x509.c b/gpxe/src/crypto/x509.c index 35adfa38..31ed412f 100644 --- a/gpxe/src/crypto/x509.c +++ b/gpxe/src/crypto/x509.c @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +FILE_LICENCE ( GPL2_OR_LATER ); + #include <stdlib.h> #include <string.h> #include <errno.h> |