Commit a5f57cffce8af8d2c11204b4e289543021c73766

Authored by Catalin Vasile
Committed by Herbert Xu
1 parent 2b22f6c547

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>

Showing 2 changed files with 79 additions and 5 deletions Side-by-side Diff

drivers/crypto/caam/caamalg.c
... ... @@ -1735,14 +1735,19 @@
1735 1735 const u8 *key, unsigned int keylen)
1736 1736 {
1737 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 1741 struct device *jrdev = ctx->jrdev;
1740 1742 int ret = 0;
1741 1743 u32 *key_jump_cmd;
1742 1744 u32 *desc;
  1745 + u32 *nonce;
1743 1746 u32 ctx1_iv_off = 0;
1744 1747 const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
1745 1748 OP_ALG_AAI_CTR_MOD128);
  1749 + const bool is_rfc3686 = (ctr_mode &&
  1750 + (strstr(alg_name, "rfc3686") != NULL));
1746 1751  
1747 1752 #ifdef DEBUG
1748 1753 print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
... ... @@ -1756,6 +1761,16 @@
1756 1761 if (ctr_mode)
1757 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 1774 memcpy(ctx->key, key, keylen);
1760 1775 ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
1761 1776 DMA_TO_DEVICE);
... ... @@ -1767,7 +1782,7 @@
1767 1782  
1768 1783 /* ablkcipher_encrypt shared descriptor */
1769 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 1786 /* Skip if already shared */
1772 1787 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1773 1788 JUMP_COND_SHRD);
1774 1789  
1775 1790  
... ... @@ -1777,12 +1792,32 @@
1777 1792 ctx->enckeylen, CLASS_1 |
1778 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 1807 set_jump_tgt_here(desc, key_jump_cmd);
1781 1808  
1782 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 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 1821 /* Load operation */
1787 1822 append_operation(desc, ctx->class1_alg_type |
1788 1823 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
... ... @@ -1806,7 +1841,7 @@
1806 1841 /* ablkcipher_decrypt shared descriptor */
1807 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 1845 /* Skip if already shared */
1811 1846 key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1812 1847 JUMP_COND_SHRD);
1813 1848  
1814 1849  
... ... @@ -1816,12 +1851,32 @@
1816 1851 ctx->enckeylen, CLASS_1 |
1817 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 1866 set_jump_tgt_here(desc, key_jump_cmd);
1820 1867  
1821 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 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 1880 /* Choose operation */
1826 1881 if (ctr_mode)
1827 1882 append_operation(desc, ctx->class1_alg_type |
... ... @@ -3561,6 +3616,24 @@
3561 3616 .min_keysize = AES_MIN_KEY_SIZE,
3562 3617 .max_keysize = AES_MAX_KEY_SIZE,
3563 3618 .ivsize = AES_BLOCK_SIZE,
  3619 + },
  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,
3564 3637 },
3565 3638 .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
3566 3639 }
drivers/crypto/caam/compat.h
... ... @@ -28,6 +28,7 @@
28 28 #include <crypto/algapi.h>
29 29 #include <crypto/null.h>
30 30 #include <crypto/aes.h>
  31 +#include <crypto/ctr.h>
31 32 #include <crypto/des.h>
32 33 #include <crypto/sha.h>
33 34 #include <crypto/md5.h>