diff options
author | Pascal van Leeuwen <pascalvanl@gmail.com> | 2019-08-30 03:40:53 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2019-09-05 00:37:00 -0400 |
commit | c7da38a71cfbb5c0f20f84864a290b9450ad78e9 (patch) | |
tree | 8c7f79250484c3319ca69985f0b530ccd346c841 | |
parent | 93369b5d06c7c45f2c9c62106c7a030f92c0eb9e (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.c | 1 | ||||
-rw-r--r-- | drivers/crypto/inside-secure/safexcel.h | 2 | ||||
-rw-r--r-- | drivers/crypto/inside-secure/safexcel_cipher.c | 124 |
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 | ||
1009 | static int safexcel_register_algorithms(struct safexcel_crypto_priv *priv) | 1010 | static 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; | |||
750 | extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes; | 751 | extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes; |
751 | extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes; | 752 | extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes; |
752 | extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes; | 753 | extern struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes; |
754 | extern 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 | |||
1752 | static 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 | |||
1814 | static 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 | |||
1825 | static 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 | |||
1833 | static 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 | |||
1841 | struct 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 | }; | ||