Page MenuHomeFreeBSD

D21017.id69937.diff
No OneTemporary

D21017.id69937.diff

Index: sys/crypto/armv8/armv8_crypto.h
===================================================================
--- sys/crypto/armv8/armv8_crypto.h
+++ sys/crypto/armv8/armv8_crypto.h
@@ -40,6 +40,7 @@
struct armv8_crypto_session {
uint32_t enc_schedule[AES_SCHED_LEN/4];
uint32_t dec_schedule[AES_SCHED_LEN/4];
+ uint32_t xts_schedule[AES_SCHED_LEN/4];
int algo;
int rounds;
};
@@ -49,4 +50,9 @@
void armv8_aes_decrypt_cbc(int, const void *, size_t, uint8_t *,
const uint8_t[static AES_BLOCK_LEN]);
+void armv8_aes_encrypt_xts(int, const void *, const void *, size_t,
+ const uint8_t *, uint8_t *, const uint8_t[AES_BLOCK_LEN]);
+void armv8_aes_decrypt_xts(int, const void *, const void *, size_t,
+ const uint8_t *, uint8_t *, const uint8_t[AES_BLOCK_LEN]);
+
#endif /* _ARMV8_CRYPTO_H_ */
Index: sys/crypto/armv8/armv8_crypto.c
===================================================================
--- sys/crypto/armv8/armv8_crypto.c
+++ sys/crypto/armv8/armv8_crypto.c
@@ -114,7 +114,7 @@
break;
}
- device_set_desc_copy(dev, "AES-CBC");
+ device_set_desc_copy(dev, "AES-CBC,AES-XTS");
/* TODO: Check more fields as we support more features */
@@ -204,22 +204,37 @@
return (EINVAL);
}
break;
+ case CRYPTO_AES_XTS:
+ if (csp->csp_ivlen != AES_XTS_IV_LEN)
+ return (EINVAL);
+ switch (csp->csp_cipher_klen * 8) {
+ case 256:
+ case 512:
+ break;
+ default:
+ return (EINVAL);
+ }
+ break;
default:
return (EINVAL);
}
+ break;
default:
return (EINVAL);
}
- return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
+ return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
}
static void
armv8_crypto_cipher_setup(struct armv8_crypto_session *ses,
- const struct crypto_session_params *csp)
+ const struct crypto_session_params *csp, const uint8_t *key, int keylen)
{
int i;
- switch (csp->csp_cipher_klen * 8) {
+ if (csp->csp_cipher_alg == CRYPTO_AES_XTS)
+ keylen /= 2;
+
+ switch (keylen * 8) {
case 128:
ses->rounds = AES128_ROUNDS;
break;
@@ -230,16 +245,19 @@
ses->rounds = AES256_ROUNDS;
break;
default:
- panic("invalid CBC key length");
+ panic("invalid AES key length");
}
- rijndaelKeySetupEnc(ses->enc_schedule, csp->csp_cipher_key,
- csp->csp_cipher_klen * 8);
- rijndaelKeySetupDec(ses->dec_schedule, csp->csp_cipher_key,
- csp->csp_cipher_klen * 8);
+ rijndaelKeySetupEnc(ses->enc_schedule, key, keylen * 8);
+ rijndaelKeySetupDec(ses->dec_schedule, key, keylen * 8);
+ if (csp->csp_cipher_alg == CRYPTO_AES_XTS)
+ rijndaelKeySetupEnc(ses->xts_schedule, key + keylen, keylen * 8);
+
for (i = 0; i < nitems(ses->enc_schedule); i++) {
ses->enc_schedule[i] = bswap32(ses->enc_schedule[i]);
ses->dec_schedule[i] = bswap32(ses->dec_schedule[i]);
+ if (csp->csp_cipher_alg == CRYPTO_AES_XTS)
+ ses->xts_schedule[i] = bswap32(ses->xts_schedule[i]);
}
}
@@ -258,7 +276,8 @@
}
ses = crypto_get_driver_session(cses);
- armv8_crypto_cipher_setup(ses, csp);
+ armv8_crypto_cipher_setup(ses, csp, csp->csp_cipher_key,
+ csp->csp_cipher_klen);
rw_wunlock(&sc->lock);
return (0);
}
@@ -332,7 +351,8 @@
}
if (crp->crp_cipher_key != NULL) {
- panic("armv8: new cipher key");
+ armv8_crypto_cipher_setup(ses, csp, crp->crp_cipher_key,
+ csp->csp_cipher_klen);
}
/* Setup iv */
@@ -354,6 +374,16 @@
armv8_aes_decrypt_cbc(ses->rounds, ses->dec_schedule,
crp->crp_payload_length, buf, iv);
break;
+ case CRYPTO_AES_XTS:
+ if (encflag)
+ armv8_aes_encrypt_xts(ses->rounds, ses->enc_schedule,
+ ses->xts_schedule, crp->crp_payload_length, buf,
+ buf, iv);
+ else
+ armv8_aes_decrypt_xts(ses->rounds, ses->dec_schedule,
+ ses->xts_schedule, crp->crp_payload_length, buf,
+ buf, iv);
+ break;
}
if (allocated)
Index: sys/crypto/armv8/armv8_crypto_wrap.c
===================================================================
--- sys/crypto/armv8/armv8_crypto_wrap.c
+++ sys/crypto/armv8/armv8_crypto_wrap.c
@@ -126,3 +126,95 @@
buf += AES_BLOCK_LEN;
}
}
+
+#define AES_XTS_BLOCKSIZE 16
+#define AES_XTS_IVSIZE 8
+#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
+
+static inline int32x4_t
+xts_crank_lfsr(int32x4_t inp)
+{
+ const int32x4_t alphamask = {AES_XTS_ALPHA, 1, 1, 1};
+ int32x4_t xtweak, ret;
+
+ /* set up xor mask */
+ xtweak = vextq_s32(inp, inp, 3);
+ xtweak = vshrq_n_s32(xtweak, 31);
+ xtweak &= alphamask;
+
+ /* next term */
+ ret = vshlq_n_s32(inp, 1);
+ ret ^= xtweak;
+
+ return ret;
+}
+
+static void
+armv8_aes_crypt_xts_block(int rounds, const uint8x16_t *key_schedule,
+ uint8x16_t *tweak, const uint8_t *from, uint8_t *to, int do_encrypt)
+{
+ uint8x16_t block;
+
+ block = vld1q_u8(from) ^ *tweak;
+
+ if (do_encrypt)
+ block = armv8_aes_enc(rounds - 1, key_schedule, block);
+ else
+ block = armv8_aes_dec(rounds - 1, key_schedule, block);
+
+ vst1q_u8(to, block ^ *tweak);
+
+ *tweak = vreinterpretq_u8_s32(xts_crank_lfsr(vreinterpretq_s32_u8(*tweak)));
+}
+
+static void
+armv8_aes_crypt_xts(int rounds, const uint8x16_t *data_schedule,
+ const uint8x16_t *tweak_schedule, size_t len, const uint8_t *from,
+ uint8_t *to, const uint8_t iv[static AES_BLOCK_LEN], int do_encrypt)
+{
+ uint8x16_t tweakreg;
+ uint8_t tweak[AES_XTS_BLOCKSIZE] __aligned(16);
+ size_t i, cnt;
+
+ /*
+ * Prepare tweak as E_k2(IV). IV is specified as LE representation
+ * of a 64-bit block number which we allow to be passed in directly.
+ */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ bcopy(iv, tweak, AES_XTS_IVSIZE);
+ /* Last 64 bits of IV are always zero. */
+ bzero(tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
+#else
+#error Only LITTLE_ENDIAN architectures are supported.
+#endif
+ tweakreg = vld1q_u8(tweak);
+ tweakreg = armv8_aes_enc(rounds - 1, tweak_schedule, tweakreg);
+
+ cnt = len / AES_XTS_BLOCKSIZE;
+ for (i = 0; i < cnt; i++) {
+ armv8_aes_crypt_xts_block(rounds, data_schedule, &tweakreg,
+ from, to, do_encrypt);
+ from += AES_XTS_BLOCKSIZE;
+ to += AES_XTS_BLOCKSIZE;
+ }
+}
+
+void
+armv8_aes_encrypt_xts(int rounds, const void *data_schedule,
+ const void *tweak_schedule, size_t len, const uint8_t *from, uint8_t *to,
+ const uint8_t iv[static AES_BLOCK_LEN])
+{
+
+ armv8_aes_crypt_xts(rounds, data_schedule, tweak_schedule, len, from, to,
+ iv, 1);
+}
+
+void
+armv8_aes_decrypt_xts(int rounds, const void *data_schedule,
+ const void *tweak_schedule, size_t len, const uint8_t *from, uint8_t *to,
+ const uint8_t iv[static AES_BLOCK_LEN])
+{
+
+ armv8_aes_crypt_xts(rounds, data_schedule, tweak_schedule, len, from, to,
+ iv, 0);
+}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 12, 6:54 PM (10 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17124423
Default Alt Text
D21017.id69937.diff (6 KB)

Event Timeline