2 * AMCC SoC PPC4xx Crypto Driver
4 * Copyright (c) 2008 Applied Micro Circuits Corporation.
5 * All rights reserved. James Hsiao <jhsiao@amcc.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * This file implements the Linux crypto algorithms.
20 #include <linux/kernel.h>
21 #include <linux/interrupt.h>
22 #include <linux/spinlock_types.h>
23 #include <linux/scatterlist.h>
24 #include <linux/crypto.h>
25 #include <linux/hash.h>
26 #include <crypto/internal/hash.h>
27 #include <linux/dma-mapping.h>
28 #include <crypto/algapi.h>
29 #include <crypto/aes.h>
30 #include <crypto/sha.h>
31 #include "crypto4xx_reg_def.h"
32 #include "crypto4xx_sa.h"
33 #include "crypto4xx_core.h"
35 static void set_dynamic_sa_command_0(struct dynamic_sa_ctl
*sa
, u32 save_h
,
36 u32 save_iv
, u32 ld_h
, u32 ld_iv
,
37 u32 hdr_proc
, u32 h
, u32 c
, u32 pad_type
,
38 u32 op_grp
, u32 op
, u32 dir
)
40 sa
->sa_command_0
.w
= 0;
41 sa
->sa_command_0
.bf
.save_hash_state
= save_h
;
42 sa
->sa_command_0
.bf
.save_iv
= save_iv
;
43 sa
->sa_command_0
.bf
.load_hash_state
= ld_h
;
44 sa
->sa_command_0
.bf
.load_iv
= ld_iv
;
45 sa
->sa_command_0
.bf
.hdr_proc
= hdr_proc
;
46 sa
->sa_command_0
.bf
.hash_alg
= h
;
47 sa
->sa_command_0
.bf
.cipher_alg
= c
;
48 sa
->sa_command_0
.bf
.pad_type
= pad_type
& 3;
49 sa
->sa_command_0
.bf
.extend_pad
= pad_type
>> 2;
50 sa
->sa_command_0
.bf
.op_group
= op_grp
;
51 sa
->sa_command_0
.bf
.opcode
= op
;
52 sa
->sa_command_0
.bf
.dir
= dir
;
55 static void set_dynamic_sa_command_1(struct dynamic_sa_ctl
*sa
, u32 cm
,
56 u32 hmac_mc
, u32 cfb
, u32 esn
,
57 u32 sn_mask
, u32 mute
, u32 cp_pad
,
58 u32 cp_pay
, u32 cp_hdr
)
60 sa
->sa_command_1
.w
= 0;
61 sa
->sa_command_1
.bf
.crypto_mode31
= (cm
& 4) >> 2;
62 sa
->sa_command_1
.bf
.crypto_mode9_8
= cm
& 3;
63 sa
->sa_command_1
.bf
.feedback_mode
= cfb
,
64 sa
->sa_command_1
.bf
.sa_rev
= 1;
65 sa
->sa_command_1
.bf
.extended_seq_num
= esn
;
66 sa
->sa_command_1
.bf
.seq_num_mask
= sn_mask
;
67 sa
->sa_command_1
.bf
.mutable_bit_proc
= mute
;
68 sa
->sa_command_1
.bf
.copy_pad
= cp_pad
;
69 sa
->sa_command_1
.bf
.copy_payload
= cp_pay
;
70 sa
->sa_command_1
.bf
.copy_hdr
= cp_hdr
;
73 int crypto4xx_encrypt(struct ablkcipher_request
*req
)
75 struct crypto4xx_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
77 ctx
->direction
= DIR_OUTBOUND
;
82 return crypto4xx_build_pd(&req
->base
, ctx
, req
->src
, req
->dst
,
83 req
->nbytes
, req
->info
,
84 get_dynamic_sa_iv_size(ctx
));
87 int crypto4xx_decrypt(struct ablkcipher_request
*req
)
89 struct crypto4xx_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
91 ctx
->direction
= DIR_INBOUND
;
96 return crypto4xx_build_pd(&req
->base
, ctx
, req
->src
, req
->dst
,
97 req
->nbytes
, req
->info
,
98 get_dynamic_sa_iv_size(ctx
));
104 static int crypto4xx_setkey_aes(struct crypto_ablkcipher
*cipher
,
110 struct crypto_tfm
*tfm
= crypto_ablkcipher_tfm(cipher
);
111 struct crypto4xx_ctx
*ctx
= crypto_tfm_ctx(tfm
);
112 struct dynamic_sa_ctl
*sa
;
115 if (keylen
!= AES_KEYSIZE_256
&&
116 keylen
!= AES_KEYSIZE_192
&& keylen
!= AES_KEYSIZE_128
) {
117 crypto_ablkcipher_set_flags(cipher
,
118 CRYPTO_TFM_RES_BAD_KEY_LEN
);
123 if (ctx
->sa_in_dma_addr
|| ctx
->sa_out_dma_addr
)
124 crypto4xx_free_sa(ctx
);
126 rc
= crypto4xx_alloc_sa(ctx
, SA_AES128_LEN
+ (keylen
-16) / 4);
130 if (ctx
->state_record_dma_addr
== 0) {
131 rc
= crypto4xx_alloc_state_record(ctx
);
133 crypto4xx_free_sa(ctx
);
138 sa
= (struct dynamic_sa_ctl
*) ctx
->sa_in
;
141 set_dynamic_sa_command_0(sa
, SA_NOT_SAVE_HASH
, SA_NOT_SAVE_IV
,
142 SA_LOAD_HASH_FROM_SA
, SA_LOAD_IV_FROM_STATE
,
143 SA_NO_HEADER_PROC
, SA_HASH_ALG_NULL
,
144 SA_CIPHER_ALG_AES
, SA_PAD_TYPE_ZERO
,
145 SA_OP_GROUP_BASIC
, SA_OPCODE_DECRYPT
,
148 set_dynamic_sa_command_1(sa
, cm
, SA_HASH_MODE_HASH
,
149 fb
, SA_EXTENDED_SN_OFF
,
150 SA_SEQ_MASK_OFF
, SA_MC_ENABLE
,
151 SA_NOT_COPY_PAD
, SA_NOT_COPY_PAYLOAD
,
153 crypto4xx_memcpy_le(ctx
->sa_in
+ get_dynamic_sa_offset_key_field(ctx
),
155 sa
->sa_contents
= SA_AES_CONTENTS
| (keylen
<< 2);
156 sa
->sa_command_1
.bf
.key_len
= keylen
>> 3;
158 ctx
->direction
= DIR_INBOUND
;
159 memcpy(ctx
->sa_in
+ get_dynamic_sa_offset_state_ptr_field(ctx
),
160 (void *)&ctx
->state_record_dma_addr
, 4);
161 ctx
->offset_to_sr_ptr
= get_dynamic_sa_offset_state_ptr_field(ctx
);
163 memcpy(ctx
->sa_out
, ctx
->sa_in
, ctx
->sa_len
* 4);
164 sa
= (struct dynamic_sa_ctl
*) ctx
->sa_out
;
165 sa
->sa_command_0
.bf
.dir
= DIR_OUTBOUND
;
170 int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher
*cipher
,
171 const u8
*key
, unsigned int keylen
)
173 return crypto4xx_setkey_aes(cipher
, key
, keylen
, CRYPTO_MODE_CBC
,
174 CRYPTO_FEEDBACK_MODE_NO_FB
);
178 * HASH SHA1 Functions
180 static int crypto4xx_hash_alg_init(struct crypto_tfm
*tfm
,
185 struct crypto_alg
*alg
= tfm
->__crt_alg
;
186 struct crypto4xx_alg
*my_alg
= crypto_alg_to_crypto4xx_alg(alg
);
187 struct crypto4xx_ctx
*ctx
= crypto_tfm_ctx(tfm
);
188 struct dynamic_sa_ctl
*sa
;
189 struct dynamic_sa_hash160
*sa_in
;
192 ctx
->dev
= my_alg
->dev
;
197 if (ctx
->sa_in_dma_addr
|| ctx
->sa_out_dma_addr
)
198 crypto4xx_free_sa(ctx
);
200 rc
= crypto4xx_alloc_sa(ctx
, sa_len
);
204 if (ctx
->state_record_dma_addr
== 0) {
205 crypto4xx_alloc_state_record(ctx
);
206 if (!ctx
->state_record_dma_addr
) {
207 crypto4xx_free_sa(ctx
);
212 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm
),
213 sizeof(struct crypto4xx_ctx
));
214 sa
= (struct dynamic_sa_ctl
*) ctx
->sa_in
;
215 set_dynamic_sa_command_0(sa
, SA_SAVE_HASH
, SA_NOT_SAVE_IV
,
216 SA_NOT_LOAD_HASH
, SA_LOAD_IV_FROM_SA
,
217 SA_NO_HEADER_PROC
, ha
, SA_CIPHER_ALG_NULL
,
218 SA_PAD_TYPE_ZERO
, SA_OP_GROUP_BASIC
,
219 SA_OPCODE_HASH
, DIR_INBOUND
);
220 set_dynamic_sa_command_1(sa
, 0, SA_HASH_MODE_HASH
,
221 CRYPTO_FEEDBACK_MODE_NO_FB
, SA_EXTENDED_SN_OFF
,
222 SA_SEQ_MASK_OFF
, SA_MC_ENABLE
,
223 SA_NOT_COPY_PAD
, SA_NOT_COPY_PAYLOAD
,
225 ctx
->direction
= DIR_INBOUND
;
226 sa
->sa_contents
= SA_HASH160_CONTENTS
;
227 sa_in
= (struct dynamic_sa_hash160
*) ctx
->sa_in
;
228 /* Need to zero hash digest in SA */
229 memset(sa_in
->inner_digest
, 0, sizeof(sa_in
->inner_digest
));
230 memset(sa_in
->outer_digest
, 0, sizeof(sa_in
->outer_digest
));
231 sa_in
->state_ptr
= ctx
->state_record_dma_addr
;
232 ctx
->offset_to_sr_ptr
= get_dynamic_sa_offset_state_ptr_field(ctx
);
237 int crypto4xx_hash_init(struct ahash_request
*req
)
239 struct crypto4xx_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
241 struct dynamic_sa_ctl
*sa
;
243 sa
= (struct dynamic_sa_ctl
*) ctx
->sa_in
;
244 ds
= crypto_ahash_digestsize(
245 __crypto_ahash_cast(req
->base
.tfm
));
246 sa
->sa_command_0
.bf
.digest_len
= ds
>> 2;
247 sa
->sa_command_0
.bf
.load_hash_state
= SA_LOAD_HASH_FROM_SA
;
249 ctx
->direction
= DIR_INBOUND
;
254 int crypto4xx_hash_update(struct ahash_request
*req
)
256 struct crypto4xx_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
261 ctx
->direction
= DIR_INBOUND
;
263 return crypto4xx_build_pd(&req
->base
, ctx
, req
->src
,
264 (struct scatterlist
*) req
->result
,
265 req
->nbytes
, NULL
, 0);
268 int crypto4xx_hash_final(struct ahash_request
*req
)
273 int crypto4xx_hash_digest(struct ahash_request
*req
)
275 struct crypto4xx_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
279 ctx
->direction
= DIR_INBOUND
;
281 return crypto4xx_build_pd(&req
->base
, ctx
, req
->src
,
282 (struct scatterlist
*) req
->result
,
283 req
->nbytes
, NULL
, 0);
289 int crypto4xx_sha1_alg_init(struct crypto_tfm
*tfm
)
291 return crypto4xx_hash_alg_init(tfm
, SA_HASH160_LEN
, SA_HASH_ALG_SHA1
,