Commit 4865b122 authored by Christian Lamparter's avatar Christian Lamparter Committed by Herbert Xu

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: default avatarChristian Lamparter <chunkeey@gmail.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 8ef8d195
...@@ -149,7 +149,7 @@ static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher, ...@@ -149,7 +149,7 @@ static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher,
SA_SEQ_MASK_OFF, SA_MC_ENABLE, SA_SEQ_MASK_OFF, SA_MC_ENABLE,
SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD, SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
SA_NOT_COPY_HDR); SA_NOT_COPY_HDR);
crypto4xx_memcpy_le(get_dynamic_sa_key_field(sa), crypto4xx_memcpy_to_le32(get_dynamic_sa_key_field(sa),
key, keylen); key, keylen);
sa->sa_contents.w = SA_AES_CONTENTS | (keylen << 2); sa->sa_contents.w = SA_AES_CONTENTS | (keylen << 2);
sa->sa_command_1.bf.key_len = keylen >> 3; sa->sa_command_1.bf.key_len = keylen >> 3;
......
...@@ -614,42 +614,6 @@ static u32 crypto4xx_pd_done(struct crypto4xx_device *dev, u32 idx) ...@@ -614,42 +614,6 @@ static u32 crypto4xx_pd_done(struct crypto4xx_device *dev, u32 idx)
return crypto4xx_ahash_done(dev, pd_uinfo); 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) static void crypto4xx_stop_all(struct crypto4xx_core_device *core_dev)
{ {
crypto4xx_destroy_pdr(core_dev->dev); crypto4xx_destroy_pdr(core_dev->dev);
...@@ -809,7 +773,7 @@ u32 crypto4xx_build_pd(struct crypto_async_request *req, ...@@ -809,7 +773,7 @@ u32 crypto4xx_build_pd(struct crypto_async_request *req,
&pd_uinfo->sr_pa, 4); &pd_uinfo->sr_pa, 4);
if (iv_len) if (iv_len)
crypto4xx_memcpy_le(pd_uinfo->sr_va->save_iv, crypto4xx_memcpy_to_le32(pd_uinfo->sr_va->save_iv,
iv, iv_len); iv, iv_len);
} else { } else {
if (ctx->direction == DIR_INBOUND) { if (ctx->direction == DIR_INBOUND) {
......
...@@ -166,9 +166,7 @@ int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size); ...@@ -166,9 +166,7 @@ int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size);
void crypto4xx_free_sa(struct crypto4xx_ctx *ctx); void crypto4xx_free_sa(struct crypto4xx_ctx *ctx);
void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx); void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx);
u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx); u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx);
void crypto4xx_memcpy_le(unsigned int *dst, int crypto4xx_build_pd(struct crypto_async_request *req,
const unsigned char *buf, int len);
u32 crypto4xx_build_pd(struct crypto_async_request *req,
struct crypto4xx_ctx *ctx, struct crypto4xx_ctx *ctx,
struct scatterlist *src, struct scatterlist *src,
struct scatterlist *dst, struct scatterlist *dst,
...@@ -193,4 +191,47 @@ int crypto4xx_hash_digest(struct ahash_request *req); ...@@ -193,4 +191,47 @@ int crypto4xx_hash_digest(struct ahash_request *req);
int crypto4xx_hash_final(struct ahash_request *req); int crypto4xx_hash_final(struct ahash_request *req);
int crypto4xx_hash_update(struct ahash_request *req); int crypto4xx_hash_update(struct ahash_request *req);
int crypto4xx_hash_init(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 #endif
...@@ -181,9 +181,12 @@ struct dynamic_sa_ctl { ...@@ -181,9 +181,12 @@ struct dynamic_sa_ctl {
* State Record for Security Association (SA) * State Record for Security Association (SA)
*/ */
struct sa_state_record { struct sa_state_record {
u32 save_iv[4]; __le32 save_iv[4];
u32 save_hash_byte_cnt[2]; __le32 save_hash_byte_cnt[2];
u32 save_digest[16]; union {
u32 save_digest[16]; /* for MD5/SHA */
__le32 save_digest_le32[16]; /* GHASH / CBC */
};
} __attribute__((packed)); } __attribute__((packed));
/** /**
...@@ -192,8 +195,8 @@ struct sa_state_record { ...@@ -192,8 +195,8 @@ struct sa_state_record {
*/ */
struct dynamic_sa_aes128 { struct dynamic_sa_aes128 {
struct dynamic_sa_ctl ctrl; struct dynamic_sa_ctl ctrl;
u32 key[4]; __le32 key[4];
u32 iv[4]; /* for CBC, OFC, and CFB mode */ __le32 iv[4]; /* for CBC, OFC, and CFB mode */
u32 state_ptr; u32 state_ptr;
u32 reserved; u32 reserved;
} __attribute__((packed)); } __attribute__((packed));
...@@ -206,8 +209,8 @@ struct dynamic_sa_aes128 { ...@@ -206,8 +209,8 @@ struct dynamic_sa_aes128 {
*/ */
struct dynamic_sa_aes192 { struct dynamic_sa_aes192 {
struct dynamic_sa_ctl ctrl; struct dynamic_sa_ctl ctrl;
u32 key[6]; __le32 key[6];
u32 iv[4]; /* for CBC, OFC, and CFB mode */ __le32 iv[4]; /* for CBC, OFC, and CFB mode */
u32 state_ptr; u32 state_ptr;
u32 reserved; u32 reserved;
} __attribute__((packed)); } __attribute__((packed));
...@@ -220,8 +223,8 @@ struct dynamic_sa_aes192 { ...@@ -220,8 +223,8 @@ struct dynamic_sa_aes192 {
*/ */
struct dynamic_sa_aes256 { struct dynamic_sa_aes256 {
struct dynamic_sa_ctl ctrl; struct dynamic_sa_ctl ctrl;
u32 key[8]; __le32 key[8];
u32 iv[4]; /* for CBC, OFC, and CFB mode */ __le32 iv[4]; /* for CBC, OFC, and CFB mode */
u32 state_ptr; u32 state_ptr;
u32 reserved; u32 reserved;
} __attribute__((packed)); } __attribute__((packed));
...@@ -235,8 +238,8 @@ struct dynamic_sa_aes256 { ...@@ -235,8 +238,8 @@ struct dynamic_sa_aes256 {
*/ */
struct dynamic_sa_hash160 { struct dynamic_sa_hash160 {
struct dynamic_sa_ctl ctrl; struct dynamic_sa_ctl ctrl;
u32 inner_digest[5]; __le32 inner_digest[5];
u32 outer_digest[5]; __le32 outer_digest[5];
u32 state_ptr; u32 state_ptr;
u32 reserved; u32 reserved;
} __attribute__((packed)); } __attribute__((packed));
...@@ -266,9 +269,9 @@ get_dynamic_sa_offset_state_ptr_field(struct dynamic_sa_ctl *cts) ...@@ -266,9 +269,9 @@ get_dynamic_sa_offset_state_ptr_field(struct dynamic_sa_ctl *cts)
return sizeof(struct dynamic_sa_ctl) + offset * 4; 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 #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment