Commit a5f57cffce8af8d2c11204b4e289543021c73766
Committed by
Herbert Xu
1 parent
2b22f6c547
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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