Index: head/sys/crypto/rijndael/rijndael-api-fst.c =================================================================== --- head/sys/crypto/rijndael/rijndael-api-fst.c (revision 274339) +++ head/sys/crypto/rijndael/rijndael-api-fst.c (revision 274340) @@ -1,441 +1,442 @@ /* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */ /* * rijndael-api-fst.c v2.3 April '2000 * * Optimised ANSI C code * * authors: v1.0: Antoon Bosselaers * v2.0: Vincent Rijmen * v2.1: Vincent Rijmen * v2.2: Vincent Rijmen * v2.3: Paulo Barreto * v2.4: Vincent Rijmen * * This code is placed in the public domain. */ #include __FBSDID("$FreeBSD$"); #include #ifdef _KERNEL #include #else #include #endif #include #include #ifndef TRUE #define TRUE 1 #endif typedef u_int8_t BYTE; -int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) { +int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, + const char *keyMaterial) { u_int8_t cipherKey[RIJNDAEL_MAXKB]; if (key == NULL) { return BAD_KEY_INSTANCE; } if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { key->direction = direction; } else { return BAD_KEY_DIR; } if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { key->keyLen = keyLen; } else { return BAD_KEY_MAT; } if (keyMaterial != NULL) { memcpy(key->keyMaterial, keyMaterial, keyLen/8); } /* initialize key schedule: */ memcpy(cipherKey, key->keyMaterial, keyLen/8); if (direction == DIR_ENCRYPT) { key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen); } else { key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen); } rijndaelKeySetupEnc(key->ek, cipherKey, keyLen); return TRUE; } int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { cipher->mode = mode; } else { return BAD_CIPHER_MODE; } if (IV != NULL) { memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE); } else { memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE); } return TRUE; } int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputLen, BYTE *outBuffer) { + const BYTE *input, int inputLen, BYTE *outBuffer) { int i, k, numBlocks; u_int8_t block[16], iv[4][4]; if (cipher == NULL || key == NULL || key->direction == DIR_DECRYPT) { return BAD_CIPHER_STATE; } if (input == NULL || inputLen <= 0) { return 0; /* nothing to do */ } numBlocks = inputLen/128; switch (cipher->mode) { case MODE_ECB: for (i = numBlocks; i > 0; i--) { rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); input += 16; outBuffer += 16; } break; case MODE_CBC: #if 1 /*STRICT_ALIGN*/ memcpy(block, cipher->IV, 16); memcpy(iv, input, 16); ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0]; ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1]; ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2]; ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3]; #else ((u_int32_t*)block)[0] = ((u_int32_t*)cipher->IV)[0] ^ ((u_int32_t*)input)[0]; ((u_int32_t*)block)[1] = ((u_int32_t*)cipher->IV)[1] ^ ((u_int32_t*)input)[1]; ((u_int32_t*)block)[2] = ((u_int32_t*)cipher->IV)[2] ^ ((u_int32_t*)input)[2]; ((u_int32_t*)block)[3] = ((u_int32_t*)cipher->IV)[3] ^ ((u_int32_t*)input)[3]; #endif rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); input += 16; for (i = numBlocks - 1; i > 0; i--) { #if 1 /*STRICT_ALIGN*/ memcpy(block, outBuffer, 16); memcpy(iv, input, 16); ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0]; ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1]; ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2]; ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3]; #else ((u_int32_t*)block)[0] = ((u_int32_t*)outBuffer)[0] ^ ((u_int32_t*)input)[0]; ((u_int32_t*)block)[1] = ((u_int32_t*)outBuffer)[1] ^ ((u_int32_t*)input)[1]; ((u_int32_t*)block)[2] = ((u_int32_t*)outBuffer)[2] ^ ((u_int32_t*)input)[2]; ((u_int32_t*)block)[3] = ((u_int32_t*)outBuffer)[3] ^ ((u_int32_t*)input)[3]; #endif outBuffer += 16; rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); input += 16; } break; case MODE_CFB1: #if 1 /*STRICT_ALIGN*/ memcpy(iv, cipher->IV, 16); #else /* !STRICT_ALIGN */ *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV )); *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4)); *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8)); *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12)); #endif /* ?STRICT_ALIGN */ for (i = numBlocks; i > 0; i--) { for (k = 0; k < 128; k++) { *((u_int32_t*) block ) = *((u_int32_t*)iv[0]); *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]); *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]); *((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]); rijndaelEncrypt(key->ek, key->Nr, block, block); outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); } } break; default: return BAD_CIPHER_STATE; } return 128*numBlocks; } /** * Encrypt data partitioned in octets, using RFC 2040-like padding. * * @param input data to be encrypted (octet sequence) * @param inputOctets input length in octets (not bits) * @param outBuffer encrypted output data * * @return length in octets (not bits) of the encrypted output buffer. */ int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputOctets, BYTE *outBuffer) { + const BYTE *input, int inputOctets, BYTE *outBuffer) { int i, numBlocks, padLen; u_int8_t block[16], *iv, *cp; if (cipher == NULL || key == NULL || key->direction == DIR_DECRYPT) { return BAD_CIPHER_STATE; } if (input == NULL || inputOctets <= 0) { return 0; /* nothing to do */ } numBlocks = inputOctets/16; switch (cipher->mode) { case MODE_ECB: for (i = numBlocks; i > 0; i--) { rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); input += 16; outBuffer += 16; } padLen = 16 - (inputOctets - 16*numBlocks); if (padLen <= 0 || padLen > 16) return BAD_CIPHER_STATE; memcpy(block, input, 16 - padLen); for (cp = block + 16 - padLen; cp < block + 16; cp++) *cp = padLen; rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); break; case MODE_CBC: iv = cipher->IV; for (i = numBlocks; i > 0; i--) { ((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0]; ((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1]; ((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2]; ((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3]; rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); iv = outBuffer; input += 16; outBuffer += 16; } padLen = 16 - (inputOctets - 16*numBlocks); if (padLen <= 0 || padLen > 16) return BAD_CIPHER_STATE; for (i = 0; i < 16 - padLen; i++) { block[i] = input[i] ^ iv[i]; } for (i = 16 - padLen; i < 16; i++) { block[i] = (BYTE)padLen ^ iv[i]; } rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); break; default: return BAD_CIPHER_STATE; } return 16*(numBlocks + 1); } int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputLen, BYTE *outBuffer) { + const BYTE *input, int inputLen, BYTE *outBuffer) { int i, k, numBlocks; u_int8_t block[16], iv[4][4]; if (cipher == NULL || key == NULL || (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { return BAD_CIPHER_STATE; } if (input == NULL || inputLen <= 0) { return 0; /* nothing to do */ } numBlocks = inputLen/128; switch (cipher->mode) { case MODE_ECB: for (i = numBlocks; i > 0; i--) { rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); input += 16; outBuffer += 16; } break; case MODE_CBC: #if 1 /*STRICT_ALIGN */ memcpy(iv, cipher->IV, 16); #else *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV )); *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4)); *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8)); *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12)); #endif for (i = numBlocks; i > 0; i--) { rijndaelDecrypt(key->rk, key->Nr, input, block); ((u_int32_t*)block)[0] ^= *((u_int32_t*)iv[0]); ((u_int32_t*)block)[1] ^= *((u_int32_t*)iv[1]); ((u_int32_t*)block)[2] ^= *((u_int32_t*)iv[2]); ((u_int32_t*)block)[3] ^= *((u_int32_t*)iv[3]); #if 1 /*STRICT_ALIGN*/ memcpy(iv, input, 16); memcpy(outBuffer, block, 16); #else *((u_int32_t*)iv[0]) = ((u_int32_t*)input)[0]; ((u_int32_t*)outBuffer)[0] = ((u_int32_t*)block)[0]; *((u_int32_t*)iv[1]) = ((u_int32_t*)input)[1]; ((u_int32_t*)outBuffer)[1] = ((u_int32_t*)block)[1]; *((u_int32_t*)iv[2]) = ((u_int32_t*)input)[2]; ((u_int32_t*)outBuffer)[2] = ((u_int32_t*)block)[2]; *((u_int32_t*)iv[3]) = ((u_int32_t*)input)[3]; ((u_int32_t*)outBuffer)[3] = ((u_int32_t*)block)[3]; #endif input += 16; outBuffer += 16; } break; case MODE_CFB1: #if 1 /*STRICT_ALIGN */ memcpy(iv, cipher->IV, 16); #else *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV)); *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4)); *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8)); *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12)); #endif for (i = numBlocks; i > 0; i--) { for (k = 0; k < 128; k++) { *((u_int32_t*) block ) = *((u_int32_t*)iv[0]); *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]); *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]); *((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]); rijndaelEncrypt(key->ek, key->Nr, block, block); iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); } } break; default: return BAD_CIPHER_STATE; } return 128*numBlocks; } int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputOctets, BYTE *outBuffer) { + const BYTE *input, int inputOctets, BYTE *outBuffer) { int i, numBlocks, padLen; u_int8_t block[16]; u_int32_t iv[4]; if (cipher == NULL || key == NULL || key->direction == DIR_ENCRYPT) { return BAD_CIPHER_STATE; } if (input == NULL || inputOctets <= 0) { return 0; /* nothing to do */ } if (inputOctets % 16 != 0) { return BAD_DATA; } numBlocks = inputOctets/16; switch (cipher->mode) { case MODE_ECB: /* all blocks but last */ for (i = numBlocks - 1; i > 0; i--) { rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); input += 16; outBuffer += 16; } /* last block */ rijndaelDecrypt(key->rk, key->Nr, input, block); padLen = block[15]; if (padLen >= 16) { return BAD_DATA; } for (i = 16 - padLen; i < 16; i++) { if (block[i] != padLen) { return BAD_DATA; } } memcpy(outBuffer, block, 16 - padLen); break; case MODE_CBC: memcpy(iv, cipher->IV, 16); /* all blocks but last */ for (i = numBlocks - 1; i > 0; i--) { rijndaelDecrypt(key->rk, key->Nr, input, block); ((u_int32_t*)block)[0] ^= iv[0]; ((u_int32_t*)block)[1] ^= iv[1]; ((u_int32_t*)block)[2] ^= iv[2]; ((u_int32_t*)block)[3] ^= iv[3]; memcpy(iv, input, 16); memcpy(outBuffer, block, 16); input += 16; outBuffer += 16; } /* last block */ rijndaelDecrypt(key->rk, key->Nr, input, block); ((u_int32_t*)block)[0] ^= iv[0]; ((u_int32_t*)block)[1] ^= iv[1]; ((u_int32_t*)block)[2] ^= iv[2]; ((u_int32_t*)block)[3] ^= iv[3]; padLen = block[15]; if (padLen <= 0 || padLen > 16) { return BAD_DATA; } for (i = 16 - padLen; i < 16; i++) { if (block[i] != padLen) { return BAD_DATA; } } memcpy(outBuffer, block, 16 - padLen); break; default: return BAD_CIPHER_STATE; } return 16*numBlocks - padLen; } Index: head/sys/crypto/rijndael/rijndael-api-fst.h =================================================================== --- head/sys/crypto/rijndael/rijndael-api-fst.h (revision 274339) +++ head/sys/crypto/rijndael/rijndael-api-fst.h (revision 274340) @@ -1,73 +1,73 @@ /* $FreeBSD$ */ /* $KAME: rijndael-api-fst.h,v 1.6 2001/05/27 00:23:23 itojun Exp $ */ /* * rijndael-api-fst.h v2.3 April '2000 * * Optimised ANSI C code * */ #ifndef __RIJNDAEL_API_FST_H #define __RIJNDAEL_API_FST_H #include /* Generic Defines */ #define DIR_ENCRYPT 0 /* Are we encrpyting? */ #define DIR_DECRYPT 1 /* Are we decrpyting? */ #define MODE_ECB 1 /* Are we ciphering in ECB mode? */ #define MODE_CBC 2 /* Are we ciphering in CBC mode? */ #define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ #define BITSPERBLOCK 128 /* Default number of bits in a cipher block */ /* Error Codes */ #define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */ #define BAD_KEY_MAT -2 /* Key material not of correct length */ #define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ #define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */ #define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */ #define BAD_BLOCK_LENGTH -6 #define BAD_CIPHER_INSTANCE -7 #define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */ #define BAD_OTHER -9 /* Unknown error */ /* Algorithm-specific Defines */ #define RIJNDAEL_MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */ #define RIJNDAEL_MAX_IV_SIZE 16 /* # bytes needed to represent an IV */ /* Typedefs */ /* The structure for key information */ typedef struct { u_int8_t direction; /* Key used for encrypting or decrypting? */ int keyLen; /* Length of the key */ char keyMaterial[RIJNDAEL_MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */ int Nr; /* key-length-dependent number of rounds */ u_int32_t rk[4*(RIJNDAEL_MAXNR + 1)]; /* key schedule */ u_int32_t ek[4*(RIJNDAEL_MAXNR + 1)]; /* CFB1 key schedule (encryption only) */ } keyInstance; /* The structure for cipher information */ typedef struct { /* changed order of the components */ u_int8_t mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ u_int8_t IV[RIJNDAEL_MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */ } cipherInstance; /* Function prototypes */ -int rijndael_makeKey(keyInstance *, u_int8_t, int, char *); +int rijndael_makeKey(keyInstance *, u_int8_t, int, const char *); int rijndael_cipherInit(cipherInstance *, u_int8_t, char *); -int rijndael_blockEncrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); -int rijndael_padEncrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); +int rijndael_blockEncrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); +int rijndael_padEncrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); -int rijndael_blockDecrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); -int rijndael_padDecrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); +int rijndael_blockDecrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); +int rijndael_padDecrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); #endif /* __RIJNDAEL_API_FST_H */ Index: head/sys/dev/random/fortuna.c =================================================================== --- head/sys/dev/random/fortuna.c (revision 274339) +++ head/sys/dev/random/fortuna.c (revision 274340) @@ -1,443 +1,438 @@ /*- * Copyright (c) 2013-2014 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* This implementation of Fortuna is based on the descriptions found in * ISBN 0-471-22357-3 "Practical Cryptography" by Ferguson and Schneier - * ("K&S"). + * ("F&S"). * - * The above book is superceded by ISBN 978-0-470-47424-2 "Cryptography - * Engineering" by Ferguson, Schneier and Kohno ("FS&K"). - * - * This code has not yet caught up with FS&K, but differences are not - * expected to be complex. + * The above book is superseded by ISBN 978-0-470-47424-2 "Cryptography + * Engineering" by Ferguson, Schneier and Kohno ("FS&K"). The code has + * not yet fully caught up with FS&K. */ #include __FBSDID("$FreeBSD$"); #ifdef _KERNEL #include "opt_random.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #else /* !_KERNEL */ #include #include #include #include #include #include #include #include "unit_test.h" #include #include #include #include #include #endif /* _KERNEL */ #if !defined(RANDOM_YARROW) && !defined(RANDOM_FORTUNA) #define RANDOM_YARROW #elif defined(RANDOM_YARROW) && defined(RANDOM_FORTUNA) #error "Must define either RANDOM_YARROW or RANDOM_FORTUNA" #endif #if defined(RANDOM_FORTUNA) #define NPOOLS 32 #define MINPOOLSIZE 64 #define DEFPOOLSIZE 256 #define MAXPOOLSIZE 65536 /* This algorithm (and code) presumes that KEYSIZE is twice as large as BLOCKSIZE */ CTASSERT(BLOCKSIZE == sizeof(uint128_t)); CTASSERT(KEYSIZE == 2*BLOCKSIZE); /* This is the beastie that needs protecting. It contains all of the * state that we are excited about. * Exactly one is instantiated. */ static struct fortuna_state { /* P_i */ struct pool { u_int length; struct randomdev_hash hash; } pool[NPOOLS]; /* ReseedCnt */ u_int reseedcount; /* C - 128 bits */ union { uint8_t byte[BLOCKSIZE]; uint128_t whole; } counter; /* K */ struct randomdev_key key; /* Extras */ u_int minpoolsize; /* Extras for the OS */ #ifdef _KERNEL /* For use when 'pacing' the reseeds */ sbintime_t lasttime; #endif } fortuna_state; /* The random_reseed_mtx mutex protects seeding and polling/blocking. */ static mtx_t random_reseed_mtx; static struct fortuna_start_cache { uint8_t junk[PAGE_SIZE]; size_t length; struct randomdev_hash hash; } fortuna_start_cache; #ifdef _KERNEL static struct sysctl_ctx_list random_clist; RANDOM_CHECK_UINT(minpoolsize, MINPOOLSIZE, MAXPOOLSIZE); #endif void random_fortuna_init_alg(void) { int i; #ifdef _KERNEL struct sysctl_oid *random_fortuna_o; #endif memset(fortuna_start_cache.junk, 0, sizeof(fortuna_start_cache.junk)); fortuna_start_cache.length = 0U; randomdev_hash_init(&fortuna_start_cache.hash); /* Set up a lock for the reseed process */ #ifdef _KERNEL mtx_init(&random_reseed_mtx, "reseed mutex", NULL, MTX_DEF); #else /* !_KERNEL */ mtx_init(&random_reseed_mtx, mtx_plain); #endif /* _KERNEL */ #ifdef _KERNEL /* Fortuna parameters. Do not adjust these unless you have * have a very good clue about what they do! */ random_fortuna_o = SYSCTL_ADD_NODE(&random_clist, SYSCTL_STATIC_CHILDREN(_kern_random), OID_AUTO, "fortuna", CTLFLAG_RW, 0, "Fortuna Parameters"); SYSCTL_ADD_PROC(&random_clist, SYSCTL_CHILDREN(random_fortuna_o), OID_AUTO, "minpoolsize", CTLTYPE_UINT|CTLFLAG_RW, &fortuna_state.minpoolsize, DEFPOOLSIZE, random_check_uint_minpoolsize, "IU", "Minimum pool size necessary to cause a reseed automatically"); fortuna_state.lasttime = 0U; #endif fortuna_state.minpoolsize = DEFPOOLSIZE; /* F&S - InitializePRNG() */ /* F&S - P_i = \epsilon */ for (i = 0; i < NPOOLS; i++) { randomdev_hash_init(&fortuna_state.pool[i].hash); fortuna_state.pool[i].length = 0U; } /* F&S - ReseedCNT = 0 */ fortuna_state.reseedcount = 0U; /* F&S - InitializeGenerator() */ /* F&S - C = 0 */ uint128_clear(&fortuna_state.counter.whole); /* F&S - K = 0 */ memset(&fortuna_state.key, 0, sizeof(fortuna_state.key)); } void random_fortuna_deinit_alg(void) { mtx_destroy(&random_reseed_mtx); memset(&fortuna_state, 0, sizeof(fortuna_state)); } /* F&S - AddRandomEvent() */ /* Process a single stochastic event off the harvest queue */ void random_fortuna_process_event(struct harvest_event *event) { u_int pl; /* We must be locked for all this as plenty of state gets messed with */ mtx_lock(&random_reseed_mtx); /* Accumulate the event into the appropriate pool * where each event carries the destination information */ /* F&S - P_i = P_i| */ /* The hash_init and hash_finish are done in random_fortuna_read() below */ pl = event->he_destination % NPOOLS; randomdev_hash_iterate(&fortuna_state.pool[pl].hash, event, sizeof(*event)); /* No point in counting above the outside maximum */ fortuna_state.pool[pl].length += event->he_size; fortuna_state.pool[pl].length = MIN(fortuna_state.pool[pl].length, MAXPOOLSIZE); /* Done with state-messing */ mtx_unlock(&random_reseed_mtx); } /* F&S - Reseed() */ /* Reseed Mutex is held */ static void reseed(uint8_t *junk, u_int length) { struct randomdev_hash context; uint8_t hash[KEYSIZE]; KASSERT(fortuna_state.minpoolsize > 0, ("random: Fortuna threshold = 0")); #ifdef _KERNEL mtx_assert(&random_reseed_mtx, MA_OWNED); #endif - /* F&S - K = Hd(K|s) where Hd(m) is H(H(m)) */ + /* FS&K - K = Hd(K|s) where Hd(m) is H(H(0^512|m)) */ randomdev_hash_init(&context); -#if 0 - /* FS&K defines Hd(m) as H(H(0^512|m)) */ - randomdev_hash_iterate(&context, zero_region, KEYSIZE); -#endif + randomdev_hash_iterate(&context, zero_region, 512/8); randomdev_hash_iterate(&context, &fortuna_state.key, sizeof(fortuna_state.key)); randomdev_hash_iterate(&context, junk, length); randomdev_hash_finish(&context, hash); randomdev_hash_init(&context); randomdev_hash_iterate(&context, hash, KEYSIZE); randomdev_hash_finish(&context, hash); randomdev_encrypt_init(&fortuna_state.key, hash); memset(hash, 0, sizeof(hash)); /* Unblock the device if it was blocked due to being unseeded */ if (uint128_is_zero(fortuna_state.counter.whole)) random_adaptor_unblock(); - /* F&S - C = C + 1 */ + /* FS&K - C = C + 1 */ uint128_increment(&fortuna_state.counter.whole); } /* F&S - GenerateBlocks() */ /* Reseed Mutex is held, and buf points to a whole number of blocks. */ static __inline void random_fortuna_genblocks(uint8_t *buf, u_int blockcount) { u_int i; for (i = 0u; i < blockcount; i++) { /* F&S - r = r|E(K,C) */ randomdev_encrypt(&fortuna_state.key, fortuna_state.counter.byte, buf, BLOCKSIZE); buf += BLOCKSIZE; /* F&S - C = C + 1 */ uint128_increment(&fortuna_state.counter.whole); } } /* F&S - PseudoRandomData() */ /* Reseed Mutex is held, and buf points to a whole number of blocks. */ static __inline void random_fortuna_genrandom(uint8_t *buf, u_int bytecount) { static uint8_t temp[BLOCKSIZE*(KEYSIZE/BLOCKSIZE)]; u_int blockcount; /* F&S - assert(n < 2^20) */ KASSERT((bytecount <= (1 << 20)), ("invalid single read request to fortuna of %d bytes", bytecount)); /* F&S - r = first-n-bytes(GenerateBlocks(ceil(n/16))) */ blockcount = (bytecount + BLOCKSIZE - 1)/BLOCKSIZE; random_fortuna_genblocks(buf, blockcount); /* F&S - K = GenerateBlocks(2) */ random_fortuna_genblocks(temp, KEYSIZE/BLOCKSIZE); randomdev_encrypt_init(&fortuna_state.key, temp); memset(temp, 0, sizeof(temp)); } /* F&S - RandomData() */ /* Used to return processed entropy from the PRNG */ /* The argument buf points to a whole number of blocks. */ void random_fortuna_read(uint8_t *buf, u_int bytecount) { #ifdef _KERNEL sbintime_t thistime; #endif struct randomdev_hash context; uint8_t s[NPOOLS*KEYSIZE], temp[KEYSIZE]; int i; u_int seedlength; /* We must be locked for all this as plenty of state gets messed with */ mtx_lock(&random_reseed_mtx); /* if buf == NULL and bytecount == 0 then this is the pre-read. */ /* if buf == NULL and bytecount != 0 then this is the post-read; ignore. */ if (buf == NULL) { if (bytecount == 0) { if (fortuna_state.pool[0].length >= fortuna_state.minpoolsize #ifdef _KERNEL /* F&S - Use 'getsbinuptime()' to prevent reseed-spamming. */ && ((thistime = getsbinuptime()) - fortuna_state.lasttime > hz/10) #endif ) { #ifdef _KERNEL fortuna_state.lasttime = thistime; #endif seedlength = 0U; /* F&S - ReseedCNT = ReseedCNT + 1 */ fortuna_state.reseedcount++; /* s = \epsilon by default */ for (i = 0; i < NPOOLS; i++) { /* F&S - if Divides(ReseedCnt, 2^i) ... */ if ((fortuna_state.reseedcount % (1 << i)) == 0U) { seedlength += KEYSIZE; /* F&S - temp = (P_i) */ randomdev_hash_finish(&fortuna_state.pool[i].hash, temp); /* F&S - P_i = \epsilon */ randomdev_hash_init(&fortuna_state.pool[i].hash); fortuna_state.pool[i].length = 0U; /* F&S - s = s|H(temp) */ randomdev_hash_init(&context); randomdev_hash_iterate(&context, temp, KEYSIZE); randomdev_hash_finish(&context, s + i*KEYSIZE); } else break; } #ifdef RANDOM_DEBUG printf("random: active reseed: reseedcount [%d] ", fortuna_state.reseedcount); for (i = 0; i < NPOOLS; i++) printf(" %d", fortuna_state.pool[i].length); printf("\n"); #endif /* F&S */ reseed(s, seedlength); /* Clean up */ memset(s, 0, seedlength); seedlength = 0U; memset(temp, 0, sizeof(temp)); memset(&context, 0, sizeof(context)); } } } /* if buf != NULL do a regular read. */ else random_fortuna_genrandom(buf, bytecount); mtx_unlock(&random_reseed_mtx); } /* Internal function to hand external entropy to the PRNG */ void random_fortuna_write(uint8_t *buf, u_int count) { uint8_t temp[KEYSIZE]; int i; uintmax_t timestamp; timestamp = get_cyclecount(); randomdev_hash_iterate(&fortuna_start_cache.hash, ×tamp, sizeof(timestamp)); randomdev_hash_iterate(&fortuna_start_cache.hash, buf, count); timestamp = get_cyclecount(); randomdev_hash_iterate(&fortuna_start_cache.hash, ×tamp, sizeof(timestamp)); randomdev_hash_finish(&fortuna_start_cache.hash, temp); for (i = 0; i < KEYSIZE; i++) fortuna_start_cache.junk[(fortuna_start_cache.length + i)%PAGE_SIZE] ^= temp[i]; fortuna_start_cache.length += KEYSIZE; #ifdef RANDOM_DEBUG printf("random: %s - ", __func__); for (i = 0; i < KEYSIZE; i++) printf("%02X", temp[i]); printf("\n"); #endif memset(temp, 0, KEYSIZE); /* We must be locked for all this as plenty of state gets messed with */ mtx_lock(&random_reseed_mtx); randomdev_hash_init(&fortuna_start_cache.hash); reseed(fortuna_start_cache.junk, MIN(PAGE_SIZE, fortuna_start_cache.length)); memset(fortuna_start_cache.junk, 0, sizeof(fortuna_start_cache.junk)); mtx_unlock(&random_reseed_mtx); } void random_fortuna_reseed(void) { /* CWOT */ } int random_fortuna_seeded(void) { return (!uint128_is_zero(fortuna_state.counter.whole)); } #endif /* RANDOM_FORTUNA */ Index: head/sys/dev/random/hash.c =================================================================== --- head/sys/dev/random/hash.c (revision 274339) +++ head/sys/dev/random/hash.c (revision 274340) @@ -1,100 +1,100 @@ /*- * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #ifdef _KERNEL #include #include #else /* !_KERNEL */ #include #include #include #include #include #include #include #include "unit_test.h" #endif /* _KERNEL */ #include #include #include /* This code presumes that KEYSIZE is twice as large as BLOCKSIZE */ CTASSERT(KEYSIZE == 2*BLOCKSIZE); /* Initialise the hash */ void randomdev_hash_init(struct randomdev_hash *context) { SHA256_Init(&context->sha); } /* Iterate the hash */ void -randomdev_hash_iterate(struct randomdev_hash *context, void *data, size_t size) +randomdev_hash_iterate(struct randomdev_hash *context, const void *data, size_t size) { SHA256_Update(&context->sha, data, size); } /* Conclude by returning the hash in the supplied <*buf> which must be * KEYSIZE bytes long. */ void randomdev_hash_finish(struct randomdev_hash *context, void *buf) { SHA256_Final(buf, &context->sha); } /* Initialise the encryption routine by setting up the key schedule * from the supplied <*data> which must be KEYSIZE bytes of binary * data. Use CBC mode for better avalanche. */ void -randomdev_encrypt_init(struct randomdev_key *context, void *data) +randomdev_encrypt_init(struct randomdev_key *context, const void *data) { rijndael_cipherInit(&context->cipher, MODE_CBC, NULL); rijndael_makeKey(&context->key, DIR_ENCRYPT, KEYSIZE*8, data); } /* Encrypt the supplied data using the key schedule preset in the context. * bytes are encrypted from <*d_in> to <*d_out>. must be * a multiple of BLOCKSIZE. */ void -randomdev_encrypt(struct randomdev_key *context, void *d_in, void *d_out, u_int length) +randomdev_encrypt(struct randomdev_key *context, const void *d_in, void *d_out, u_int length) { rijndael_blockEncrypt(&context->cipher, &context->key, d_in, length*8, d_out); } Index: head/sys/dev/random/hash.h =================================================================== --- head/sys/dev/random/hash.h (revision 274339) +++ head/sys/dev/random/hash.h (revision 274340) @@ -1,50 +1,50 @@ /*- * Copyright (c) 2000-2013 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef SYS_DEV_RANDOM_HASH_H_INCLUDED #define SYS_DEV_RANDOM_HASH_H_INCLUDED #define KEYSIZE 32 /* (in bytes) == 256 bits */ #define BLOCKSIZE 16 /* (in bytes) == 128 bits */ struct randomdev_hash { /* Big! Make static! */ SHA256_CTX sha; }; struct randomdev_key { /* Big! Make static! */ keyInstance key; /* Key schedule */ cipherInstance cipher; /* Rijndael internal */ }; void randomdev_hash_init(struct randomdev_hash *); -void randomdev_hash_iterate(struct randomdev_hash *, void *, size_t); +void randomdev_hash_iterate(struct randomdev_hash *, const void *, size_t); void randomdev_hash_finish(struct randomdev_hash *, void *); -void randomdev_encrypt_init(struct randomdev_key *, void *); -void randomdev_encrypt(struct randomdev_key *context, void *, void *, u_int); +void randomdev_encrypt_init(struct randomdev_key *, const void *); +void randomdev_encrypt(struct randomdev_key *context, const void *, void *, u_int); #endif Index: head/sys/geom/bde/g_bde.h =================================================================== --- head/sys/geom/bde/g_bde.h (revision 274339) +++ head/sys/geom/bde/g_bde.h (revision 274340) @@ -1,211 +1,211 @@ /*- * Copyright (c) 2002 Poul-Henning Kamp * Copyright (c) 2002 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed for the FreeBSD Project by Poul-Henning Kamp * and NAI Labs, the Security Research Division of Network Associates, Inc. * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the * DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _SYS_GEOM_BDE_G_BDE_H_ #define _SYS_GEOM_BDE_G_BDE_H_ 1 /* * These are quite, but not entirely unlike constants. * * They are not commented in details here, to prevent unadvisable * experimentation. Please consult the code where they are used before you * even think about modifying these. */ #define G_BDE_MKEYLEN (2048/8) #define G_BDE_SKEYBITS 128 #define G_BDE_SKEYLEN (G_BDE_SKEYBITS/8) #define G_BDE_KKEYBITS 128 #define G_BDE_KKEYLEN (G_BDE_KKEYBITS/8) #define G_BDE_MAXKEYS 4 #define G_BDE_LOCKSIZE 384 #define NLOCK_FIELDS 13 /* This just needs to be "large enough" */ #define G_BDE_KEYBYTES 304 struct g_bde_work; struct g_bde_softc; struct g_bde_sector { struct g_bde_work *owner; struct g_bde_softc *softc; off_t offset; u_int size; u_int ref; void *data; TAILQ_ENTRY(g_bde_sector) list; u_char valid; u_char malloc; enum {JUNK, IO, VALID} state; int error; time_t used; }; struct g_bde_work { struct mtx mutex; off_t offset; off_t length; void *data; struct bio *bp; struct g_bde_softc *softc; off_t so; off_t kso; u_int ko; struct g_bde_sector *sp; struct g_bde_sector *ksp; TAILQ_ENTRY(g_bde_work) list; enum {SETUP, WAIT, FINISH} state; int error; }; /* * The decrypted contents of the lock sectors. Notice that this is not * the same as the on-disk layout. The on-disk layout is dynamic and * dependent on the pass-phrase. */ struct g_bde_key { uint64_t sector0; /* Physical byte offset of 1st byte used */ uint64_t sectorN; /* Physical byte offset of 1st byte not used */ uint64_t keyoffset; /* Number of bytes the disk image is skewed. */ uint64_t lsector[G_BDE_MAXKEYS]; /* Physical byte offsets of lock sectors */ uint32_t sectorsize; /* Our "logical" sector size */ uint32_t flags; #define GBDE_F_SECT0 1 uint8_t salt[16]; /* Used to frustate the kkey generation */ uint8_t spare[32]; /* For future use, random contents */ uint8_t mkey[G_BDE_MKEYLEN]; /* Our masterkey. */ /* Non-stored help-fields */ uint64_t zone_width; /* On-disk width of zone */ uint64_t zone_cont; /* Payload width of zone */ uint64_t media_width; /* Non-magic width of zone */ u_int keys_per_sector; }; struct g_bde_softc { off_t mediasize; u_int sectorsize; uint64_t zone_cont; struct g_geom *geom; struct g_consumer *consumer; TAILQ_HEAD(, g_bde_sector) freelist; TAILQ_HEAD(, g_bde_work) worklist; struct mtx worklist_mutex; struct proc *thread; struct g_bde_key key; int dead; u_int nwork; u_int nsect; u_int ncache; u_char sha2[SHA512_DIGEST_LENGTH]; }; /* g_bde_crypt.c */ void g_bde_crypt_delete(struct g_bde_work *wp); void g_bde_crypt_read(struct g_bde_work *wp); void g_bde_crypt_write(struct g_bde_work *wp); /* g_bde_key.c */ void g_bde_zap_key(struct g_bde_softc *sc); int g_bde_get_key(struct g_bde_softc *sc, void *ptr, int len); int g_bde_init_keybytes(struct g_bde_softc *sc, char *passp, int len); /* g_bde_lock .c */ int g_bde_encode_lock(u_char *sha2, struct g_bde_key *gl, u_char *ptr); int g_bde_decode_lock(struct g_bde_softc *sc, struct g_bde_key *gl, u_char *ptr); int g_bde_keyloc_encrypt(u_char *sha2, uint64_t v0, uint64_t v1, void *output); int g_bde_keyloc_decrypt(u_char *sha2, void *input, uint64_t *output); int g_bde_decrypt_lock(struct g_bde_softc *sc, u_char *keymat, u_char *meta, off_t mediasize, u_int sectorsize, u_int *nkey); void g_bde_hash_pass(struct g_bde_softc *sc, const void *input, u_int len); /* g_bde_math .c */ uint64_t g_bde_max_sector(struct g_bde_key *lp); void g_bde_map_sector(struct g_bde_work *wp); /* g_bde_work.c */ void g_bde_start1(struct bio *bp); void g_bde_worker(void *arg); /* * These four functions wrap the raw Rijndael functions and make sure we * explode if something fails which shouldn't. */ static __inline void AES_init(cipherInstance *ci) { int error; error = rijndael_cipherInit(ci, MODE_CBC, NULL); KASSERT(error > 0, ("rijndael_cipherInit %d", error)); } static __inline void -AES_makekey(keyInstance *ki, int dir, u_int len, void *key) +AES_makekey(keyInstance *ki, int dir, u_int len, const void *key) { int error; error = rijndael_makeKey(ki, dir, len, key); KASSERT(error > 0, ("rijndael_makeKey %d", error)); } static __inline void -AES_encrypt(cipherInstance *ci, keyInstance *ki, void *in, void *out, u_int len) +AES_encrypt(cipherInstance *ci, keyInstance *ki, const void *in, void *out, u_int len) { int error; error = rijndael_blockEncrypt(ci, ki, in, len * 8, out); KASSERT(error > 0, ("rijndael_blockEncrypt %d", error)); } static __inline void -AES_decrypt(cipherInstance *ci, keyInstance *ki, void *in, void *out, u_int len) +AES_decrypt(cipherInstance *ci, keyInstance *ki, const void *in, void *out, u_int len) { int error; error = rijndael_blockDecrypt(ci, ki, in, len * 8, out); KASSERT(error > 0, ("rijndael_blockDecrypt %d", error)); } #endif /* _SYS_GEOM_BDE_G_BDE_H_ */