|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2007 Michael Brown <[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: /** ! 22: * @file ! 23: * ! 24: * Keyed-Hashing for Message Authentication ! 25: */ ! 26: ! 27: #include <string.h> ! 28: #include <assert.h> ! 29: #include <ipxe/crypto.h> ! 30: #include <ipxe/hmac.h> ! 31: ! 32: /** ! 33: * Reduce HMAC key length ! 34: * ! 35: * @v digest Digest algorithm to use ! 36: * @v digest_ctx Digest context ! 37: * @v key Key ! 38: * @v key_len Length of key ! 39: */ ! 40: static void hmac_reduce_key ( struct digest_algorithm *digest, ! 41: void *key, size_t *key_len ) { ! 42: uint8_t digest_ctx[digest->ctxsize]; ! 43: ! 44: digest_init ( digest, digest_ctx ); ! 45: digest_update ( digest, digest_ctx, key, *key_len ); ! 46: digest_final ( digest, digest_ctx, key ); ! 47: *key_len = digest->digestsize; ! 48: } ! 49: ! 50: /** ! 51: * Initialise HMAC ! 52: * ! 53: * @v digest Digest algorithm to use ! 54: * @v digest_ctx Digest context ! 55: * @v key Key ! 56: * @v key_len Length of key ! 57: * ! 58: * The length of the key should be less than the block size of the ! 59: * digest algorithm being used. (If the key length is greater, it ! 60: * will be replaced with its own digest, and key_len will be updated ! 61: * accordingly). ! 62: */ ! 63: void hmac_init ( struct digest_algorithm *digest, void *digest_ctx, ! 64: void *key, size_t *key_len ) { ! 65: unsigned char k_ipad[digest->blocksize]; ! 66: unsigned int i; ! 67: ! 68: /* Reduce key if necessary */ ! 69: if ( *key_len > sizeof ( k_ipad ) ) ! 70: hmac_reduce_key ( digest, key, key_len ); ! 71: ! 72: /* Construct input pad */ ! 73: memset ( k_ipad, 0, sizeof ( k_ipad ) ); ! 74: memcpy ( k_ipad, key, *key_len ); ! 75: for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) { ! 76: k_ipad[i] ^= 0x36; ! 77: } ! 78: ! 79: /* Start inner hash */ ! 80: digest_init ( digest, digest_ctx ); ! 81: digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) ); ! 82: } ! 83: ! 84: /** ! 85: * Finalise HMAC ! 86: * ! 87: * @v digest Digest algorithm to use ! 88: * @v digest_ctx Digest context ! 89: * @v key Key ! 90: * @v key_len Length of key ! 91: * @v hmac HMAC digest to fill in ! 92: * ! 93: * The length of the key should be less than the block size of the ! 94: * digest algorithm being used. (If the key length is greater, it ! 95: * will be replaced with its own digest, and key_len will be updated ! 96: * accordingly). ! 97: */ ! 98: void hmac_final ( struct digest_algorithm *digest, void *digest_ctx, ! 99: void *key, size_t *key_len, void *hmac ) { ! 100: unsigned char k_opad[digest->blocksize]; ! 101: unsigned int i; ! 102: ! 103: /* Reduce key if necessary */ ! 104: if ( *key_len > sizeof ( k_opad ) ) ! 105: hmac_reduce_key ( digest, key, key_len ); ! 106: ! 107: /* Construct output pad */ ! 108: memset ( k_opad, 0, sizeof ( k_opad ) ); ! 109: memcpy ( k_opad, key, *key_len ); ! 110: for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) { ! 111: k_opad[i] ^= 0x5c; ! 112: } ! 113: ! 114: /* Finish inner hash */ ! 115: digest_final ( digest, digest_ctx, hmac ); ! 116: ! 117: /* Perform outer hash */ ! 118: digest_init ( digest, digest_ctx ); ! 119: digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) ); ! 120: digest_update ( digest, digest_ctx, hmac, digest->digestsize ); ! 121: digest_final ( digest, digest_ctx, hmac ); ! 122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.