summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal van Leeuwen <pascalvanl@gmail.com>2019-08-30 03:40:53 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-09-05 00:37:00 -0400
commitc7da38a71cfbb5c0f20f84864a290b9450ad78e9 (patch)
tree8c7f79250484c3319ca69985f0b530ccd346c841
parent93369b5d06c7c45f2c9c62106c7a030f92c0eb9e (diff)
crypto: inside-secure - Add support for the AES-XTS algorithm
This patch adds support for the AES-XTS skcipher algorithm. Signed-off-by: Pascal van Leeuwen <pvanleeuwen@verimatrix.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/inside-secure/safexcel.c1
-rw-r--r--drivers/crypto/inside-secure/safexcel.h2
-rw-r--r--drivers/crypto/inside-secure/safexcel_cipher.c124
3 files changed, 123 insertions, 4 deletions
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index e12a2a3a5422..9941861ae1d8 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -1004,6 +1004,7 @@ static struct safexcel_alg_template *safexcel_algs[] = {
1004 &safexcel_alg_authenc_hmac_sha256_ctr_aes, 1004 &safexcel_alg_authenc_hmac_sha256_ctr_aes,
1005 &safexcel_alg_authenc_hmac_sha384_ctr_aes, 1005 &safexcel_alg_authenc_hmac_sha384_ctr_aes,
1006 &safexcel_alg_authenc_hmac_sha512_ctr_aes, 1006 &safexcel_alg_authenc_hmac_sha512_ctr_aes,
1007 &safexcel_alg_xts_aes,
1007}; 1008};
1008 1009
1009static int safexcel_register_algorithms(struct safexcel_crypto_priv *priv) 1010static int safexcel_register_algorithms(struct safexcel_crypto_priv *priv)
diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
index 33e5f663c249..0a30a7bf4fe0 100644
--- a/drivers/crypto/inside-secure/safexcel.h
+++ b/drivers/crypto/inside-secure/safexcel.h
@@ -334,6 +334,7 @@ struct safexcel_context_record {
334#define CONTEXT_CONTROL_CRYPTO_MODE_ECB (0 << 0) 334#define CONTEXT_CONTROL_CRYPTO_MODE_ECB (0 << 0)
335#define CONTEXT_CONTROL_CRYPTO_MODE_CBC (1 << 0) 335#define CONTEXT_CONTROL_CRYPTO_MODE_CBC (1 << 0)
336#define CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD (6 << 0) 336#define CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD (6 << 0)
337#define CONTEXT_CONTROL_CRYPTO_MODE_XTS (7 << 0)
337#define CONTEXT_CONTROL_IV0 BIT(5) 338#define CONTEXT_CONTROL_IV0 BIT(5)
338#define CONTEXT_CONTROL_IV1 BIT(6) 339#define CONTEXT_CONTROL_IV1 BIT(6)
339#define CONTEXT_CONTROL_IV2 BIT(7) 340#define CONTEXT_CONTROL_IV2 BIT(7)
@@ -750,5 +751,6 @@ extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes;
750extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes; 751extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes;
751extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes; 752extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes;
752extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes; 753extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes;
754extern struct safexcel_alg_template safexcel_alg_xts_aes;
753 755
754#endif 756#endif
diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c
index ba40166897f9..05e34c62945c 100644
--- a/drivers/crypto/inside-secure/safexcel_cipher.c
+++ b/drivers/crypto/inside-secure/safexcel_cipher.c
@@ -15,6 +15,7 @@
15#include <crypto/ctr.h> 15#include <crypto/ctr.h>
16#include <crypto/internal/des.h> 16#include <crypto/internal/des.h>
17#include <crypto/sha.h> 17#include <crypto/sha.h>
18#include <crypto/xts.h>
18#include <crypto/skcipher.h> 19#include <crypto/skcipher.h>
19#include <crypto/internal/aead.h> 20#include <crypto/internal/aead.h>
20#include <crypto/internal/skcipher.h> 21#include <crypto/internal/skcipher.h>
@@ -40,9 +41,9 @@ struct safexcel_cipher_ctx {
40 enum safexcel_cipher_alg alg; 41 enum safexcel_cipher_alg alg;
41 bool aead; 42 bool aead;
42 43
43 __le32 key[8]; 44 __le32 key[16];
44 u32 nonce; 45 u32 nonce;
45 unsigned int key_len; 46 unsigned int key_len, xts;
46 47
47 /* All the below is AEAD specific */ 48 /* All the below is AEAD specific */
48 u32 hash_alg; 49 u32 hash_alg;
@@ -351,7 +352,7 @@ static int safexcel_context_control(struct safexcel_cipher_ctx *ctx,
351 } else if (ctx->alg == SAFEXCEL_3DES) { 352 } else if (ctx->alg == SAFEXCEL_3DES) {
352 cdesc->control_data.control0 |= CONTEXT_CONTROL_CRYPTO_ALG_3DES; 353 cdesc->control_data.control0 |= CONTEXT_CONTROL_CRYPTO_ALG_3DES;
353 } else if (ctx->alg == SAFEXCEL_AES) { 354 } else if (ctx->alg == SAFEXCEL_AES) {
354 switch (ctx->key_len) { 355 switch (ctx->key_len >> ctx->xts) {
355 case AES_KEYSIZE_128: 356 case AES_KEYSIZE_128:
356 cdesc->control_data.control0 |= CONTEXT_CONTROL_CRYPTO_ALG_AES128; 357 cdesc->control_data.control0 |= CONTEXT_CONTROL_CRYPTO_ALG_AES128;
357 break; 358 break;
@@ -363,7 +364,7 @@ static int safexcel_context_control(struct safexcel_cipher_ctx *ctx,
363 break; 364 break;
364 default: 365 default:
365 dev_err(priv->dev, "aes keysize not supported: %u\n", 366 dev_err(priv->dev, "aes keysize not supported: %u\n",
366 ctx->key_len); 367 ctx->key_len >> ctx->xts);
367 return -EINVAL; 368 return -EINVAL;
368 } 369 }
369 } 370 }
@@ -1747,3 +1748,118 @@ struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = {
1747 }, 1748 },
1748 }, 1749 },
1749}; 1750};
1751
1752static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm,
1753 const u8 *key, unsigned int len)
1754{
1755 struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
1756 struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1757 struct safexcel_crypto_priv *priv = ctx->priv;
1758 struct crypto_aes_ctx aes;
1759 int ret, i;
1760 unsigned int keylen;
1761
1762 /* Check for illegal XTS keys */
1763 ret = xts_verify_key(ctfm, key, len);
1764 if (ret)
1765 return ret;
1766
1767 /* Only half of the key data is cipher key */
1768 keylen = (len >> 1);
1769 ret = aes_expandkey(&aes, key, keylen);
1770 if (ret) {
1771 crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
1772 return ret;
1773 }
1774
1775 if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
1776 for (i = 0; i < keylen / sizeof(u32); i++) {
1777 if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
1778 ctx->base.needs_inv = true;
1779 break;
1780 }
1781 }
1782 }
1783
1784 for (i = 0; i < keylen / sizeof(u32); i++)
1785 ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
1786
1787 /* The other half is the tweak key */
1788 ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen);
1789 if (ret) {
1790 crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
1791 return ret;
1792 }
1793
1794 if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
1795 for (i = 0; i < keylen / sizeof(u32); i++) {
1796 if (ctx->key[i + keylen / sizeof(u32)] !=
1797 cpu_to_le32(aes.key_enc[i])) {
1798 ctx->base.needs_inv = true;
1799 break;
1800 }
1801 }
1802 }
1803
1804 for (i = 0; i < keylen / sizeof(u32); i++)
1805 ctx->key[i + keylen / sizeof(u32)] =
1806 cpu_to_le32(aes.key_enc[i]);
1807
1808 ctx->key_len = keylen << 1;
1809
1810 memzero_explicit(&aes, sizeof(aes));
1811 return 0;
1812}
1813
1814static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm)
1815{
1816 struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1817
1818 safexcel_skcipher_cra_init(tfm);
1819 ctx->alg = SAFEXCEL_AES;
1820 ctx->xts = 1;
1821 ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS;
1822 return 0;
1823}
1824
1825static int safexcel_encrypt_xts(struct skcipher_request *req)
1826{
1827 if (req->cryptlen < XTS_BLOCK_SIZE)
1828 return -EINVAL;
1829 return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
1830 SAFEXCEL_ENCRYPT);
1831}
1832
1833static int safexcel_decrypt_xts(struct skcipher_request *req)
1834{
1835 if (req->cryptlen < XTS_BLOCK_SIZE)
1836 return -EINVAL;
1837 return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
1838 SAFEXCEL_DECRYPT);
1839}
1840
1841struct safexcel_alg_template safexcel_alg_xts_aes = {
1842 .type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1843 .alg.skcipher = {
1844 .setkey = safexcel_skcipher_aesxts_setkey,
1845 .encrypt = safexcel_encrypt_xts,
1846 .decrypt = safexcel_decrypt_xts,
1847 /* XTS actually uses 2 AES keys glued together */
1848 .min_keysize = AES_MIN_KEY_SIZE * 2,
1849 .max_keysize = AES_MAX_KEY_SIZE * 2,
1850 .ivsize = XTS_BLOCK_SIZE,
1851 .base = {
1852 .cra_name = "xts(aes)",
1853 .cra_driver_name = "safexcel-xts-aes",
1854 .cra_priority = 300,
1855 .cra_flags = CRYPTO_ALG_ASYNC |
1856 CRYPTO_ALG_KERN_DRIVER_ONLY,
1857 .cra_blocksize = XTS_BLOCK_SIZE,
1858 .cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1859 .cra_alignmask = 0,
1860 .cra_init = safexcel_skcipher_aes_xts_cra_init,
1861 .cra_exit = safexcel_skcipher_cra_exit,
1862 .cra_module = THIS_MODULE,
1863 },
1864 },
1865};