summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan OpenSolaris Anderson <opensolaris@drydog.com>2009-04-17 14:48:17 -0700
committerDan OpenSolaris Anderson <opensolaris@drydog.com>2009-04-17 14:48:17 -0700
commit54034eb2d6e7d811adf4a1fe5105eac6fea6b0b5 (patch)
treecdec82b912346eb19f5e81b87d059a252e74f0a8
parentaa8cf21aa2aaa2df3db469354ccc0c47f8cdaab9 (diff)
downloadillumos-joyent-54034eb2d6e7d811adf4a1fe5105eac6fea6b0b5.tar.gz
6767618 Need an optimized AES leveraging Intel's AES instructions
6747587 Remove redundant code in ccm.c --HG-- rename : usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE => usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman rename : usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.descrip => usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman.descrip
-rw-r--r--usr/src/common/crypto/aes/Makefile18
-rw-r--r--usr/src/common/crypto/aes/aes_impl.c340
-rw-r--r--usr/src/common/crypto/aes/aes_impl.h50
-rw-r--r--usr/src/common/crypto/aes/aes_modes.c144
-rw-r--r--usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman (renamed from usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE)0
-rw-r--r--usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman.descrip (renamed from usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.descrip)0
-rw-r--r--usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl127
-rw-r--r--usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl.descrip1
-rw-r--r--usr/src/common/crypto/aes/amd64/aes_amd64.s44
-rw-r--r--usr/src/common/crypto/aes/amd64/aes_intel.s916
-rw-r--r--usr/src/common/crypto/aes/amd64/aeskey.c13
-rw-r--r--usr/src/common/crypto/aes/sun4u/aes_crypt_asm.s95
-rw-r--r--usr/src/common/crypto/arcfour/Makefile21
-rw-r--r--usr/src/common/crypto/modes/ccm.c19
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/Makefile.com4
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile5
-rw-r--r--usr/src/pkgdefs/SUNWckr/Makefile7
-rw-r--r--usr/src/pkgdefs/SUNWcslr/Makefile7
-rw-r--r--usr/src/tools/opensolaris/license-list17
-rw-r--r--usr/src/uts/common/Makefile.files2
-rw-r--r--usr/src/uts/common/crypto/io/aes.c15
-rw-r--r--usr/src/uts/intel/aes/Makefile21
-rw-r--r--usr/src/uts/sun4u/Makefile.files2
23 files changed, 1567 insertions, 301 deletions
diff --git a/usr/src/common/crypto/aes/Makefile b/usr/src/common/crypto/aes/Makefile
index 241b319157..1962b8ad7a 100644
--- a/usr/src/common/crypto/aes/Makefile
+++ b/usr/src/common/crypto/aes/Makefile
@@ -19,9 +19,7 @@
# CDDL HEADER END
#
#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# common/crypto/aes/Makefile
@@ -36,7 +34,8 @@ FRC:
# EXPORT DELETE START
EXPORT_SRC:
- $(RM) Makefile+ aes_impl.c+ aes_impl.h+ sun4u/aes_crypt_asm.s+
+ $(RM) Makefile+ aes_impl.c+ aes_impl.h+ amd64/aes_amd64.s+ \
+ amd64/aes_intel.s+ sun4u/aes_crypt_asm.s+
sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
< aes_impl.c > aes_impl.c+
$(MV) aes_impl.c+ aes_impl.c
@@ -44,12 +43,19 @@ EXPORT_SRC:
< aes_impl.h > aes_impl.h+
$(MV) aes_impl.h+ aes_impl.h
sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
+ < amd64/aes_amd64.s > amd64/aes_amd64.s+
+ $(MV) amd64/aes_amd64.s+ amd64/aes_amd64.s
+ sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
+ < amd64/aes_intel.s > amd64/aes_intel.s+
+ $(MV) amd64/aes_intel.s+ amd64/aes_intel.s
+ sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
< sun4u/aes_crypt_asm.s > sun4u/aes_crypt_asm.s+
$(MV) sun4u/aes_crypt_asm.s+ sun4u/aes_crypt_asm.s
sed -e "/^# EXPORT DELETE START/,/^# EXPORT DELETE END/d" \
< Makefile > Makefile+
$(RM) Makefile
- $(MV) Makefile+ Makefile
- $(CHMOD) 444 Makefile aes_impl.c aes_impl.h sun4u/aes_crypt_asm.s
+ $(MV) Makefile+ Makefile
+ $(CHMOD) 444 Makefile aes_impl.c aes_impl.h amd64/aes_amd64.s \
+ amd64/aes_intel.s sun4u/aes_crypt_asm.s
# EXPORT DELETE END
diff --git a/usr/src/common/crypto/aes/aes_impl.c b/usr/src/common/crypto/aes/aes_impl.c
index 2e3ea76ab4..37a998522f 100644
--- a/usr/src/common/crypto/aes/aes_impl.c
+++ b/usr/src/common/crypto/aes/aes_impl.c
@@ -25,18 +25,33 @@
#include <sys/types.h>
#include <sys/systm.h>
-#include <sys/ddi.h>
#include <sys/sysmacros.h>
-#include <sys/strsun.h>
#include <netinet/in.h>
-#include <sys/crypto/spi.h>
-#include <modes/modes.h>
#include "aes_impl.h"
#ifndef _KERNEL
#include <strings.h>
#include <stdlib.h>
#endif /* !_KERNEL */
+#ifdef __amd64
+
+#ifdef _KERNEL
+#include <sys/cpuvar.h> /* cpu_t, CPU */
+#include <sys/x86_archext.h> /* x86_feature, X86_AES */
+#include <sys/disp.h> /* kpreempt_disable(), kpreempt_enable */
+
+/* Workaround for no XMM kernel thread save/restore */
+#define KPREEMPT_DISABLE kpreempt_disable()
+#define KPREEMPT_ENABLE kpreempt_enable()
+
+#else
+#include <sys/auxv.h> /* getisax() */
+#include <sys/auxv_386.h> /* AV_386_AES bit */
+#define KPREEMPT_DISABLE
+#define KPREEMPT_ENABLE
+#endif /* _KERNEL */
+#endif /* __amd64 */
+
/*
* This file is derived from the file rijndael-alg-fst.c taken from the
@@ -75,25 +90,47 @@
/* EXPORT DELETE START */
-#if defined(sun4u) || defined(__amd64)
+#if defined(sun4u)
/* 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 AES_ENCRYPT_IMPL(a, b, c, d, e) aes_encrypt_impl(a, b, c, d)
+#define AES_DECRYPT_IMPL(a, b, c, d, e) aes_decrypt_impl(a, b, c, d)
+
+#elif defined(__amd64)
+
+/* These functions are used to execute amd64 instructions for AMD or Intel: */
+extern int rijndael_key_setup_enc_amd64(uint32_t rk[],
+ const uint32_t cipherKey[], int keyBits);
+extern int rijndael_key_setup_dec_amd64(uint32_t rk[],
+ const uint32_t cipherKey[], int keyBits);
+extern void aes_encrypt_amd64(const uint32_t rk[], int Nr,
+ const uint32_t pt[4], uint32_t ct[4]);
+extern void aes_decrypt_amd64(const uint32_t rk[], int Nr,
+ const uint32_t ct[4], uint32_t pt[4]);
+
+/* These functions are used to execute Intel-specific AES-NI instructions: */
+extern int rijndael_key_setup_enc_intel(uint32_t rk[],
+ const uint32_t cipherKey[], uint64_t keyBits);
+extern int rijndael_key_setup_dec_intel(uint32_t rk[],
+ const uint32_t cipherKey[], uint64_t keyBits);
+extern void aes_encrypt_intel(const uint32_t rk[], int Nr,
+ const uint32_t pt[4], uint32_t ct[4]);
+extern void aes_decrypt_intel(const uint32_t rk[], int Nr,
+ const uint32_t ct[4], uint32_t pt[4]);
+
+static int intel_aes_instructions_present(void);
+
+#define AES_ENCRYPT_IMPL(a, b, c, d, e) rijndael_encrypt(a, b, c, d, e)
+#define AES_DECRYPT_IMPL(a, b, c, d, e) rijndael_decrypt(a, b, c, d, e)
+
+#else /* Generic C implementation */
+
+#define AES_ENCRYPT_IMPL(a, b, c, d, e) rijndael_encrypt(a, b, c, d)
+#define AES_DECRYPT_IMPL(a, b, c, d, e) rijndael_decrypt(a, b, c, d)
#define rijndael_key_setup_enc_raw rijndael_key_setup_enc
#endif /* sun4u || __amd64 */
@@ -401,6 +438,7 @@ static const uint32_t Te3[256] =
};
#endif /* !sun4u */
+
static const uint32_t Te4[256] =
{
0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
@@ -814,6 +852,7 @@ static const uint32_t Td4[256] =
};
#endif /* !sun4u */
+
/* Rcon is Round Constant; used for encryption key expansion */
static const uint32_t rcon[RC_LENGTH] =
{
@@ -1090,7 +1129,95 @@ aes_setupkeys(aes_key_t *key, const uint32_t *keyarr32, int keybits)
}
-#elif !defined(__amd64)
+#elif defined(__amd64)
+
+/*
+ * 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)
+{
+ if (intel_aes_instructions_present()) {
+ key->flags = INTEL_AES_NI_CAPABLE;
+ KPREEMPT_DISABLE;
+ key->nr = rijndael_key_setup_enc_intel(&(key->encr_ks.ks32[0]),
+ keyarr32, keybits);
+ key->nr = rijndael_key_setup_dec_intel(&(key->decr_ks.ks32[0]),
+ keyarr32, keybits);
+ KPREEMPT_ENABLE;
+ } else {
+ key->flags = 0;
+ key->nr = rijndael_key_setup_enc_amd64(&(key->encr_ks.ks32[0]),
+ keyarr32, keybits);
+ key->nr = rijndael_key_setup_dec_amd64(&(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).
+ *
+ * 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
+ * flags Indicates whether we're on Intel AES-NI-capable hardware
+ */
+static void
+rijndael_encrypt(const uint32_t rk[], int Nr, const uint32_t pt[4],
+ uint32_t ct[4], int flags) {
+ if (flags & INTEL_AES_NI_CAPABLE) {
+ KPREEMPT_DISABLE;
+ aes_encrypt_intel(rk, Nr, pt, ct);
+ KPREEMPT_ENABLE;
+ } else {
+ aes_encrypt_amd64(rk, Nr, pt, ct);
+ }
+}
+
+/*
+ * Decrypt 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
+ * ct Input block (crypto text)
+ * pt Output block (plain text). Can overlap with pt
+ * flags Indicates whether we're on Intel AES-NI-capable hardware
+ */
+static void
+rijndael_decrypt(const uint32_t rk[], int Nr, const uint32_t ct[4],
+ uint32_t pt[4], int flags) {
+ if (flags & INTEL_AES_NI_CAPABLE) {
+ KPREEMPT_DISABLE;
+ aes_decrypt_intel(rk, Nr, ct, pt);
+ KPREEMPT_ENABLE;
+ } else {
+ aes_decrypt_amd64(rk, Nr, ct, pt);
+ }
+}
+
+
+#else /* generic C implementation */
/*
* Expand the cipher key into the decryption key schedule.
@@ -1157,6 +1284,26 @@ rijndael_key_setup_dec(uint32_t rk[], const uint32_t cipherKey[], int keyBits)
/*
+ * 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;
+}
+
+
+/*
* 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
@@ -1409,33 +1556,12 @@ rijndael_decrypt(const uint32_t rk[], int Nr, const uint32_t ct[4],
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 */
+#endif /* sun4u, __amd64 */
/* EXPORT DELETE END */
/*
- * Initialize key schedules for AES
+ * Initialize AES encryption and decryption key schedules.
*
* Parameters:
* cipherKey User key
@@ -1502,6 +1628,7 @@ aes_init_keysched(const uint8_t *cipherKey, uint_t keyBits, void *keysched)
/* EXPORT DELETE END */
}
+
/*
* Encrypt one block using AES.
* Align if needed and (for x86 32-bit only) byte-swap.
@@ -1519,9 +1646,10 @@ aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct)
#ifndef AES_BYTE_SWAP
if (IS_P2ALIGNED2(pt, ct, sizeof (uint32_t))) {
+ /* LINTED: pointer alignment */
AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
/* LINTED: pointer alignment */
- (uint32_t *)pt, (uint32_t *)ct);
+ (uint32_t *)pt, (uint32_t *)ct, ksch->flags);
} else {
#endif
uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
@@ -1538,7 +1666,7 @@ aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct)
#endif
AES_ENCRYPT_IMPL(&ksch->encr_ks.ks32[0], ksch->nr,
- buffer, buffer);
+ buffer, buffer, ksch->flags);
/* Copy result from buffer to output block */
#ifndef AES_BYTE_SWAP
@@ -1555,6 +1683,7 @@ aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct)
return (CRYPTO_SUCCESS);
}
+
/*
* Decrypt one block using AES.
* Align and byte-swap if needed.
@@ -1572,9 +1701,10 @@ aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt)
#ifndef AES_BYTE_SWAP
if (IS_P2ALIGNED2(ct, pt, sizeof (uint32_t))) {
+ /* LINTED: pointer alignment */
AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
/* LINTED: pointer alignment */
- (uint32_t *)ct, (uint32_t *)pt);
+ (uint32_t *)ct, (uint32_t *)pt, ksch->flags);
} else {
#endif
uint32_t buffer[AES_BLOCK_LEN / sizeof (uint32_t)];
@@ -1591,7 +1721,7 @@ aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt)
#endif
AES_DECRYPT_IMPL(&ksch->decr_ks.ks32[0], ksch->nr,
- buffer, buffer);
+ buffer, buffer, ksch->flags);
/* Copy result from buffer to output block */
#ifndef AES_BYTE_SWAP
@@ -1641,112 +1771,32 @@ aes_alloc_keysched(size_t *size, int kmflag)
return (NULL);
}
-void
-aes_copy_block(uint8_t *in, uint8_t *out)
-{
- if (IS_P2ALIGNED(in, sizeof (uint32_t)) &&
- IS_P2ALIGNED(out, sizeof (uint32_t))) {
- /* LINTED: pointer alignment */
- *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
- /* LINTED: pointer alignment */
- *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
- /* LINTED: pointer alignment */
- *(uint32_t *)&out[8] = *(uint32_t *)&in[8];
- /* LINTED: pointer alignment */
- *(uint32_t *)&out[12] = *(uint32_t *)&in[12];
- } else {
- AES_COPY_BLOCK(in, out);
- }
-}
-
-/* XOR block of data into dest */
-void
-aes_xor_block(uint8_t *data, uint8_t *dst)
-{
- if (IS_P2ALIGNED(dst, sizeof (uint32_t)) &&
- IS_P2ALIGNED(data, sizeof (uint32_t))) {
- /* LINTED: pointer alignment */
- *(uint32_t *)&dst[0] ^= *(uint32_t *)&data[0];
- /* LINTED: pointer alignment */
- *(uint32_t *)&dst[4] ^= *(uint32_t *)&data[4];
- /* LINTED: pointer alignment */
- *(uint32_t *)&dst[8] ^= *(uint32_t *)&data[8];
- /* LINTED: pointer alignment */
- *(uint32_t *)&dst[12] ^= *(uint32_t *)&data[12];
- } else {
- AES_XOR_BLOCK(data, dst);
- }
-}
+#ifdef __amd64
/*
- * Encrypt multiple blocks of data according to mode.
+ * Return 1 if executing on Intel with AES-NI instructions,
+ * otherwise 0 (i.e., Intel without AES-NI or AMD64).
+ * Cache the result, as the CPU can't change.
+ *
+ * Note: the userland version uses getisax(). The kernel version uses
+ * global variable x86_feature.
*/
-/* ARGSUSED */
-int
-aes_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
- crypto_data_t *out)
+static int
+intel_aes_instructions_present(void)
{
- aes_ctx_t *aes_ctx = ctx;
- int rv;
+ static int cached_result = -1;
- if (aes_ctx->ac_flags & CTR_MODE) {
- rv = ctr_mode_contiguous_blocks(ctx, data, length, out,
- AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
+ if (cached_result == -1) { /* first time */
#ifdef _KERNEL
- } else if (aes_ctx->ac_flags & CCM_MODE) {
- rv = ccm_mode_encrypt_contiguous_blocks(ctx, data, length,
- out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
- aes_xor_block);
- } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
- rv = gcm_mode_encrypt_contiguous_blocks(ctx, data, length,
- out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
- aes_xor_block);
-#endif
- } else if (aes_ctx->ac_flags & CBC_MODE) {
- rv = cbc_encrypt_contiguous_blocks(ctx,
- data, length, out, AES_BLOCK_LEN, aes_encrypt_block,
- aes_copy_block, aes_xor_block);
- } else {
- rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
- AES_BLOCK_LEN, aes_encrypt_block);
- }
- return (rv);
-}
+ cached_result = (x86_feature & X86_AES) != 0;
+#else
+ uint_t ui = 0;
-/*
- * Decrypt multiple blocks of data according to mode.
- */
-int
-aes_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
- crypto_data_t *out)
-{
- aes_ctx_t *aes_ctx = ctx;
- int rv;
-
- if (aes_ctx->ac_flags & CTR_MODE) {
- rv = ctr_mode_contiguous_blocks(ctx, data, length, out,
- AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
- if (rv == CRYPTO_DATA_LEN_RANGE)
- rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
-#ifdef _KERNEL
- } else if (aes_ctx->ac_flags & CCM_MODE) {
- rv = ccm_mode_decrypt_contiguous_blocks(ctx, data, length,
- out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
- aes_xor_block);
- } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
- rv = gcm_mode_decrypt_contiguous_blocks(ctx, data, length,
- out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
- aes_xor_block);
-#endif
- } else if (aes_ctx->ac_flags & CBC_MODE) {
- rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out,
- AES_BLOCK_LEN, aes_decrypt_block, aes_copy_block,
- aes_xor_block);
- } else {
- rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
- AES_BLOCK_LEN, aes_decrypt_block);
- if (rv == CRYPTO_DATA_LEN_RANGE)
- rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
+ (void) getisax(&ui, 1);
+ cached_result = (ui & AV_386_AES) != 0;
+#endif /* _KERNEL */
}
- return (rv);
+
+ return (cached_result);
}
+#endif /* __amd64 */
diff --git a/usr/src/common/crypto/aes/aes_impl.h b/usr/src/common/crypto/aes/aes_impl.h
index 10b8d4b56c..bb96a44394 100644
--- a/usr/src/common/crypto/aes/aes_impl.h
+++ b/usr/src/common/crypto/aes/aes_impl.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _AES_IMPL_H
#define _AES_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Common definitions used by AES.
*/
@@ -108,25 +106,45 @@ typedef union {
uint32_t ks32[((MAX_AES_NR) + 1) * (MAX_AES_NB)];
} aes_ks_t;
+/* aes_key.flags value: */
+#define INTEL_AES_NI_CAPABLE 0x1 /* AES-NI instructions present */
+
typedef struct aes_key aes_key_t;
struct aes_key {
- int nr;
- int type;
- aes_ks_t encr_ks;
- aes_ks_t decr_ks;
+ aes_ks_t encr_ks; /* encryption key schedule */
+ aes_ks_t decr_ks; /* decryption key schedule */
+#ifdef __amd64
+ long double align128; /* Align fields above for Intel AES-NI */
+ int flags; /* implementation-dependent flags */
+#endif /* __amd64 */
+ int nr; /* number of rounds (10, 12, or 14) */
+ int type; /* key schedule size (32 or 64 bits) */
};
-extern int aes_encrypt_contiguous_blocks(void *, char *, size_t,
- crypto_data_t *);
-extern int aes_decrypt_contiguous_blocks(void *, char *, size_t,
- crypto_data_t *);
-extern int aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct);
-extern int aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt);
+/*
+ * Core AES functions.
+ * ks and keysched are pointers to aes_key_t.
+ * They are declared void* as they are intended to be opaque types.
+ * Use function aes_alloc_keysched() to allocate memory for ks and keysched.
+ */
+extern void *aes_alloc_keysched(size_t *size, int kmflag);
extern void aes_init_keysched(const uint8_t *cipherKey, uint_t keyBits,
void *keysched);
-extern void *aes_alloc_keysched(size_t *size, int kmflag);
-extern void aes_copy_block(uint8_t *, uint8_t *);
-extern void aes_xor_block(uint8_t *, uint8_t *);
+extern int aes_encrypt_block(const void *ks, const uint8_t *pt, uint8_t *ct);
+extern int aes_decrypt_block(const void *ks, const uint8_t *ct, uint8_t *pt);
+
+/*
+ * AES mode functions.
+ * The first 2 functions operate on 16-byte AES blocks.
+ */
+extern void aes_copy_block(uint8_t *in, uint8_t *out);
+extern void aes_xor_block(uint8_t *data, uint8_t *dst);
+
+/* Note: ctx is a pointer to aes_ctx_t defined in modes.h */
+extern int aes_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
+ crypto_data_t *out);
+extern int aes_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
+ crypto_data_t *out);
#ifdef __cplusplus
}
diff --git a/usr/src/common/crypto/aes/aes_modes.c b/usr/src/common/crypto/aes/aes_modes.c
new file mode 100644
index 0000000000..a41f4d9fe4
--- /dev/null
+++ b/usr/src/common/crypto/aes/aes_modes.c
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <modes/modes.h>
+#include "aes_impl.h"
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif /* !_KERNEL */
+
+
+/* Copy a 16-byte AES block from "in" to "out" */
+void
+aes_copy_block(uint8_t *in, uint8_t *out)
+{
+ if (IS_P2ALIGNED2(in, out, sizeof (uint32_t))) {
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&out[0] = *(uint32_t *)&in[0];
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&out[4] = *(uint32_t *)&in[4];
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&out[8] = *(uint32_t *)&in[8];
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&out[12] = *(uint32_t *)&in[12];
+ } else {
+ AES_COPY_BLOCK(in, out);
+ }
+}
+
+
+/* XOR a 16-byte AES block of data into dst */
+void
+aes_xor_block(uint8_t *data, uint8_t *dst)
+{
+ if (IS_P2ALIGNED2(dst, data, sizeof (uint32_t))) {
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&dst[0] ^= *(uint32_t *)&data[0];
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&dst[4] ^= *(uint32_t *)&data[4];
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&dst[8] ^= *(uint32_t *)&data[8];
+ /* LINTED: pointer alignment */
+ *(uint32_t *)&dst[12] ^= *(uint32_t *)&data[12];
+ } else {
+ AES_XOR_BLOCK(data, dst);
+ }
+}
+
+
+/*
+ * Encrypt multiple blocks of data according to mode.
+ */
+int
+aes_encrypt_contiguous_blocks(void *ctx, char *data, size_t length,
+ crypto_data_t *out)
+{
+ aes_ctx_t *aes_ctx = ctx;
+ int rv;
+
+ if (aes_ctx->ac_flags & CTR_MODE) {
+ rv = ctr_mode_contiguous_blocks(ctx, data, length, out,
+ AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
+#ifdef _KERNEL
+ } else if (aes_ctx->ac_flags & CCM_MODE) {
+ rv = ccm_mode_encrypt_contiguous_blocks(ctx, data, length,
+ out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
+ aes_xor_block);
+ } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
+ rv = gcm_mode_encrypt_contiguous_blocks(ctx, data, length,
+ out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
+ aes_xor_block);
+#endif
+ } else if (aes_ctx->ac_flags & CBC_MODE) {
+ rv = cbc_encrypt_contiguous_blocks(ctx,
+ data, length, out, AES_BLOCK_LEN, aes_encrypt_block,
+ aes_copy_block, aes_xor_block);
+ } else {
+ rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
+ AES_BLOCK_LEN, aes_encrypt_block);
+ }
+ return (rv);
+}
+
+
+/*
+ * Decrypt multiple blocks of data according to mode.
+ */
+int
+aes_decrypt_contiguous_blocks(void *ctx, char *data, size_t length,
+ crypto_data_t *out)
+{
+ aes_ctx_t *aes_ctx = ctx;
+ int rv;
+
+ if (aes_ctx->ac_flags & CTR_MODE) {
+ rv = ctr_mode_contiguous_blocks(ctx, data, length, out,
+ AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block);
+ if (rv == CRYPTO_DATA_LEN_RANGE)
+ rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
+#ifdef _KERNEL
+ } else if (aes_ctx->ac_flags & CCM_MODE) {
+ rv = ccm_mode_decrypt_contiguous_blocks(ctx, data, length,
+ out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
+ aes_xor_block);
+ } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) {
+ rv = gcm_mode_decrypt_contiguous_blocks(ctx, data, length,
+ out, AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block,
+ aes_xor_block);
+#endif
+ } else if (aes_ctx->ac_flags & CBC_MODE) {
+ rv = cbc_decrypt_contiguous_blocks(ctx, data, length, out,
+ AES_BLOCK_LEN, aes_decrypt_block, aes_copy_block,
+ aes_xor_block);
+ } else {
+ rv = ecb_cipher_contiguous_blocks(ctx, data, length, out,
+ AES_BLOCK_LEN, aes_decrypt_block);
+ if (rv == CRYPTO_DATA_LEN_RANGE)
+ rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
+ }
+ return (rv);
+}
diff --git a/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman
index 48fea7bb33..48fea7bb33 100644
--- a/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE
+++ b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman
diff --git a/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.descrip b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman.descrip
index 5f822cf275..5f822cf275 100644
--- a/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.descrip
+++ b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman.descrip
diff --git a/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl
new file mode 100644
index 0000000000..a2c4adcbe6
--- /dev/null
+++ b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl
@@ -0,0 +1,127 @@
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. Actually both licenses are BSD-style
+ Open Source licenses. In case of any license issues related to OpenSSL
+ please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2008 The OpenSSL Project. 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.
+ *
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
diff --git a/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl.descrip b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl.descrip
new file mode 100644
index 0000000000..5f822cf275
--- /dev/null
+++ b/usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl.descrip
@@ -0,0 +1 @@
+PORTIONS OF AES FUNCTIONALITY
diff --git a/usr/src/common/crypto/aes/amd64/aes_amd64.s b/usr/src/common/crypto/aes/amd64/aes_amd64.s
index 2c12008296..a119c2b895 100644
--- a/usr/src/common/crypto/aes/amd64/aes_amd64.s
+++ b/usr/src/common/crypto/aes/amd64/aes_amd64.s
@@ -156,7 +156,8 @@
* sub rax,[ebx+ecx*4-20h] sub -0x20(%ebx,%ecx,4),%rax
*
* 5. Added OpenSolaris ENTRY_NP/SET_SIZE macros from
- * /usr/include/sys/asm_linkage.h, .ident keywords, and lint(1B) guards.
+ * /usr/include/sys/asm_linkage.h, lint(1B) guards, EXPORT DELETE START
+ * and EXPORT DELETE END markers, and dummy C function definitions for lint.
*
* 6. Renamed functions and reordered parameters to match OpenSolaris:
* Original Gladman interface:
@@ -171,9 +172,9 @@
* 10, 12, or 14 bytes.
*
* OpenSolaris OS interface:
- * void aes_encrypt_impl(const aes_ks_t *ks, int Nr,
+ * void aes_encrypt_amd64(const aes_ks_t *ks, int Nr,
* const uint32_t pt[4], uint32_t ct[4])/
- * void aes_decrypt_impl(const aes_ks_t *ks, int Nr,
+ * void aes_decrypt_amd64(const aes_ks_t *ks, int Nr,
* const uint32_t pt[4], uint32_t ct[4])/
* typedef union {uint64_t ks64[(MAX_AES_NR + 1) * 4]/
* uint32_t ks32[(MAX_AES_NR + 1) * 4]/ } aes_ks_t/
@@ -182,8 +183,23 @@
* For the x86 64-bit architecture, OpenSolaris OS uses ks32 instead of ks64.
*/
-#if !defined(lint) && !defined(__lint)
- .ident "%Z%%M% %I% %E% SMI"
+#if defined(lint) || defined(__lint)
+
+#include <sys/types.h>
+/* ARGSUSED */
+void
+aes_encrypt_amd64(const uint32_t rk[], int Nr, const uint32_t pt[4],
+ uint32_t ct[4]) {
+}
+/* ARGSUSED */
+void
+aes_decrypt_amd64(const uint32_t rk[], int Nr, const uint32_t ct[4],
+ uint32_t pt[4]) {
+}
+
+
+#else
+
#include <sys/asm_linkage.h>
#define KS_LENGTH 60
@@ -671,7 +687,7 @@
/*
* OpenSolaris OS:
- * void aes_encrypt_impl(const aes_ks_t *ks, int Nr,
+ * void aes_encrypt_amd64(const aes_ks_t *ks, int Nr,
* const uint32_t pt[4], uint32_t ct[4])/
*
* Original interface:
@@ -687,7 +703,7 @@ enc_tab:
#endif
- ENTRY_NP(aes_encrypt_impl)
+ ENTRY_NP(aes_encrypt_amd64)
/* EXPORT DELETE START */
#ifdef GLADMAN_INTERFACE
/ Original interface
@@ -773,11 +789,11 @@ enc_tab:
/* EXPORT DELETE END */
ret
- SET_SIZE(aes_encrypt_impl)
+ SET_SIZE(aes_encrypt_amd64)
/*
* OpenSolaris OS:
- * void aes_decrypt_impl(const aes_ks_t *ks, int Nr,
+ * void aes_decrypt_amd64(const aes_ks_t *ks, int Nr,
* const uint32_t pt[4], uint32_t ct[4])/
*
* Original interface:
@@ -793,7 +809,7 @@ dec_tab:
#endif
- ENTRY_NP(aes_decrypt_impl)
+ ENTRY_NP(aes_decrypt_amd64)
/* EXPORT DELETE START */
#ifdef GLADMAN_INTERFACE
/ Original interface
@@ -885,9 +901,5 @@ dec_tab:
/* EXPORT DELETE END */
ret
- SET_SIZE(aes_decrypt_impl)
-
-#else
- /* LINTED */
- /* Nothing to be linted in this file--it's pure assembly source. */
-#endif /* !lint && !__lint */
+ SET_SIZE(aes_decrypt_amd64)
+#endif /* lint || __lint */
diff --git a/usr/src/common/crypto/aes/amd64/aes_intel.s b/usr/src/common/crypto/aes/amd64/aes_intel.s
new file mode 100644
index 0000000000..96cd6acece
--- /dev/null
+++ b/usr/src/common/crypto/aes/amd64/aes_intel.s
@@ -0,0 +1,916 @@
+/*
+ * ====================================================================
+ * Written by Intel Corporation for the OpenSSL project to add support
+ * for Intel AES-NI instructions. Rights for redistribution and usage
+ * in source and binary forms are granted according to the OpenSSL
+ * license.
+ *
+ * Author: Huang Ying <ying.huang at intel dot com>
+ * Vinodh Gopal <vinodh.gopal at intel dot com>
+ * Kahraman Akdemir
+ *
+ * Intel AES-NI is a new set of Single Instruction Multiple Data (SIMD)
+ * instructions that are going to be introduced in the next generation
+ * of Intel processor, as of 2009. These instructions enable fast and
+ * secure data encryption and decryption, using the Advanced Encryption
+ * Standard (AES), defined by FIPS Publication number 197. The
+ * architecture introduces six instructions that offer full hardware
+ * support for AES. Four of them support high performance data
+ * encryption and decryption, and the other two instructions support
+ * the AES key expansion procedure.
+ * ====================================================================
+ */
+
+/*
+ * ====================================================================
+ * Copyright (c) 1998-2008 The OpenSSL Project. 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.
+ *
+ * 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.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowleoudgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 OpenSSL PROJECT OR
+ * ITS 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.
+ * ====================================================================
+ */
+
+/*
+ * ====================================================================
+ * OpenSolaris OS modifications
+ *
+ * This source originates as files aes-intel.S and eng_aesni_asm.pl, in
+ * patches sent sent Dec. 9, 2008 and Dec. 24, 2008, respectively, by
+ * Huang Ying of Intel to the openssl-dev mailing list under the subject
+ * of "Add support to Intel AES-NI instruction set for x86_64 platform".
+ *
+ * This OpenSolaris version has these major changes from the original source:
+ *
+ * 1. Added OpenSolaris ENTRY_NP/SET_SIZE macros from
+ * /usr/include/sys/asm_linkage.h, lint(1B) guards, EXPORT DELETE START
+ * and EXPORT DELETE END markers, and dummy C function definitions for lint.
+ *
+ * 2. Formatted code, added comments, and added #includes and #defines.
+ *
+ * 3. Replaced aes* and palignr instructions with .byte sequences
+ * (as they are not supported yet by all of the gas, as, and aw assemblers).
+ *
+ * 4. If bit CR0.TS is set, clear and set the TS bit, after and before
+ * calling kpreempt_disable() and kpreempt_enable().
+ * If the TS bit is not set, Save and restore %xmm registers at the beginning
+ * and end of function calls (%xmm* registers are not saved and restored by
+ * during kernel thread preemption).
+ *
+ * 5. Renamed functions, reordered parameters, and changed return value
+ * to match OpenSolaris:
+ *
+ * OpenSSL interface:
+ * int intel_AES_set_encrypt_key(const unsigned char *userKey,
+ * const int bits, AES_KEY *key);
+ * int intel_AES_set_decrypt_key(const unsigned char *userKey,
+ * const int bits, AES_KEY *key);
+ * Return values for above are non-zero on error, 0 on success.
+ *
+ * void intel_AES_encrypt(const unsigned char *in, unsigned char *out,
+ * const AES_KEY *key);
+ * void intel_AES_decrypt(const unsigned char *in, unsigned char *out,
+ * const AES_KEY *key);
+ * typedef struct aes_key_st {
+ * unsigned int rd_key[4 *(AES_MAXNR + 1)];
+ * int rounds;
+ * unsigned int pad[3];
+ * } AES_KEY;
+ * Note: AES_LONG is undefined (that is, Intel uses 32-bit key schedules
+ * (ks32) instead of 64-bit (ks64).
+ * Number of rounds (aka round count) is at offset 240 of AES_KEY.
+ *
+ * OpenSolaris OS interface (#ifdefs removed for readability):
+ * int rijndael_key_setup_dec_intel(uint32_t rk[],
+ * const uint32_t cipherKey[], uint64_t keyBits);
+ * int rijndael_key_setup_enc_intel(uint32_t rk[],
+ * const uint32_t cipherKey[], uint64_t keyBits);
+ * Return values for above are 0 on error, number of rounds on success.
+ *
+ * void aes_encrypt_intel(const aes_ks_t *ks, int Nr,
+ * const uint32_t pt[4], uint32_t ct[4]);
+ * void aes_decrypt_intel(const aes_ks_t *ks, int Nr,
+ * const uint32_t pt[4], uint32_t ct[4]);
+ * typedef union {uint64_t ks64[(MAX_AES_NR + 1) * 4];
+ * uint32_t ks32[(MAX_AES_NR + 1) * 4]; } aes_ks_t;
+ *
+ * typedef union {
+ * uint32_t ks32[((MAX_AES_NR) + 1) * (MAX_AES_NB)];
+ * } aes_ks_t;
+ * typedef struct aes_key {
+ * aes_ks_t encr_ks, decr_ks;
+ * long double align128;
+ * int flags, nr, type;
+ * } aes_key_t;
+ *
+ * Note: ks is the AES key schedule, Nr is number of rounds, pt is plain text,
+ * ct is crypto text, and MAX_AES_NR is 14.
+ * For the x86 64-bit architecture, OpenSolaris OS uses ks32 instead of ks64.
+ * Note2: aes_ks_t must be aligned on a 0 mod 128 byte boundary.
+ * ====================================================================
+ */
+
+#if defined(lint) || defined(__lint)
+
+#include <sys/types.h>
+
+/* ARGSUSED */
+void
+aes_encrypt_intel(const uint32_t rk[], int Nr, const uint32_t pt[4],
+ uint32_t ct[4]) {
+}
+/* ARGSUSED */
+void
+aes_decrypt_intel(const uint32_t rk[], int Nr, const uint32_t ct[4],
+ uint32_t pt[4]) {
+}
+/* ARGSUSED */
+int
+rijndael_key_setup_enc_intel(uint32_t rk[], const uint32_t cipherKey[],
+ uint64_t keyBits) {
+ return (0);
+}
+/* ARGSUSED */
+int
+rijndael_key_setup_dec_intel(uint32_t rk[], const uint32_t cipherKey[],
+ uint64_t keyBits) {
+ return (0);
+}
+
+
+#else /* lint */
+
+#include <sys/asm_linkage.h>
+#include <sys/controlregs.h>
+#ifdef _KERNEL
+#include <sys/machprivregs.h>
+#endif
+
+#ifdef _KERNEL
+ /*
+ * Note: the CLTS macro clobbers P2 (%rsi) under i86xpv. That is,
+ * it calls HYPERVISOR_fpu_taskswitch() which modifies %rsi when it
+ * uses it to pass P2 to syscall.
+ * This also occurs with the STTS macro, but we don't care if
+ * P2 (%rsi) is modified just before function exit.
+ * The CLTS and STTS macros push and pop P1 (%rdi) already.
+ */
+#ifdef __xpv
+#define PROTECTED_CLTS \
+ push %rsi; \
+ CLTS; \
+ pop %rsi
+#else
+#define PROTECTED_CLTS \
+ CLTS
+#endif /* __xpv */
+
+#define CLEAR_TS_OR_PUSH_XMM0_XMM1(tmpreg) \
+ push %rbp; \
+ mov %rsp, %rbp; \
+ movq %cr0, tmpreg; \
+ testq $CR0_TS, tmpreg; \
+ jnz 1f; \
+ and $-XMM_ALIGN, %rsp; \
+ sub $[XMM_SIZE * 2], %rsp; \
+ movaps %xmm0, 16(%rsp); \
+ movaps %xmm1, (%rsp); \
+ jmp 2f; \
+1: \
+ PROTECTED_CLTS; \
+2:
+
+ /*
+ * If CR0_TS was not set above, pop %xmm0 and %xmm1 off stack,
+ * otherwise set CR0_TS.
+ */
+#define SET_TS_OR_POP_XMM0_XMM1(tmpreg) \
+ testq $CR0_TS, tmpreg; \
+ jnz 1f; \
+ movaps (%rsp), %xmm1; \
+ movaps 16(%rsp), %xmm0; \
+ jmp 2f; \
+1: \
+ STTS(tmpreg); \
+2: \
+ mov %rbp, %rsp; \
+ pop %rbp
+
+ /*
+ * If CR0_TS is not set, align stack (with push %rbp) and push
+ * %xmm0 - %xmm6 on stack, otherwise clear CR0_TS
+ */
+#define CLEAR_TS_OR_PUSH_XMM0_TO_XMM6(tmpreg) \
+ push %rbp; \
+ mov %rsp, %rbp; \
+ movq %cr0, tmpreg; \
+ testq $CR0_TS, tmpreg; \
+ jnz 1f; \
+ and $-XMM_ALIGN, %rsp; \
+ sub $[XMM_SIZE * 7], %rsp; \
+ movaps %xmm0, 96(%rsp); \
+ movaps %xmm1, 80(%rsp); \
+ movaps %xmm2, 64(%rsp); \
+ movaps %xmm3, 48(%rsp); \
+ movaps %xmm4, 32(%rsp); \
+ movaps %xmm5, 16(%rsp); \
+ movaps %xmm6, (%rsp); \
+ jmp 2f; \
+1: \
+ PROTECTED_CLTS; \
+2:
+
+
+ /*
+ * If CR0_TS was not set above, pop %xmm0 - %xmm6 off stack,
+ * otherwise set CR0_TS.
+ */
+#define SET_TS_OR_POP_XMM0_TO_XMM6(tmpreg) \
+ testq $CR0_TS, tmpreg; \
+ jnz 1f; \
+ movaps (%rsp), %xmm6; \
+ movaps 16(%rsp), %xmm5; \
+ movaps 32(%rsp), %xmm4; \
+ movaps 48(%rsp), %xmm3; \
+ movaps 64(%rsp), %xmm2; \
+ movaps 80(%rsp), %xmm1; \
+ movaps 96(%rsp), %xmm0; \
+ jmp 2f; \
+1: \
+ STTS(tmpreg); \
+2: \
+ mov %rbp, %rsp; \
+ pop %rbp
+
+
+#else
+#define PROTECTED_CLTS
+#define CLEAR_TS_OR_PUSH_XMM0_XMM1(tmpreg)
+#define SET_TS_OR_POP_XMM0_XMM1(tmpreg)
+#define CLEAR_TS_OR_PUSH_XMM0_TO_XMM6(tmpreg)
+#define SET_TS_OR_POP_XMM0_TO_XMM6(tmpreg)
+#endif /* _KERNEL */
+
+
+/*
+ * _key_expansion_128(), * _key_expansion_192a(), _key_expansion_192b(),
+ * _key_expansion_256a(), _key_expansion_256b()
+ *
+ * Helper functions called by rijndael_key_setup_inc_intel().
+ * Also used indirectly by rijndael_key_setup_dec_intel().
+ *
+ * Input:
+ * %xmm0 User-provided cipher key
+ * %xmm1 Round constant
+ * Output:
+ * (%rcx) AES key
+ */
+
+ /* EXPORT DELETE START */
+.align 16
+_key_expansion_128:
+_key_expansion_256a:
+ pshufd $0b11111111, %xmm1, %xmm1
+ shufps $0b00010000, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ shufps $0b10001100, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ pxor %xmm1, %xmm0
+ movaps %xmm0, (%rcx)
+ add $0x10, %rcx
+ ret
+ SET_SIZE(_key_expansion_128)
+ SET_SIZE(_key_expansion_256a)
+
+.align 16
+_key_expansion_192a:
+ pshufd $0b01010101, %xmm1, %xmm1
+ shufps $0b00010000, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ shufps $0b10001100, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ pxor %xmm1, %xmm0
+
+ movaps %xmm2, %xmm5
+ movaps %xmm2, %xmm6
+ pslldq $4, %xmm5
+ pshufd $0b11111111, %xmm0, %xmm3
+ pxor %xmm3, %xmm2
+ pxor %xmm5, %xmm2
+
+ movaps %xmm0, %xmm1
+ shufps $0b01000100, %xmm0, %xmm6
+ movaps %xmm6, (%rcx)
+ shufps $0b01001110, %xmm2, %xmm1
+ movaps %xmm1, 0x10(%rcx)
+ add $0x20, %rcx
+ ret
+ SET_SIZE(_key_expansion_192a)
+
+.align 16
+_key_expansion_192b:
+ pshufd $0b01010101, %xmm1, %xmm1
+ shufps $0b00010000, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ shufps $0b10001100, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ pxor %xmm1, %xmm0
+
+ movaps %xmm2, %xmm5
+ pslldq $4, %xmm5
+ pshufd $0b11111111, %xmm0, %xmm3
+ pxor %xmm3, %xmm2
+ pxor %xmm5, %xmm2
+
+ movaps %xmm0, (%rcx)
+ add $0x10, %rcx
+ ret
+ SET_SIZE(_key_expansion_192b)
+
+.align 16
+_key_expansion_256b:
+ pshufd $0b10101010, %xmm1, %xmm1
+ shufps $0b00010000, %xmm2, %xmm4
+ pxor %xmm4, %xmm2
+ shufps $0b10001100, %xmm2, %xmm4
+ pxor %xmm4, %xmm2
+ pxor %xmm1, %xmm2
+ movaps %xmm2, (%rcx)
+ add $0x10, %rcx
+ ret
+ SET_SIZE(_key_expansion_256b)
+ /* EXPORT DELETE END */
+
+
+/*
+ * rijndael_key_setup_enc_intel()
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * For kernel code, caller is responsible for ensuring kpreempt_disable()
+ * has been called. This is because %xmm registers are not saved/restored.
+ * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set
+ * on entry. Otherwise, if TS is not set, save and restore %xmm registers
+ * on the stack.
+ *
+ * OpenSolaris interface:
+ * int rijndael_key_setup_enc_intel(uint32_t rk[], const uint32_t cipherKey[],
+ * uint64_t keyBits);
+ * Return value is 0 on error, number of rounds on success.
+ *
+ * Original Intel OpenSSL interface:
+ * int intel_AES_set_encrypt_key(const unsigned char *userKey,
+ * const int bits, AES_KEY *key);
+ * Return value is non-zero on error, 0 on success.
+ */
+
+#ifdef OPENSSL_INTERFACE
+#define rijndael_key_setup_enc_intel intel_AES_set_encrypt_key
+#define rijndael_key_setup_dec_intel intel_AES_set_decrypt_key
+
+#define USERCIPHERKEY rdi /* P1, 64 bits */
+#define KEYSIZE32 esi /* P2, 32 bits */
+#define KEYSIZE64 rsi /* P2, 64 bits */
+#define AESKEY rdx /* P3, 64 bits */
+
+#else /* OpenSolaris Interface */
+#define AESKEY rdi /* P1, 64 bits */
+#define USERCIPHERKEY rsi /* P2, 64 bits */
+#define KEYSIZE32 edx /* P3, 32 bits */
+#define KEYSIZE64 rdx /* P3, 64 bits */
+#endif /* OPENSSL_INTERFACE */
+
+#define ROUNDS32 KEYSIZE32 /* temp */
+#define ROUNDS64 KEYSIZE64 /* temp */
+#define ENDAESKEY USERCIPHERKEY /* temp */
+
+
+ENTRY_NP(rijndael_key_setup_enc_intel)
+ /* EXPORT DELETE START */
+ CLEAR_TS_OR_PUSH_XMM0_TO_XMM6(%r10)
+
+ / NULL pointer sanity check
+ test %USERCIPHERKEY, %USERCIPHERKEY
+ jz .Lenc_key_invalid_param
+ test %AESKEY, %AESKEY
+ jz .Lenc_key_invalid_param
+
+ movups (%USERCIPHERKEY), %xmm0 / user key (first 16 bytes)
+ movaps %xmm0, (%AESKEY)
+ lea 0x10(%AESKEY), %rcx / key addr
+ pxor %xmm4, %xmm4 / xmm4 is assumed 0 in _key_expansion_x
+
+ cmp $256, %KEYSIZE32
+ jnz .Lenc_key192
+
+ / AES 256: 14 rounds
+#ifdef OPENSSL_INTERFACE
+ mov $14, %ROUNDS32
+ movl %ROUNDS32, 240(%AESKEY) / key.rounds = 14
+#endif /* OPENSSL_INTERFACE */
+
+ movups 0x10(%USERCIPHERKEY), %xmm2 / other user key (2nd 16 bytes)
+ movaps %xmm2, (%rcx)
+ add $0x10, %rcx
+
+ / aeskeygenassist $0x1, %xmm2, %xmm1 / round 1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+ call _key_expansion_256a
+ / aeskeygenassist $0x1, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+ call _key_expansion_256b
+ / aeskeygenassist $0x2, %xmm2, %xmm1 / round 2
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+ call _key_expansion_256a
+ / aeskeygenassist $0x2, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+ call _key_expansion_256b
+ / aeskeygenassist $0x4, %xmm2, %xmm1 / round 3
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+ call _key_expansion_256a
+ / aeskeygenassist $0x4, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+ call _key_expansion_256b
+ / aeskeygenassist $0x8, %xmm2, %xmm1 / round 4
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+ call _key_expansion_256a
+ / aeskeygenassist $0x8, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+ call _key_expansion_256b
+ / aeskeygenassist $0x10, %xmm2, %xmm1 / round 5
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+ call _key_expansion_256a
+ / aeskeygenassist $0x10, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+ call _key_expansion_256b
+ / aeskeygenassist $0x20, %xmm2, %xmm1 / round 6
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+ call _key_expansion_256a
+ / aeskeygenassist $0x20, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+ call _key_expansion_256b
+ / aeskeygenassist $0x40, %xmm2, %xmm1 / round 7
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+ call _key_expansion_256a
+
+ SET_TS_OR_POP_XMM0_TO_XMM6(%r10)
+#ifdef OPENSSL_INTERFACE
+ xor %rax, %rax / return 0 (OK)
+#else /* Open Solaris Interface */
+ mov $14, %rax / return # rounds = 14
+#endif
+ ret
+
+.align 4
+.Lenc_key192:
+ cmp $192, %KEYSIZE32
+ jnz .Lenc_key128
+
+ / AES 192: 12 rounds
+#ifdef OPENSSL_INTERFACE
+ mov $12, %ROUNDS32
+ movl %ROUNDS32, 240(%AESKEY) / key.rounds = 12
+#endif /* OPENSSL_INTERFACE */
+
+ movq 0x10(%USERCIPHERKEY), %xmm2 / other user key
+ / aeskeygenassist $0x1, %xmm2, %xmm1 / round 1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+ call _key_expansion_192a
+ / aeskeygenassist $0x2, %xmm2, %xmm1 / round 2
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+ call _key_expansion_192b
+ / aeskeygenassist $0x4, %xmm2, %xmm1 / round 3
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+ call _key_expansion_192a
+ / aeskeygenassist $0x8, %xmm2, %xmm1 / round 4
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+ call _key_expansion_192b
+ / aeskeygenassist $0x10, %xmm2, %xmm1 / round 5
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+ call _key_expansion_192a
+ / aeskeygenassist $0x20, %xmm2, %xmm1 / round 6
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+ call _key_expansion_192b
+ / aeskeygenassist $0x40, %xmm2, %xmm1 / round 7
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+ call _key_expansion_192a
+ / aeskeygenassist $0x80, %xmm2, %xmm1 / round 8
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x80
+ call _key_expansion_192b
+
+ SET_TS_OR_POP_XMM0_TO_XMM6(%r10)
+#ifdef OPENSSL_INTERFACE
+ xor %rax, %rax / return 0 (OK)
+#else /* OpenSolaris Interface */
+ mov $12, %rax / return # rounds = 12
+#endif
+ ret
+
+.align 4
+.Lenc_key128:
+ cmp $128, %KEYSIZE32
+ jnz .Lenc_key_invalid_key_bits
+#ifdef OPENSSL_INTERFACE
+ mov $10, %ROUNDS32
+ movl %ROUNDS32, 240(%AESKEY) / key.rounds = 10
+#endif /* OPENSSL_INTERFACE */
+
+ / aeskeygenassist $0x1, %xmm0, %xmm1 / round 1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+ call _key_expansion_128
+ / aeskeygenassist $0x2, %xmm0, %xmm1 / round 2
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+ call _key_expansion_128
+ / aeskeygenassist $0x4, %xmm0, %xmm1 / round 3
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+ call _key_expansion_128
+ / aeskeygenassist $0x8, %xmm0, %xmm1 / round 4
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+ call _key_expansion_128
+ / aeskeygenassist $0x10, %xmm0, %xmm1 / round 5
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+ call _key_expansion_128
+ / aeskeygenassist $0x20, %xmm0, %xmm1 / round 6
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+ call _key_expansion_128
+ / aeskeygenassist $0x40, %xmm0, %xmm1 / round 7
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x40
+ call _key_expansion_128
+ / aeskeygenassist $0x80, %xmm0, %xmm1 / round 8
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x80
+ call _key_expansion_128
+ / aeskeygenassist $0x1b, %xmm0, %xmm1 / round 9
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x1b
+ call _key_expansion_128
+ / aeskeygenassist $0x36, %xmm0, %xmm1 / round 10
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x36
+ call _key_expansion_128
+
+ SET_TS_OR_POP_XMM0_TO_XMM6(%r10)
+#ifdef OPENSSL_INTERFACE
+ xor %rax, %rax / return 0 (OK)
+#else /* OpenSolaris Interface */
+ mov $10, %rax / return # rounds = 10
+#endif
+ ret
+
+.Lenc_key_invalid_param:
+#ifdef OPENSSL_INTERFACE
+ SET_TS_OR_POP_XMM0_TO_XMM6(%r10)
+ mov $-1, %rax / user key or AES key pointer is NULL
+ ret
+#else
+ /* FALLTHROUGH */
+#endif /* OPENSSL_INTERFACE */
+
+.Lenc_key_invalid_key_bits:
+ SET_TS_OR_POP_XMM0_TO_XMM6(%r10)
+#ifdef OPENSSL_INTERFACE
+ mov $-2, %rax / keysize is invalid
+#else /* Open Solaris Interface */
+ xor %rax, %rax / a key pointer is NULL or invalid keysize
+#endif /* OPENSSL_INTERFACE */
+
+ /* EXPORT DELETE END */
+ ret
+ SET_SIZE(rijndael_key_setup_enc_intel)
+
+
+/*
+ * rijndael_key_setup_dec_intel()
+ * Expand the cipher key into the decryption key schedule.
+ *
+ * For kernel code, caller is responsible for ensuring kpreempt_disable()
+ * has been called. This is because %xmm registers are not saved/restored.
+ * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set
+ * on entry. Otherwise, if TS is not set, save and restore %xmm registers
+ * on the stack.
+ *
+ * OpenSolaris interface:
+ * int rijndael_key_setup_dec_intel(uint32_t rk[], const uint32_t cipherKey[],
+ * uint64_t keyBits);
+ * Return value is 0 on error, number of rounds on success.
+ * P1->P2, P2->P3, P3->P1
+ *
+ * Original Intel OpenSSL interface:
+ * int intel_AES_set_decrypt_key(const unsigned char *userKey,
+ * const int bits, AES_KEY *key);
+ * Return value is non-zero on error, 0 on success.
+ */
+ENTRY_NP(rijndael_key_setup_dec_intel)
+ /* EXPORT DELETE START */
+ call rijndael_key_setup_enc_intel
+ test %rax, %rax
+#ifdef OPENSSL_INTERFACE
+ jnz .Ldec_key_exit / Failed if returned non-0
+#else /* OpenSolaris Interface */
+ jz .Ldec_key_exit / Failed if returned 0
+#endif /* OPENSSL_INTERFACE */
+
+ CLEAR_TS_OR_PUSH_XMM0_XMM1(%r10)
+
+#ifndef OPENSSL_INTERFACE /* OpenSolaris Interface */
+ mov %rax, %ROUNDS64 / set # rounds (10, 12, or 14)
+ / (already set for OpenSSL)
+#endif
+
+ lea 0x10(%AESKEY), %rcx / key addr
+ shl $4, %ROUNDS32
+ add %AESKEY, %ROUNDS64
+ mov %ROUNDS64, %ENDAESKEY
+
+.align 4
+.Ldec_key_reorder_loop:
+ movaps (%AESKEY), %xmm0
+ movaps (%ROUNDS64), %xmm1
+ movaps %xmm0, (%ROUNDS64)
+ movaps %xmm1, (%AESKEY)
+ lea 0x10(%AESKEY), %AESKEY
+ lea -0x10(%ROUNDS64), %ROUNDS64
+ cmp %AESKEY, %ROUNDS64
+ ja .Ldec_key_reorder_loop
+
+.align 4
+.Ldec_key_inv_loop:
+ movaps (%rcx), %xmm0
+ /aesimc %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x38, 0xdb, 0xc8
+ movaps %xmm1, (%rcx)
+ lea 0x10(%rcx), %rcx
+ cmp %ENDAESKEY, %rcx
+ jnz .Ldec_key_inv_loop
+
+ SET_TS_OR_POP_XMM0_XMM1(%r10)
+
+.Ldec_key_exit:
+ / OpenSolaris: rax = # rounds (10, 12, or 14) or 0 for error
+ / OpenSSL: rax = 0 for OK, or non-zero for error
+ /* EXPORT DELETE END */
+ ret
+ SET_SIZE(rijndael_key_setup_dec_intel)
+
+
+/*
+ * aes_encrypt_intel()
+ * Encrypt a single block (in and out can overlap).
+ *
+ * For kernel code, caller is responsible for ensuring kpreempt_disable()
+ * has been called. This is because %xmm registers are not saved/restored.
+ * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set
+ * on entry. Otherwise, if TS is not set, save and restore %xmm registers
+ * on the stack.
+ *
+ * Temporary register usage:
+ * %xmm0 State
+ * %xmm1 Key
+ *
+ * Original OpenSolaris Interface:
+ * void aes_encrypt_intel(const aes_ks_t *ks, int Nr,
+ * const uint32_t pt[4], uint32_t ct[4])
+ *
+ * Original Intel OpenSSL Interface:
+ * void intel_AES_encrypt(const unsigned char *in, unsigned char *out,
+ * const AES_KEY *key)
+ */
+
+#ifdef OPENSSL_INTERFACE
+#define aes_encrypt_intel intel_AES_encrypt
+#define aes_decrypt_intel intel_AES_decrypt
+
+#define INP rdi /* P1, 64 bits */
+#define OUTP rsi /* P2, 64 bits */
+#define KEYP rdx /* P3, 64 bits */
+
+/* No NROUNDS parameter--offset 240 from KEYP saved in %ecx: */
+#define NROUNDS32 ecx /* temporary, 32 bits */
+#define NROUNDS cl /* temporary, 8 bits */
+
+#else /* OpenSolaris Interface */
+#define KEYP rdi /* P1, 64 bits */
+#define NROUNDS esi /* P2, 32 bits */
+#define INP rdx /* P3, 64 bits */
+#define OUTP rcx /* P4, 64 bits */
+#endif /* OPENSSL_INTERFACE */
+
+#define STATE xmm0 /* temporary, 128 bits */
+#define KEY xmm1 /* temporary, 128 bits */
+
+ENTRY_NP(aes_encrypt_intel)
+ /* EXPORT DELETE START */
+ CLEAR_TS_OR_PUSH_XMM0_XMM1(%r10)
+
+ movups (%INP), %STATE / input
+ movaps (%KEYP), %KEY / key
+#ifdef OPENSSL_INTERFACE
+ mov 240(%KEYP), %NROUNDS32 / round count
+#else /* OpenSolaris Interface */
+ /* Round count is already present as P2 in %rsi/%esi */
+#endif /* OPENSSL_INTERFACE */
+
+ pxor %KEY, %STATE / round 0
+ lea 0x30(%KEYP), %KEYP
+ cmp $12, %NROUNDS
+ jb .Lenc128
+ lea 0x20(%KEYP), %KEYP
+ je .Lenc192
+
+ / AES 256
+ lea 0x20(%KEYP), %KEYP
+ movaps -0x60(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps -0x50(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+
+.align 4
+.Lenc192:
+ / AES 192 and 256
+ movaps -0x40(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps -0x30(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+
+.align 4
+.Lenc128:
+ / AES 128, 192, and 256
+ movaps -0x20(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps -0x10(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps (%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps 0x10(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps 0x20(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps 0x30(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps 0x40(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps 0x50(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps 0x60(%KEYP), %KEY
+ /aesenc %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc1
+ movaps 0x70(%KEYP), %KEY
+ /aesenclast %KEY, %STATE / last round
+ .byte 0x66, 0x0f, 0x38, 0xdd, 0xc1
+ movups %STATE, (%OUTP) / output
+
+ SET_TS_OR_POP_XMM0_XMM1(%r10)
+ /* EXPORT DELETE END */
+ ret
+ SET_SIZE(aes_encrypt_intel)
+
+
+/*
+ * aes_decrypt_intel()
+ * Decrypt a single block (in and out can overlap).
+ *
+ * For kernel code, caller is responsible for ensuring kpreempt_disable()
+ * has been called. This is because %xmm registers are not saved/restored.
+ * Clear and set the CR0.TS bit on entry and exit, respectively, if TS is set
+ * on entry. Otherwise, if TS is not set, save and restore %xmm registers
+ * on the stack.
+ *
+ * Temporary register usage:
+ * %xmm0 State
+ * %xmm1 Key
+ *
+ * Original OpenSolaris Interface:
+ * void aes_decrypt_intel(const aes_ks_t *ks, int Nr,
+ * const uint32_t pt[4], uint32_t ct[4])/
+ *
+ * Original Intel OpenSSL Interface:
+ * void intel_AES_decrypt(const unsigned char *in, unsigned char *out,
+ * const AES_KEY *key);
+ */
+ENTRY_NP(aes_decrypt_intel)
+ /* EXPORT DELETE START */
+ CLEAR_TS_OR_PUSH_XMM0_XMM1(%r10)
+
+ movups (%INP), %STATE / input
+ movaps (%KEYP), %KEY / key
+#ifdef OPENSSL_INTERFACE
+ mov 240(%KEYP), %NROUNDS32 / round count
+#else /* OpenSolaris Interface */
+ /* Round count is already present as P2 in %rsi/%esi */
+#endif /* OPENSSL_INTERFACE */
+
+ pxor %KEY, %STATE / round 0
+ lea 0x30(%KEYP), %KEYP
+ cmp $12, %NROUNDS
+ jb .Ldec128
+ lea 0x20(%KEYP), %KEYP
+ je .Ldec192
+
+ / AES 256
+ lea 0x20(%KEYP), %KEYP
+ movaps -0x60(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps -0x50(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+
+.align 4
+.Ldec192:
+ / AES 192 and 256
+ movaps -0x40(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps -0x30(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+
+.align 4
+.Ldec128:
+ / AES 128, 192, and 256
+ movaps -0x20(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps -0x10(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps (%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps 0x10(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps 0x20(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps 0x30(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps 0x40(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps 0x50(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps 0x60(%KEYP), %KEY
+ /aesdec %KEY, %STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc1
+ movaps 0x70(%KEYP), %KEY
+ /aesdeclast %KEY, %STATE / last round
+ .byte 0x66, 0x0f, 0x38, 0xdf, 0xc1
+ movups %STATE, (%OUTP) / output
+
+ SET_TS_OR_POP_XMM0_XMM1(%r10)
+ ret
+ /* EXPORT DELETE END */
+ SET_SIZE(aes_decrypt_intel)
+
+#endif /* lint || __lint */
diff --git a/usr/src/common/crypto/aes/amd64/aeskey.c b/usr/src/common/crypto/aes/amd64/aeskey.c
index dbfe5718f6..8855c08b55 100644
--- a/usr/src/common/crypto/aes/amd64/aeskey.c
+++ b/usr/src/common/crypto/aes/amd64/aeskey.c
@@ -25,8 +25,6 @@
* Issue Date: 20/12/2007
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "aes_impl.h"
#include "aesopt.h"
#include "aestab.h"
@@ -61,10 +59,9 @@
* 5. Changed aes_encrypt_key* aes_decrypt_key* functions to "static void"
* 6. Changed N_COLS to MAX_AES_NB
* 7. Replaced functions aes_encrypt_key and aes_decrypt_key with
- * OpenSolaris-compatible functions rijndael_key_setup_enc and
- * rijndael_key_setup_dec
+ * OpenSolaris-compatible functions rijndael_key_setup_enc_amd64 and
+ * rijndael_key_setup_dec_amd64
* 8. cstyled code and removed lint warnings
- *
*/
#if defined(REDUCE_CODE_SIZE)
@@ -214,7 +211,8 @@ aes_encrypt_key256(const unsigned char *key, uint32_t rk[])
* keyBits AES key size (128, 192, or 256 bits)
*/
int
-rijndael_key_setup_enc(uint32_t rk[], const uint32_t cipherKey[], int keyBits)
+rijndael_key_setup_enc_amd64(uint32_t rk[], const uint32_t cipherKey[],
+ int keyBits)
{
switch (keyBits) {
case 128:
@@ -561,7 +559,8 @@ aes_decrypt_key256(const unsigned char *key, uint32_t rk[])
* keyBits AES key size (128, 192, or 256 bits)
*/
int
-rijndael_key_setup_dec(uint32_t rk[], const uint32_t cipherKey[], int keyBits)
+rijndael_key_setup_dec_amd64(uint32_t rk[], const uint32_t cipherKey[],
+ int keyBits)
{
switch (keyBits) {
case 128:
diff --git a/usr/src/common/crypto/aes/sun4u/aes_crypt_asm.s b/usr/src/common/crypto/aes/sun4u/aes_crypt_asm.s
index 4962aaf802..e6ea0f8084 100644
--- a/usr/src/common/crypto/aes/sun4u/aes_crypt_asm.s
+++ b/usr/src/common/crypto/aes/sun4u/aes_crypt_asm.s
@@ -19,48 +19,55 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Unified version for both position independent and non position independent
- * for both v8plus and v9
- * compile with:
+ * for both v8plus and v9.
+ * Compile with:
*
* cc -c -xarch=v8plus aes_crypt_asm.S or
* cc -c -arch=v9 aes_crypt_asm.S
- * for kernel use (no -KPIC)
+ * for kernel use (no -KPIC).
*
* and with
*
* cc -c -xarch=v8plus -KPIC -DPIC aes_crypt_asm.S or
* cc -c -arch=v9 -KPIC -DPIC aes_crypt_asm.S
- * for .so use
+ * for .so use.
*
*
- * The tables were generated by a C program, compiled into the C version
+ * The tables were generated by a C program, compiled into the C version
* of this function, from which a .s was generated by the C compiler and
* that .s was used as a starting point for this one, in particular for
* the data definitions. It is important, though that the tables and
* the code both remain in the text section and in this order, otherwise,
* at least on UltraSparc-II processors, collisions in the E-cache are
* highly probable between the code and the data it is using which can
- * result in up to 40% performance loss
+ * result in up to 40% performance loss.
*
- * For a description of the AES algithm (a.k.a. Rijndael), see NIST
- * publication FIPS PUB 197
+ * For a description of the AES algorithm (a.k.a. Rijndael), see NIST
+ * publication FIPS PUB 197.
*
*/
#include <sys/stack.h>
-
+
#if defined(lint) || defined(__lint)
- /* LINTED */
- /* Nothing to be linted in this file, its pure assembly source */
-#else /* lint || __lint */
+
+#include <sys/types.h>
+/* ARGSUSED */
+void aes_encrypt_impl(const uint32_t rk[], int Nr, const uint32_t pt[4],
+ uint32_t ct[4]) {
+}
+/* ARGSUSED */
+void aes_decrypt_impl(const uint32_t rk[], int Nr, const uint32_t ct[4],
+ uint32_t pt[4]) {
+}
+
+#else /* lint || __lint */
.section ".text",#alloc,#execinstr
.file "aes_crypt_asm.s"
@@ -2468,14 +2475,14 @@ aes_const:
!
! SUBROUTINE aes_encrypt_impl
!
-! void aes_encrypt_impl(const uint64_t *ks, int Nr, const uint32_t *inblock,
-! uint32_t *outblock);
+! void aes_encrypt_impl(const uint32_t rk[], int Nr, const uint32_t pt[4],
+! uint32_t ct[4]);
!
! OFFSET SOURCE LINE LABEL INSTRUCTION
.global aes_encrypt_impl
aes_encrypt_impl:
-
+
#ifdef __sparcv9
save %sp, -SA(MINFRAME), %sp
@@ -2488,7 +2495,7 @@ aes_const:
sethi %hi(_GLOBAL_OFFSET_TABLE_-(.L1-.)), %l1
or %l0, %lo(aes_const), %l0
ld [%i2], %g1
-
+
or %l1, %lo(_GLOBAL_OFFSET_TABLE_-(.L1-.)), %l1
sethi %hi(0xff000000), %i5
@@ -2503,23 +2510,23 @@ aes_const:
#else /* PIC */
sethi %hh(aes_const), %l0
sethi %lm(aes_const), %l7
-
+
or %l0, %hm(aes_const), %l0
or %l7, %lo(aes_const), %l7
sllx %l0, 32, %l0
sethi %hi(0xff000000), %i5
ld [%i2], %g1
-
+
sethi %hi(0x7fff8), %l6
or %l0, %l7, %l7
-
+
and %g1, %i5, %o0
or %l6, %lo(0x7ff8), %l6
sll %g1, 8, %o5
#endif /* PIC */
-
+
#else /* __sparcv9 */
save %sp, -SA(MINFRAME), %sp
@@ -2532,7 +2539,7 @@ aes_const:
sethi %hi(_GLOBAL_OFFSET_TABLE_-(.L1-.)), %l1
or %l0, %lo(aes_const), %l0
ld [%i2], %g1
-
+
or %l1, %lo(_GLOBAL_OFFSET_TABLE_-(.L1-.)), %l1
sethi %hi(0xff000000), %i5
@@ -2548,15 +2555,15 @@ aes_const:
or %l0, %lo(aes_const), %l7
sethi %hi(0xff000000), %i5
ld [%i2], %g1
-
+
sethi %hi(0x7fff8), %l6
-
+
and %g1, %i5, %o0
or %l6, %lo(0x7ff8), %l6
sll %g1, 8, %o5
#endif /* PIC */
-
+
#endif /* __sparcv9 */
sll %g1, 3, %g1
@@ -2701,7 +2708,7 @@ aes_const:
xor %o5, %g5,%g5
ldx [%i0 + 24], %o5
-.L3:
+.L3:
srl %g3, 8, %l6
xor %g5, %o0, %g5
ldx [%l0 + %l4], %o0
@@ -2787,7 +2794,7 @@ aes_const:
and %l6, 0x7f8, %l6
xor %g5, %o5, %o4
ldx [%l1 + %l5], %o5
-
+
and %o4, 0x7f8, %l7
add %i0, 32, %i0
ldx [%l2 + %l6], %g5
@@ -2983,16 +2990,20 @@ aes_const:
.type aes_encrypt_impl,2
.size aes_encrypt_impl,(.-aes_encrypt_impl)
+
.section ".text",#alloc,#execinstr
.align 8192
!
! SUBROUTINE aes_decrypt_impl
!
+! void aes_decrypt_impl(const uint32_t rk[], int Nr, const uint32_t ct[4],
+! uint32_t pt[4]);
+!
! OFFSET SOURCE LINE LABEL INSTRUCTION
.global aes_decrypt_impl
aes_decrypt_impl:
-
+
#ifdef __sparcv9
save %sp, -SA(MINFRAME), %sp
@@ -3005,7 +3016,7 @@ aes_const:
sethi %hi(_GLOBAL_OFFSET_TABLE_-(.L1d-.)), %l1
or %l0, %lo(aes_const), %l0
ld [%i2 + 12], %g1
-
+
or %l1, %lo(_GLOBAL_OFFSET_TABLE_-(.L1d-.)), %l1
sethi %hi(0xff000000), %i5
@@ -3020,25 +3031,25 @@ aes_const:
#else /* PIC */
sethi %hh(aes_const), %l0
sethi %lm(aes_const), %l7
-
+
or %l0, %hm(aes_const), %l0
or %l7, %lo(aes_const), %l7
sllx %l0, 32, %l0
sethi %hi(0xff000000), %i5
ld [%i2 + 12], %g1
-
+
sethi %hi(0x7fff8), %l6
or %l0, %l7, %l7
-
+
and %g1, %i5, %o0
or %l6, %lo(0x7ff8), %l6
sll %g1, 8, %o5
#endif /* PIC */
-
+
#else /* __sparcv9 */
-
+
save %sp, -SA(MINFRAME), %sp
sethi %hi(aes_const), %l0
@@ -3049,7 +3060,7 @@ aes_const:
sethi %hi(_GLOBAL_OFFSET_TABLE_-(.L1d-.)), %l1
or %l0, %lo(aes_const), %l0
ld [%i2 + 12], %g1
-
+
or %l1, %lo(_GLOBAL_OFFSET_TABLE_-(.L1d-.)), %l1
sethi %hi(0xff000000), %i5
@@ -3067,7 +3078,7 @@ aes_const:
ld [%i2 + 12], %g1
sethi %hi(0x7fff8), %l6
-
+
and %g1, %i5, %o0
or %l6, %lo(0x7ff8), %l6
@@ -3218,7 +3229,7 @@ aes_const:
xor %o5, %g5,%g5
ldx [%i0 + 24], %o5
-.L3d:
+.L3d:
srl %g3, 8, %l6
xor %g5, %o0, %g5
ldx [%l0 + %l4], %o0
@@ -3304,7 +3315,7 @@ aes_const:
and %l6, 0x7f8, %l6
xor %g5, %o5, %o4
ldx [%l1 + %l5], %o5
-
+
and %o4, 0x7f8, %l7
add %i0, 32, %i0
ldx [%l2 + %l6], %g5
@@ -5857,7 +5868,7 @@ rcon:
.size rcon,40
/* EXPORT DELETE END */
-
+
! Begin Disassembling Stabs
.xstabs ".stab.index","Xa ; O ; P ; V=3.1 ; R=WorkShop Compilers 5.0 99/02/25 C 5.0 patch 107289-01",60,0,0,0 ! (/tmp/acompAAA5jaWsZ:1)
! End Disassembling Stabs
@@ -5866,5 +5877,5 @@ rcon:
.ident "cg: WorkShop Compilers 5.0 99/04/15 Compiler Common 5.0 Patch 107357-02" ! (NO SOURCE LINE)
.ident "acomp: WorkShop Compilers 5.0 99/02/25 C 5.0 patch 107289-01" ! (/tmp/acompAAA5jaWsZ:4675)
! End Disassembling Ident
-
+
#endif /* lint || __lint */
diff --git a/usr/src/common/crypto/arcfour/Makefile b/usr/src/common/crypto/arcfour/Makefile
index f378e04549..00f84b382d 100644
--- a/usr/src/common/crypto/arcfour/Makefile
+++ b/usr/src/common/crypto/arcfour/Makefile
@@ -2,9 +2,8 @@
# 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.
+# 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.
@@ -20,9 +19,7 @@
# CDDL HEADER END
#
#
-#pragma ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# common/crypto/arcfour/Makefile
@@ -36,17 +33,25 @@ FRC:
# EXPORT DELETE START
EXPORT_SRC:
- $(RM) Makefile+ arcfour_crypt.c+ sun4u/arcfour_crypt_asm.s+
+ $(RM) Makefile+ arcfour_crypt.c+ amd64/arcfour-x86_64.pl+ \
+ sun4u/arcfour_crypt_asm.s+ sun4v/arcfour_crypt.c+
sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
< arcfour_crypt.c > arcfour_crypt.c+
$(MV) arcfour_crypt.c+ arcfour_crypt.c
sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
+ < amd64/arcfour-x86_64.c > amd64/arcfour-x86_64.c+
+ $(MV) amd64/arcfour-x86_64.c+ amd64/arcfour-x86_64.c
+ sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
< sun4u/arcfour_crypt_asm.s > sun4u/arcfour_crypt_asm.s+
$(MV) sun4u/arcfour_crypt_asm.s+ sun4u/arcfour_crypt_asm.s
+ sed -e "/EXPORT DELETE START/,/EXPORT DELETE END/d" \
+ < sun4v/arcfour_crypt.c > sun4v/arcfour_crypt.c+
+ $(MV) sun4v/arcfour_crypt.c+ sun4v/arcfour_crypt.c
sed -e "/^# EXPORT DELETE START/,/^# EXPORT DELETE END/d" \
< Makefile > Makefile+
$(RM) Makefile
$(MV) Makefile+ Makefile
- $(CHMOD) 444 Makefile arcfour_crypt.c sun4u/arcfour_crypt_asm.s
+ $(CHMOD) 444 Makefile arcfour_crypt.c amd64/arcfour-x86_64.pl \
+ sun4u/arcfour_crypt_asm.s sun4v/arcfour_crypt.c
# EXPORT DELETE END
diff --git a/usr/src/common/crypto/modes/ccm.c b/usr/src/common/crypto/modes/ccm.c
index a0de6fc50c..617400db14 100644
--- a/usr/src/common/crypto/modes/ccm.c
+++ b/usr/src/common/crypto/modes/ccm.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,9 +35,9 @@
#include <modes/modes.h>
#include <sys/crypto/common.h>
#include <sys/crypto/impl.h>
+#include <sys/byteorder.h>
#if defined(__i386) || defined(__amd64)
-#include <sys/byteorder.h>
#define UNALIGNED_POINTERS_PERMITTED
#endif
@@ -116,13 +116,8 @@ ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
* Increment counter. Counter bits are confined
* to the bottom 64 bits of the counter block.
*/
-#ifdef _LITTLE_ENDIAN
counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
counter = htonll(counter + 1);
-#else
- counter = ctx->ccm_cb[1] & ctx->ccm_counter_mask;
- counter++;
-#endif /* _LITTLE_ENDIAN */
counter &= ctx->ccm_counter_mask;
ctx->ccm_cb[1] =
(ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
@@ -476,13 +471,8 @@ ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *ctx, char *data, size_t length,
* Increment counter.
* Counter bits are confined to the bottom 64 bits
*/
-#ifdef _LITTLE_ENDIAN
counter = ntohll(ctx->ccm_cb[1] & ctx->ccm_counter_mask);
counter = htonll(counter + 1);
-#else
- counter = ctx->ccm_cb[1] & ctx->ccm_counter_mask;
- counter++;
-#endif /* _LITTLE_ENDIAN */
counter &= ctx->ccm_counter_mask;
ctx->ccm_cb[1] =
(ctx->ccm_cb[1] & ~(ctx->ccm_counter_mask)) | counter;
@@ -702,10 +692,7 @@ ccm_format_initial_blocks(uchar_t *nonce, ulong_t nonceSize,
mask |= (1ULL << q);
}
-#ifdef _LITTLE_ENDIAN
- mask = htonll(mask);
-#endif
- aes_ctx->ccm_counter_mask = mask;
+ aes_ctx->ccm_counter_mask = htonll(mask);
/*
* During calculation, we start using counter block 1, we will
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com b/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com
index e83926da50..3ea8d44f99 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com
+++ b/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# lib/pkcs11/libsoftcrypto/Makefile.com
@@ -27,7 +27,7 @@
# AES
AES_DIR= $(SRC)/common/crypto/aes
-AES_COMMON_OBJS= aes_impl.o
+AES_COMMON_OBJS= aes_impl.o aes_modes.o
AES_COMMON_SRC= $(AES_COMMON_OBJS:%.o=$(AES_DIR)/%.c)
AES_FLAGS= -I$(AES_DIR)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile
index d8c3e5ed3e..2428cd56e0 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile
@@ -28,8 +28,9 @@
LIBRARY= libsoftcrypto.a
VERS= .1
-AES_PSM_OBJS= aes_amd64.o aeskey.o
-AES_PSM_SRC= $(AES_DIR)/$(MACH64)/aes_amd64.s $(AES_DIR)/$(MACH64)/aeskey.c
+AES_PSM_OBJS= aes_amd64.o aes_intel.o aeskey.o
+AES_PSM_SRC= $(AES_DIR)/$(MACH64)/aes_amd64.s $(AES_DIR)/$(MACH64)/aes_intel.s \
+ $(AES_DIR)/$(MACH64)/aeskey.c
ARCFOUR_PSM_OBJS= arcfour-x86_64.o
ARCFOUR_PSM_SRC= arcfour-x86_64.s
diff --git a/usr/src/pkgdefs/SUNWckr/Makefile b/usr/src/pkgdefs/SUNWckr/Makefile
index f2a3c037f0..2646501ffc 100644
--- a/usr/src/pkgdefs/SUNWckr/Makefile
+++ b/usr/src/pkgdefs/SUNWckr/Makefile
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
include ../Makefile.com
@@ -34,7 +32,8 @@ MACHDATAFILES += i.sdconf
CLOBBERFILES += $(MACHDATAFILES)
LICENSEFILES_i386 = \
- ../../common/crypto/aes/amd64/THIRDPARTYLICENSE \
+ ../../common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman \
+ ../../common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl \
../../common/crypto/md5/amd64/THIRDPARTYLICENSE \
../../common/crypto/THIRDPARTYLICENSE.cryptogams \
../../uts/intel/io/acpica/THIRDPARTYLICENSE
diff --git a/usr/src/pkgdefs/SUNWcslr/Makefile b/usr/src/pkgdefs/SUNWcslr/Makefile
index 81e098c400..11894abc48 100644
--- a/usr/src/pkgdefs/SUNWcslr/Makefile
+++ b/usr/src/pkgdefs/SUNWcslr/Makefile
@@ -19,18 +19,17 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
include ../Makefile.com
DATAFILES += depend
LICENSEFILES_i386 = \
- ../../common/crypto/aes/amd64/THIRDPARTYLICENSE \
+ ../../common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman \
+ ../../common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl \
../../common/crypto/md5/amd64/THIRDPARTYLICENSE \
../../common/crypto/THIRDPARTYLICENSE.cryptogams
diff --git a/usr/src/tools/opensolaris/license-list b/usr/src/tools/opensolaris/license-list
index eac54fe576..af6de7d6f7 100644
--- a/usr/src/tools/opensolaris/license-list
+++ b/usr/src/tools/opensolaris/license-list
@@ -70,9 +70,11 @@ usr/src/cmd/which/THIRDPARTYLICENSE
usr/src/cmd/xntpd/THIRDPARTYLICENSE
usr/src/cmd/xstr/THIRDPARTYLICENSE
usr/src/common/crypto/THIRDPARTYLICENSE.cryptogams
-usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE
+usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.gladman
+usr/src/common/crypto/aes/amd64/THIRDPARTYLICENSE.openssl
usr/src/common/crypto/ecc/THIRDPARTYLICENSE
usr/src/common/crypto/md5/amd64/THIRDPARTYLICENSE
+usr/src/common/mpi/THIRDPARTYLICENSE
usr/src/common/openssl/LICENSE
usr/src/grub/grub-0.97/COPYING
usr/src/lib/gss_mechs/mech_krb5/THIRDPARTYLICENSE
@@ -84,8 +86,8 @@ usr/src/lib/libbsdmalloc/THIRDPARTYLICENSE
usr/src/lib/libcmd/THIRDPARTYLICENSE
usr/src/lib/libdll/THIRDPARTYLICENSE
usr/src/lib/libdns_sd/THIRDPARTYLICENSE
-usr/src/lib/libima/THIRDPARTYLICENSE
usr/src/lib/libgss/THIRDPARTYLICENSE
+usr/src/lib/libima/THIRDPARTYLICENSE
usr/src/lib/libinetutil/common/THIRDPARTYLICENSE
usr/src/lib/libkmf/THIRDPARTYLICENSE
usr/src/lib/libldap5/THIRDPARTYLICENSE
@@ -95,6 +97,10 @@ usr/src/lib/libresolv/THIRDPARTYLICENSE
usr/src/lib/libresolv2/THIRDPARTYLICENSE
usr/src/lib/libsasl/THIRDPARTYLICENSE
usr/src/lib/libshell/THIRDPARTYLICENSE
+usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.apple
+usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.boris_popov
+usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.bsd4
+usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.microsoft
usr/src/lib/libsum/THIRDPARTYLICENSE
usr/src/lib/libtecla/THIRDPARTYLICENSE
usr/src/lib/libwrap/THIRDPARTYLICENSE
@@ -143,6 +149,7 @@ usr/src/uts/common/io/iwk/fw-iw/LICENSE
usr/src/uts/common/io/ixgbe/THIRDPARTYLICENSE
usr/src/uts/common/io/mega_sas/THIRDPARTYLICENSE
usr/src/uts/common/io/mxfe/THIRDPARTYLICENSE
+usr/src/uts/common/io/ntxn/THIRDPARTYLICENSE
usr/src/uts/common/io/pcan/THIRDPARTYLICENSE
usr/src/uts/common/io/pcwl/THIRDPARTYLICENSE
usr/src/uts/common/io/ppp/THIRDPARTYLICENSE
@@ -167,9 +174,3 @@ usr/src/uts/intel/io/amr/THIRDPARTYLICENSE
usr/src/uts/intel/pcbe/THIRDPARTYLICENSE
usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE
usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE
-usr/src/common/mpi/THIRDPARTYLICENSE
-usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.apple
-usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.boris_popov
-usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.bsd4
-usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.microsoft
-usr/src/uts/common/io/ntxn/THIRDPARTYLICENSE
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 6b9b948050..cd5192a54b 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -1414,7 +1414,7 @@ DPROV_OBJS += dprov.o
DCA_OBJS += dca.o dca_3des.o dca_debug.o dca_dsa.o dca_kstat.o dca_rng.o \
dca_rsa.o
-AESPROV_OBJS += aes.o aes_impl.o
+AESPROV_OBJS += aes.o aes_impl.o aes_modes.o
ARCFOURPROV_OBJS += arcfour.o arcfour_crypt.o
diff --git a/usr/src/uts/common/crypto/io/aes.c b/usr/src/uts/common/crypto/io/aes.c
index 1665b6e538..5f0e8f4c75 100644
--- a/usr/src/uts/common/crypto/io/aes.c
+++ b/usr/src/uts/common/crypto/io/aes.c
@@ -454,7 +454,7 @@ aes_copy_block64(uint8_t *in, uint64_t *out)
}
}
-/* ARGSUSED */
+
static int
aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
crypto_data_t *ciphertext, crypto_req_handle_t req)
@@ -570,11 +570,10 @@ aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
/* EXPORT DELETE END */
- /* LINTED */
return (ret);
}
-/* ARGSUSED */
+
static int
aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
crypto_data_t *plaintext, crypto_req_handle_t req)
@@ -689,10 +688,10 @@ cleanup:
/* EXPORT DELETE END */
- /* LINTED */
return (ret);
}
+
/* ARGSUSED */
static int
aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
@@ -768,7 +767,7 @@ aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext,
return (ret);
}
-/* ARGSUSED */
+
static int
aes_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
crypto_data_t *plaintext, crypto_req_handle_t req)
@@ -1367,7 +1366,7 @@ aes_create_ctx_template(crypto_provider_handle_t provider,
return (CRYPTO_SUCCESS);
}
-/* ARGSUSED */
+
static int
aes_free_context(crypto_ctx_t *ctx)
{
@@ -1392,7 +1391,7 @@ aes_free_context(crypto_ctx_t *ctx)
return (CRYPTO_SUCCESS);
}
-/* ARGSUSED */
+
static int
aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
crypto_mechanism_t *mechanism, crypto_key_t *key, int kmflag,
@@ -1436,7 +1435,7 @@ aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template,
mechanism->cm_param_len != sizeof (CK_AES_CTR_PARAMS)) {
return (CRYPTO_MECHANISM_PARAM_INVALID);
}
- pp = (CK_AES_CTR_PARAMS *)mechanism->cm_param;
+ pp = (CK_AES_CTR_PARAMS *)(void *)mechanism->cm_param;
rv = ctr_init_ctx((ctr_ctx_t *)aes_ctx, pp->ulCounterBits,
pp->cb, aes_copy_block);
break;
diff --git a/usr/src/uts/intel/aes/Makefile b/usr/src/uts/intel/aes/Makefile
index 44e77ce333..b2b6ee68f3 100644
--- a/usr/src/uts/intel/aes/Makefile
+++ b/usr/src/uts/intel/aes/Makefile
@@ -19,14 +19,12 @@
# CDDL HEADER END
#
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
# This makefile drives the production of the AES KEF provider.
#
-# intel implementation architecture dependent
+# Intel implementation architecture dependent
#
#
@@ -41,7 +39,7 @@ COM_DIR = $(COMMONBASE)/crypto/aes
MODULE = aes
LINTS = $(AESPROV_OBJS:%.o=$(LINTS_DIR)/%.ln)
AESPROV_OBJS_32 =
-AESPROV_OBJS_64 = aes_amd64.o aeskey.o
+AESPROV_OBJS_64 = aes_amd64.o aes_intel.o aeskey.o
AESPROV_OBJS += $(AESPROV_OBJS_$(CLASS))
OBJECTS = $(AESPROV_OBJS:%=$(OBJS_DIR)/%)
ROOTMODULE = $(ROOT_CRYPTO_DIR)/$(MODULE)
@@ -68,14 +66,7 @@ LDFLAGS += -dy -Nmisc/kcf
CPPFLAGS += -I$(COM_DIR) -I$(COM_DIR)/..
CPPFLAGS += -DCRYPTO_PROVIDER_NAME=\"$(MODULE)\"
-
-#
-# For now, disable these lint checks; maintainers should endeavor
-# to investigate and remove these for maximum lint coverage.
-# Please do not carry these forward to new Makefiles.
-#
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED
+AS_CPPFLAGS += -I../../$(PLATFORM)
#
# Default build targets.
@@ -110,9 +101,9 @@ $(OBJS_DIR)/%.o: $(COM_DIR)/amd64/%.c
$(COMPILE.c) -o $@ $(COM_DIR)/amd64/${@F:.o=.c}
$(POST_PROCESS_O)
-$(OBJS_DIR)/aes_amd64.o: $(COM_DIR)/amd64/aes_amd64.s
+$(OBJS_DIR)/%.o: $(COM_DIR)/amd64/%.s
$(COMPILE.s) -o $@ $(COM_DIR)/amd64/${@F:.o=.s}
$(POST_PROCESS_O)
-$(OBJS_DIR)/aes_amd64.ln: $(COM_DIR)/amd64/aes_amd64.s
+$(OBJS_DIR)/%.ln: $(COM_DIR)/amd64/%.s
@($(LHEAD) $(LINT.s) $(COM_DIR)/amd64/${@F:.ln=.s} $(LTAIL))
diff --git a/usr/src/uts/sun4u/Makefile.files b/usr/src/uts/sun4u/Makefile.files
index 15f7e7d22a..802789bec9 100644
--- a/usr/src/uts/sun4u/Makefile.files
+++ b/usr/src/uts/sun4u/Makefile.files
@@ -148,7 +148,7 @@ MEM_CACHE_OBJS += mem_cache.o panther_asm.o
BIGNUM_PSR_OBJS += mont_mulf_kernel_v9.o
-AES_OBJS += aes.o aes_impl.o aes_crypt_asm.o
+AES_OBJS += aes.o aes_impl.o aes_modes.o aes_crypt_asm.o
DES_OBJS += des_crypt_asm.o