From 780477d17c0e73e54397a0f3cebff08634e7231a Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 7 Jan 2018 21:27:50 +0100 Subject: apm821xx: backport crypto4xx patches from 4.15 This patch backports changes to crypto4xx in order to get the crypto4xx operational. Signed-off-by: Christian Lamparter --- ...to4xx-use-the-correct-LE32-format-for-IV-.patch | 236 +++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 target/linux/apm821xx/patches-4.14/020-0018-crypto-crypto4xx-use-the-correct-LE32-format-for-IV-.patch (limited to 'target/linux/apm821xx/patches-4.14/020-0018-crypto-crypto4xx-use-the-correct-LE32-format-for-IV-.patch') diff --git a/target/linux/apm821xx/patches-4.14/020-0018-crypto-crypto4xx-use-the-correct-LE32-format-for-IV-.patch b/target/linux/apm821xx/patches-4.14/020-0018-crypto-crypto4xx-use-the-correct-LE32-format-for-IV-.patch new file mode 100644 index 0000000000..22d2a317f5 --- /dev/null +++ b/target/linux/apm821xx/patches-4.14/020-0018-crypto-crypto4xx-use-the-correct-LE32-format-for-IV-.patch @@ -0,0 +1,236 @@ +From 4865b122d4aff5151c88d2f7442d5a87f7e795ae Mon Sep 17 00:00:00 2001 +From: Christian Lamparter +Date: Wed, 4 Oct 2017 01:00:10 +0200 +Subject: [PATCH 18/25] crypto: crypto4xx - use the correct LE32 format for IV + and key defs + +The hardware expects that the keys, IVs (and inner/outer hashes) +are in the le32 format. + +This patch changes all hardware interface declarations to use +the correct LE32 data format for each field. + +In order to pass __CHECK_ENDIAN__ checks, crypto4xx_memcpy_le +has to be honest about the endianness of its parameters. +The function was split and moved to the common crypto4xx_core.h +header. This allows the compiler to generate better code if the +sizes/len is a constant (various *_IV_LEN). + +Please note that the hardware isn't consistent with the endiannes +of the save_digest field in the state record struct though. +The hashes produced by GHASH and CBC (for CCM) will be in LE32. +Whereas md5 and sha{1/,256,...} do not need any conversion. + +Signed-off-by: Christian Lamparter +Signed-off-by: Herbert Xu +--- + drivers/crypto/amcc/crypto4xx_alg.c | 4 +-- + drivers/crypto/amcc/crypto4xx_core.c | 40 ++---------------------------- + drivers/crypto/amcc/crypto4xx_core.h | 47 +++++++++++++++++++++++++++++++++--- + drivers/crypto/amcc/crypto4xx_sa.h | 29 ++++++++++++---------- + 4 files changed, 64 insertions(+), 56 deletions(-) + +--- a/drivers/crypto/amcc/crypto4xx_alg.c ++++ b/drivers/crypto/amcc/crypto4xx_alg.c +@@ -149,8 +149,8 @@ static int crypto4xx_setkey_aes(struct c + SA_SEQ_MASK_OFF, SA_MC_ENABLE, + SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD, + SA_NOT_COPY_HDR); +- crypto4xx_memcpy_le(get_dynamic_sa_key_field(sa), +- key, keylen); ++ crypto4xx_memcpy_to_le32(get_dynamic_sa_key_field(sa), ++ key, keylen); + sa->sa_contents.w = SA_AES_CONTENTS | (keylen << 2); + sa->sa_command_1.bf.key_len = keylen >> 3; + ctx->is_hash = 0; +--- a/drivers/crypto/amcc/crypto4xx_core.c ++++ b/drivers/crypto/amcc/crypto4xx_core.c +@@ -614,42 +614,6 @@ static u32 crypto4xx_pd_done(struct cryp + return crypto4xx_ahash_done(dev, pd_uinfo); + } + +-/** +- * Note: Only use this function to copy items that is word aligned. +- */ +-void crypto4xx_memcpy_le(unsigned int *dst, +- const unsigned char *buf, +- int len) +-{ +- u8 *tmp; +- for (; len >= 4; buf += 4, len -= 4) +- *dst++ = cpu_to_le32(*(unsigned int *) buf); +- +- tmp = (u8 *)dst; +- switch (len) { +- case 3: +- *tmp++ = 0; +- *tmp++ = *(buf+2); +- *tmp++ = *(buf+1); +- *tmp++ = *buf; +- break; +- case 2: +- *tmp++ = 0; +- *tmp++ = 0; +- *tmp++ = *(buf+1); +- *tmp++ = *buf; +- break; +- case 1: +- *tmp++ = 0; +- *tmp++ = 0; +- *tmp++ = 0; +- *tmp++ = *buf; +- break; +- default: +- break; +- } +-} +- + static void crypto4xx_stop_all(struct crypto4xx_core_device *core_dev) + { + crypto4xx_destroy_pdr(core_dev->dev); +@@ -809,8 +773,8 @@ u32 crypto4xx_build_pd(struct crypto_asy + &pd_uinfo->sr_pa, 4); + + if (iv_len) +- crypto4xx_memcpy_le(pd_uinfo->sr_va->save_iv, +- iv, iv_len); ++ crypto4xx_memcpy_to_le32(pd_uinfo->sr_va->save_iv, ++ iv, iv_len); + } else { + if (ctx->direction == DIR_INBOUND) { + pd->sa = ctx->sa_in_dma_addr; +--- a/drivers/crypto/amcc/crypto4xx_core.h ++++ b/drivers/crypto/amcc/crypto4xx_core.h +@@ -166,9 +166,7 @@ int crypto4xx_alloc_sa(struct crypto4xx_ + void crypto4xx_free_sa(struct crypto4xx_ctx *ctx); + void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx); + u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx); +-void crypto4xx_memcpy_le(unsigned int *dst, +- const unsigned char *buf, int len); +-u32 crypto4xx_build_pd(struct crypto_async_request *req, ++int crypto4xx_build_pd(struct crypto_async_request *req, + struct crypto4xx_ctx *ctx, + struct scatterlist *src, + struct scatterlist *dst, +@@ -193,4 +191,47 @@ int crypto4xx_hash_digest(struct ahash_r + int crypto4xx_hash_final(struct ahash_request *req); + int crypto4xx_hash_update(struct ahash_request *req); + int crypto4xx_hash_init(struct ahash_request *req); ++ ++/** ++ * Note: Only use this function to copy items that is word aligned. ++ */ ++static inline void crypto4xx_memcpy_swab32(u32 *dst, const void *buf, ++ size_t len) ++{ ++ for (; len >= 4; buf += 4, len -= 4) ++ *dst++ = __swab32p((u32 *) buf); ++ ++ if (len) { ++ const u8 *tmp = (u8 *)buf; ++ ++ switch (len) { ++ case 3: ++ *dst = (tmp[2] << 16) | ++ (tmp[1] << 8) | ++ tmp[0]; ++ break; ++ case 2: ++ *dst = (tmp[1] << 8) | ++ tmp[0]; ++ break; ++ case 1: ++ *dst = tmp[0]; ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static inline void crypto4xx_memcpy_from_le32(u32 *dst, const void *buf, ++ size_t len) ++{ ++ crypto4xx_memcpy_swab32(dst, buf, len); ++} ++ ++static inline void crypto4xx_memcpy_to_le32(__le32 *dst, const void *buf, ++ size_t len) ++{ ++ crypto4xx_memcpy_swab32((u32 *)dst, buf, len); ++} + #endif +--- a/drivers/crypto/amcc/crypto4xx_sa.h ++++ b/drivers/crypto/amcc/crypto4xx_sa.h +@@ -181,9 +181,12 @@ struct dynamic_sa_ctl { + * State Record for Security Association (SA) + */ + struct sa_state_record { +- u32 save_iv[4]; +- u32 save_hash_byte_cnt[2]; +- u32 save_digest[16]; ++ __le32 save_iv[4]; ++ __le32 save_hash_byte_cnt[2]; ++ union { ++ u32 save_digest[16]; /* for MD5/SHA */ ++ __le32 save_digest_le32[16]; /* GHASH / CBC */ ++ }; + } __attribute__((packed)); + + /** +@@ -192,8 +195,8 @@ struct sa_state_record { + */ + struct dynamic_sa_aes128 { + struct dynamic_sa_ctl ctrl; +- u32 key[4]; +- u32 iv[4]; /* for CBC, OFC, and CFB mode */ ++ __le32 key[4]; ++ __le32 iv[4]; /* for CBC, OFC, and CFB mode */ + u32 state_ptr; + u32 reserved; + } __attribute__((packed)); +@@ -206,8 +209,8 @@ struct dynamic_sa_aes128 { + */ + struct dynamic_sa_aes192 { + struct dynamic_sa_ctl ctrl; +- u32 key[6]; +- u32 iv[4]; /* for CBC, OFC, and CFB mode */ ++ __le32 key[6]; ++ __le32 iv[4]; /* for CBC, OFC, and CFB mode */ + u32 state_ptr; + u32 reserved; + } __attribute__((packed)); +@@ -220,8 +223,8 @@ struct dynamic_sa_aes192 { + */ + struct dynamic_sa_aes256 { + struct dynamic_sa_ctl ctrl; +- u32 key[8]; +- u32 iv[4]; /* for CBC, OFC, and CFB mode */ ++ __le32 key[8]; ++ __le32 iv[4]; /* for CBC, OFC, and CFB mode */ + u32 state_ptr; + u32 reserved; + } __attribute__((packed)); +@@ -235,8 +238,8 @@ struct dynamic_sa_aes256 { + */ + struct dynamic_sa_hash160 { + struct dynamic_sa_ctl ctrl; +- u32 inner_digest[5]; +- u32 outer_digest[5]; ++ __le32 inner_digest[5]; ++ __le32 outer_digest[5]; + u32 state_ptr; + u32 reserved; + } __attribute__((packed)); +@@ -266,9 +269,9 @@ get_dynamic_sa_offset_state_ptr_field(st + return sizeof(struct dynamic_sa_ctl) + offset * 4; + } + +-static inline u32 *get_dynamic_sa_key_field(struct dynamic_sa_ctl *cts) ++static inline __le32 *get_dynamic_sa_key_field(struct dynamic_sa_ctl *cts) + { +- return (u32 *) ((unsigned long)cts + sizeof(struct dynamic_sa_ctl)); ++ return (__le32 *) ((unsigned long)cts + sizeof(struct dynamic_sa_ctl)); + } + + #endif -- cgit v1.2.3