22d2a317f533213596f28eb91f7715ff3daf8011
[oweals/openwrt.git] /
1 From 4865b122d4aff5151c88d2f7442d5a87f7e795ae Mon Sep 17 00:00:00 2001
2 From: Christian Lamparter <chunkeey@gmail.com>
3 Date: Wed, 4 Oct 2017 01:00:10 +0200
4 Subject: [PATCH 18/25] crypto: crypto4xx - use the correct LE32 format for IV
5  and key defs
6
7 The hardware expects that the keys, IVs (and inner/outer hashes)
8 are in the le32 format.
9
10 This patch changes all hardware interface declarations to use
11 the correct LE32 data format for each field.
12
13 In order to pass __CHECK_ENDIAN__ checks, crypto4xx_memcpy_le
14 has to be honest about the endianness of its parameters.
15 The function was split and moved to the common crypto4xx_core.h
16 header. This allows the compiler to generate better code if the
17 sizes/len is a constant (various *_IV_LEN).
18
19 Please note that the hardware isn't consistent with the endiannes
20 of the save_digest field in the state record struct though.
21 The hashes produced by GHASH and CBC (for CCM) will be in LE32.
22 Whereas md5 and sha{1/,256,...} do not need any conversion.
23
24 Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
25 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
26 ---
27  drivers/crypto/amcc/crypto4xx_alg.c  |  4 +--
28  drivers/crypto/amcc/crypto4xx_core.c | 40 ++----------------------------
29  drivers/crypto/amcc/crypto4xx_core.h | 47 +++++++++++++++++++++++++++++++++---
30  drivers/crypto/amcc/crypto4xx_sa.h   | 29 ++++++++++++----------
31  4 files changed, 64 insertions(+), 56 deletions(-)
32
33 --- a/drivers/crypto/amcc/crypto4xx_alg.c
34 +++ b/drivers/crypto/amcc/crypto4xx_alg.c
35 @@ -149,8 +149,8 @@ static int crypto4xx_setkey_aes(struct c
36                                  SA_SEQ_MASK_OFF, SA_MC_ENABLE,
37                                  SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
38                                  SA_NOT_COPY_HDR);
39 -       crypto4xx_memcpy_le(get_dynamic_sa_key_field(sa),
40 -                           key, keylen);
41 +       crypto4xx_memcpy_to_le32(get_dynamic_sa_key_field(sa),
42 +                                key, keylen);
43         sa->sa_contents.w = SA_AES_CONTENTS | (keylen << 2);
44         sa->sa_command_1.bf.key_len = keylen >> 3;
45         ctx->is_hash = 0;
46 --- a/drivers/crypto/amcc/crypto4xx_core.c
47 +++ b/drivers/crypto/amcc/crypto4xx_core.c
48 @@ -614,42 +614,6 @@ static u32 crypto4xx_pd_done(struct cryp
49                 return crypto4xx_ahash_done(dev, pd_uinfo);
50  }
51  
52 -/**
53 - * Note: Only use this function to copy items that is word aligned.
54 - */
55 -void crypto4xx_memcpy_le(unsigned int *dst,
56 -                        const unsigned char *buf,
57 -                        int len)
58 -{
59 -       u8 *tmp;
60 -       for (; len >= 4; buf += 4, len -= 4)
61 -               *dst++ = cpu_to_le32(*(unsigned int *) buf);
62 -
63 -       tmp = (u8 *)dst;
64 -       switch (len) {
65 -       case 3:
66 -               *tmp++ = 0;
67 -               *tmp++ = *(buf+2);
68 -               *tmp++ = *(buf+1);
69 -               *tmp++ = *buf;
70 -               break;
71 -       case 2:
72 -               *tmp++ = 0;
73 -               *tmp++ = 0;
74 -               *tmp++ = *(buf+1);
75 -               *tmp++ = *buf;
76 -               break;
77 -       case 1:
78 -               *tmp++ = 0;
79 -               *tmp++ = 0;
80 -               *tmp++ = 0;
81 -               *tmp++ = *buf;
82 -               break;
83 -       default:
84 -               break;
85 -       }
86 -}
87 -
88  static void crypto4xx_stop_all(struct crypto4xx_core_device *core_dev)
89  {
90         crypto4xx_destroy_pdr(core_dev->dev);
91 @@ -809,8 +773,8 @@ u32 crypto4xx_build_pd(struct crypto_asy
92                         &pd_uinfo->sr_pa, 4);
93  
94                 if (iv_len)
95 -                       crypto4xx_memcpy_le(pd_uinfo->sr_va->save_iv,
96 -                                           iv, iv_len);
97 +                       crypto4xx_memcpy_to_le32(pd_uinfo->sr_va->save_iv,
98 +                                                iv, iv_len);
99         } else {
100                 if (ctx->direction == DIR_INBOUND) {
101                         pd->sa = ctx->sa_in_dma_addr;
102 --- a/drivers/crypto/amcc/crypto4xx_core.h
103 +++ b/drivers/crypto/amcc/crypto4xx_core.h
104 @@ -166,9 +166,7 @@ int crypto4xx_alloc_sa(struct crypto4xx_
105  void crypto4xx_free_sa(struct crypto4xx_ctx *ctx);
106  void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx);
107  u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx);
108 -void crypto4xx_memcpy_le(unsigned int *dst,
109 -                        const unsigned char *buf, int len);
110 -u32 crypto4xx_build_pd(struct crypto_async_request *req,
111 +int crypto4xx_build_pd(struct crypto_async_request *req,
112                        struct crypto4xx_ctx *ctx,
113                        struct scatterlist *src,
114                        struct scatterlist *dst,
115 @@ -193,4 +191,47 @@ int crypto4xx_hash_digest(struct ahash_r
116  int crypto4xx_hash_final(struct ahash_request *req);
117  int crypto4xx_hash_update(struct ahash_request *req);
118  int crypto4xx_hash_init(struct ahash_request *req);
119 +
120 +/**
121 + * Note: Only use this function to copy items that is word aligned.
122 + */
123 +static inline void crypto4xx_memcpy_swab32(u32 *dst, const void *buf,
124 +                                          size_t len)
125 +{
126 +       for (; len >= 4; buf += 4, len -= 4)
127 +               *dst++ = __swab32p((u32 *) buf);
128 +
129 +       if (len) {
130 +               const u8 *tmp = (u8 *)buf;
131 +
132 +               switch (len) {
133 +               case 3:
134 +                       *dst = (tmp[2] << 16) |
135 +                              (tmp[1] << 8) |
136 +                              tmp[0];
137 +                       break;
138 +               case 2:
139 +                       *dst = (tmp[1] << 8) |
140 +                              tmp[0];
141 +                       break;
142 +               case 1:
143 +                       *dst = tmp[0];
144 +                       break;
145 +               default:
146 +                       break;
147 +               }
148 +       }
149 +}
150 +
151 +static inline void crypto4xx_memcpy_from_le32(u32 *dst, const void *buf,
152 +                                             size_t len)
153 +{
154 +       crypto4xx_memcpy_swab32(dst, buf, len);
155 +}
156 +
157 +static inline void crypto4xx_memcpy_to_le32(__le32 *dst, const void *buf,
158 +                                           size_t len)
159 +{
160 +       crypto4xx_memcpy_swab32((u32 *)dst, buf, len);
161 +}
162  #endif
163 --- a/drivers/crypto/amcc/crypto4xx_sa.h
164 +++ b/drivers/crypto/amcc/crypto4xx_sa.h
165 @@ -181,9 +181,12 @@ struct dynamic_sa_ctl {
166   * State Record for Security Association (SA)
167   */
168  struct  sa_state_record {
169 -       u32 save_iv[4];
170 -       u32 save_hash_byte_cnt[2];
171 -       u32 save_digest[16];
172 +       __le32 save_iv[4];
173 +       __le32 save_hash_byte_cnt[2];
174 +       union {
175 +               u32 save_digest[16]; /* for MD5/SHA */
176 +               __le32 save_digest_le32[16]; /* GHASH / CBC */
177 +       };
178  } __attribute__((packed));
179  
180  /**
181 @@ -192,8 +195,8 @@ struct  sa_state_record {
182   */
183  struct dynamic_sa_aes128 {
184         struct dynamic_sa_ctl   ctrl;
185 -       u32 key[4];
186 -       u32 iv[4]; /* for CBC, OFC, and CFB mode */
187 +       __le32 key[4];
188 +       __le32 iv[4]; /* for CBC, OFC, and CFB mode */
189         u32 state_ptr;
190         u32 reserved;
191  } __attribute__((packed));
192 @@ -206,8 +209,8 @@ struct dynamic_sa_aes128 {
193   */
194  struct dynamic_sa_aes192 {
195         struct dynamic_sa_ctl ctrl;
196 -       u32 key[6];
197 -       u32 iv[4]; /* for CBC, OFC, and CFB mode */
198 +       __le32 key[6];
199 +       __le32 iv[4]; /* for CBC, OFC, and CFB mode */
200         u32 state_ptr;
201         u32 reserved;
202  } __attribute__((packed));
203 @@ -220,8 +223,8 @@ struct dynamic_sa_aes192 {
204   */
205  struct dynamic_sa_aes256 {
206         struct dynamic_sa_ctl ctrl;
207 -       u32 key[8];
208 -       u32 iv[4]; /* for CBC, OFC, and CFB mode */
209 +       __le32 key[8];
210 +       __le32 iv[4]; /* for CBC, OFC, and CFB mode */
211         u32 state_ptr;
212         u32 reserved;
213  } __attribute__((packed));
214 @@ -235,8 +238,8 @@ struct dynamic_sa_aes256 {
215   */
216  struct dynamic_sa_hash160 {
217         struct dynamic_sa_ctl ctrl;
218 -       u32 inner_digest[5];
219 -       u32 outer_digest[5];
220 +       __le32 inner_digest[5];
221 +       __le32 outer_digest[5];
222         u32 state_ptr;
223         u32 reserved;
224  } __attribute__((packed));
225 @@ -266,9 +269,9 @@ get_dynamic_sa_offset_state_ptr_field(st
226         return sizeof(struct dynamic_sa_ctl) + offset * 4;
227  }
228  
229 -static inline u32 *get_dynamic_sa_key_field(struct dynamic_sa_ctl *cts)
230 +static inline __le32 *get_dynamic_sa_key_field(struct dynamic_sa_ctl *cts)
231  {
232 -       return (u32 *) ((unsigned long)cts + sizeof(struct dynamic_sa_ctl));
233 +       return (__le32 *) ((unsigned long)cts + sizeof(struct dynamic_sa_ctl));
234  }
235  
236  #endif