|
|
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 <stdlib.h> ! 22: #include <string.h> ! 23: #include <ipxe/crypto.h> ! 24: #include <ipxe/aes.h> ! 25: ! 26: /** ! 27: * Wrap a key or other data using AES Key Wrap (RFC 3394) ! 28: * ! 29: * @v kek Key Encryption Key, 16 bytes ! 30: * @v src Data to encrypt ! 31: * @v nblk Number of 8-byte blocks in @a data ! 32: * @ret dest Encrypted data (8 bytes longer than input) ! 33: * ! 34: * The algorithm is implemented such that @a src and @a dest may point ! 35: * to the same buffer. ! 36: */ ! 37: int aes_wrap ( const void *kek, const void *src, void *dest, int nblk ) ! 38: { ! 39: u8 *A = dest; ! 40: u8 B[16]; ! 41: u8 *R; ! 42: int i, j; ! 43: void *aes_ctx = malloc ( AES_CTX_SIZE ); ! 44: ! 45: if ( ! aes_ctx ) ! 46: return -1; ! 47: ! 48: cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 ); ! 49: ! 50: /* Set up */ ! 51: memset ( A, 0xA6, sizeof ( A ) ); ! 52: memmove ( dest + 8, src, nblk * 8 ); ! 53: ! 54: /* Wrap */ ! 55: for ( j = 0; j < 6; j++ ) { ! 56: R = dest + 8; ! 57: for ( i = 1; i <= nblk; i++ ) { ! 58: memcpy ( B, A, 8 ); ! 59: memcpy ( B + 8, R, 8 ); ! 60: cipher_encrypt ( &aes_algorithm, aes_ctx, B, B, 16 ); ! 61: memcpy ( A, B, 8 ); ! 62: A[7] ^= ( nblk * j ) + i; ! 63: memcpy ( R, B + 8, 8 ); ! 64: R += 8; ! 65: } ! 66: } ! 67: ! 68: free ( aes_ctx ); ! 69: return 0; ! 70: } ! 71: ! 72: /** ! 73: * Unwrap a key or other data using AES Key Wrap (RFC 3394) ! 74: * ! 75: * @v kek Key Encryption Key, 16 bytes ! 76: * @v src Data to decrypt ! 77: * @v nblk Number of 8-byte blocks in @e plaintext key ! 78: * @ret dest Decrypted data (8 bytes shorter than input) ! 79: * @ret rc Zero on success, nonzero on IV mismatch ! 80: * ! 81: * The algorithm is implemented such that @a src and @a dest may point ! 82: * to the same buffer. ! 83: */ ! 84: int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk ) ! 85: { ! 86: u8 A[8], B[16]; ! 87: u8 *R; ! 88: int i, j; ! 89: void *aes_ctx = malloc ( AES_CTX_SIZE ); ! 90: ! 91: if ( ! aes_ctx ) ! 92: return -1; ! 93: ! 94: cipher_setkey ( &aes_algorithm, aes_ctx, kek, 16 ); ! 95: ! 96: /* Set up */ ! 97: memcpy ( A, src, 8 ); ! 98: memmove ( dest, src + 8, nblk * 8 ); ! 99: ! 100: /* Unwrap */ ! 101: for ( j = 5; j >= 0; j-- ) { ! 102: R = dest + ( nblk - 1 ) * 8; ! 103: for ( i = nblk; i >= 1; i-- ) { ! 104: memcpy ( B, A, 8 ); ! 105: memcpy ( B + 8, R, 8 ); ! 106: B[7] ^= ( nblk * j ) + i; ! 107: cipher_decrypt ( &aes_algorithm, aes_ctx, B, B, 16 ); ! 108: memcpy ( A, B, 8 ); ! 109: memcpy ( R, B + 8, 8 ); ! 110: R -= 8; ! 111: } ! 112: } ! 113: ! 114: free ( aes_ctx ); ! 115: ! 116: /* Check IV */ ! 117: for ( i = 0; i < 8; i++ ) { ! 118: if ( A[i] != 0xA6 ) ! 119: return -1; ! 120: } ! 121: ! 122: return 0; ! 123: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.