aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorCatalin Vasile <catalin.vasile@freescale.com>2014-10-31 06:45:36 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-11-06 10:15:04 -0500
commita5f57cffce8af8d2c11204b4e289543021c73766 (patch)
tree08ec752fd9a894b33437827a7c7bf1e46f3d337e /drivers/crypto
parent2b22f6c547f90e1a41e3f39ad8d569e3efc74d42 (diff)
crypto: caam - add support for rfc3686(ctr(aes))
Add support for Advanced Encryption Standard (AES) in Counter Mode (CTR) as provided in IPsec implementation standard RFC3686. ablkcipher shared descriptors now save context registers after job execution. This is used to load Nonce specific to RFC3686 only at first execution of shared job descriptor. Signed-off-by: Catalin Vasile <catalin.vasile@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/caamalg.c83
-rw-r--r--drivers/crypto/caam/compat.h1
2 files changed, 79 insertions, 5 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 2dc85f8304bb..e9a4fd16031d 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1735,14 +1735,19 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1735 const u8 *key, unsigned int keylen) 1735 const u8 *key, unsigned int keylen)
1736{ 1736{
1737 struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); 1737 struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1738 struct ablkcipher_tfm *tfm = &ablkcipher->base.crt_ablkcipher; 1738 struct ablkcipher_tfm *crt = &ablkcipher->base.crt_ablkcipher;
1739 struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher);
1740 const char *alg_name = crypto_tfm_alg_name(tfm);
1739 struct device *jrdev = ctx->jrdev; 1741 struct device *jrdev = ctx->jrdev;
1740 int ret = 0; 1742 int ret = 0;
1741 u32 *key_jump_cmd; 1743 u32 *key_jump_cmd;
1742 u32 *desc; 1744 u32 *desc;
1745 u32 *nonce;
1743 u32 ctx1_iv_off = 0; 1746 u32 ctx1_iv_off = 0;
1744 const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == 1747 const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
1745 OP_ALG_AAI_CTR_MOD128); 1748 OP_ALG_AAI_CTR_MOD128);
1749 const bool is_rfc3686 = (ctr_mode &&
1750 (strstr(alg_name, "rfc3686") != NULL));
1746 1751
1747#ifdef DEBUG 1752#ifdef DEBUG
1748 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ", 1753 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
@@ -1756,6 +1761,16 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1756 if (ctr_mode) 1761 if (ctr_mode)
1757 ctx1_iv_off = 16; 1762 ctx1_iv_off = 16;
1758 1763
1764 /*
1765 * RFC3686 specific:
1766 * | CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1767 * | *key = {KEY, NONCE}
1768 */
1769 if (is_rfc3686) {
1770 ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
1771 keylen -= CTR_RFC3686_NONCE_SIZE;
1772 }
1773
1759 memcpy(ctx->key, key, keylen); 1774 memcpy(ctx->key, key, keylen);
1760 ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen, 1775 ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
1761 DMA_TO_DEVICE); 1776 DMA_TO_DEVICE);
@@ -1767,7 +1782,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1767 1782
1768 /* ablkcipher_encrypt shared descriptor */ 1783 /* ablkcipher_encrypt shared descriptor */
1769 desc = ctx->sh_desc_enc; 1784 desc = ctx->sh_desc_enc;
1770 init_sh_desc(desc, HDR_SHARE_SERIAL); 1785 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1771 /* Skip if already shared */ 1786 /* Skip if already shared */
1772 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 1787 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1773 JUMP_COND_SHRD); 1788 JUMP_COND_SHRD);
@@ -1777,12 +1792,32 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1777 ctx->enckeylen, CLASS_1 | 1792 ctx->enckeylen, CLASS_1 |
1778 KEY_DEST_CLASS_REG); 1793 KEY_DEST_CLASS_REG);
1779 1794
1795 /* Load nonce into CONTEXT1 reg */
1796 if (is_rfc3686) {
1797 nonce = (u32 *)(key + keylen);
1798 append_load_imm_u32(desc, *nonce, LDST_CLASS_IND_CCB |
1799 LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1800 append_move(desc, MOVE_WAITCOMP |
1801 MOVE_SRC_OUTFIFO |
1802 MOVE_DEST_CLASS1CTX |
1803 (16 << MOVE_OFFSET_SHIFT) |
1804 (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1805 }
1806
1780 set_jump_tgt_here(desc, key_jump_cmd); 1807 set_jump_tgt_here(desc, key_jump_cmd);
1781 1808
1782 /* Load iv */ 1809 /* Load iv */
1783 append_seq_load(desc, tfm->ivsize, LDST_SRCDST_BYTE_CONTEXT | 1810 append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
1784 LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT)); 1811 LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1785 1812
1813 /* Load counter into CONTEXT1 reg */
1814 if (is_rfc3686)
1815 append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
1816 LDST_CLASS_1_CCB |
1817 LDST_SRCDST_BYTE_CONTEXT |
1818 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1819 LDST_OFFSET_SHIFT));
1820
1786 /* Load operation */ 1821 /* Load operation */
1787 append_operation(desc, ctx->class1_alg_type | 1822 append_operation(desc, ctx->class1_alg_type |
1788 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT); 1823 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
@@ -1806,7 +1841,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1806 /* ablkcipher_decrypt shared descriptor */ 1841 /* ablkcipher_decrypt shared descriptor */
1807 desc = ctx->sh_desc_dec; 1842 desc = ctx->sh_desc_dec;
1808 1843
1809 init_sh_desc(desc, HDR_SHARE_SERIAL); 1844 init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1810 /* Skip if already shared */ 1845 /* Skip if already shared */
1811 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | 1846 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1812 JUMP_COND_SHRD); 1847 JUMP_COND_SHRD);
@@ -1816,12 +1851,32 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1816 ctx->enckeylen, CLASS_1 | 1851 ctx->enckeylen, CLASS_1 |
1817 KEY_DEST_CLASS_REG); 1852 KEY_DEST_CLASS_REG);
1818 1853
1854 /* Load nonce into CONTEXT1 reg */
1855 if (is_rfc3686) {
1856 nonce = (u32 *)(key + keylen);
1857 append_load_imm_u32(desc, *nonce, LDST_CLASS_IND_CCB |
1858 LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1859 append_move(desc, MOVE_WAITCOMP |
1860 MOVE_SRC_OUTFIFO |
1861 MOVE_DEST_CLASS1CTX |
1862 (16 << MOVE_OFFSET_SHIFT) |
1863 (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1864 }
1865
1819 set_jump_tgt_here(desc, key_jump_cmd); 1866 set_jump_tgt_here(desc, key_jump_cmd);
1820 1867
1821 /* load IV */ 1868 /* load IV */
1822 append_seq_load(desc, tfm->ivsize, LDST_SRCDST_BYTE_CONTEXT | 1869 append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
1823 LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT)); 1870 LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1824 1871
1872 /* Load counter into CONTEXT1 reg */
1873 if (is_rfc3686)
1874 append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
1875 LDST_CLASS_1_CCB |
1876 LDST_SRCDST_BYTE_CONTEXT |
1877 ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1878 LDST_OFFSET_SHIFT));
1879
1825 /* Choose operation */ 1880 /* Choose operation */
1826 if (ctr_mode) 1881 if (ctr_mode)
1827 append_operation(desc, ctx->class1_alg_type | 1882 append_operation(desc, ctx->class1_alg_type |
@@ -3563,6 +3618,24 @@ static struct caam_alg_template driver_algs[] = {
3563 .ivsize = AES_BLOCK_SIZE, 3618 .ivsize = AES_BLOCK_SIZE,
3564 }, 3619 },
3565 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128, 3620 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
3621 },
3622 {
3623 .name = "rfc3686(ctr(aes))",
3624 .driver_name = "rfc3686-ctr-aes-caam",
3625 .blocksize = 1,
3626 .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
3627 .template_ablkcipher = {
3628 .setkey = ablkcipher_setkey,
3629 .encrypt = ablkcipher_encrypt,
3630 .decrypt = ablkcipher_decrypt,
3631 .geniv = "seqiv",
3632 .min_keysize = AES_MIN_KEY_SIZE +
3633 CTR_RFC3686_NONCE_SIZE,
3634 .max_keysize = AES_MAX_KEY_SIZE +
3635 CTR_RFC3686_NONCE_SIZE,
3636 .ivsize = CTR_RFC3686_IV_SIZE,
3637 },
3638 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
3566 } 3639 }
3567}; 3640};
3568 3641
diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h
index f227922cea38..acd7743e2603 100644
--- a/drivers/crypto/caam/compat.h
+++ b/drivers/crypto/caam/compat.h
@@ -28,6 +28,7 @@
28#include <crypto/algapi.h> 28#include <crypto/algapi.h>
29#include <crypto/null.h> 29#include <crypto/null.h>
30#include <crypto/aes.h> 30#include <crypto/aes.h>
31#include <crypto/ctr.h>
31#include <crypto/des.h> 32#include <crypto/des.h>
32#include <crypto/sha.h> 33#include <crypto/sha.h>
33#include <crypto/md5.h> 34#include <crypto/md5.h>