Print this page
5072963 Need an optimized AES implementation for amd64

*** 1,12 **** /* * CDDL HEADER START * * The contents of this file are subject to the terms of the ! * Common Development and Distribution License, Version 1.0 only ! * (the "License"). You may not use this file except in compliance ! * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. --- 1,11 ---- /* * CDDL HEADER START * * The contents of this file are subject to the terms of the ! * Common Development and Distribution License (the "License"). ! * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License.
*** 18,31 **** * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* ! * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include <sys/types.h> #include <sys/systm.h> #include <sys/ddi.h> #include <sys/sysmacros.h> #include <sys/strsun.h> --- 17,32 ---- * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* ! * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + #pragma ident "@(#)aes_impl.c 1.3 08/06/12 SMI" + #include <sys/types.h> #include <sys/systm.h> #include <sys/ddi.h> #include <sys/sysmacros.h> #include <sys/strsun.h>
*** 34,50 **** #ifndef _KERNEL #include <strings.h> #include <stdlib.h> #endif /* !_KERNEL */ - #pragma ident "@(#)aes_impl.c 1.2 05/06/08 SMI" /* * This file is derived from the file rijndael-alg-fst.c taken from the * "optimized C code v3.0" on the "rijndael home page" ! * (http://www.esat.kuleuven.ac.be/~rijmen/rijndael/) ! * pointed by the NIST web-site (http://nist.gov) * * The following note is from the original file: */ /* --- 35,50 ---- #ifndef _KERNEL #include <strings.h> #include <stdlib.h> #endif /* !_KERNEL */ /* * This file is derived from the file rijndael-alg-fst.c taken from the * "optimized C code v3.0" on the "rijndael home page" ! * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/ ! * pointed by the NIST web-site http://csrc.nist.gov/archive/aes/ * * The following note is from the original file: */ /*
*** 73,85 **** * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* EXPORT DELETE START */ ! #ifndef _RIJNDAEL_TBL_H ! #define _RIJNDAEL_TBL_H /* * Constant tables */ /* --- 73,109 ---- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* EXPORT DELETE START */ ! #if defined(sun4u) || defined(__amd64) ! /* External assembly functions: */ ! extern void aes_encrypt_impl(const uint32_t rk[], int Nr, const uint32_t pt[4], ! uint32_t ct[4]); ! extern void aes_decrypt_impl(const uint32_t rk[], int Nr, const uint32_t ct[4], ! uint32_t pt[4]); ! #define AES_ENCRYPT_IMPL aes_encrypt_impl ! #define AES_DECRYPT_IMPL aes_decrypt_impl + #ifdef __amd64 + extern int rijndael_key_setup_enc(uint32_t rk[], const uint32_t cipherKey[], + int keyBits); + extern int rijndael_key_setup_dec(uint32_t rk[], const uint32_t cipherKey[], + int keyBits); + #endif + + #else + #define AES_ENCRYPT_IMPL rijndael_encrypt + #define AES_DECRYPT_IMPL rijndael_decrypt + #define rijndael_key_setup_enc_raw rijndael_key_setup_enc + #endif /* sun4u || __amd64 */ + + #if defined(_LITTLE_ENDIAN) && !defined(__amd64) + #define AES_BYTE_SWAP + #endif + + #ifndef __amd64 /* * Constant tables */ /*
*** 94,103 **** --- 118,128 ---- * Td2[x] = Si[x].[0d, 0b, 0e, 09]; * Td3[x] = Si[x].[09, 0d, 0b, 0e]; * Td4[x] = Si[x].[01, 01, 01, 01]; */ + /* Encrypt Sbox constants (for the substitute bytes operation) */ static const uint32_t Te0[256] = { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
*** 438,447 **** --- 463,474 ---- 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U }; + /* Decrypt Sbox constants (for the substitute bytes operation) */ + static const uint32_t Td0[256] = { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
*** 779,802 **** 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU }; ! static const uint32_t rcon[] = { /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; - #endif /* * Expand the cipher key into the encryption key schedule. ! * return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). */ static int rijndael_key_setup_enc_raw(uint32_t rk[], const uint32_t cipherKey[], int keyBits) { --- 806,836 ---- 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU }; ! /* Rcon is Round Constant; used for encryption key expansion */ ! static const uint32_t rcon[RC_LENGTH] = { /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; + /* * Expand the cipher key into the encryption key schedule. ! * ! * Return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk AES key schedule 32-bit array to be initialized + * cipherKey User key + * keyBits AES key size (128, 192, or 256 bits) */ static int rijndael_key_setup_enc_raw(uint32_t rk[], const uint32_t cipherKey[], int keyBits) {
*** 887,906 **** } } return (0); } #ifdef sun4u /* ! * Expand the cipher key into the enryption key schedule as used * by the sun4u optimized assembly implementation. ! * return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). */ static int rijndael_key_setup_enc(uint64_t rk[], const uint32_t cipherKey[], int keyBits) { uint32_t rk1[4 * (MAX_AES_NR + 1)]; --- 921,947 ---- } } return (0); } + #endif /* !__amd64 */ #ifdef sun4u /* ! * Expand the cipher key into the encryption key schedule. * by the sun4u optimized assembly implementation. ! * ! * Return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk AES key schedule 64-bit array to be initialized + * cipherKey User key + * keyBits AES key size (128, 192, or 256 bits) */ static int rijndael_key_setup_enc(uint64_t rk[], const uint32_t cipherKey[], int keyBits) { uint32_t rk1[4 * (MAX_AES_NR + 1)];
*** 929,941 **** /* * Expand the cipher key into the decryption key schedule as used * by the sun4u optimized assembly implementation. ! * return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). */ static int rijndael_key_setup_dec_raw(uint32_t rk[], const uint32_t cipherKey[], int keyBits) { --- 970,988 ---- /* * Expand the cipher key into the decryption key schedule as used * by the sun4u optimized assembly implementation. ! * ! * Return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk AES key schedule 32-bit array to be initialized + * cipherKey User key + * keyBits AES key size (128, 192, or 256 bits) */ static int rijndael_key_setup_dec_raw(uint32_t rk[], const uint32_t cipherKey[], int keyBits) {
*** 982,993 **** /* * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). */ ! int rijndael_key_setup_dec(uint64_t rk[], const uint32_t cipherKey[], int keyBits) { uint32_t rk1[4 * (MAX_AES_NR + 1)]; uint64_t *rk64 = (uint64_t *)rk; uint32_t *rkt; --- 1029,1045 ---- /* * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk AES key schedule 64-bit array to be initialized + * cipherKey User key + * keyBits AES key size (128, 192, or 256 bits) */ ! static int rijndael_key_setup_dec(uint64_t rk[], const uint32_t cipherKey[], int keyBits) { uint32_t rk1[4 * (MAX_AES_NR + 1)]; uint64_t *rk64 = (uint64_t *)rk; uint32_t *rkt;
*** 1010,1049 **** return (Nr); } static void ! aes_setupkeys(aes_key_t *key, uint32_t *keyarr32, int keybits) { key->nr = rijndael_key_setup_enc(&(key->encr_ks.ks64[0]), keyarr32, keybits); key->nr = rijndael_key_setup_dec(&(key->decr_ks.ks64[0]), keyarr32, keybits); key->type = AES_64BIT_KS; } - #else /* !sun4u */ ! /* ! * Expand the cipher key into the encryption key schedule. ! * return the number of rounds for the given cipher key size. ! * The size of the key schedule depends on the number of rounds ! * (which can be computed from the size of the key), i.e. 4*(Nr + 1). ! */ ! static int ! rijndael_key_setup_enc(uint32_t rk[], const uint32_t cipherKey[], int keyBits) ! { ! return (rijndael_key_setup_enc_raw(rk, cipherKey, keyBits)); ! } - /* * Expand the cipher key into the decryption key schedule. ! * @return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). */ static int rijndael_key_setup_dec(uint32_t rk[], const uint32_t cipherKey[], int keyBits) { int Nr, i, j; --- 1062,1103 ---- return (Nr); } + /* + * Expand the 64-bit AES cipher key array into the encryption and decryption + * key schedules. + * + * Parameters: + * key AES key schedule to be initialized + * keyarr32 User key + * keyBits AES key size (128, 192, or 256 bits) + */ static void ! aes_setupkeys(aes_key_t *key, const uint32_t *keyarr32, int keybits) { key->nr = rijndael_key_setup_enc(&(key->encr_ks.ks64[0]), keyarr32, keybits); key->nr = rijndael_key_setup_dec(&(key->decr_ks.ks64[0]), keyarr32, keybits); key->type = AES_64BIT_KS; } ! #elif !defined(__amd64) /* * Expand the cipher key into the decryption key schedule. ! * Return the number of rounds for the given cipher key size. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk AES key schedule 32-bit array to be initialized + * cipherKey User key + * keyBits AES key size (128, 192, or 256 bits) */ static int rijndael_key_setup_dec(uint32_t rk[], const uint32_t cipherKey[], int keyBits) { int Nr, i, j;
*** 1094,1122 **** return (Nr); } - static void - aes_setupkeys(aes_key_t *key, uint32_t *keyarr32, int keybits) - { - key->nr = rijndael_key_setup_enc(&(key->encr_ks.ks32[0]), keyarr32, - keybits); - key->nr = rijndael_key_setup_dec(&(key->decr_ks.ks32[0]), keyarr32, - keybits); - key->type = AES_32BIT_KS; - } - /* * Encrypt one block of data. The block is assumed to be an array * of four uint32_t values, so copy for alignment (and byte-order * reversal for little endian systems might be necessary on the * input and output byte streams. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). */ ! void rijndael_encrypt(const uint32_t rk[], int Nr, const uint32_t pt[4], uint32_t ct[4]) { uint32_t s0, s1, s2, s3, t0, t1, t2, t3; int r; --- 1148,1172 ---- return (Nr); } /* * Encrypt one block of data. The block is assumed to be an array * of four uint32_t values, so copy for alignment (and byte-order * reversal for little endian systems might be necessary on the * input and output byte streams. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk Key schedule, of aes_ks_t (60 32-bit integers) + * Nr Number of rounds + * pt Input block (plain text) + * ct Output block (crypto text). Can overlap with pt */ ! static void rijndael_encrypt(const uint32_t rk[], int Nr, const uint32_t pt[4], uint32_t ct[4]) { uint32_t s0, s1, s2, s3, t0, t1, t2, t3; int r;
*** 1233,1244 **** * of four uint32_t values, so copy for alignment (and byte-order * reversal for little endian systems might be necessary on the * input and output byte streams. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). */ ! void rijndael_decrypt(const uint32_t rk[], int Nr, const uint32_t ct[4], uint32_t pt[4]) { uint32_t s0, s1, s2, s3, t0, t1, t2, t3; int r; --- 1283,1300 ---- * of four uint32_t values, so copy for alignment (and byte-order * reversal for little endian systems might be necessary on the * input and output byte streams. * The size of the key schedule depends on the number of rounds * (which can be computed from the size of the key), i.e. 4*(Nr + 1). + * + * Parameters: + * rk Key schedule, of aes_ks_t (60 32-bit integers) + * Nr Number of rounds + * ct Input block (crypto text) + * pt Output block (plain text). Can overlap with pt */ ! static void rijndael_decrypt(const uint32_t rk[], int Nr, const uint32_t ct[4], uint32_t pt[4]) { uint32_t s0, s1, s2, s3, t0, t1, t2, t3; int r;
*** 1345,1384 **** (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[t0 & 0xff] & 0x000000ff) ^ rk[3]; pt[3] = s3; } ! void ! aes_encrypt_impl(const aes_ks_t *ks, int Nr, const uint32_t pt[4], ! uint32_t ct[4]) { ! rijndael_encrypt(&(ks->ks32[0]), Nr, pt, ct); } - - void - aes_decrypt_impl(const aes_ks_t *ks, int Nr, const uint32_t ct[4], - uint32_t pt[4]) - { - rijndael_decrypt(&(ks->ks32[0]), Nr, ct, pt); - } - #endif /* sun4u */ /* EXPORT DELETE END */ /* * Initialize key schedules for AES */ void ! aes_init_keysched(uint8_t *cipherKey, uint_t keyBits, void *keysched) { /* EXPORT DELETE START */ aes_key_t *newbie = keysched; - uint64_t keyarr64[4]; - uint32_t *keyarr32 = (uint32_t *)keyarr64; uint_t keysize, i, j; switch (keyBits) { case 128: newbie->nr = 10; break; --- 1401,1454 ---- (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[t0 & 0xff] & 0x000000ff) ^ rk[3]; pt[3] = s3; } + #endif /* sun4u, !__amd64 */ ! #ifndef sun4u ! /* ! * Expand the 32-bit AES cipher key array into the encryption and decryption ! * key schedules. ! * ! * Parameters: ! * key AES key schedule to be initialized ! * keyarr32 User key ! * keyBits AES key size (128, 192, or 256 bits) ! */ ! static void ! aes_setupkeys(aes_key_t *key, const uint32_t *keyarr32, int keybits) { ! key->nr = rijndael_key_setup_enc(&(key->encr_ks.ks32[0]), keyarr32, ! keybits); ! key->nr = rijndael_key_setup_dec(&(key->decr_ks.ks32[0]), keyarr32, ! keybits); ! key->type = AES_32BIT_KS; } #endif /* sun4u */ /* EXPORT DELETE END */ /* * Initialize key schedules for AES + * + * Parameters: + * cipherKey User key + * keyBits AES key size (128, 192, or 256 bits) + * keysched AES key schedule to be initialized, of type aes_key_t. + * Allocated by aes_alloc_keysched(). */ void ! aes_init_keysched(const uint8_t *cipherKey, uint_t keyBits, void *keysched) { /* EXPORT DELETE START */ aes_key_t *newbie = keysched; uint_t keysize, i, j; + union { + uint64_t ka64[4]; + uint32_t ka32[8]; + } keyarr; switch (keyBits) { case 128: newbie->nr = 10; break;
*** 1396,1464 **** return; } keysize = keyBits >> 3; /* ! * The code below, that is always executed on LITTLE_ENDIAN machines, ! * reverses every 4 bytes in the key. On BIG_ENDIAN, the same code ! * copies the key without reversing bytes. */ ! #ifdef _BIG_ENDIAN if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) { for (i = 0, j = 0; j < keysize; i++, j += 8) { /* LINTED: pointer alignment */ ! keyarr64[i] = *((uint64_t *)&cipherKey[j]); } } else { ! #endif for (i = 0, j = 0; j < keysize; i++, j += 4) { ! keyarr32[i] = (((uint32_t)cipherKey[j] << 24) | ((uint32_t)cipherKey[j + 1] << 16) | ((uint32_t)cipherKey[j + 2] << 8) | (uint32_t)cipherKey[j + 3]); } - #ifdef _BIG_ENDIAN - } #endif - aes_setupkeys(newbie, keyarr32, keyBits); /* EXPORT DELETE END */ } void ! aes_encrypt_block(void *ks, uint8_t *pt, uint8_t *ct) { /* EXPORT DELETE START */ - aes_key_t *ksch = (aes_key_t *)ks; ! #ifdef _BIG_ENDIAN ! if (IS_P2ALIGNED(pt, sizeof (uint32_t)) && ! IS_P2ALIGNED(ct, sizeof (uint32_t))) { /* LINTED: pointer alignment */ ! aes_encrypt_impl(&ksch->encr_ks, ksch->nr, (uint32_t *)pt, ! /* LINTED: pointer alignment */ ! (uint32_t *)ct); } else { #endif uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)]; buffer[0] = (((uint32_t)pt[0] << 24) | ((uint32_t)pt[1] << 16) | ((uint32_t)pt[2] << 8) | (uint32_t)pt[3]); - buffer[1] = (((uint32_t)pt[4] << 24) | ((uint32_t)pt[5] << 16) | ((uint32_t)pt[6] << 8) | (uint32_t)pt[7]); - buffer[2] = (((uint32_t)pt[8] << 24) | ((uint32_t)pt[9] << 16) | ((uint32_t)pt[10] << 8) | (uint32_t)pt[11]); - buffer[3] = (((uint32_t)pt[12] << 24) | ((uint32_t)pt[13] << 16) | ((uint32_t)pt[14] << 8) | (uint32_t)pt[15]); ! aes_encrypt_impl(&ksch->encr_ks, ksch->nr, buffer, buffer); ct[0] = buffer[0] >> 24; ct[1] = buffer[0] >> 16; ct[2] = buffer[0] >> 8; ct[3] = (uint8_t)buffer[0]; ct[4] = buffer[1] >> 24; --- 1466,1556 ---- return; } keysize = keyBits >> 3; /* ! * For _LITTLE_ENDIAN machines (except AMD64), reverse every ! * 4 bytes in the key. On _BIG_ENDIAN and AMD64, copy the key ! * without reversing bytes. ! * For AMD64, do not byte swap for aes_setupkeys(). ! * ! * SPARCv8/v9 uses a key schedule array with 64-bit elements. ! * X86/AMD64 uses a key schedule array with 32-bit elements. */ ! #ifndef AES_BYTE_SWAP if (IS_P2ALIGNED(cipherKey, sizeof (uint64_t))) { for (i = 0, j = 0; j < keysize; i++, j += 8) { /* LINTED: pointer alignment */ ! keyarr.ka64[i] = *((uint64_t *)&cipherKey[j]); } } else { ! bcopy(cipherKey, keyarr.ka32, keysize); ! } ! ! #else /* byte swap */ for (i = 0, j = 0; j < keysize; i++, j += 4) { ! keyarr.ka32[i] = (((uint32_t)cipherKey[j] << 24) | ((uint32_t)cipherKey[j + 1] << 16) | ((uint32_t)cipherKey[j + 2] << 8) | (uint32_t)cipherKey[j + 3]); } #endif + aes_setupkeys(newbie, keyarr.ka32, keyBits); /* EXPORT DELETE END */ } + + /* + * Encrypt one block using AES. + * Align if needed and (for x86 32-bit only) byte-swap. + * + * Parameters: + * ks Key schedule, of type aes_key_t + * pt Input block (plain text) + * ct Output block (crypto text). Can overlap with pt + */ void ! aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct) { /* EXPORT DELETE START */ aes_key_t *ksch = (aes_key_t *)ks; ! #ifndef AES_BYTE_SWAP ! if (IS_P2ALIGNED2(pt, ct, sizeof (uint32_t))) { ! AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr, /* LINTED: pointer alignment */ ! (uint32_t *)pt, (uint32_t *)ct); } else { #endif uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)]; + /* Copy input block into buffer */ + #ifndef AES_BYTE_SWAP + bcopy(pt, &buffer, AES_BLOCK_LEN); + + #else /* byte swap */ buffer[0] = (((uint32_t)pt[0] << 24) | ((uint32_t)pt[1] << 16) | ((uint32_t)pt[2] << 8) | (uint32_t)pt[3]); buffer[1] = (((uint32_t)pt[4] << 24) | ((uint32_t)pt[5] << 16) | ((uint32_t)pt[6] << 8) | (uint32_t)pt[7]); buffer[2] = (((uint32_t)pt[8] << 24) | ((uint32_t)pt[9] << 16) | ((uint32_t)pt[10] << 8) | (uint32_t)pt[11]); buffer[3] = (((uint32_t)pt[12] << 24) | ((uint32_t)pt[13] << 16) | ((uint32_t)pt[14] << 8) | (uint32_t)pt[15]); + #endif ! AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr, ! buffer, buffer); + /* Copy result from buffer to output block */ + #ifndef AES_BYTE_SWAP + bcopy(&buffer, ct, AES_BLOCK_LEN); + } + + #else /* byte swap */ ct[0] = buffer[0] >> 24; ct[1] = buffer[0] >> 16; ct[2] = buffer[0] >> 8; ct[3] = (uint8_t)buffer[0]; ct[4] = buffer[1] >> 24;
*** 1471,1505 **** ct[11] = (uint8_t)buffer[2]; ct[12] = buffer[3] >> 24; ct[13] = buffer[3] >> 16; ct[14] = buffer[3] >> 8; ct[15] = (uint8_t)buffer[3]; - #ifdef _BIG_ENDIAN - } #endif - /* EXPORT DELETE END */ } void ! aes_decrypt_block(void *ks, uint8_t *ct, uint8_t *pt) { /* EXPORT DELETE START */ - aes_key_t *ksch = (aes_key_t *)ks; ! #ifdef _BIG_ENDIAN ! if (IS_P2ALIGNED(ct, sizeof (uint32_t)) && ! IS_P2ALIGNED(pt, sizeof (uint32_t))) { /* LINTED: pointer alignment */ ! aes_decrypt_impl(&ksch->decr_ks, ksch->nr, (uint32_t *)ct, ! /* LINTED: pointer alignment */ ! (uint32_t *)pt); } else { #endif uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)]; buffer[0] = (((uint32_t)ct[0] << 24) | ((uint32_t)ct[1] << 16) | ((uint32_t)ct[2] << 8) | (uint32_t)ct[3]); buffer[1] = (((uint32_t)ct[4] << 24) | ((uint32_t)ct[5] << 16) | ((uint32_t)ct[6] << 8) | (uint32_t)ct[7]); --- 1563,1606 ---- ct[11] = (uint8_t)buffer[2]; ct[12] = buffer[3] >> 24; ct[13] = buffer[3] >> 16; ct[14] = buffer[3] >> 8; ct[15] = (uint8_t)buffer[3]; #endif /* EXPORT DELETE END */ } + + /* + * Decrypt one block using AES. + * Align and byte-swap if needed. + * + * Parameters: + * ks Key schedule, of type aes_key_t + * ct Input block (crypto text) + * pt Output block (plain text). Can overlap with pt + */ void ! aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt) { /* EXPORT DELETE START */ aes_key_t *ksch = (aes_key_t *)ks; ! #ifndef AES_BYTE_SWAP ! if (IS_P2ALIGNED2(ct, pt, sizeof (uint32_t))) { ! AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr, /* LINTED: pointer alignment */ ! (uint32_t *)ct, (uint32_t *)pt); } else { #endif uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)]; + /* Copy input block into buffer */ + #ifndef AES_BYTE_SWAP + bcopy(ct, &buffer, AES_BLOCK_LEN); + + #else /* byte swap */ buffer[0] = (((uint32_t)ct[0] << 24) | ((uint32_t)ct[1] << 16) | ((uint32_t)ct[2] << 8) | (uint32_t)ct[3]); buffer[1] = (((uint32_t)ct[4] << 24) | ((uint32_t)ct[5] << 16) | ((uint32_t)ct[6] << 8) | (uint32_t)ct[7]);
*** 1508,1520 **** ((uint32_t)ct[10] << 8) | (uint32_t)ct[11]); buffer[3] = (((uint32_t)ct[12] << 24) | ((uint32_t)ct[13] << 16) | ((uint32_t)ct[14] << 8) | (uint32_t)ct[15]); ! aes_decrypt_impl(&ksch->decr_ks, ksch->nr, buffer, buffer); pt[0] = buffer[0] >> 24; pt[1] = buffer[0] >> 16; pt[2] = buffer[0] >> 8; pt[3] = (uint8_t)buffer[0]; pt[4] = buffer[1] >> 24; --- 1609,1629 ---- ((uint32_t)ct[10] << 8) | (uint32_t)ct[11]); buffer[3] = (((uint32_t)ct[12] << 24) | ((uint32_t)ct[13] << 16) | ((uint32_t)ct[14] << 8) | (uint32_t)ct[15]); + #endif ! AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr, ! buffer, buffer); + /* Copy result from buffer to output block */ + #ifndef AES_BYTE_SWAP + bcopy(&buffer, pt, AES_BLOCK_LEN); + } + + #else /* byte swap */ pt[0] = buffer[0] >> 24; pt[1] = buffer[0] >> 16; pt[2] = buffer[0] >> 8; pt[3] = (uint8_t)buffer[0]; pt[4] = buffer[1] >> 24;
*** 1527,1553 **** pt[11] = (uint8_t)buffer[2]; pt[12] = buffer[3] >> 24; pt[13] = buffer[3] >> 16; pt[14] = buffer[3] >> 8; pt[15] = (uint8_t)buffer[3]; - #ifdef _BIG_ENDIAN - } #endif /* EXPORT DELETE END */ } /* ! * Allocate key schedule for AES */ /* ARGSUSED */ void * aes_alloc_keysched(size_t *size, int kmflag) { - /* EXPORT DELETE START */ - aes_key_t *keysched; #ifdef _KERNEL keysched = (aes_key_t *)kmem_alloc(sizeof (aes_key_t), kmflag); #else /* !_KERNEL */ --- 1636,1666 ---- pt[11] = (uint8_t)buffer[2]; pt[12] = buffer[3] >> 24; pt[13] = buffer[3] >> 16; pt[14] = buffer[3] >> 8; pt[15] = (uint8_t)buffer[3]; #endif /* EXPORT DELETE END */ } + /* ! * Allocate key schedule for AES. ! * ! * Return the pointer and set size to the number of bytes allocated. ! * Memory allocated must be freed by the caller when done. ! * ! * Parameters: ! * size Size of key schedule allocated, in bytes ! * kmflag Flag passed to kmem_alloc(9F); ignored in userland. */ /* ARGSUSED */ void * aes_alloc_keysched(size_t *size, int kmflag) { /* EXPORT DELETE START */ aes_key_t *keysched; #ifdef _KERNEL keysched = (aes_key_t *)kmem_alloc(sizeof (aes_key_t), kmflag); #else /* !_KERNEL */
*** 1556,1565 **** if (keysched != NULL) { *size = sizeof (aes_key_t); return (keysched); } - /* EXPORT DELETE END */ - return (NULL); } --- 1669,1676 ----