diff options
41 files changed, 7660 insertions, 422 deletions
diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt new file mode 100644 index 000000000000..bf57ecd5d73a --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt | |||
@@ -0,0 +1,397 @@ | |||
1 | ===================================================================== | ||
2 | SEC 4 Device Tree Binding | ||
3 | Copyright (C) 2008-2011 Freescale Semiconductor Inc. | ||
4 | |||
5 | CONTENTS | ||
6 | -Overview | ||
7 | -SEC 4 Node | ||
8 | -Job Ring Node | ||
9 | -Run Time Integrity Check (RTIC) Node | ||
10 | -Run Time Integrity Check (RTIC) Memory Node | ||
11 | -Secure Non-Volatile Storage (SNVS) Node | ||
12 | -Full Example | ||
13 | |||
14 | NOTE: the SEC 4 is also known as Freescale's Cryptographic Accelerator | ||
15 | Accelerator and Assurance Module (CAAM). | ||
16 | |||
17 | ===================================================================== | ||
18 | Overview | ||
19 | |||
20 | DESCRIPTION | ||
21 | |||
22 | SEC 4 h/w can process requests from 2 types of sources. | ||
23 | 1. DPAA Queue Interface (HW interface between Queue Manager & SEC 4). | ||
24 | 2. Job Rings (HW interface between cores & SEC 4 registers). | ||
25 | |||
26 | High Speed Data Path Configuration: | ||
27 | |||
28 | HW interface between QM & SEC 4 and also BM & SEC 4, on DPAA-enabled parts | ||
29 | such as the P4080. The number of simultaneous dequeues the QI can make is | ||
30 | equal to the number of Descriptor Controller (DECO) engines in a particular | ||
31 | SEC version. E.g., the SEC 4.0 in the P4080 has 5 DECOs and can thus | ||
32 | dequeue from 5 subportals simultaneously. | ||
33 | |||
34 | Job Ring Data Path Configuration: | ||
35 | |||
36 | Each JR is located on a separate 4k page, they may (or may not) be made visible | ||
37 | in the memory partition devoted to a particular core. The P4080 has 4 JRs, so | ||
38 | up to 4 JRs can be configured; and all 4 JRs process requests in parallel. | ||
39 | |||
40 | ===================================================================== | ||
41 | SEC 4 Node | ||
42 | |||
43 | Description | ||
44 | |||
45 | Node defines the base address of the SEC 4 block. | ||
46 | This block specifies the address range of all global | ||
47 | configuration registers for the SEC 4 block. It | ||
48 | also receives interrupts from the Run Time Integrity Check | ||
49 | (RTIC) function within the SEC 4 block. | ||
50 | |||
51 | PROPERTIES | ||
52 | |||
53 | - compatible | ||
54 | Usage: required | ||
55 | Value type: <string> | ||
56 | Definition: Must include "fsl,sec-v4.0" | ||
57 | |||
58 | - #address-cells | ||
59 | Usage: required | ||
60 | Value type: <u32> | ||
61 | Definition: A standard property. Defines the number of cells | ||
62 | for representing physical addresses in child nodes. | ||
63 | |||
64 | - #size-cells | ||
65 | Usage: required | ||
66 | Value type: <u32> | ||
67 | Definition: A standard property. Defines the number of cells | ||
68 | for representing the size of physical addresses in | ||
69 | child nodes. | ||
70 | |||
71 | - reg | ||
72 | Usage: required | ||
73 | Value type: <prop-encoded-array> | ||
74 | Definition: A standard property. Specifies the physical | ||
75 | address and length of the SEC4 configuration registers. | ||
76 | registers | ||
77 | |||
78 | - ranges | ||
79 | Usage: required | ||
80 | Value type: <prop-encoded-array> | ||
81 | Definition: A standard property. Specifies the physical address | ||
82 | range of the SEC 4.0 register space (-SNVS not included). A | ||
83 | triplet that includes the child address, parent address, & | ||
84 | length. | ||
85 | |||
86 | - interrupts | ||
87 | Usage: required | ||
88 | Value type: <prop_encoded-array> | ||
89 | Definition: Specifies the interrupts generated by this | ||
90 | device. The value of the interrupts property | ||
91 | consists of one interrupt specifier. The format | ||
92 | of the specifier is defined by the binding document | ||
93 | describing the node's interrupt parent. | ||
94 | |||
95 | - interrupt-parent | ||
96 | Usage: (required if interrupt property is defined) | ||
97 | Value type: <phandle> | ||
98 | Definition: A single <phandle> value that points | ||
99 | to the interrupt parent to which the child domain | ||
100 | is being mapped. | ||
101 | |||
102 | Note: All other standard properties (see the ePAPR) are allowed | ||
103 | but are optional. | ||
104 | |||
105 | |||
106 | EXAMPLE | ||
107 | crypto@300000 { | ||
108 | compatible = "fsl,sec-v4.0"; | ||
109 | #address-cells = <1>; | ||
110 | #size-cells = <1>; | ||
111 | reg = <0x300000 0x10000>; | ||
112 | ranges = <0 0x300000 0x10000>; | ||
113 | interrupt-parent = <&mpic>; | ||
114 | interrupts = <92 2>; | ||
115 | }; | ||
116 | |||
117 | ===================================================================== | ||
118 | Job Ring (JR) Node | ||
119 | |||
120 | Child of the crypto node defines data processing interface to SEC 4 | ||
121 | across the peripheral bus for purposes of processing | ||
122 | cryptographic descriptors. The specified address | ||
123 | range can be made visible to one (or more) cores. | ||
124 | The interrupt defined for this node is controlled within | ||
125 | the address range of this node. | ||
126 | |||
127 | - compatible | ||
128 | Usage: required | ||
129 | Value type: <string> | ||
130 | Definition: Must include "fsl,sec-v4.0-job-ring" | ||
131 | |||
132 | - reg | ||
133 | Usage: required | ||
134 | Value type: <prop-encoded-array> | ||
135 | Definition: Specifies a two JR parameters: an offset from | ||
136 | the parent physical address and the length the JR registers. | ||
137 | |||
138 | - fsl,liodn | ||
139 | Usage: optional-but-recommended | ||
140 | Value type: <prop-encoded-array> | ||
141 | Definition: | ||
142 | Specifies the LIODN to be used in conjunction with | ||
143 | the ppid-to-liodn table that specifies the PPID to LIODN mapping. | ||
144 | Needed if the PAMU is used. Value is a 12 bit value | ||
145 | where value is a LIODN ID for this JR. This property is | ||
146 | normally set by boot firmware. | ||
147 | |||
148 | - interrupts | ||
149 | Usage: required | ||
150 | Value type: <prop_encoded-array> | ||
151 | Definition: Specifies the interrupts generated by this | ||
152 | device. The value of the interrupts property | ||
153 | consists of one interrupt specifier. The format | ||
154 | of the specifier is defined by the binding document | ||
155 | describing the node's interrupt parent. | ||
156 | |||
157 | - interrupt-parent | ||
158 | Usage: (required if interrupt property is defined) | ||
159 | Value type: <phandle> | ||
160 | Definition: A single <phandle> value that points | ||
161 | to the interrupt parent to which the child domain | ||
162 | is being mapped. | ||
163 | |||
164 | EXAMPLE | ||
165 | jr@1000 { | ||
166 | compatible = "fsl,sec-v4.0-job-ring"; | ||
167 | reg = <0x1000 0x1000>; | ||
168 | fsl,liodn = <0x081>; | ||
169 | interrupt-parent = <&mpic>; | ||
170 | interrupts = <88 2>; | ||
171 | }; | ||
172 | |||
173 | |||
174 | ===================================================================== | ||
175 | Run Time Integrity Check (RTIC) Node | ||
176 | |||
177 | Child node of the crypto node. Defines a register space that | ||
178 | contains up to 5 sets of addresses and their lengths (sizes) that | ||
179 | will be checked at run time. After an initial hash result is | ||
180 | calculated, these addresses are checked by HW to monitor any | ||
181 | change. If any memory is modified, a Security Violation is | ||
182 | triggered (see SNVS definition). | ||
183 | |||
184 | |||
185 | - compatible | ||
186 | Usage: required | ||
187 | Value type: <string> | ||
188 | Definition: Must include "fsl,sec-v4.0-rtic". | ||
189 | |||
190 | - #address-cells | ||
191 | Usage: required | ||
192 | Value type: <u32> | ||
193 | Definition: A standard property. Defines the number of cells | ||
194 | for representing physical addresses in child nodes. Must | ||
195 | have a value of 1. | ||
196 | |||
197 | - #size-cells | ||
198 | Usage: required | ||
199 | Value type: <u32> | ||
200 | Definition: A standard property. Defines the number of cells | ||
201 | for representing the size of physical addresses in | ||
202 | child nodes. Must have a value of 1. | ||
203 | |||
204 | - reg | ||
205 | Usage: required | ||
206 | Value type: <prop-encoded-array> | ||
207 | Definition: A standard property. Specifies a two parameters: | ||
208 | an offset from the parent physical address and the length | ||
209 | the SEC4 registers. | ||
210 | |||
211 | - ranges | ||
212 | Usage: required | ||
213 | Value type: <prop-encoded-array> | ||
214 | Definition: A standard property. Specifies the physical address | ||
215 | range of the SEC 4 register space (-SNVS not included). A | ||
216 | triplet that includes the child address, parent address, & | ||
217 | length. | ||
218 | |||
219 | EXAMPLE | ||
220 | rtic@6000 { | ||
221 | compatible = "fsl,sec-v4.0-rtic"; | ||
222 | #address-cells = <1>; | ||
223 | #size-cells = <1>; | ||
224 | reg = <0x6000 0x100>; | ||
225 | ranges = <0x0 0x6100 0xe00>; | ||
226 | }; | ||
227 | |||
228 | ===================================================================== | ||
229 | Run Time Integrity Check (RTIC) Memory Node | ||
230 | A child node that defines individual RTIC memory regions that are used to | ||
231 | perform run-time integrity check of memory areas that should not modified. | ||
232 | The node defines a register that contains the memory address & | ||
233 | length (combined) and a second register that contains the hash result | ||
234 | in big endian format. | ||
235 | |||
236 | - compatible | ||
237 | Usage: required | ||
238 | Value type: <string> | ||
239 | Definition: Must include "fsl,sec-v4.0-rtic-memory". | ||
240 | |||
241 | - reg | ||
242 | Usage: required | ||
243 | Value type: <prop-encoded-array> | ||
244 | Definition: A standard property. Specifies two parameters: | ||
245 | an offset from the parent physical address and the length: | ||
246 | |||
247 | 1. The location of the RTIC memory address & length registers. | ||
248 | 2. The location RTIC hash result. | ||
249 | |||
250 | - fsl,rtic-region | ||
251 | Usage: optional-but-recommended | ||
252 | Value type: <prop-encoded-array> | ||
253 | Definition: | ||
254 | Specifies the HW address (36 bit address) for this region | ||
255 | followed by the length of the HW partition to be checked; | ||
256 | the address is represented as a 64 bit quantity followed | ||
257 | by a 32 bit length. | ||
258 | |||
259 | - fsl,liodn | ||
260 | Usage: optional-but-recommended | ||
261 | Value type: <prop-encoded-array> | ||
262 | Definition: | ||
263 | Specifies the LIODN to be used in conjunction with | ||
264 | the ppid-to-liodn table that specifies the PPID to LIODN | ||
265 | mapping. Needed if the PAMU is used. Value is a 12 bit value | ||
266 | where value is a LIODN ID for this RTIC memory region. This | ||
267 | property is normally set by boot firmware. | ||
268 | |||
269 | EXAMPLE | ||
270 | rtic-a@0 { | ||
271 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
272 | reg = <0x00 0x20 0x100 0x80>; | ||
273 | fsl,liodn = <0x03c>; | ||
274 | fsl,rtic-region = <0x12345678 0x12345678 0x12345678>; | ||
275 | }; | ||
276 | |||
277 | ===================================================================== | ||
278 | Secure Non-Volatile Storage (SNVS) Node | ||
279 | |||
280 | Node defines address range and the associated | ||
281 | interrupt for the SNVS function. This function | ||
282 | monitors security state information & reports | ||
283 | security violations. | ||
284 | |||
285 | - compatible | ||
286 | Usage: required | ||
287 | Value type: <string> | ||
288 | Definition: Must include "fsl,sec-v4.0-mon". | ||
289 | |||
290 | - reg | ||
291 | Usage: required | ||
292 | Value type: <prop-encoded-array> | ||
293 | Definition: A standard property. Specifies the physical | ||
294 | address and length of the SEC4 configuration | ||
295 | registers. | ||
296 | |||
297 | - interrupts | ||
298 | Usage: required | ||
299 | Value type: <prop_encoded-array> | ||
300 | Definition: Specifies the interrupts generated by this | ||
301 | device. The value of the interrupts property | ||
302 | consists of one interrupt specifier. The format | ||
303 | of the specifier is defined by the binding document | ||
304 | describing the node's interrupt parent. | ||
305 | |||
306 | - interrupt-parent | ||
307 | Usage: (required if interrupt property is defined) | ||
308 | Value type: <phandle> | ||
309 | Definition: A single <phandle> value that points | ||
310 | to the interrupt parent to which the child domain | ||
311 | is being mapped. | ||
312 | |||
313 | EXAMPLE | ||
314 | sec_mon@314000 { | ||
315 | compatible = "fsl,sec-v4.0-mon"; | ||
316 | reg = <0x314000 0x1000>; | ||
317 | interrupt-parent = <&mpic>; | ||
318 | interrupts = <93 2>; | ||
319 | }; | ||
320 | |||
321 | ===================================================================== | ||
322 | FULL EXAMPLE | ||
323 | |||
324 | crypto: crypto@300000 { | ||
325 | compatible = "fsl,sec-v4.0"; | ||
326 | #address-cells = <1>; | ||
327 | #size-cells = <1>; | ||
328 | reg = <0x300000 0x10000>; | ||
329 | ranges = <0 0x300000 0x10000>; | ||
330 | interrupt-parent = <&mpic>; | ||
331 | interrupts = <92 2>; | ||
332 | |||
333 | sec_jr0: jr@1000 { | ||
334 | compatible = "fsl,sec-v4.0-job-ring"; | ||
335 | reg = <0x1000 0x1000>; | ||
336 | interrupt-parent = <&mpic>; | ||
337 | interrupts = <88 2>; | ||
338 | }; | ||
339 | |||
340 | sec_jr1: jr@2000 { | ||
341 | compatible = "fsl,sec-v4.0-job-ring"; | ||
342 | reg = <0x2000 0x1000>; | ||
343 | interrupt-parent = <&mpic>; | ||
344 | interrupts = <89 2>; | ||
345 | }; | ||
346 | |||
347 | sec_jr2: jr@3000 { | ||
348 | compatible = "fsl,sec-v4.0-job-ring"; | ||
349 | reg = <0x3000 0x1000>; | ||
350 | interrupt-parent = <&mpic>; | ||
351 | interrupts = <90 2>; | ||
352 | }; | ||
353 | |||
354 | sec_jr3: jr@4000 { | ||
355 | compatible = "fsl,sec-v4.0-job-ring"; | ||
356 | reg = <0x4000 0x1000>; | ||
357 | interrupt-parent = <&mpic>; | ||
358 | interrupts = <91 2>; | ||
359 | }; | ||
360 | |||
361 | rtic@6000 { | ||
362 | compatible = "fsl,sec-v4.0-rtic"; | ||
363 | #address-cells = <1>; | ||
364 | #size-cells = <1>; | ||
365 | reg = <0x6000 0x100>; | ||
366 | ranges = <0x0 0x6100 0xe00>; | ||
367 | |||
368 | rtic_a: rtic-a@0 { | ||
369 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
370 | reg = <0x00 0x20 0x100 0x80>; | ||
371 | }; | ||
372 | |||
373 | rtic_b: rtic-b@20 { | ||
374 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
375 | reg = <0x20 0x20 0x200 0x80>; | ||
376 | }; | ||
377 | |||
378 | rtic_c: rtic-c@40 { | ||
379 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
380 | reg = <0x40 0x20 0x300 0x80>; | ||
381 | }; | ||
382 | |||
383 | rtic_d: rtic-d@60 { | ||
384 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
385 | reg = <0x60 0x20 0x500 0x80>; | ||
386 | }; | ||
387 | }; | ||
388 | }; | ||
389 | |||
390 | sec_mon: sec_mon@314000 { | ||
391 | compatible = "fsl,sec-v4.0-mon"; | ||
392 | reg = <0x314000 0x1000>; | ||
393 | interrupt-parent = <&mpic>; | ||
394 | interrupts = <93 2>; | ||
395 | }; | ||
396 | |||
397 | ===================================================================== | ||
diff --git a/arch/powerpc/boot/dts/p4080ds.dts b/arch/powerpc/boot/dts/p4080ds.dts index 5b7fc29dd6cf..927f94d16e9b 100644 --- a/arch/powerpc/boot/dts/p4080ds.dts +++ b/arch/powerpc/boot/dts/p4080ds.dts | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * P4080DS Device Tree Source | 2 | * P4080DS Device Tree Source |
3 | * | 3 | * |
4 | * Copyright 2009 Freescale Semiconductor Inc. | 4 | * Copyright 2009-2011 Freescale Semiconductor Inc. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -33,6 +33,17 @@ | |||
33 | dma1 = &dma1; | 33 | dma1 = &dma1; |
34 | sdhc = &sdhc; | 34 | sdhc = &sdhc; |
35 | 35 | ||
36 | crypto = &crypto; | ||
37 | sec_jr0 = &sec_jr0; | ||
38 | sec_jr1 = &sec_jr1; | ||
39 | sec_jr2 = &sec_jr2; | ||
40 | sec_jr3 = &sec_jr3; | ||
41 | rtic_a = &rtic_a; | ||
42 | rtic_b = &rtic_b; | ||
43 | rtic_c = &rtic_c; | ||
44 | rtic_d = &rtic_d; | ||
45 | sec_mon = &sec_mon; | ||
46 | |||
36 | rio0 = &rapidio0; | 47 | rio0 = &rapidio0; |
37 | }; | 48 | }; |
38 | 49 | ||
@@ -410,6 +421,79 @@ | |||
410 | dr_mode = "host"; | 421 | dr_mode = "host"; |
411 | phy_type = "ulpi"; | 422 | phy_type = "ulpi"; |
412 | }; | 423 | }; |
424 | |||
425 | crypto: crypto@300000 { | ||
426 | compatible = "fsl,sec-v4.0"; | ||
427 | #address-cells = <1>; | ||
428 | #size-cells = <1>; | ||
429 | reg = <0x300000 0x10000>; | ||
430 | ranges = <0 0x300000 0x10000>; | ||
431 | interrupt-parent = <&mpic>; | ||
432 | interrupts = <92 2>; | ||
433 | |||
434 | sec_jr0: jr@1000 { | ||
435 | compatible = "fsl,sec-v4.0-job-ring"; | ||
436 | reg = <0x1000 0x1000>; | ||
437 | interrupt-parent = <&mpic>; | ||
438 | interrupts = <88 2>; | ||
439 | }; | ||
440 | |||
441 | sec_jr1: jr@2000 { | ||
442 | compatible = "fsl,sec-v4.0-job-ring"; | ||
443 | reg = <0x2000 0x1000>; | ||
444 | interrupt-parent = <&mpic>; | ||
445 | interrupts = <89 2>; | ||
446 | }; | ||
447 | |||
448 | sec_jr2: jr@3000 { | ||
449 | compatible = "fsl,sec-v4.0-job-ring"; | ||
450 | reg = <0x3000 0x1000>; | ||
451 | interrupt-parent = <&mpic>; | ||
452 | interrupts = <90 2>; | ||
453 | }; | ||
454 | |||
455 | sec_jr3: jr@4000 { | ||
456 | compatible = "fsl,sec-v4.0-job-ring"; | ||
457 | reg = <0x4000 0x1000>; | ||
458 | interrupt-parent = <&mpic>; | ||
459 | interrupts = <91 2>; | ||
460 | }; | ||
461 | |||
462 | rtic@6000 { | ||
463 | compatible = "fsl,sec-v4.0-rtic"; | ||
464 | #address-cells = <1>; | ||
465 | #size-cells = <1>; | ||
466 | reg = <0x6000 0x100>; | ||
467 | ranges = <0x0 0x6100 0xe00>; | ||
468 | |||
469 | rtic_a: rtic-a@0 { | ||
470 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
471 | reg = <0x00 0x20 0x100 0x80>; | ||
472 | }; | ||
473 | |||
474 | rtic_b: rtic-b@20 { | ||
475 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
476 | reg = <0x20 0x20 0x200 0x80>; | ||
477 | }; | ||
478 | |||
479 | rtic_c: rtic-c@40 { | ||
480 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
481 | reg = <0x40 0x20 0x300 0x80>; | ||
482 | }; | ||
483 | |||
484 | rtic_d: rtic-d@60 { | ||
485 | compatible = "fsl,sec-v4.0-rtic-memory"; | ||
486 | reg = <0x60 0x20 0x500 0x80>; | ||
487 | }; | ||
488 | }; | ||
489 | }; | ||
490 | |||
491 | sec_mon: sec_mon@314000 { | ||
492 | compatible = "fsl,sec-v4.0-mon"; | ||
493 | reg = <0x314000 0x1000>; | ||
494 | interrupt-parent = <&mpic>; | ||
495 | interrupts = <93 2>; | ||
496 | }; | ||
413 | }; | 497 | }; |
414 | 498 | ||
415 | rapidio0: rapidio@ffe0c0000 { | 499 | rapidio0: rapidio@ffe0c0000 { |
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile index 1cf81d77c5a5..7f0b7cda6259 100644 --- a/arch/s390/crypto/Makefile +++ b/arch/s390/crypto/Makefile | |||
@@ -8,3 +8,4 @@ obj-$(CONFIG_CRYPTO_SHA512_S390) += sha512_s390.o sha_common.o | |||
8 | obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o | 8 | obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o |
9 | obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o | 9 | obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o |
10 | obj-$(CONFIG_S390_PRNG) += prng.o | 10 | obj-$(CONFIG_S390_PRNG) += prng.o |
11 | obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o | ||
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 58f46734465f..a9ce135893f8 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -31,7 +31,8 @@ | |||
31 | #define AES_KEYLEN_192 2 | 31 | #define AES_KEYLEN_192 2 |
32 | #define AES_KEYLEN_256 4 | 32 | #define AES_KEYLEN_256 4 |
33 | 33 | ||
34 | static char keylen_flag = 0; | 34 | static u8 *ctrblk; |
35 | static char keylen_flag; | ||
35 | 36 | ||
36 | struct s390_aes_ctx { | 37 | struct s390_aes_ctx { |
37 | u8 iv[AES_BLOCK_SIZE]; | 38 | u8 iv[AES_BLOCK_SIZE]; |
@@ -45,6 +46,24 @@ struct s390_aes_ctx { | |||
45 | } fallback; | 46 | } fallback; |
46 | }; | 47 | }; |
47 | 48 | ||
49 | struct pcc_param { | ||
50 | u8 key[32]; | ||
51 | u8 tweak[16]; | ||
52 | u8 block[16]; | ||
53 | u8 bit[16]; | ||
54 | u8 xts[16]; | ||
55 | }; | ||
56 | |||
57 | struct s390_xts_ctx { | ||
58 | u8 key[32]; | ||
59 | u8 xts_param[16]; | ||
60 | struct pcc_param pcc; | ||
61 | long enc; | ||
62 | long dec; | ||
63 | int key_len; | ||
64 | struct crypto_blkcipher *fallback; | ||
65 | }; | ||
66 | |||
48 | /* | 67 | /* |
49 | * Check if the key_len is supported by the HW. | 68 | * Check if the key_len is supported by the HW. |
50 | * Returns 0 if it is, a positive number if it is not and software fallback is | 69 | * Returns 0 if it is, a positive number if it is not and software fallback is |
@@ -504,15 +523,337 @@ static struct crypto_alg cbc_aes_alg = { | |||
504 | } | 523 | } |
505 | }; | 524 | }; |
506 | 525 | ||
526 | static int xts_fallback_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
527 | unsigned int len) | ||
528 | { | ||
529 | struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm); | ||
530 | unsigned int ret; | ||
531 | |||
532 | xts_ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; | ||
533 | xts_ctx->fallback->base.crt_flags |= (tfm->crt_flags & | ||
534 | CRYPTO_TFM_REQ_MASK); | ||
535 | |||
536 | ret = crypto_blkcipher_setkey(xts_ctx->fallback, key, len); | ||
537 | if (ret) { | ||
538 | tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; | ||
539 | tfm->crt_flags |= (xts_ctx->fallback->base.crt_flags & | ||
540 | CRYPTO_TFM_RES_MASK); | ||
541 | } | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | static int xts_fallback_decrypt(struct blkcipher_desc *desc, | ||
546 | struct scatterlist *dst, struct scatterlist *src, | ||
547 | unsigned int nbytes) | ||
548 | { | ||
549 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); | ||
550 | struct crypto_blkcipher *tfm; | ||
551 | unsigned int ret; | ||
552 | |||
553 | tfm = desc->tfm; | ||
554 | desc->tfm = xts_ctx->fallback; | ||
555 | |||
556 | ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes); | ||
557 | |||
558 | desc->tfm = tfm; | ||
559 | return ret; | ||
560 | } | ||
561 | |||
562 | static int xts_fallback_encrypt(struct blkcipher_desc *desc, | ||
563 | struct scatterlist *dst, struct scatterlist *src, | ||
564 | unsigned int nbytes) | ||
565 | { | ||
566 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); | ||
567 | struct crypto_blkcipher *tfm; | ||
568 | unsigned int ret; | ||
569 | |||
570 | tfm = desc->tfm; | ||
571 | desc->tfm = xts_ctx->fallback; | ||
572 | |||
573 | ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes); | ||
574 | |||
575 | desc->tfm = tfm; | ||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | ||
580 | unsigned int key_len) | ||
581 | { | ||
582 | struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm); | ||
583 | u32 *flags = &tfm->crt_flags; | ||
584 | |||
585 | switch (key_len) { | ||
586 | case 32: | ||
587 | xts_ctx->enc = KM_XTS_128_ENCRYPT; | ||
588 | xts_ctx->dec = KM_XTS_128_DECRYPT; | ||
589 | memcpy(xts_ctx->key + 16, in_key, 16); | ||
590 | memcpy(xts_ctx->pcc.key + 16, in_key + 16, 16); | ||
591 | break; | ||
592 | case 48: | ||
593 | xts_ctx->enc = 0; | ||
594 | xts_ctx->dec = 0; | ||
595 | xts_fallback_setkey(tfm, in_key, key_len); | ||
596 | break; | ||
597 | case 64: | ||
598 | xts_ctx->enc = KM_XTS_256_ENCRYPT; | ||
599 | xts_ctx->dec = KM_XTS_256_DECRYPT; | ||
600 | memcpy(xts_ctx->key, in_key, 32); | ||
601 | memcpy(xts_ctx->pcc.key, in_key + 32, 32); | ||
602 | break; | ||
603 | default: | ||
604 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
605 | return -EINVAL; | ||
606 | } | ||
607 | xts_ctx->key_len = key_len; | ||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static int xts_aes_crypt(struct blkcipher_desc *desc, long func, | ||
612 | struct s390_xts_ctx *xts_ctx, | ||
613 | struct blkcipher_walk *walk) | ||
614 | { | ||
615 | unsigned int offset = (xts_ctx->key_len >> 1) & 0x10; | ||
616 | int ret = blkcipher_walk_virt(desc, walk); | ||
617 | unsigned int nbytes = walk->nbytes; | ||
618 | unsigned int n; | ||
619 | u8 *in, *out; | ||
620 | void *param; | ||
621 | |||
622 | if (!nbytes) | ||
623 | goto out; | ||
624 | |||
625 | memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block)); | ||
626 | memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit)); | ||
627 | memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts)); | ||
628 | memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak)); | ||
629 | param = xts_ctx->pcc.key + offset; | ||
630 | ret = crypt_s390_pcc(func, param); | ||
631 | BUG_ON(ret < 0); | ||
632 | |||
633 | memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16); | ||
634 | param = xts_ctx->key + offset; | ||
635 | do { | ||
636 | /* only use complete blocks */ | ||
637 | n = nbytes & ~(AES_BLOCK_SIZE - 1); | ||
638 | out = walk->dst.virt.addr; | ||
639 | in = walk->src.virt.addr; | ||
640 | |||
641 | ret = crypt_s390_km(func, param, out, in, n); | ||
642 | BUG_ON(ret < 0 || ret != n); | ||
643 | |||
644 | nbytes &= AES_BLOCK_SIZE - 1; | ||
645 | ret = blkcipher_walk_done(desc, walk, nbytes); | ||
646 | } while ((nbytes = walk->nbytes)); | ||
647 | out: | ||
648 | return ret; | ||
649 | } | ||
650 | |||
651 | static int xts_aes_encrypt(struct blkcipher_desc *desc, | ||
652 | struct scatterlist *dst, struct scatterlist *src, | ||
653 | unsigned int nbytes) | ||
654 | { | ||
655 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); | ||
656 | struct blkcipher_walk walk; | ||
657 | |||
658 | if (unlikely(xts_ctx->key_len == 48)) | ||
659 | return xts_fallback_encrypt(desc, dst, src, nbytes); | ||
660 | |||
661 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
662 | return xts_aes_crypt(desc, xts_ctx->enc, xts_ctx, &walk); | ||
663 | } | ||
664 | |||
665 | static int xts_aes_decrypt(struct blkcipher_desc *desc, | ||
666 | struct scatterlist *dst, struct scatterlist *src, | ||
667 | unsigned int nbytes) | ||
668 | { | ||
669 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); | ||
670 | struct blkcipher_walk walk; | ||
671 | |||
672 | if (unlikely(xts_ctx->key_len == 48)) | ||
673 | return xts_fallback_decrypt(desc, dst, src, nbytes); | ||
674 | |||
675 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
676 | return xts_aes_crypt(desc, xts_ctx->dec, xts_ctx, &walk); | ||
677 | } | ||
678 | |||
679 | static int xts_fallback_init(struct crypto_tfm *tfm) | ||
680 | { | ||
681 | const char *name = tfm->__crt_alg->cra_name; | ||
682 | struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm); | ||
683 | |||
684 | xts_ctx->fallback = crypto_alloc_blkcipher(name, 0, | ||
685 | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); | ||
686 | |||
687 | if (IS_ERR(xts_ctx->fallback)) { | ||
688 | pr_err("Allocating XTS fallback algorithm %s failed\n", | ||
689 | name); | ||
690 | return PTR_ERR(xts_ctx->fallback); | ||
691 | } | ||
692 | return 0; | ||
693 | } | ||
694 | |||
695 | static void xts_fallback_exit(struct crypto_tfm *tfm) | ||
696 | { | ||
697 | struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm); | ||
698 | |||
699 | crypto_free_blkcipher(xts_ctx->fallback); | ||
700 | xts_ctx->fallback = NULL; | ||
701 | } | ||
702 | |||
703 | static struct crypto_alg xts_aes_alg = { | ||
704 | .cra_name = "xts(aes)", | ||
705 | .cra_driver_name = "xts-aes-s390", | ||
706 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | ||
707 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | | ||
708 | CRYPTO_ALG_NEED_FALLBACK, | ||
709 | .cra_blocksize = AES_BLOCK_SIZE, | ||
710 | .cra_ctxsize = sizeof(struct s390_xts_ctx), | ||
711 | .cra_type = &crypto_blkcipher_type, | ||
712 | .cra_module = THIS_MODULE, | ||
713 | .cra_list = LIST_HEAD_INIT(xts_aes_alg.cra_list), | ||
714 | .cra_init = xts_fallback_init, | ||
715 | .cra_exit = xts_fallback_exit, | ||
716 | .cra_u = { | ||
717 | .blkcipher = { | ||
718 | .min_keysize = 2 * AES_MIN_KEY_SIZE, | ||
719 | .max_keysize = 2 * AES_MAX_KEY_SIZE, | ||
720 | .ivsize = AES_BLOCK_SIZE, | ||
721 | .setkey = xts_aes_set_key, | ||
722 | .encrypt = xts_aes_encrypt, | ||
723 | .decrypt = xts_aes_decrypt, | ||
724 | } | ||
725 | } | ||
726 | }; | ||
727 | |||
728 | static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | ||
729 | unsigned int key_len) | ||
730 | { | ||
731 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); | ||
732 | |||
733 | switch (key_len) { | ||
734 | case 16: | ||
735 | sctx->enc = KMCTR_AES_128_ENCRYPT; | ||
736 | sctx->dec = KMCTR_AES_128_DECRYPT; | ||
737 | break; | ||
738 | case 24: | ||
739 | sctx->enc = KMCTR_AES_192_ENCRYPT; | ||
740 | sctx->dec = KMCTR_AES_192_DECRYPT; | ||
741 | break; | ||
742 | case 32: | ||
743 | sctx->enc = KMCTR_AES_256_ENCRYPT; | ||
744 | sctx->dec = KMCTR_AES_256_DECRYPT; | ||
745 | break; | ||
746 | } | ||
747 | |||
748 | return aes_set_key(tfm, in_key, key_len); | ||
749 | } | ||
750 | |||
751 | static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, | ||
752 | struct s390_aes_ctx *sctx, struct blkcipher_walk *walk) | ||
753 | { | ||
754 | int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE); | ||
755 | unsigned int i, n, nbytes; | ||
756 | u8 buf[AES_BLOCK_SIZE]; | ||
757 | u8 *out, *in; | ||
758 | |||
759 | if (!walk->nbytes) | ||
760 | return ret; | ||
761 | |||
762 | memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE); | ||
763 | while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { | ||
764 | out = walk->dst.virt.addr; | ||
765 | in = walk->src.virt.addr; | ||
766 | while (nbytes >= AES_BLOCK_SIZE) { | ||
767 | /* only use complete blocks, max. PAGE_SIZE */ | ||
768 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : | ||
769 | nbytes & ~(AES_BLOCK_SIZE - 1); | ||
770 | for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { | ||
771 | memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE, | ||
772 | AES_BLOCK_SIZE); | ||
773 | crypto_inc(ctrblk + i, AES_BLOCK_SIZE); | ||
774 | } | ||
775 | ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk); | ||
776 | BUG_ON(ret < 0 || ret != n); | ||
777 | if (n > AES_BLOCK_SIZE) | ||
778 | memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE, | ||
779 | AES_BLOCK_SIZE); | ||
780 | crypto_inc(ctrblk, AES_BLOCK_SIZE); | ||
781 | out += n; | ||
782 | in += n; | ||
783 | nbytes -= n; | ||
784 | } | ||
785 | ret = blkcipher_walk_done(desc, walk, nbytes); | ||
786 | } | ||
787 | /* | ||
788 | * final block may be < AES_BLOCK_SIZE, copy only nbytes | ||
789 | */ | ||
790 | if (nbytes) { | ||
791 | out = walk->dst.virt.addr; | ||
792 | in = walk->src.virt.addr; | ||
793 | ret = crypt_s390_kmctr(func, sctx->key, buf, in, | ||
794 | AES_BLOCK_SIZE, ctrblk); | ||
795 | BUG_ON(ret < 0 || ret != AES_BLOCK_SIZE); | ||
796 | memcpy(out, buf, nbytes); | ||
797 | crypto_inc(ctrblk, AES_BLOCK_SIZE); | ||
798 | ret = blkcipher_walk_done(desc, walk, 0); | ||
799 | } | ||
800 | memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE); | ||
801 | return ret; | ||
802 | } | ||
803 | |||
804 | static int ctr_aes_encrypt(struct blkcipher_desc *desc, | ||
805 | struct scatterlist *dst, struct scatterlist *src, | ||
806 | unsigned int nbytes) | ||
807 | { | ||
808 | struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | ||
809 | struct blkcipher_walk walk; | ||
810 | |||
811 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
812 | return ctr_aes_crypt(desc, sctx->enc, sctx, &walk); | ||
813 | } | ||
814 | |||
815 | static int ctr_aes_decrypt(struct blkcipher_desc *desc, | ||
816 | struct scatterlist *dst, struct scatterlist *src, | ||
817 | unsigned int nbytes) | ||
818 | { | ||
819 | struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | ||
820 | struct blkcipher_walk walk; | ||
821 | |||
822 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
823 | return ctr_aes_crypt(desc, sctx->dec, sctx, &walk); | ||
824 | } | ||
825 | |||
826 | static struct crypto_alg ctr_aes_alg = { | ||
827 | .cra_name = "ctr(aes)", | ||
828 | .cra_driver_name = "ctr-aes-s390", | ||
829 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | ||
830 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
831 | .cra_blocksize = 1, | ||
832 | .cra_ctxsize = sizeof(struct s390_aes_ctx), | ||
833 | .cra_type = &crypto_blkcipher_type, | ||
834 | .cra_module = THIS_MODULE, | ||
835 | .cra_list = LIST_HEAD_INIT(ctr_aes_alg.cra_list), | ||
836 | .cra_u = { | ||
837 | .blkcipher = { | ||
838 | .min_keysize = AES_MIN_KEY_SIZE, | ||
839 | .max_keysize = AES_MAX_KEY_SIZE, | ||
840 | .ivsize = AES_BLOCK_SIZE, | ||
841 | .setkey = ctr_aes_set_key, | ||
842 | .encrypt = ctr_aes_encrypt, | ||
843 | .decrypt = ctr_aes_decrypt, | ||
844 | } | ||
845 | } | ||
846 | }; | ||
847 | |||
507 | static int __init aes_s390_init(void) | 848 | static int __init aes_s390_init(void) |
508 | { | 849 | { |
509 | int ret; | 850 | int ret; |
510 | 851 | ||
511 | if (crypt_s390_func_available(KM_AES_128_ENCRYPT)) | 852 | if (crypt_s390_func_available(KM_AES_128_ENCRYPT, CRYPT_S390_MSA)) |
512 | keylen_flag |= AES_KEYLEN_128; | 853 | keylen_flag |= AES_KEYLEN_128; |
513 | if (crypt_s390_func_available(KM_AES_192_ENCRYPT)) | 854 | if (crypt_s390_func_available(KM_AES_192_ENCRYPT, CRYPT_S390_MSA)) |
514 | keylen_flag |= AES_KEYLEN_192; | 855 | keylen_flag |= AES_KEYLEN_192; |
515 | if (crypt_s390_func_available(KM_AES_256_ENCRYPT)) | 856 | if (crypt_s390_func_available(KM_AES_256_ENCRYPT, CRYPT_S390_MSA)) |
516 | keylen_flag |= AES_KEYLEN_256; | 857 | keylen_flag |= AES_KEYLEN_256; |
517 | 858 | ||
518 | if (!keylen_flag) | 859 | if (!keylen_flag) |
@@ -535,9 +876,40 @@ static int __init aes_s390_init(void) | |||
535 | if (ret) | 876 | if (ret) |
536 | goto cbc_aes_err; | 877 | goto cbc_aes_err; |
537 | 878 | ||
879 | if (crypt_s390_func_available(KM_XTS_128_ENCRYPT, | ||
880 | CRYPT_S390_MSA | CRYPT_S390_MSA4) && | ||
881 | crypt_s390_func_available(KM_XTS_256_ENCRYPT, | ||
882 | CRYPT_S390_MSA | CRYPT_S390_MSA4)) { | ||
883 | ret = crypto_register_alg(&xts_aes_alg); | ||
884 | if (ret) | ||
885 | goto xts_aes_err; | ||
886 | } | ||
887 | |||
888 | if (crypt_s390_func_available(KMCTR_AES_128_ENCRYPT, | ||
889 | CRYPT_S390_MSA | CRYPT_S390_MSA4) && | ||
890 | crypt_s390_func_available(KMCTR_AES_192_ENCRYPT, | ||
891 | CRYPT_S390_MSA | CRYPT_S390_MSA4) && | ||
892 | crypt_s390_func_available(KMCTR_AES_256_ENCRYPT, | ||
893 | CRYPT_S390_MSA | CRYPT_S390_MSA4)) { | ||
894 | ctrblk = (u8 *) __get_free_page(GFP_KERNEL); | ||
895 | if (!ctrblk) { | ||
896 | ret = -ENOMEM; | ||
897 | goto ctr_aes_err; | ||
898 | } | ||
899 | ret = crypto_register_alg(&ctr_aes_alg); | ||
900 | if (ret) { | ||
901 | free_page((unsigned long) ctrblk); | ||
902 | goto ctr_aes_err; | ||
903 | } | ||
904 | } | ||
905 | |||
538 | out: | 906 | out: |
539 | return ret; | 907 | return ret; |
540 | 908 | ||
909 | ctr_aes_err: | ||
910 | crypto_unregister_alg(&xts_aes_alg); | ||
911 | xts_aes_err: | ||
912 | crypto_unregister_alg(&cbc_aes_alg); | ||
541 | cbc_aes_err: | 913 | cbc_aes_err: |
542 | crypto_unregister_alg(&ecb_aes_alg); | 914 | crypto_unregister_alg(&ecb_aes_alg); |
543 | ecb_aes_err: | 915 | ecb_aes_err: |
@@ -548,6 +920,9 @@ aes_err: | |||
548 | 920 | ||
549 | static void __exit aes_s390_fini(void) | 921 | static void __exit aes_s390_fini(void) |
550 | { | 922 | { |
923 | crypto_unregister_alg(&ctr_aes_alg); | ||
924 | free_page((unsigned long) ctrblk); | ||
925 | crypto_unregister_alg(&xts_aes_alg); | ||
551 | crypto_unregister_alg(&cbc_aes_alg); | 926 | crypto_unregister_alg(&cbc_aes_alg); |
552 | crypto_unregister_alg(&ecb_aes_alg); | 927 | crypto_unregister_alg(&ecb_aes_alg); |
553 | crypto_unregister_alg(&aes_alg); | 928 | crypto_unregister_alg(&aes_alg); |
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index 7ee9a1b4ad9f..49676771bd66 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h | |||
@@ -24,13 +24,18 @@ | |||
24 | #define CRYPT_S390_PRIORITY 300 | 24 | #define CRYPT_S390_PRIORITY 300 |
25 | #define CRYPT_S390_COMPOSITE_PRIORITY 400 | 25 | #define CRYPT_S390_COMPOSITE_PRIORITY 400 |
26 | 26 | ||
27 | #define CRYPT_S390_MSA 0x1 | ||
28 | #define CRYPT_S390_MSA3 0x2 | ||
29 | #define CRYPT_S390_MSA4 0x4 | ||
30 | |||
27 | /* s390 cryptographic operations */ | 31 | /* s390 cryptographic operations */ |
28 | enum crypt_s390_operations { | 32 | enum crypt_s390_operations { |
29 | CRYPT_S390_KM = 0x0100, | 33 | CRYPT_S390_KM = 0x0100, |
30 | CRYPT_S390_KMC = 0x0200, | 34 | CRYPT_S390_KMC = 0x0200, |
31 | CRYPT_S390_KIMD = 0x0300, | 35 | CRYPT_S390_KIMD = 0x0300, |
32 | CRYPT_S390_KLMD = 0x0400, | 36 | CRYPT_S390_KLMD = 0x0400, |
33 | CRYPT_S390_KMAC = 0x0500 | 37 | CRYPT_S390_KMAC = 0x0500, |
38 | CRYPT_S390_KMCTR = 0x0600 | ||
34 | }; | 39 | }; |
35 | 40 | ||
36 | /* | 41 | /* |
@@ -51,6 +56,10 @@ enum crypt_s390_km_func { | |||
51 | KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, | 56 | KM_AES_192_DECRYPT = CRYPT_S390_KM | 0x13 | 0x80, |
52 | KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, | 57 | KM_AES_256_ENCRYPT = CRYPT_S390_KM | 0x14, |
53 | KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, | 58 | KM_AES_256_DECRYPT = CRYPT_S390_KM | 0x14 | 0x80, |
59 | KM_XTS_128_ENCRYPT = CRYPT_S390_KM | 0x32, | ||
60 | KM_XTS_128_DECRYPT = CRYPT_S390_KM | 0x32 | 0x80, | ||
61 | KM_XTS_256_ENCRYPT = CRYPT_S390_KM | 0x34, | ||
62 | KM_XTS_256_DECRYPT = CRYPT_S390_KM | 0x34 | 0x80, | ||
54 | }; | 63 | }; |
55 | 64 | ||
56 | /* | 65 | /* |
@@ -75,6 +84,26 @@ enum crypt_s390_kmc_func { | |||
75 | }; | 84 | }; |
76 | 85 | ||
77 | /* | 86 | /* |
87 | * function codes for KMCTR (CIPHER MESSAGE WITH COUNTER) | ||
88 | * instruction | ||
89 | */ | ||
90 | enum crypt_s390_kmctr_func { | ||
91 | KMCTR_QUERY = CRYPT_S390_KMCTR | 0x0, | ||
92 | KMCTR_DEA_ENCRYPT = CRYPT_S390_KMCTR | 0x1, | ||
93 | KMCTR_DEA_DECRYPT = CRYPT_S390_KMCTR | 0x1 | 0x80, | ||
94 | KMCTR_TDEA_128_ENCRYPT = CRYPT_S390_KMCTR | 0x2, | ||
95 | KMCTR_TDEA_128_DECRYPT = CRYPT_S390_KMCTR | 0x2 | 0x80, | ||
96 | KMCTR_TDEA_192_ENCRYPT = CRYPT_S390_KMCTR | 0x3, | ||
97 | KMCTR_TDEA_192_DECRYPT = CRYPT_S390_KMCTR | 0x3 | 0x80, | ||
98 | KMCTR_AES_128_ENCRYPT = CRYPT_S390_KMCTR | 0x12, | ||
99 | KMCTR_AES_128_DECRYPT = CRYPT_S390_KMCTR | 0x12 | 0x80, | ||
100 | KMCTR_AES_192_ENCRYPT = CRYPT_S390_KMCTR | 0x13, | ||
101 | KMCTR_AES_192_DECRYPT = CRYPT_S390_KMCTR | 0x13 | 0x80, | ||
102 | KMCTR_AES_256_ENCRYPT = CRYPT_S390_KMCTR | 0x14, | ||
103 | KMCTR_AES_256_DECRYPT = CRYPT_S390_KMCTR | 0x14 | 0x80, | ||
104 | }; | ||
105 | |||
106 | /* | ||
78 | * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) | 107 | * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) |
79 | * instruction | 108 | * instruction |
80 | */ | 109 | */ |
@@ -83,6 +112,7 @@ enum crypt_s390_kimd_func { | |||
83 | KIMD_SHA_1 = CRYPT_S390_KIMD | 1, | 112 | KIMD_SHA_1 = CRYPT_S390_KIMD | 1, |
84 | KIMD_SHA_256 = CRYPT_S390_KIMD | 2, | 113 | KIMD_SHA_256 = CRYPT_S390_KIMD | 2, |
85 | KIMD_SHA_512 = CRYPT_S390_KIMD | 3, | 114 | KIMD_SHA_512 = CRYPT_S390_KIMD | 3, |
115 | KIMD_GHASH = CRYPT_S390_KIMD | 65, | ||
86 | }; | 116 | }; |
87 | 117 | ||
88 | /* | 118 | /* |
@@ -284,6 +314,45 @@ static inline int crypt_s390_kmac(long func, void *param, | |||
284 | } | 314 | } |
285 | 315 | ||
286 | /** | 316 | /** |
317 | * crypt_s390_kmctr: | ||
318 | * @func: the function code passed to KMCTR; see crypt_s390_kmctr_func | ||
319 | * @param: address of parameter block; see POP for details on each func | ||
320 | * @dest: address of destination memory area | ||
321 | * @src: address of source memory area | ||
322 | * @src_len: length of src operand in bytes | ||
323 | * @counter: address of counter value | ||
324 | * | ||
325 | * Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU. | ||
326 | * | ||
327 | * Returns -1 for failure, 0 for the query func, number of processed | ||
328 | * bytes for encryption/decryption funcs | ||
329 | */ | ||
330 | static inline int crypt_s390_kmctr(long func, void *param, u8 *dest, | ||
331 | const u8 *src, long src_len, u8 *counter) | ||
332 | { | ||
333 | register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; | ||
334 | register void *__param asm("1") = param; | ||
335 | register const u8 *__src asm("2") = src; | ||
336 | register long __src_len asm("3") = src_len; | ||
337 | register u8 *__dest asm("4") = dest; | ||
338 | register u8 *__ctr asm("6") = counter; | ||
339 | int ret = -1; | ||
340 | |||
341 | asm volatile( | ||
342 | "0: .insn rrf,0xb92d0000,%3,%1,%4,0 \n" /* KMCTR opcode */ | ||
343 | "1: brc 1,0b \n" /* handle partial completion */ | ||
344 | " la %0,0\n" | ||
345 | "2:\n" | ||
346 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | ||
347 | : "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest), | ||
348 | "+a" (__ctr) | ||
349 | : "d" (__func), "a" (__param) : "cc", "memory"); | ||
350 | if (ret < 0) | ||
351 | return ret; | ||
352 | return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; | ||
353 | } | ||
354 | |||
355 | /** | ||
287 | * crypt_s390_func_available: | 356 | * crypt_s390_func_available: |
288 | * @func: the function code of the specific function; 0 if op in general | 357 | * @func: the function code of the specific function; 0 if op in general |
289 | * | 358 | * |
@@ -291,13 +360,17 @@ static inline int crypt_s390_kmac(long func, void *param, | |||
291 | * | 360 | * |
292 | * Returns 1 if func available; 0 if func or op in general not available | 361 | * Returns 1 if func available; 0 if func or op in general not available |
293 | */ | 362 | */ |
294 | static inline int crypt_s390_func_available(int func) | 363 | static inline int crypt_s390_func_available(int func, |
364 | unsigned int facility_mask) | ||
295 | { | 365 | { |
296 | unsigned char status[16]; | 366 | unsigned char status[16]; |
297 | int ret; | 367 | int ret; |
298 | 368 | ||
299 | /* check if CPACF facility (bit 17) is available */ | 369 | if (facility_mask & CRYPT_S390_MSA && !test_facility(17)) |
300 | if (!test_facility(17)) | 370 | return 0; |
371 | if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76)) | ||
372 | return 0; | ||
373 | if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77)) | ||
301 | return 0; | 374 | return 0; |
302 | 375 | ||
303 | switch (func & CRYPT_S390_OP_MASK) { | 376 | switch (func & CRYPT_S390_OP_MASK) { |
@@ -316,6 +389,10 @@ static inline int crypt_s390_func_available(int func) | |||
316 | case CRYPT_S390_KMAC: | 389 | case CRYPT_S390_KMAC: |
317 | ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); | 390 | ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0); |
318 | break; | 391 | break; |
392 | case CRYPT_S390_KMCTR: | ||
393 | ret = crypt_s390_kmctr(KMCTR_QUERY, &status, NULL, NULL, 0, | ||
394 | NULL); | ||
395 | break; | ||
319 | default: | 396 | default: |
320 | return 0; | 397 | return 0; |
321 | } | 398 | } |
@@ -326,4 +403,31 @@ static inline int crypt_s390_func_available(int func) | |||
326 | return (status[func >> 3] & (0x80 >> (func & 7))) != 0; | 403 | return (status[func >> 3] & (0x80 >> (func & 7))) != 0; |
327 | } | 404 | } |
328 | 405 | ||
406 | /** | ||
407 | * crypt_s390_pcc: | ||
408 | * @func: the function code passed to KM; see crypt_s390_km_func | ||
409 | * @param: address of parameter block; see POP for details on each func | ||
410 | * | ||
411 | * Executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) operation of the CPU. | ||
412 | * | ||
413 | * Returns -1 for failure, 0 for success. | ||
414 | */ | ||
415 | static inline int crypt_s390_pcc(long func, void *param) | ||
416 | { | ||
417 | register long __func asm("0") = func & 0x7f; /* encrypt or decrypt */ | ||
418 | register void *__param asm("1") = param; | ||
419 | int ret = -1; | ||
420 | |||
421 | asm volatile( | ||
422 | "0: .insn rre,0xb92c0000,0,0 \n" /* PCC opcode */ | ||
423 | "1: brc 1,0b \n" /* handle partial completion */ | ||
424 | " la %0,0\n" | ||
425 | "2:\n" | ||
426 | EX_TABLE(0b,2b) EX_TABLE(1b,2b) | ||
427 | : "+d" (ret) | ||
428 | : "d" (__func), "a" (__param) : "cc", "memory"); | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | |||
329 | #endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ | 433 | #endif /* _CRYPTO_ARCH_S390_CRYPT_S390_H */ |
diff --git a/arch/s390/crypto/des_check_key.c b/arch/s390/crypto/des_check_key.c deleted file mode 100644 index 5706af266442..000000000000 --- a/arch/s390/crypto/des_check_key.c +++ /dev/null | |||
@@ -1,132 +0,0 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * Function for checking keys for the DES and Tripple DES Encryption | ||
5 | * algorithms. | ||
6 | * | ||
7 | * Originally released as descore by Dana L. How <how@isl.stanford.edu>. | ||
8 | * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel. | ||
9 | * Derived from Cryptoapi and Nettle implementations, adapted for in-place | ||
10 | * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL. | ||
11 | * | ||
12 | * s390 Version: | ||
13 | * Copyright IBM Corp. 2003 | ||
14 | * Author(s): Thomas Spatzier | ||
15 | * Jan Glauber (jan.glauber@de.ibm.com) | ||
16 | * | ||
17 | * Derived from "crypto/des.c" | ||
18 | * Copyright (c) 1992 Dana L. How. | ||
19 | * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de> | ||
20 | * Copyright (c) Gisle Sflensminde <gisle@ii.uib.no> | ||
21 | * Copyright (C) 2001 Niels Mvller. | ||
22 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | ||
23 | * | ||
24 | * This program is free software; you can redistribute it and/or modify | ||
25 | * it under the terms of the GNU General Public License as published by | ||
26 | * the Free Software Foundation; either version 2 of the License, or | ||
27 | * (at your option) any later version. | ||
28 | * | ||
29 | */ | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/crypto.h> | ||
34 | #include "crypto_des.h" | ||
35 | |||
36 | #define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o)) | ||
37 | |||
38 | static const u8 parity[] = { | ||
39 | 8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3, | ||
40 | 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, | ||
41 | 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, | ||
42 | 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, | ||
43 | 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, | ||
44 | 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, | ||
45 | 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, | ||
46 | 4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8, | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * RFC2451: Weak key checks SHOULD be performed. | ||
51 | */ | ||
52 | int | ||
53 | crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags) | ||
54 | { | ||
55 | u32 n, w; | ||
56 | |||
57 | n = parity[key[0]]; n <<= 4; | ||
58 | n |= parity[key[1]]; n <<= 4; | ||
59 | n |= parity[key[2]]; n <<= 4; | ||
60 | n |= parity[key[3]]; n <<= 4; | ||
61 | n |= parity[key[4]]; n <<= 4; | ||
62 | n |= parity[key[5]]; n <<= 4; | ||
63 | n |= parity[key[6]]; n <<= 4; | ||
64 | n |= parity[key[7]]; | ||
65 | w = 0x88888888L; | ||
66 | |||
67 | if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) | ||
68 | && !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */ | ||
69 | if (n < 0x41415151) { | ||
70 | if (n < 0x31312121) { | ||
71 | if (n < 0x14141515) { | ||
72 | /* 01 01 01 01 01 01 01 01 */ | ||
73 | if (n == 0x11111111) goto weak; | ||
74 | /* 01 1F 01 1F 01 0E 01 0E */ | ||
75 | if (n == 0x13131212) goto weak; | ||
76 | } else { | ||
77 | /* 01 E0 01 E0 01 F1 01 F1 */ | ||
78 | if (n == 0x14141515) goto weak; | ||
79 | /* 01 FE 01 FE 01 FE 01 FE */ | ||
80 | if (n == 0x16161616) goto weak; | ||
81 | } | ||
82 | } else { | ||
83 | if (n < 0x34342525) { | ||
84 | /* 1F 01 1F 01 0E 01 0E 01 */ | ||
85 | if (n == 0x31312121) goto weak; | ||
86 | /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */ | ||
87 | if (n == 0x33332222) goto weak; | ||
88 | } else { | ||
89 | /* 1F E0 1F E0 0E F1 0E F1 */ | ||
90 | if (n == 0x34342525) goto weak; | ||
91 | /* 1F FE 1F FE 0E FE 0E FE */ | ||
92 | if (n == 0x36362626) goto weak; | ||
93 | } | ||
94 | } | ||
95 | } else { | ||
96 | if (n < 0x61616161) { | ||
97 | if (n < 0x44445555) { | ||
98 | /* E0 01 E0 01 F1 01 F1 01 */ | ||
99 | if (n == 0x41415151) goto weak; | ||
100 | /* E0 1F E0 1F F1 0E F1 0E */ | ||
101 | if (n == 0x43435252) goto weak; | ||
102 | } else { | ||
103 | /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */ | ||
104 | if (n == 0x44445555) goto weak; | ||
105 | /* E0 FE E0 FE F1 FE F1 FE */ | ||
106 | if (n == 0x46465656) goto weak; | ||
107 | } | ||
108 | } else { | ||
109 | if (n < 0x64646565) { | ||
110 | /* FE 01 FE 01 FE 01 FE 01 */ | ||
111 | if (n == 0x61616161) goto weak; | ||
112 | /* FE 1F FE 1F FE 0E FE 0E */ | ||
113 | if (n == 0x63636262) goto weak; | ||
114 | } else { | ||
115 | /* FE E0 FE E0 FE F1 FE F1 */ | ||
116 | if (n == 0x64646565) goto weak; | ||
117 | /* FE FE FE FE FE FE FE FE */ | ||
118 | if (n == 0x66666666) goto weak; | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | return 0; | ||
124 | weak: | ||
125 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | |||
129 | EXPORT_SYMBOL(crypto_des_check_key); | ||
130 | |||
131 | MODULE_LICENSE("GPL"); | ||
132 | MODULE_DESCRIPTION("Key Check function for DES & DES3 Cipher Algorithms"); | ||
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index cc5420118393..a52bfd124d86 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * s390 implementation of the DES Cipher Algorithm. | 4 | * s390 implementation of the DES Cipher Algorithm. |
5 | * | 5 | * |
6 | * Copyright IBM Corp. 2003,2007 | 6 | * Copyright IBM Corp. 2003,2011 |
7 | * Author(s): Thomas Spatzier | 7 | * Author(s): Thomas Spatzier |
8 | * Jan Glauber (jan.glauber@de.ibm.com) | 8 | * Jan Glauber (jan.glauber@de.ibm.com) |
9 | * | 9 | * |
@@ -22,22 +22,19 @@ | |||
22 | 22 | ||
23 | #include "crypt_s390.h" | 23 | #include "crypt_s390.h" |
24 | 24 | ||
25 | #define DES3_192_KEY_SIZE (3 * DES_KEY_SIZE) | 25 | #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) |
26 | 26 | ||
27 | struct crypt_s390_des_ctx { | 27 | static u8 *ctrblk; |
28 | u8 iv[DES_BLOCK_SIZE]; | ||
29 | u8 key[DES_KEY_SIZE]; | ||
30 | }; | ||
31 | 28 | ||
32 | struct crypt_s390_des3_192_ctx { | 29 | struct s390_des_ctx { |
33 | u8 iv[DES_BLOCK_SIZE]; | 30 | u8 iv[DES_BLOCK_SIZE]; |
34 | u8 key[DES3_192_KEY_SIZE]; | 31 | u8 key[DES3_KEY_SIZE]; |
35 | }; | 32 | }; |
36 | 33 | ||
37 | static int des_setkey(struct crypto_tfm *tfm, const u8 *key, | 34 | static int des_setkey(struct crypto_tfm *tfm, const u8 *key, |
38 | unsigned int keylen) | 35 | unsigned int key_len) |
39 | { | 36 | { |
40 | struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); | 37 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); |
41 | u32 *flags = &tfm->crt_flags; | 38 | u32 *flags = &tfm->crt_flags; |
42 | u32 tmp[DES_EXPKEY_WORDS]; | 39 | u32 tmp[DES_EXPKEY_WORDS]; |
43 | 40 | ||
@@ -47,22 +44,22 @@ static int des_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
47 | return -EINVAL; | 44 | return -EINVAL; |
48 | } | 45 | } |
49 | 46 | ||
50 | memcpy(dctx->key, key, keylen); | 47 | memcpy(ctx->key, key, key_len); |
51 | return 0; | 48 | return 0; |
52 | } | 49 | } |
53 | 50 | ||
54 | static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | 51 | static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) |
55 | { | 52 | { |
56 | struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); | 53 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); |
57 | 54 | ||
58 | crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE); | 55 | crypt_s390_km(KM_DEA_ENCRYPT, ctx->key, out, in, DES_BLOCK_SIZE); |
59 | } | 56 | } |
60 | 57 | ||
61 | static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | 58 | static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) |
62 | { | 59 | { |
63 | struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); | 60 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); |
64 | 61 | ||
65 | crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE); | 62 | crypt_s390_km(KM_DEA_DECRYPT, ctx->key, out, in, DES_BLOCK_SIZE); |
66 | } | 63 | } |
67 | 64 | ||
68 | static struct crypto_alg des_alg = { | 65 | static struct crypto_alg des_alg = { |
@@ -71,7 +68,7 @@ static struct crypto_alg des_alg = { | |||
71 | .cra_priority = CRYPT_S390_PRIORITY, | 68 | .cra_priority = CRYPT_S390_PRIORITY, |
72 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | 69 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, |
73 | .cra_blocksize = DES_BLOCK_SIZE, | 70 | .cra_blocksize = DES_BLOCK_SIZE, |
74 | .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), | 71 | .cra_ctxsize = sizeof(struct s390_des_ctx), |
75 | .cra_module = THIS_MODULE, | 72 | .cra_module = THIS_MODULE, |
76 | .cra_list = LIST_HEAD_INIT(des_alg.cra_list), | 73 | .cra_list = LIST_HEAD_INIT(des_alg.cra_list), |
77 | .cra_u = { | 74 | .cra_u = { |
@@ -86,7 +83,7 @@ static struct crypto_alg des_alg = { | |||
86 | }; | 83 | }; |
87 | 84 | ||
88 | static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, | 85 | static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, |
89 | void *param, struct blkcipher_walk *walk) | 86 | u8 *key, struct blkcipher_walk *walk) |
90 | { | 87 | { |
91 | int ret = blkcipher_walk_virt(desc, walk); | 88 | int ret = blkcipher_walk_virt(desc, walk); |
92 | unsigned int nbytes; | 89 | unsigned int nbytes; |
@@ -97,7 +94,7 @@ static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, | |||
97 | u8 *out = walk->dst.virt.addr; | 94 | u8 *out = walk->dst.virt.addr; |
98 | u8 *in = walk->src.virt.addr; | 95 | u8 *in = walk->src.virt.addr; |
99 | 96 | ||
100 | ret = crypt_s390_km(func, param, out, in, n); | 97 | ret = crypt_s390_km(func, key, out, in, n); |
101 | BUG_ON((ret < 0) || (ret != n)); | 98 | BUG_ON((ret < 0) || (ret != n)); |
102 | 99 | ||
103 | nbytes &= DES_BLOCK_SIZE - 1; | 100 | nbytes &= DES_BLOCK_SIZE - 1; |
@@ -108,7 +105,7 @@ static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, | |||
108 | } | 105 | } |
109 | 106 | ||
110 | static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, | 107 | static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, |
111 | void *param, struct blkcipher_walk *walk) | 108 | u8 *iv, struct blkcipher_walk *walk) |
112 | { | 109 | { |
113 | int ret = blkcipher_walk_virt(desc, walk); | 110 | int ret = blkcipher_walk_virt(desc, walk); |
114 | unsigned int nbytes = walk->nbytes; | 111 | unsigned int nbytes = walk->nbytes; |
@@ -116,20 +113,20 @@ static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, | |||
116 | if (!nbytes) | 113 | if (!nbytes) |
117 | goto out; | 114 | goto out; |
118 | 115 | ||
119 | memcpy(param, walk->iv, DES_BLOCK_SIZE); | 116 | memcpy(iv, walk->iv, DES_BLOCK_SIZE); |
120 | do { | 117 | do { |
121 | /* only use complete blocks */ | 118 | /* only use complete blocks */ |
122 | unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); | 119 | unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); |
123 | u8 *out = walk->dst.virt.addr; | 120 | u8 *out = walk->dst.virt.addr; |
124 | u8 *in = walk->src.virt.addr; | 121 | u8 *in = walk->src.virt.addr; |
125 | 122 | ||
126 | ret = crypt_s390_kmc(func, param, out, in, n); | 123 | ret = crypt_s390_kmc(func, iv, out, in, n); |
127 | BUG_ON((ret < 0) || (ret != n)); | 124 | BUG_ON((ret < 0) || (ret != n)); |
128 | 125 | ||
129 | nbytes &= DES_BLOCK_SIZE - 1; | 126 | nbytes &= DES_BLOCK_SIZE - 1; |
130 | ret = blkcipher_walk_done(desc, walk, nbytes); | 127 | ret = blkcipher_walk_done(desc, walk, nbytes); |
131 | } while ((nbytes = walk->nbytes)); | 128 | } while ((nbytes = walk->nbytes)); |
132 | memcpy(walk->iv, param, DES_BLOCK_SIZE); | 129 | memcpy(walk->iv, iv, DES_BLOCK_SIZE); |
133 | 130 | ||
134 | out: | 131 | out: |
135 | return ret; | 132 | return ret; |
@@ -139,22 +136,22 @@ static int ecb_des_encrypt(struct blkcipher_desc *desc, | |||
139 | struct scatterlist *dst, struct scatterlist *src, | 136 | struct scatterlist *dst, struct scatterlist *src, |
140 | unsigned int nbytes) | 137 | unsigned int nbytes) |
141 | { | 138 | { |
142 | struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 139 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
143 | struct blkcipher_walk walk; | 140 | struct blkcipher_walk walk; |
144 | 141 | ||
145 | blkcipher_walk_init(&walk, dst, src, nbytes); | 142 | blkcipher_walk_init(&walk, dst, src, nbytes); |
146 | return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk); | 143 | return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, ctx->key, &walk); |
147 | } | 144 | } |
148 | 145 | ||
149 | static int ecb_des_decrypt(struct blkcipher_desc *desc, | 146 | static int ecb_des_decrypt(struct blkcipher_desc *desc, |
150 | struct scatterlist *dst, struct scatterlist *src, | 147 | struct scatterlist *dst, struct scatterlist *src, |
151 | unsigned int nbytes) | 148 | unsigned int nbytes) |
152 | { | 149 | { |
153 | struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 150 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
154 | struct blkcipher_walk walk; | 151 | struct blkcipher_walk walk; |
155 | 152 | ||
156 | blkcipher_walk_init(&walk, dst, src, nbytes); | 153 | blkcipher_walk_init(&walk, dst, src, nbytes); |
157 | return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk); | 154 | return ecb_desall_crypt(desc, KM_DEA_DECRYPT, ctx->key, &walk); |
158 | } | 155 | } |
159 | 156 | ||
160 | static struct crypto_alg ecb_des_alg = { | 157 | static struct crypto_alg ecb_des_alg = { |
@@ -163,7 +160,7 @@ static struct crypto_alg ecb_des_alg = { | |||
163 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | 160 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, |
164 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 161 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, |
165 | .cra_blocksize = DES_BLOCK_SIZE, | 162 | .cra_blocksize = DES_BLOCK_SIZE, |
166 | .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), | 163 | .cra_ctxsize = sizeof(struct s390_des_ctx), |
167 | .cra_type = &crypto_blkcipher_type, | 164 | .cra_type = &crypto_blkcipher_type, |
168 | .cra_module = THIS_MODULE, | 165 | .cra_module = THIS_MODULE, |
169 | .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list), | 166 | .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list), |
@@ -182,22 +179,22 @@ static int cbc_des_encrypt(struct blkcipher_desc *desc, | |||
182 | struct scatterlist *dst, struct scatterlist *src, | 179 | struct scatterlist *dst, struct scatterlist *src, |
183 | unsigned int nbytes) | 180 | unsigned int nbytes) |
184 | { | 181 | { |
185 | struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 182 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
186 | struct blkcipher_walk walk; | 183 | struct blkcipher_walk walk; |
187 | 184 | ||
188 | blkcipher_walk_init(&walk, dst, src, nbytes); | 185 | blkcipher_walk_init(&walk, dst, src, nbytes); |
189 | return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk); | 186 | return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk); |
190 | } | 187 | } |
191 | 188 | ||
192 | static int cbc_des_decrypt(struct blkcipher_desc *desc, | 189 | static int cbc_des_decrypt(struct blkcipher_desc *desc, |
193 | struct scatterlist *dst, struct scatterlist *src, | 190 | struct scatterlist *dst, struct scatterlist *src, |
194 | unsigned int nbytes) | 191 | unsigned int nbytes) |
195 | { | 192 | { |
196 | struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 193 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
197 | struct blkcipher_walk walk; | 194 | struct blkcipher_walk walk; |
198 | 195 | ||
199 | blkcipher_walk_init(&walk, dst, src, nbytes); | 196 | blkcipher_walk_init(&walk, dst, src, nbytes); |
200 | return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk); | 197 | return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk); |
201 | } | 198 | } |
202 | 199 | ||
203 | static struct crypto_alg cbc_des_alg = { | 200 | static struct crypto_alg cbc_des_alg = { |
@@ -206,7 +203,7 @@ static struct crypto_alg cbc_des_alg = { | |||
206 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | 203 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, |
207 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 204 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, |
208 | .cra_blocksize = DES_BLOCK_SIZE, | 205 | .cra_blocksize = DES_BLOCK_SIZE, |
209 | .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), | 206 | .cra_ctxsize = sizeof(struct s390_des_ctx), |
210 | .cra_type = &crypto_blkcipher_type, | 207 | .cra_type = &crypto_blkcipher_type, |
211 | .cra_module = THIS_MODULE, | 208 | .cra_module = THIS_MODULE, |
212 | .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list), | 209 | .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list), |
@@ -235,10 +232,10 @@ static struct crypto_alg cbc_des_alg = { | |||
235 | * property. | 232 | * property. |
236 | * | 233 | * |
237 | */ | 234 | */ |
238 | static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, | 235 | static int des3_setkey(struct crypto_tfm *tfm, const u8 *key, |
239 | unsigned int keylen) | 236 | unsigned int key_len) |
240 | { | 237 | { |
241 | struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); | 238 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); |
242 | u32 *flags = &tfm->crt_flags; | 239 | u32 *flags = &tfm->crt_flags; |
243 | 240 | ||
244 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && | 241 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && |
@@ -248,141 +245,276 @@ static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
248 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | 245 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; |
249 | return -EINVAL; | 246 | return -EINVAL; |
250 | } | 247 | } |
251 | memcpy(dctx->key, key, keylen); | 248 | memcpy(ctx->key, key, key_len); |
252 | return 0; | 249 | return 0; |
253 | } | 250 | } |
254 | 251 | ||
255 | static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | 252 | static void des3_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) |
256 | { | 253 | { |
257 | struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); | 254 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); |
258 | 255 | ||
259 | crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src, | 256 | crypt_s390_km(KM_TDEA_192_ENCRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); |
260 | DES_BLOCK_SIZE); | ||
261 | } | 257 | } |
262 | 258 | ||
263 | static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | 259 | static void des3_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) |
264 | { | 260 | { |
265 | struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); | 261 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); |
266 | 262 | ||
267 | crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src, | 263 | crypt_s390_km(KM_TDEA_192_DECRYPT, ctx->key, dst, src, DES_BLOCK_SIZE); |
268 | DES_BLOCK_SIZE); | ||
269 | } | 264 | } |
270 | 265 | ||
271 | static struct crypto_alg des3_192_alg = { | 266 | static struct crypto_alg des3_alg = { |
272 | .cra_name = "des3_ede", | 267 | .cra_name = "des3_ede", |
273 | .cra_driver_name = "des3_ede-s390", | 268 | .cra_driver_name = "des3_ede-s390", |
274 | .cra_priority = CRYPT_S390_PRIORITY, | 269 | .cra_priority = CRYPT_S390_PRIORITY, |
275 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | 270 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, |
276 | .cra_blocksize = DES_BLOCK_SIZE, | 271 | .cra_blocksize = DES_BLOCK_SIZE, |
277 | .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), | 272 | .cra_ctxsize = sizeof(struct s390_des_ctx), |
278 | .cra_module = THIS_MODULE, | 273 | .cra_module = THIS_MODULE, |
279 | .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), | 274 | .cra_list = LIST_HEAD_INIT(des3_alg.cra_list), |
280 | .cra_u = { | 275 | .cra_u = { |
281 | .cipher = { | 276 | .cipher = { |
282 | .cia_min_keysize = DES3_192_KEY_SIZE, | 277 | .cia_min_keysize = DES3_KEY_SIZE, |
283 | .cia_max_keysize = DES3_192_KEY_SIZE, | 278 | .cia_max_keysize = DES3_KEY_SIZE, |
284 | .cia_setkey = des3_192_setkey, | 279 | .cia_setkey = des3_setkey, |
285 | .cia_encrypt = des3_192_encrypt, | 280 | .cia_encrypt = des3_encrypt, |
286 | .cia_decrypt = des3_192_decrypt, | 281 | .cia_decrypt = des3_decrypt, |
287 | } | 282 | } |
288 | } | 283 | } |
289 | }; | 284 | }; |
290 | 285 | ||
291 | static int ecb_des3_192_encrypt(struct blkcipher_desc *desc, | 286 | static int ecb_des3_encrypt(struct blkcipher_desc *desc, |
292 | struct scatterlist *dst, | 287 | struct scatterlist *dst, struct scatterlist *src, |
293 | struct scatterlist *src, unsigned int nbytes) | 288 | unsigned int nbytes) |
294 | { | 289 | { |
295 | struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 290 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
296 | struct blkcipher_walk walk; | 291 | struct blkcipher_walk walk; |
297 | 292 | ||
298 | blkcipher_walk_init(&walk, dst, src, nbytes); | 293 | blkcipher_walk_init(&walk, dst, src, nbytes); |
299 | return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk); | 294 | return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, ctx->key, &walk); |
300 | } | 295 | } |
301 | 296 | ||
302 | static int ecb_des3_192_decrypt(struct blkcipher_desc *desc, | 297 | static int ecb_des3_decrypt(struct blkcipher_desc *desc, |
303 | struct scatterlist *dst, | 298 | struct scatterlist *dst, struct scatterlist *src, |
304 | struct scatterlist *src, unsigned int nbytes) | 299 | unsigned int nbytes) |
305 | { | 300 | { |
306 | struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 301 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
307 | struct blkcipher_walk walk; | 302 | struct blkcipher_walk walk; |
308 | 303 | ||
309 | blkcipher_walk_init(&walk, dst, src, nbytes); | 304 | blkcipher_walk_init(&walk, dst, src, nbytes); |
310 | return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk); | 305 | return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, ctx->key, &walk); |
311 | } | 306 | } |
312 | 307 | ||
313 | static struct crypto_alg ecb_des3_192_alg = { | 308 | static struct crypto_alg ecb_des3_alg = { |
314 | .cra_name = "ecb(des3_ede)", | 309 | .cra_name = "ecb(des3_ede)", |
315 | .cra_driver_name = "ecb-des3_ede-s390", | 310 | .cra_driver_name = "ecb-des3_ede-s390", |
316 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | 311 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, |
317 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 312 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, |
318 | .cra_blocksize = DES_BLOCK_SIZE, | 313 | .cra_blocksize = DES_BLOCK_SIZE, |
319 | .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), | 314 | .cra_ctxsize = sizeof(struct s390_des_ctx), |
320 | .cra_type = &crypto_blkcipher_type, | 315 | .cra_type = &crypto_blkcipher_type, |
321 | .cra_module = THIS_MODULE, | 316 | .cra_module = THIS_MODULE, |
322 | .cra_list = LIST_HEAD_INIT( | 317 | .cra_list = LIST_HEAD_INIT( |
323 | ecb_des3_192_alg.cra_list), | 318 | ecb_des3_alg.cra_list), |
324 | .cra_u = { | 319 | .cra_u = { |
325 | .blkcipher = { | 320 | .blkcipher = { |
326 | .min_keysize = DES3_192_KEY_SIZE, | 321 | .min_keysize = DES3_KEY_SIZE, |
327 | .max_keysize = DES3_192_KEY_SIZE, | 322 | .max_keysize = DES3_KEY_SIZE, |
328 | .setkey = des3_192_setkey, | 323 | .setkey = des3_setkey, |
329 | .encrypt = ecb_des3_192_encrypt, | 324 | .encrypt = ecb_des3_encrypt, |
330 | .decrypt = ecb_des3_192_decrypt, | 325 | .decrypt = ecb_des3_decrypt, |
331 | } | 326 | } |
332 | } | 327 | } |
333 | }; | 328 | }; |
334 | 329 | ||
335 | static int cbc_des3_192_encrypt(struct blkcipher_desc *desc, | 330 | static int cbc_des3_encrypt(struct blkcipher_desc *desc, |
336 | struct scatterlist *dst, | 331 | struct scatterlist *dst, struct scatterlist *src, |
337 | struct scatterlist *src, unsigned int nbytes) | 332 | unsigned int nbytes) |
338 | { | 333 | { |
339 | struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 334 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
340 | struct blkcipher_walk walk; | 335 | struct blkcipher_walk walk; |
341 | 336 | ||
342 | blkcipher_walk_init(&walk, dst, src, nbytes); | 337 | blkcipher_walk_init(&walk, dst, src, nbytes); |
343 | return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk); | 338 | return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk); |
344 | } | 339 | } |
345 | 340 | ||
346 | static int cbc_des3_192_decrypt(struct blkcipher_desc *desc, | 341 | static int cbc_des3_decrypt(struct blkcipher_desc *desc, |
347 | struct scatterlist *dst, | 342 | struct scatterlist *dst, struct scatterlist *src, |
348 | struct scatterlist *src, unsigned int nbytes) | 343 | unsigned int nbytes) |
349 | { | 344 | { |
350 | struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm); | 345 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); |
351 | struct blkcipher_walk walk; | 346 | struct blkcipher_walk walk; |
352 | 347 | ||
353 | blkcipher_walk_init(&walk, dst, src, nbytes); | 348 | blkcipher_walk_init(&walk, dst, src, nbytes); |
354 | return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk); | 349 | return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk); |
355 | } | 350 | } |
356 | 351 | ||
357 | static struct crypto_alg cbc_des3_192_alg = { | 352 | static struct crypto_alg cbc_des3_alg = { |
358 | .cra_name = "cbc(des3_ede)", | 353 | .cra_name = "cbc(des3_ede)", |
359 | .cra_driver_name = "cbc-des3_ede-s390", | 354 | .cra_driver_name = "cbc-des3_ede-s390", |
360 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | 355 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, |
361 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 356 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, |
362 | .cra_blocksize = DES_BLOCK_SIZE, | 357 | .cra_blocksize = DES_BLOCK_SIZE, |
363 | .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), | 358 | .cra_ctxsize = sizeof(struct s390_des_ctx), |
364 | .cra_type = &crypto_blkcipher_type, | 359 | .cra_type = &crypto_blkcipher_type, |
365 | .cra_module = THIS_MODULE, | 360 | .cra_module = THIS_MODULE, |
366 | .cra_list = LIST_HEAD_INIT( | 361 | .cra_list = LIST_HEAD_INIT( |
367 | cbc_des3_192_alg.cra_list), | 362 | cbc_des3_alg.cra_list), |
368 | .cra_u = { | 363 | .cra_u = { |
369 | .blkcipher = { | 364 | .blkcipher = { |
370 | .min_keysize = DES3_192_KEY_SIZE, | 365 | .min_keysize = DES3_KEY_SIZE, |
371 | .max_keysize = DES3_192_KEY_SIZE, | 366 | .max_keysize = DES3_KEY_SIZE, |
372 | .ivsize = DES_BLOCK_SIZE, | 367 | .ivsize = DES_BLOCK_SIZE, |
373 | .setkey = des3_192_setkey, | 368 | .setkey = des3_setkey, |
374 | .encrypt = cbc_des3_192_encrypt, | 369 | .encrypt = cbc_des3_encrypt, |
375 | .decrypt = cbc_des3_192_decrypt, | 370 | .decrypt = cbc_des3_decrypt, |
376 | } | 371 | } |
377 | } | 372 | } |
378 | }; | 373 | }; |
379 | 374 | ||
380 | static int des_s390_init(void) | 375 | static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, |
376 | struct s390_des_ctx *ctx, struct blkcipher_walk *walk) | ||
377 | { | ||
378 | int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); | ||
379 | unsigned int i, n, nbytes; | ||
380 | u8 buf[DES_BLOCK_SIZE]; | ||
381 | u8 *out, *in; | ||
382 | |||
383 | memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE); | ||
384 | while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { | ||
385 | out = walk->dst.virt.addr; | ||
386 | in = walk->src.virt.addr; | ||
387 | while (nbytes >= DES_BLOCK_SIZE) { | ||
388 | /* align to block size, max. PAGE_SIZE */ | ||
389 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : | ||
390 | nbytes & ~(DES_BLOCK_SIZE - 1); | ||
391 | for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { | ||
392 | memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE, | ||
393 | DES_BLOCK_SIZE); | ||
394 | crypto_inc(ctrblk + i, DES_BLOCK_SIZE); | ||
395 | } | ||
396 | ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk); | ||
397 | BUG_ON((ret < 0) || (ret != n)); | ||
398 | if (n > DES_BLOCK_SIZE) | ||
399 | memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE, | ||
400 | DES_BLOCK_SIZE); | ||
401 | crypto_inc(ctrblk, DES_BLOCK_SIZE); | ||
402 | out += n; | ||
403 | in += n; | ||
404 | nbytes -= n; | ||
405 | } | ||
406 | ret = blkcipher_walk_done(desc, walk, nbytes); | ||
407 | } | ||
408 | |||
409 | /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ | ||
410 | if (nbytes) { | ||
411 | out = walk->dst.virt.addr; | ||
412 | in = walk->src.virt.addr; | ||
413 | ret = crypt_s390_kmctr(func, ctx->key, buf, in, | ||
414 | DES_BLOCK_SIZE, ctrblk); | ||
415 | BUG_ON(ret < 0 || ret != DES_BLOCK_SIZE); | ||
416 | memcpy(out, buf, nbytes); | ||
417 | crypto_inc(ctrblk, DES_BLOCK_SIZE); | ||
418 | ret = blkcipher_walk_done(desc, walk, 0); | ||
419 | } | ||
420 | memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE); | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | static int ctr_des_encrypt(struct blkcipher_desc *desc, | ||
425 | struct scatterlist *dst, struct scatterlist *src, | ||
426 | unsigned int nbytes) | ||
427 | { | ||
428 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
429 | struct blkcipher_walk walk; | ||
430 | |||
431 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
432 | return ctr_desall_crypt(desc, KMCTR_DEA_ENCRYPT, ctx, &walk); | ||
433 | } | ||
434 | |||
435 | static int ctr_des_decrypt(struct blkcipher_desc *desc, | ||
436 | struct scatterlist *dst, struct scatterlist *src, | ||
437 | unsigned int nbytes) | ||
438 | { | ||
439 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
440 | struct blkcipher_walk walk; | ||
441 | |||
442 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
443 | return ctr_desall_crypt(desc, KMCTR_DEA_DECRYPT, ctx, &walk); | ||
444 | } | ||
445 | |||
446 | static struct crypto_alg ctr_des_alg = { | ||
447 | .cra_name = "ctr(des)", | ||
448 | .cra_driver_name = "ctr-des-s390", | ||
449 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | ||
450 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
451 | .cra_blocksize = 1, | ||
452 | .cra_ctxsize = sizeof(struct s390_des_ctx), | ||
453 | .cra_type = &crypto_blkcipher_type, | ||
454 | .cra_module = THIS_MODULE, | ||
455 | .cra_list = LIST_HEAD_INIT(ctr_des_alg.cra_list), | ||
456 | .cra_u = { | ||
457 | .blkcipher = { | ||
458 | .min_keysize = DES_KEY_SIZE, | ||
459 | .max_keysize = DES_KEY_SIZE, | ||
460 | .ivsize = DES_BLOCK_SIZE, | ||
461 | .setkey = des_setkey, | ||
462 | .encrypt = ctr_des_encrypt, | ||
463 | .decrypt = ctr_des_decrypt, | ||
464 | } | ||
465 | } | ||
466 | }; | ||
467 | |||
468 | static int ctr_des3_encrypt(struct blkcipher_desc *desc, | ||
469 | struct scatterlist *dst, struct scatterlist *src, | ||
470 | unsigned int nbytes) | ||
471 | { | ||
472 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
473 | struct blkcipher_walk walk; | ||
474 | |||
475 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
476 | return ctr_desall_crypt(desc, KMCTR_TDEA_192_ENCRYPT, ctx, &walk); | ||
477 | } | ||
478 | |||
479 | static int ctr_des3_decrypt(struct blkcipher_desc *desc, | ||
480 | struct scatterlist *dst, struct scatterlist *src, | ||
481 | unsigned int nbytes) | ||
482 | { | ||
483 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
484 | struct blkcipher_walk walk; | ||
485 | |||
486 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
487 | return ctr_desall_crypt(desc, KMCTR_TDEA_192_DECRYPT, ctx, &walk); | ||
488 | } | ||
489 | |||
490 | static struct crypto_alg ctr_des3_alg = { | ||
491 | .cra_name = "ctr(des3_ede)", | ||
492 | .cra_driver_name = "ctr-des3_ede-s390", | ||
493 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | ||
494 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
495 | .cra_blocksize = 1, | ||
496 | .cra_ctxsize = sizeof(struct s390_des_ctx), | ||
497 | .cra_type = &crypto_blkcipher_type, | ||
498 | .cra_module = THIS_MODULE, | ||
499 | .cra_list = LIST_HEAD_INIT(ctr_des3_alg.cra_list), | ||
500 | .cra_u = { | ||
501 | .blkcipher = { | ||
502 | .min_keysize = DES3_KEY_SIZE, | ||
503 | .max_keysize = DES3_KEY_SIZE, | ||
504 | .ivsize = DES_BLOCK_SIZE, | ||
505 | .setkey = des3_setkey, | ||
506 | .encrypt = ctr_des3_encrypt, | ||
507 | .decrypt = ctr_des3_decrypt, | ||
508 | } | ||
509 | } | ||
510 | }; | ||
511 | |||
512 | static int __init des_s390_init(void) | ||
381 | { | 513 | { |
382 | int ret; | 514 | int ret; |
383 | 515 | ||
384 | if (!crypt_s390_func_available(KM_DEA_ENCRYPT) || | 516 | if (!crypt_s390_func_available(KM_DEA_ENCRYPT, CRYPT_S390_MSA) || |
385 | !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)) | 517 | !crypt_s390_func_available(KM_TDEA_192_ENCRYPT, CRYPT_S390_MSA)) |
386 | return -EOPNOTSUPP; | 518 | return -EOPNOTSUPP; |
387 | 519 | ||
388 | ret = crypto_register_alg(&des_alg); | 520 | ret = crypto_register_alg(&des_alg); |
@@ -394,23 +526,46 @@ static int des_s390_init(void) | |||
394 | ret = crypto_register_alg(&cbc_des_alg); | 526 | ret = crypto_register_alg(&cbc_des_alg); |
395 | if (ret) | 527 | if (ret) |
396 | goto cbc_des_err; | 528 | goto cbc_des_err; |
397 | ret = crypto_register_alg(&des3_192_alg); | 529 | ret = crypto_register_alg(&des3_alg); |
398 | if (ret) | 530 | if (ret) |
399 | goto des3_192_err; | 531 | goto des3_err; |
400 | ret = crypto_register_alg(&ecb_des3_192_alg); | 532 | ret = crypto_register_alg(&ecb_des3_alg); |
401 | if (ret) | 533 | if (ret) |
402 | goto ecb_des3_192_err; | 534 | goto ecb_des3_err; |
403 | ret = crypto_register_alg(&cbc_des3_192_alg); | 535 | ret = crypto_register_alg(&cbc_des3_alg); |
404 | if (ret) | 536 | if (ret) |
405 | goto cbc_des3_192_err; | 537 | goto cbc_des3_err; |
538 | |||
539 | if (crypt_s390_func_available(KMCTR_DEA_ENCRYPT, | ||
540 | CRYPT_S390_MSA | CRYPT_S390_MSA4) && | ||
541 | crypt_s390_func_available(KMCTR_TDEA_192_ENCRYPT, | ||
542 | CRYPT_S390_MSA | CRYPT_S390_MSA4)) { | ||
543 | ret = crypto_register_alg(&ctr_des_alg); | ||
544 | if (ret) | ||
545 | goto ctr_des_err; | ||
546 | ret = crypto_register_alg(&ctr_des3_alg); | ||
547 | if (ret) | ||
548 | goto ctr_des3_err; | ||
549 | ctrblk = (u8 *) __get_free_page(GFP_KERNEL); | ||
550 | if (!ctrblk) { | ||
551 | ret = -ENOMEM; | ||
552 | goto ctr_mem_err; | ||
553 | } | ||
554 | } | ||
406 | out: | 555 | out: |
407 | return ret; | 556 | return ret; |
408 | 557 | ||
409 | cbc_des3_192_err: | 558 | ctr_mem_err: |
410 | crypto_unregister_alg(&ecb_des3_192_alg); | 559 | crypto_unregister_alg(&ctr_des3_alg); |
411 | ecb_des3_192_err: | 560 | ctr_des3_err: |
412 | crypto_unregister_alg(&des3_192_alg); | 561 | crypto_unregister_alg(&ctr_des_alg); |
413 | des3_192_err: | 562 | ctr_des_err: |
563 | crypto_unregister_alg(&cbc_des3_alg); | ||
564 | cbc_des3_err: | ||
565 | crypto_unregister_alg(&ecb_des3_alg); | ||
566 | ecb_des3_err: | ||
567 | crypto_unregister_alg(&des3_alg); | ||
568 | des3_err: | ||
414 | crypto_unregister_alg(&cbc_des_alg); | 569 | crypto_unregister_alg(&cbc_des_alg); |
415 | cbc_des_err: | 570 | cbc_des_err: |
416 | crypto_unregister_alg(&ecb_des_alg); | 571 | crypto_unregister_alg(&ecb_des_alg); |
@@ -422,9 +577,14 @@ des_err: | |||
422 | 577 | ||
423 | static void __exit des_s390_exit(void) | 578 | static void __exit des_s390_exit(void) |
424 | { | 579 | { |
425 | crypto_unregister_alg(&cbc_des3_192_alg); | 580 | if (ctrblk) { |
426 | crypto_unregister_alg(&ecb_des3_192_alg); | 581 | crypto_unregister_alg(&ctr_des_alg); |
427 | crypto_unregister_alg(&des3_192_alg); | 582 | crypto_unregister_alg(&ctr_des3_alg); |
583 | free_page((unsigned long) ctrblk); | ||
584 | } | ||
585 | crypto_unregister_alg(&cbc_des3_alg); | ||
586 | crypto_unregister_alg(&ecb_des3_alg); | ||
587 | crypto_unregister_alg(&des3_alg); | ||
428 | crypto_unregister_alg(&cbc_des_alg); | 588 | crypto_unregister_alg(&cbc_des_alg); |
429 | crypto_unregister_alg(&ecb_des_alg); | 589 | crypto_unregister_alg(&ecb_des_alg); |
430 | crypto_unregister_alg(&des_alg); | 590 | crypto_unregister_alg(&des_alg); |
diff --git a/arch/s390/crypto/ghash_s390.c b/arch/s390/crypto/ghash_s390.c new file mode 100644 index 000000000000..b1bd170f24b1 --- /dev/null +++ b/arch/s390/crypto/ghash_s390.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * s390 implementation of the GHASH algorithm for GCM (Galois/Counter Mode). | ||
5 | * | ||
6 | * Copyright IBM Corp. 2011 | ||
7 | * Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com> | ||
8 | */ | ||
9 | |||
10 | #include <crypto/internal/hash.h> | ||
11 | #include <linux/module.h> | ||
12 | |||
13 | #include "crypt_s390.h" | ||
14 | |||
15 | #define GHASH_BLOCK_SIZE 16 | ||
16 | #define GHASH_DIGEST_SIZE 16 | ||
17 | |||
18 | struct ghash_ctx { | ||
19 | u8 icv[16]; | ||
20 | u8 key[16]; | ||
21 | }; | ||
22 | |||
23 | struct ghash_desc_ctx { | ||
24 | u8 buffer[GHASH_BLOCK_SIZE]; | ||
25 | u32 bytes; | ||
26 | }; | ||
27 | |||
28 | static int ghash_init(struct shash_desc *desc) | ||
29 | { | ||
30 | struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); | ||
31 | |||
32 | memset(dctx, 0, sizeof(*dctx)); | ||
33 | |||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | static int ghash_setkey(struct crypto_shash *tfm, | ||
38 | const u8 *key, unsigned int keylen) | ||
39 | { | ||
40 | struct ghash_ctx *ctx = crypto_shash_ctx(tfm); | ||
41 | |||
42 | if (keylen != GHASH_BLOCK_SIZE) { | ||
43 | crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
44 | return -EINVAL; | ||
45 | } | ||
46 | |||
47 | memcpy(ctx->key, key, GHASH_BLOCK_SIZE); | ||
48 | memset(ctx->icv, 0, GHASH_BLOCK_SIZE); | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static int ghash_update(struct shash_desc *desc, | ||
54 | const u8 *src, unsigned int srclen) | ||
55 | { | ||
56 | struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); | ||
57 | struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); | ||
58 | unsigned int n; | ||
59 | u8 *buf = dctx->buffer; | ||
60 | int ret; | ||
61 | |||
62 | if (dctx->bytes) { | ||
63 | u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes); | ||
64 | |||
65 | n = min(srclen, dctx->bytes); | ||
66 | dctx->bytes -= n; | ||
67 | srclen -= n; | ||
68 | |||
69 | memcpy(pos, src, n); | ||
70 | src += n; | ||
71 | |||
72 | if (!dctx->bytes) { | ||
73 | ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, | ||
74 | GHASH_BLOCK_SIZE); | ||
75 | BUG_ON(ret != GHASH_BLOCK_SIZE); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | n = srclen & ~(GHASH_BLOCK_SIZE - 1); | ||
80 | if (n) { | ||
81 | ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); | ||
82 | BUG_ON(ret != n); | ||
83 | src += n; | ||
84 | srclen -= n; | ||
85 | } | ||
86 | |||
87 | if (srclen) { | ||
88 | dctx->bytes = GHASH_BLOCK_SIZE - srclen; | ||
89 | memcpy(buf, src, srclen); | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) | ||
96 | { | ||
97 | u8 *buf = dctx->buffer; | ||
98 | int ret; | ||
99 | |||
100 | if (dctx->bytes) { | ||
101 | u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes); | ||
102 | |||
103 | memset(pos, 0, dctx->bytes); | ||
104 | |||
105 | ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE); | ||
106 | BUG_ON(ret != GHASH_BLOCK_SIZE); | ||
107 | } | ||
108 | |||
109 | dctx->bytes = 0; | ||
110 | } | ||
111 | |||
112 | static int ghash_final(struct shash_desc *desc, u8 *dst) | ||
113 | { | ||
114 | struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); | ||
115 | struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); | ||
116 | |||
117 | ghash_flush(ctx, dctx); | ||
118 | memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static struct shash_alg ghash_alg = { | ||
124 | .digestsize = GHASH_DIGEST_SIZE, | ||
125 | .init = ghash_init, | ||
126 | .update = ghash_update, | ||
127 | .final = ghash_final, | ||
128 | .setkey = ghash_setkey, | ||
129 | .descsize = sizeof(struct ghash_desc_ctx), | ||
130 | .base = { | ||
131 | .cra_name = "ghash", | ||
132 | .cra_driver_name = "ghash-s390", | ||
133 | .cra_priority = CRYPT_S390_PRIORITY, | ||
134 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
135 | .cra_blocksize = GHASH_BLOCK_SIZE, | ||
136 | .cra_ctxsize = sizeof(struct ghash_ctx), | ||
137 | .cra_module = THIS_MODULE, | ||
138 | .cra_list = LIST_HEAD_INIT(ghash_alg.base.cra_list), | ||
139 | }, | ||
140 | }; | ||
141 | |||
142 | static int __init ghash_mod_init(void) | ||
143 | { | ||
144 | if (!crypt_s390_func_available(KIMD_GHASH, | ||
145 | CRYPT_S390_MSA | CRYPT_S390_MSA4)) | ||
146 | return -EOPNOTSUPP; | ||
147 | |||
148 | return crypto_register_shash(&ghash_alg); | ||
149 | } | ||
150 | |||
151 | static void __exit ghash_mod_exit(void) | ||
152 | { | ||
153 | crypto_unregister_shash(&ghash_alg); | ||
154 | } | ||
155 | |||
156 | module_init(ghash_mod_init); | ||
157 | module_exit(ghash_mod_exit); | ||
158 | |||
159 | MODULE_ALIAS("ghash"); | ||
160 | |||
161 | MODULE_LICENSE("GPL"); | ||
162 | MODULE_DESCRIPTION("GHASH Message Digest Algorithm, s390 implementation"); | ||
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 8b16c479585b..0808fbf0f7d3 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c | |||
@@ -166,7 +166,7 @@ static int __init prng_init(void) | |||
166 | int ret; | 166 | int ret; |
167 | 167 | ||
168 | /* check if the CPU has a PRNG */ | 168 | /* check if the CPU has a PRNG */ |
169 | if (!crypt_s390_func_available(KMC_PRNG)) | 169 | if (!crypt_s390_func_available(KMC_PRNG, CRYPT_S390_MSA)) |
170 | return -EOPNOTSUPP; | 170 | return -EOPNOTSUPP; |
171 | 171 | ||
172 | if (prng_chunk_size < 8) | 172 | if (prng_chunk_size < 8) |
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c index f6de7826c979..e9868c6e0a08 100644 --- a/arch/s390/crypto/sha1_s390.c +++ b/arch/s390/crypto/sha1_s390.c | |||
@@ -90,7 +90,7 @@ static struct shash_alg alg = { | |||
90 | 90 | ||
91 | static int __init sha1_s390_init(void) | 91 | static int __init sha1_s390_init(void) |
92 | { | 92 | { |
93 | if (!crypt_s390_func_available(KIMD_SHA_1)) | 93 | if (!crypt_s390_func_available(KIMD_SHA_1, CRYPT_S390_MSA)) |
94 | return -EOPNOTSUPP; | 94 | return -EOPNOTSUPP; |
95 | return crypto_register_shash(&alg); | 95 | return crypto_register_shash(&alg); |
96 | } | 96 | } |
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index 61a7db372121..5ed8d64fc2ed 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c | |||
@@ -86,7 +86,7 @@ static struct shash_alg alg = { | |||
86 | 86 | ||
87 | static int sha256_s390_init(void) | 87 | static int sha256_s390_init(void) |
88 | { | 88 | { |
89 | if (!crypt_s390_func_available(KIMD_SHA_256)) | 89 | if (!crypt_s390_func_available(KIMD_SHA_256, CRYPT_S390_MSA)) |
90 | return -EOPNOTSUPP; | 90 | return -EOPNOTSUPP; |
91 | 91 | ||
92 | return crypto_register_shash(&alg); | 92 | return crypto_register_shash(&alg); |
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c index 4bf73d0dc525..32a81383b69c 100644 --- a/arch/s390/crypto/sha512_s390.c +++ b/arch/s390/crypto/sha512_s390.c | |||
@@ -132,7 +132,7 @@ static int __init init(void) | |||
132 | { | 132 | { |
133 | int ret; | 133 | int ret; |
134 | 134 | ||
135 | if (!crypt_s390_func_available(KIMD_SHA_512)) | 135 | if (!crypt_s390_func_available(KIMD_SHA_512, CRYPT_S390_MSA)) |
136 | return -EOPNOTSUPP; | 136 | return -EOPNOTSUPP; |
137 | if ((ret = crypto_register_shash(&sha512_alg)) < 0) | 137 | if ((ret = crypto_register_shash(&sha512_alg)) < 0) |
138 | goto out; | 138 | goto out; |
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 1a58ad89fdf7..c04f1b7a9139 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile | |||
@@ -2,8 +2,6 @@ | |||
2 | # Arch-specific CryptoAPI modules. | 2 | # Arch-specific CryptoAPI modules. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_CRYPTO_FPU) += fpu.o | ||
6 | |||
7 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o | 5 | obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o |
8 | obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o | 6 | obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o |
9 | obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o | 7 | obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o |
@@ -24,6 +22,6 @@ aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o | |||
24 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o | 22 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o |
25 | salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o | 23 | salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o |
26 | 24 | ||
27 | aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o | 25 | aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o |
28 | 26 | ||
29 | ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o | 27 | ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o |
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 2577613fb32b..feee8ff1d05e 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c | |||
@@ -94,6 +94,10 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out, | |||
94 | const u8 *in, unsigned int len, u8 *iv); | 94 | const u8 *in, unsigned int len, u8 *iv); |
95 | asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, | 95 | asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, |
96 | const u8 *in, unsigned int len, u8 *iv); | 96 | const u8 *in, unsigned int len, u8 *iv); |
97 | |||
98 | int crypto_fpu_init(void); | ||
99 | void crypto_fpu_exit(void); | ||
100 | |||
97 | #ifdef CONFIG_X86_64 | 101 | #ifdef CONFIG_X86_64 |
98 | asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, | 102 | asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, |
99 | const u8 *in, unsigned int len, u8 *iv); | 103 | const u8 *in, unsigned int len, u8 *iv); |
@@ -1257,6 +1261,8 @@ static int __init aesni_init(void) | |||
1257 | return -ENODEV; | 1261 | return -ENODEV; |
1258 | } | 1262 | } |
1259 | 1263 | ||
1264 | if ((err = crypto_fpu_init())) | ||
1265 | goto fpu_err; | ||
1260 | if ((err = crypto_register_alg(&aesni_alg))) | 1266 | if ((err = crypto_register_alg(&aesni_alg))) |
1261 | goto aes_err; | 1267 | goto aes_err; |
1262 | if ((err = crypto_register_alg(&__aesni_alg))) | 1268 | if ((err = crypto_register_alg(&__aesni_alg))) |
@@ -1334,6 +1340,7 @@ blk_ecb_err: | |||
1334 | __aes_err: | 1340 | __aes_err: |
1335 | crypto_unregister_alg(&aesni_alg); | 1341 | crypto_unregister_alg(&aesni_alg); |
1336 | aes_err: | 1342 | aes_err: |
1343 | fpu_err: | ||
1337 | return err; | 1344 | return err; |
1338 | } | 1345 | } |
1339 | 1346 | ||
@@ -1363,6 +1370,8 @@ static void __exit aesni_exit(void) | |||
1363 | crypto_unregister_alg(&blk_ecb_alg); | 1370 | crypto_unregister_alg(&blk_ecb_alg); |
1364 | crypto_unregister_alg(&__aesni_alg); | 1371 | crypto_unregister_alg(&__aesni_alg); |
1365 | crypto_unregister_alg(&aesni_alg); | 1372 | crypto_unregister_alg(&aesni_alg); |
1373 | |||
1374 | crypto_fpu_exit(); | ||
1366 | } | 1375 | } |
1367 | 1376 | ||
1368 | module_init(aesni_init); | 1377 | module_init(aesni_init); |
diff --git a/arch/x86/crypto/fpu.c b/arch/x86/crypto/fpu.c index 1a8f8649c035..98d7a188f46b 100644 --- a/arch/x86/crypto/fpu.c +++ b/arch/x86/crypto/fpu.c | |||
@@ -150,18 +150,12 @@ static struct crypto_template crypto_fpu_tmpl = { | |||
150 | .module = THIS_MODULE, | 150 | .module = THIS_MODULE, |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static int __init crypto_fpu_module_init(void) | 153 | int __init crypto_fpu_init(void) |
154 | { | 154 | { |
155 | return crypto_register_template(&crypto_fpu_tmpl); | 155 | return crypto_register_template(&crypto_fpu_tmpl); |
156 | } | 156 | } |
157 | 157 | ||
158 | static void __exit crypto_fpu_module_exit(void) | 158 | void __exit crypto_fpu_exit(void) |
159 | { | 159 | { |
160 | crypto_unregister_template(&crypto_fpu_tmpl); | 160 | crypto_unregister_template(&crypto_fpu_tmpl); |
161 | } | 161 | } |
162 | |||
163 | module_init(crypto_fpu_module_init); | ||
164 | module_exit(crypto_fpu_module_exit); | ||
165 | |||
166 | MODULE_LICENSE("GPL"); | ||
167 | MODULE_DESCRIPTION("FPU block cipher wrapper"); | ||
diff --git a/crypto/Kconfig b/crypto/Kconfig index 4b7cb0e691cd..87b22ca9c223 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -264,11 +264,6 @@ config CRYPTO_XTS | |||
264 | key size 256, 384 or 512 bits. This implementation currently | 264 | key size 256, 384 or 512 bits. This implementation currently |
265 | can't handle a sectorsize which is not a multiple of 16 bytes. | 265 | can't handle a sectorsize which is not a multiple of 16 bytes. |
266 | 266 | ||
267 | config CRYPTO_FPU | ||
268 | tristate | ||
269 | select CRYPTO_BLKCIPHER | ||
270 | select CRYPTO_MANAGER | ||
271 | |||
272 | comment "Hash modes" | 267 | comment "Hash modes" |
273 | 268 | ||
274 | config CRYPTO_HMAC | 269 | config CRYPTO_HMAC |
@@ -543,7 +538,6 @@ config CRYPTO_AES_NI_INTEL | |||
543 | select CRYPTO_AES_586 if !64BIT | 538 | select CRYPTO_AES_586 if !64BIT |
544 | select CRYPTO_CRYPTD | 539 | select CRYPTO_CRYPTD |
545 | select CRYPTO_ALGAPI | 540 | select CRYPTO_ALGAPI |
546 | select CRYPTO_FPU | ||
547 | help | 541 | help |
548 | Use Intel AES-NI instructions for AES algorithm. | 542 | Use Intel AES-NI instructions for AES algorithm. |
549 | 543 | ||
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index e912ea5def3d..2222617b3bed 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c | |||
@@ -1009,6 +1009,10 @@ static int do_test(int m) | |||
1009 | speed_template_32_48_64); | 1009 | speed_template_32_48_64); |
1010 | test_cipher_speed("xts(aes)", DECRYPT, sec, NULL, 0, | 1010 | test_cipher_speed("xts(aes)", DECRYPT, sec, NULL, 0, |
1011 | speed_template_32_48_64); | 1011 | speed_template_32_48_64); |
1012 | test_cipher_speed("ctr(aes)", ENCRYPT, sec, NULL, 0, | ||
1013 | speed_template_16_24_32); | ||
1014 | test_cipher_speed("ctr(aes)", DECRYPT, sec, NULL, 0, | ||
1015 | speed_template_16_24_32); | ||
1012 | break; | 1016 | break; |
1013 | 1017 | ||
1014 | case 201: | 1018 | case 201: |
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 2854865f2434..b6b93d416351 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -2219,6 +2219,22 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
2219 | } | 2219 | } |
2220 | } | 2220 | } |
2221 | }, { | 2221 | }, { |
2222 | .alg = "ofb(aes)", | ||
2223 | .test = alg_test_skcipher, | ||
2224 | .fips_allowed = 1, | ||
2225 | .suite = { | ||
2226 | .cipher = { | ||
2227 | .enc = { | ||
2228 | .vecs = aes_ofb_enc_tv_template, | ||
2229 | .count = AES_OFB_ENC_TEST_VECTORS | ||
2230 | }, | ||
2231 | .dec = { | ||
2232 | .vecs = aes_ofb_dec_tv_template, | ||
2233 | .count = AES_OFB_DEC_TEST_VECTORS | ||
2234 | } | ||
2235 | } | ||
2236 | } | ||
2237 | }, { | ||
2222 | .alg = "pcbc(fcrypt)", | 2238 | .alg = "pcbc(fcrypt)", |
2223 | .test = alg_test_skcipher, | 2239 | .test = alg_test_skcipher, |
2224 | .suite = { | 2240 | .suite = { |
diff --git a/crypto/testmgr.h b/crypto/testmgr.h index aa6dac05f843..27e60619538e 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h | |||
@@ -2980,6 +2980,8 @@ static struct cipher_testvec cast6_dec_tv_template[] = { | |||
2980 | #define AES_XTS_DEC_TEST_VECTORS 4 | 2980 | #define AES_XTS_DEC_TEST_VECTORS 4 |
2981 | #define AES_CTR_ENC_TEST_VECTORS 3 | 2981 | #define AES_CTR_ENC_TEST_VECTORS 3 |
2982 | #define AES_CTR_DEC_TEST_VECTORS 3 | 2982 | #define AES_CTR_DEC_TEST_VECTORS 3 |
2983 | #define AES_OFB_ENC_TEST_VECTORS 1 | ||
2984 | #define AES_OFB_DEC_TEST_VECTORS 1 | ||
2983 | #define AES_CTR_3686_ENC_TEST_VECTORS 7 | 2985 | #define AES_CTR_3686_ENC_TEST_VECTORS 7 |
2984 | #define AES_CTR_3686_DEC_TEST_VECTORS 6 | 2986 | #define AES_CTR_3686_DEC_TEST_VECTORS 6 |
2985 | #define AES_GCM_ENC_TEST_VECTORS 9 | 2987 | #define AES_GCM_ENC_TEST_VECTORS 9 |
@@ -5506,6 +5508,64 @@ static struct cipher_testvec aes_ctr_rfc3686_dec_tv_template[] = { | |||
5506 | }, | 5508 | }, |
5507 | }; | 5509 | }; |
5508 | 5510 | ||
5511 | static struct cipher_testvec aes_ofb_enc_tv_template[] = { | ||
5512 | /* From NIST Special Publication 800-38A, Appendix F.5 */ | ||
5513 | { | ||
5514 | .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6" | ||
5515 | "\xab\xf7\x15\x88\x09\xcf\x4f\x3c", | ||
5516 | .klen = 16, | ||
5517 | .iv = "\x00\x01\x02\x03\x04\x05\x06\x07\x08" | ||
5518 | "\x09\x0a\x0b\x0c\x0d\x0e\x0f", | ||
5519 | .input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96" | ||
5520 | "\xe9\x3d\x7e\x11\x73\x93\x17\x2a" | ||
5521 | "\xae\x2d\x8a\x57\x1e\x03\xac\x9c" | ||
5522 | "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" | ||
5523 | "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11" | ||
5524 | "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" | ||
5525 | "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17" | ||
5526 | "\xad\x2b\x41\x7b\xe6\x6c\x37\x10", | ||
5527 | .ilen = 64, | ||
5528 | .result = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20" | ||
5529 | "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" | ||
5530 | "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5" | ||
5531 | "\x3c\x52\xda\xc5\x4e\xd8\x25" | ||
5532 | "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43" | ||
5533 | "\x44\xf7\xa8\x22\x60\xed\xcc" | ||
5534 | "\x30\x4c\x65\x28\xf6\x59\xc7\x78" | ||
5535 | "\x66\xa5\x10\xd9\xc1\xd6\xae\x5e", | ||
5536 | .rlen = 64, | ||
5537 | } | ||
5538 | }; | ||
5539 | |||
5540 | static struct cipher_testvec aes_ofb_dec_tv_template[] = { | ||
5541 | /* From NIST Special Publication 800-38A, Appendix F.5 */ | ||
5542 | { | ||
5543 | .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6" | ||
5544 | "\xab\xf7\x15\x88\x09\xcf\x4f\x3c", | ||
5545 | .klen = 16, | ||
5546 | .iv = "\x00\x01\x02\x03\x04\x05\x06\x07\x08" | ||
5547 | "\x09\x0a\x0b\x0c\x0d\x0e\x0f", | ||
5548 | .input = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20" | ||
5549 | "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" | ||
5550 | "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5" | ||
5551 | "\x3c\x52\xda\xc5\x4e\xd8\x25" | ||
5552 | "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43" | ||
5553 | "\x44\xf7\xa8\x22\x60\xed\xcc" | ||
5554 | "\x30\x4c\x65\x28\xf6\x59\xc7\x78" | ||
5555 | "\x66\xa5\x10\xd9\xc1\xd6\xae\x5e", | ||
5556 | .ilen = 64, | ||
5557 | .result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96" | ||
5558 | "\xe9\x3d\x7e\x11\x73\x93\x17\x2a" | ||
5559 | "\xae\x2d\x8a\x57\x1e\x03\xac\x9c" | ||
5560 | "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" | ||
5561 | "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11" | ||
5562 | "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" | ||
5563 | "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17" | ||
5564 | "\xad\x2b\x41\x7b\xe6\x6c\x37\x10", | ||
5565 | .rlen = 64, | ||
5566 | } | ||
5567 | }; | ||
5568 | |||
5509 | static struct aead_testvec aes_gcm_enc_tv_template[] = { | 5569 | static struct aead_testvec aes_gcm_enc_tv_template[] = { |
5510 | { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */ | 5570 | { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */ |
5511 | .key = zeroed_string, | 5571 | .key = zeroed_string, |
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index beecd1cf9b99..a60043b3e409 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -49,7 +49,7 @@ config HW_RANDOM_INTEL | |||
49 | 49 | ||
50 | config HW_RANDOM_AMD | 50 | config HW_RANDOM_AMD |
51 | tristate "AMD HW Random Number Generator support" | 51 | tristate "AMD HW Random Number Generator support" |
52 | depends on HW_RANDOM && X86 && PCI | 52 | depends on HW_RANDOM && (X86 || PPC_MAPLE) && PCI |
53 | default HW_RANDOM | 53 | default HW_RANDOM |
54 | ---help--- | 54 | ---help--- |
55 | This driver provides kernel-side support for the Random Number | 55 | This driver provides kernel-side support for the Random Number |
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c index 0d8c5788b8e4..c6af038682f1 100644 --- a/drivers/char/hw_random/amd-rng.c +++ b/drivers/char/hw_random/amd-rng.c | |||
@@ -133,6 +133,12 @@ found: | |||
133 | pmbase &= 0x0000FF00; | 133 | pmbase &= 0x0000FF00; |
134 | if (pmbase == 0) | 134 | if (pmbase == 0) |
135 | goto out; | 135 | goto out; |
136 | if (!request_region(pmbase + 0xF0, 8, "AMD HWRNG")) { | ||
137 | dev_err(&pdev->dev, "AMD HWRNG region 0x%x already in use!\n", | ||
138 | pmbase + 0xF0); | ||
139 | err = -EBUSY; | ||
140 | goto out; | ||
141 | } | ||
136 | amd_rng.priv = (unsigned long)pmbase; | 142 | amd_rng.priv = (unsigned long)pmbase; |
137 | amd_pdev = pdev; | 143 | amd_pdev = pdev; |
138 | 144 | ||
@@ -141,6 +147,7 @@ found: | |||
141 | if (err) { | 147 | if (err) { |
142 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", | 148 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", |
143 | err); | 149 | err); |
150 | release_region(pmbase + 0xF0, 8); | ||
144 | goto out; | 151 | goto out; |
145 | } | 152 | } |
146 | out: | 153 | out: |
@@ -149,6 +156,8 @@ out: | |||
149 | 156 | ||
150 | static void __exit mod_exit(void) | 157 | static void __exit mod_exit(void) |
151 | { | 158 | { |
159 | u32 pmbase = (unsigned long)amd_rng.priv; | ||
160 | release_region(pmbase + 0xF0, 8); | ||
152 | hwrng_unregister(&amd_rng); | 161 | hwrng_unregister(&amd_rng); |
153 | } | 162 | } |
154 | 163 | ||
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index e54185223c8c..c64c3807f516 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
@@ -91,6 +91,8 @@ config CRYPTO_SHA1_S390 | |||
91 | This is the s390 hardware accelerated implementation of the | 91 | This is the s390 hardware accelerated implementation of the |
92 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). | 92 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). |
93 | 93 | ||
94 | It is available as of z990. | ||
95 | |||
94 | config CRYPTO_SHA256_S390 | 96 | config CRYPTO_SHA256_S390 |
95 | tristate "SHA256 digest algorithm" | 97 | tristate "SHA256 digest algorithm" |
96 | depends on S390 | 98 | depends on S390 |
@@ -99,8 +101,7 @@ config CRYPTO_SHA256_S390 | |||
99 | This is the s390 hardware accelerated implementation of the | 101 | This is the s390 hardware accelerated implementation of the |
100 | SHA256 secure hash standard (DFIPS 180-2). | 102 | SHA256 secure hash standard (DFIPS 180-2). |
101 | 103 | ||
102 | This version of SHA implements a 256 bit hash with 128 bits of | 104 | It is available as of z9. |
103 | security against collision attacks. | ||
104 | 105 | ||
105 | config CRYPTO_SHA512_S390 | 106 | config CRYPTO_SHA512_S390 |
106 | tristate "SHA384 and SHA512 digest algorithm" | 107 | tristate "SHA384 and SHA512 digest algorithm" |
@@ -110,10 +111,7 @@ config CRYPTO_SHA512_S390 | |||
110 | This is the s390 hardware accelerated implementation of the | 111 | This is the s390 hardware accelerated implementation of the |
111 | SHA512 secure hash standard. | 112 | SHA512 secure hash standard. |
112 | 113 | ||
113 | This version of SHA implements a 512 bit hash with 256 bits of | 114 | It is available as of z10. |
114 | security against collision attacks. The code also includes SHA-384, | ||
115 | a 384 bit hash with 192 bits of security against collision attacks. | ||
116 | |||
117 | 115 | ||
118 | config CRYPTO_DES_S390 | 116 | config CRYPTO_DES_S390 |
119 | tristate "DES and Triple DES cipher algorithms" | 117 | tristate "DES and Triple DES cipher algorithms" |
@@ -121,9 +119,12 @@ config CRYPTO_DES_S390 | |||
121 | select CRYPTO_ALGAPI | 119 | select CRYPTO_ALGAPI |
122 | select CRYPTO_BLKCIPHER | 120 | select CRYPTO_BLKCIPHER |
123 | help | 121 | help |
124 | This us the s390 hardware accelerated implementation of the | 122 | This is the s390 hardware accelerated implementation of the |
125 | DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). | 123 | DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). |
126 | 124 | ||
125 | As of z990 the ECB and CBC mode are hardware accelerated. | ||
126 | As of z196 the CTR mode is hardware accelerated. | ||
127 | |||
127 | config CRYPTO_AES_S390 | 128 | config CRYPTO_AES_S390 |
128 | tristate "AES cipher algorithms" | 129 | tristate "AES cipher algorithms" |
129 | depends on S390 | 130 | depends on S390 |
@@ -131,20 +132,15 @@ config CRYPTO_AES_S390 | |||
131 | select CRYPTO_BLKCIPHER | 132 | select CRYPTO_BLKCIPHER |
132 | help | 133 | help |
133 | This is the s390 hardware accelerated implementation of the | 134 | This is the s390 hardware accelerated implementation of the |
134 | AES cipher algorithms (FIPS-197). AES uses the Rijndael | 135 | AES cipher algorithms (FIPS-197). |
135 | algorithm. | ||
136 | |||
137 | Rijndael appears to be consistently a very good performer in | ||
138 | both hardware and software across a wide range of computing | ||
139 | environments regardless of its use in feedback or non-feedback | ||
140 | modes. Its key setup time is excellent, and its key agility is | ||
141 | good. Rijndael's very low memory requirements make it very well | ||
142 | suited for restricted-space environments, in which it also | ||
143 | demonstrates excellent performance. Rijndael's operations are | ||
144 | among the easiest to defend against power and timing attacks. | ||
145 | 136 | ||
146 | On s390 the System z9-109 currently only supports the key size | 137 | As of z9 the ECB and CBC modes are hardware accelerated |
147 | of 128 bit. | 138 | for 128 bit keys. |
139 | As of z10 the ECB and CBC modes are hardware accelerated | ||
140 | for all AES key sizes. | ||
141 | As of z196 the CTR mode is hardware accelerated for all AES | ||
142 | key sizes and XTS mode is hardware accelerated for 256 and | ||
143 | 512 bit keys. | ||
148 | 144 | ||
149 | config S390_PRNG | 145 | config S390_PRNG |
150 | tristate "Pseudo random number generator device driver" | 146 | tristate "Pseudo random number generator device driver" |
@@ -154,8 +150,20 @@ config S390_PRNG | |||
154 | Select this option if you want to use the s390 pseudo random number | 150 | Select this option if you want to use the s390 pseudo random number |
155 | generator. The PRNG is part of the cryptographic processor functions | 151 | generator. The PRNG is part of the cryptographic processor functions |
156 | and uses triple-DES to generate secure random numbers like the | 152 | and uses triple-DES to generate secure random numbers like the |
157 | ANSI X9.17 standard. The PRNG is usable via the char device | 153 | ANSI X9.17 standard. User-space programs access the |
158 | /dev/prandom. | 154 | pseudo-random-number device through the char device /dev/prandom. |
155 | |||
156 | It is available as of z9. | ||
157 | |||
158 | config CRYPTO_GHASH_S390 | ||
159 | tristate "GHASH digest algorithm" | ||
160 | depends on S390 | ||
161 | select CRYPTO_HASH | ||
162 | help | ||
163 | This is the s390 hardware accelerated implementation of the | ||
164 | GHASH message digest algorithm for GCM (Galois/Counter Mode). | ||
165 | |||
166 | It is available as of z196. | ||
159 | 167 | ||
160 | config CRYPTO_DEV_MV_CESA | 168 | config CRYPTO_DEV_MV_CESA |
161 | tristate "Marvell's Cryptographic Engine" | 169 | tristate "Marvell's Cryptographic Engine" |
@@ -200,6 +208,8 @@ config CRYPTO_DEV_HIFN_795X_RNG | |||
200 | Select this option if you want to enable the random number generator | 208 | Select this option if you want to enable the random number generator |
201 | on the HIFN 795x crypto adapters. | 209 | on the HIFN 795x crypto adapters. |
202 | 210 | ||
211 | source drivers/crypto/caam/Kconfig | ||
212 | |||
203 | config CRYPTO_DEV_TALITOS | 213 | config CRYPTO_DEV_TALITOS |
204 | tristate "Talitos Freescale Security Engine (SEC)" | 214 | tristate "Talitos Freescale Security Engine (SEC)" |
205 | select CRYPTO_ALGAPI | 215 | select CRYPTO_ALGAPI |
@@ -269,4 +279,15 @@ config CRYPTO_DEV_PICOXCELL | |||
269 | 279 | ||
270 | Saying m here will build a module named pipcoxcell_crypto. | 280 | Saying m here will build a module named pipcoxcell_crypto. |
271 | 281 | ||
282 | config CRYPTO_DEV_S5P | ||
283 | tristate "Support for Samsung S5PV210 crypto accelerator" | ||
284 | depends on ARCH_S5PV210 | ||
285 | select CRYPTO_AES | ||
286 | select CRYPTO_ALGAPI | ||
287 | select CRYPTO_BLKCIPHER | ||
288 | help | ||
289 | This option allows you to have support for S5P crypto acceleration. | ||
290 | Select this to offload Samsung S5PV210 or S5PC110 from AES | ||
291 | algorithms execution. | ||
292 | |||
272 | endif # CRYPTO_HW | 293 | endif # CRYPTO_HW |
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 5203e34248d7..53ea50155319 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile | |||
@@ -6,8 +6,10 @@ n2_crypto-y := n2_core.o n2_asm.o | |||
6 | obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o | 6 | obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o |
7 | obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o | 7 | obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o |
8 | obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o | 8 | obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o |
9 | obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/ | ||
9 | obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o | 10 | obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o |
10 | obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ | 11 | obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ |
11 | obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o | 12 | obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o |
12 | obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o | 13 | obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o |
13 | obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o | 14 | obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o |
15 | obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o | ||
diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig new file mode 100644 index 000000000000..2d876bb98ff4 --- /dev/null +++ b/drivers/crypto/caam/Kconfig | |||
@@ -0,0 +1,72 @@ | |||
1 | config CRYPTO_DEV_FSL_CAAM | ||
2 | tristate "Freescale CAAM-Multicore driver backend" | ||
3 | depends on FSL_SOC | ||
4 | help | ||
5 | Enables the driver module for Freescale's Cryptographic Accelerator | ||
6 | and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). | ||
7 | This module adds a job ring operation interface, and configures h/w | ||
8 | to operate as a DPAA component automatically, depending | ||
9 | on h/w feature availability. | ||
10 | |||
11 | To compile this driver as a module, choose M here: the module | ||
12 | will be called caam. | ||
13 | |||
14 | config CRYPTO_DEV_FSL_CAAM_RINGSIZE | ||
15 | int "Job Ring size" | ||
16 | depends on CRYPTO_DEV_FSL_CAAM | ||
17 | range 2 9 | ||
18 | default "9" | ||
19 | help | ||
20 | Select size of Job Rings as a power of 2, within the | ||
21 | range 2-9 (ring size 4-512). | ||
22 | Examples: | ||
23 | 2 => 4 | ||
24 | 3 => 8 | ||
25 | 4 => 16 | ||
26 | 5 => 32 | ||
27 | 6 => 64 | ||
28 | 7 => 128 | ||
29 | 8 => 256 | ||
30 | 9 => 512 | ||
31 | |||
32 | config CRYPTO_DEV_FSL_CAAM_INTC | ||
33 | bool "Job Ring interrupt coalescing" | ||
34 | depends on CRYPTO_DEV_FSL_CAAM | ||
35 | default y | ||
36 | help | ||
37 | Enable the Job Ring's interrupt coalescing feature. | ||
38 | |||
39 | config CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD | ||
40 | int "Job Ring interrupt coalescing count threshold" | ||
41 | depends on CRYPTO_DEV_FSL_CAAM_INTC | ||
42 | range 1 255 | ||
43 | default 255 | ||
44 | help | ||
45 | Select number of descriptor completions to queue before | ||
46 | raising an interrupt, in the range 1-255. Note that a selection | ||
47 | of 1 functionally defeats the coalescing feature, and a selection | ||
48 | equal or greater than the job ring size will force timeouts. | ||
49 | |||
50 | config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD | ||
51 | int "Job Ring interrupt coalescing timer threshold" | ||
52 | depends on CRYPTO_DEV_FSL_CAAM_INTC | ||
53 | range 1 65535 | ||
54 | default 2048 | ||
55 | help | ||
56 | Select number of bus clocks/64 to timeout in the case that one or | ||
57 | more descriptor completions are queued without reaching the count | ||
58 | threshold. Range is 1-65535. | ||
59 | |||
60 | config CRYPTO_DEV_FSL_CAAM_CRYPTO_API | ||
61 | tristate "Register algorithm implementations with the Crypto API" | ||
62 | depends on CRYPTO_DEV_FSL_CAAM | ||
63 | default y | ||
64 | select CRYPTO_ALGAPI | ||
65 | select CRYPTO_AUTHENC | ||
66 | help | ||
67 | Selecting this will offload crypto for users of the | ||
68 | scatterlist crypto API (such as the linux native IPSec | ||
69 | stack) to the SEC4 via job ring. | ||
70 | |||
71 | To compile this as a module, choose M here: the module | ||
72 | will be called caamalg. | ||
diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile new file mode 100644 index 000000000000..ef39011b4505 --- /dev/null +++ b/drivers/crypto/caam/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the CAAM backend and dependent components | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o | ||
6 | obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o | ||
7 | |||
8 | caam-objs := ctrl.o jr.o error.o | ||
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c new file mode 100644 index 000000000000..d0e65d6ddc77 --- /dev/null +++ b/drivers/crypto/caam/caamalg.c | |||
@@ -0,0 +1,1268 @@ | |||
1 | /* | ||
2 | * caam - Freescale FSL CAAM support for crypto API | ||
3 | * | ||
4 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
5 | * | ||
6 | * Based on talitos crypto API driver. | ||
7 | * | ||
8 | * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008): | ||
9 | * | ||
10 | * --------------- --------------- | ||
11 | * | JobDesc #1 |-------------------->| ShareDesc | | ||
12 | * | *(packet 1) | | (PDB) | | ||
13 | * --------------- |------------->| (hashKey) | | ||
14 | * . | | (cipherKey) | | ||
15 | * . | |-------->| (operation) | | ||
16 | * --------------- | | --------------- | ||
17 | * | JobDesc #2 |------| | | ||
18 | * | *(packet 2) | | | ||
19 | * --------------- | | ||
20 | * . | | ||
21 | * . | | ||
22 | * --------------- | | ||
23 | * | JobDesc #3 |------------ | ||
24 | * | *(packet 3) | | ||
25 | * --------------- | ||
26 | * | ||
27 | * The SharedDesc never changes for a connection unless rekeyed, but | ||
28 | * each packet will likely be in a different place. So all we need | ||
29 | * to know to process the packet is where the input is, where the | ||
30 | * output goes, and what context we want to process with. Context is | ||
31 | * in the SharedDesc, packet references in the JobDesc. | ||
32 | * | ||
33 | * So, a job desc looks like: | ||
34 | * | ||
35 | * --------------------- | ||
36 | * | Header | | ||
37 | * | ShareDesc Pointer | | ||
38 | * | SEQ_OUT_PTR | | ||
39 | * | (output buffer) | | ||
40 | * | SEQ_IN_PTR | | ||
41 | * | (input buffer) | | ||
42 | * | LOAD (to DECO) | | ||
43 | * --------------------- | ||
44 | */ | ||
45 | |||
46 | #include "compat.h" | ||
47 | |||
48 | #include "regs.h" | ||
49 | #include "intern.h" | ||
50 | #include "desc_constr.h" | ||
51 | #include "jr.h" | ||
52 | #include "error.h" | ||
53 | |||
54 | /* | ||
55 | * crypto alg | ||
56 | */ | ||
57 | #define CAAM_CRA_PRIORITY 3000 | ||
58 | /* max key is sum of AES_MAX_KEY_SIZE, max split key size */ | ||
59 | #define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + \ | ||
60 | SHA512_DIGEST_SIZE * 2) | ||
61 | /* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ | ||
62 | #define CAAM_MAX_IV_LENGTH 16 | ||
63 | |||
64 | /* length of descriptors text */ | ||
65 | #define DESC_AEAD_SHARED_TEXT_LEN 4 | ||
66 | #define DESC_AEAD_ENCRYPT_TEXT_LEN 21 | ||
67 | #define DESC_AEAD_DECRYPT_TEXT_LEN 24 | ||
68 | #define DESC_AEAD_GIVENCRYPT_TEXT_LEN 27 | ||
69 | |||
70 | #ifdef DEBUG | ||
71 | /* for print_hex_dumps with line references */ | ||
72 | #define xstr(s) str(s) | ||
73 | #define str(s) #s | ||
74 | #define debug(format, arg...) printk(format, arg) | ||
75 | #else | ||
76 | #define debug(format, arg...) | ||
77 | #endif | ||
78 | |||
79 | /* | ||
80 | * per-session context | ||
81 | */ | ||
82 | struct caam_ctx { | ||
83 | struct device *jrdev; | ||
84 | u32 *sh_desc; | ||
85 | dma_addr_t shared_desc_phys; | ||
86 | u32 class1_alg_type; | ||
87 | u32 class2_alg_type; | ||
88 | u32 alg_op; | ||
89 | u8 *key; | ||
90 | dma_addr_t key_phys; | ||
91 | unsigned int enckeylen; | ||
92 | unsigned int split_key_len; | ||
93 | unsigned int split_key_pad_len; | ||
94 | unsigned int authsize; | ||
95 | }; | ||
96 | |||
97 | static int aead_authenc_setauthsize(struct crypto_aead *authenc, | ||
98 | unsigned int authsize) | ||
99 | { | ||
100 | struct caam_ctx *ctx = crypto_aead_ctx(authenc); | ||
101 | |||
102 | ctx->authsize = authsize; | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | struct split_key_result { | ||
108 | struct completion completion; | ||
109 | int err; | ||
110 | }; | ||
111 | |||
112 | static void split_key_done(struct device *dev, u32 *desc, u32 err, | ||
113 | void *context) | ||
114 | { | ||
115 | struct split_key_result *res = context; | ||
116 | |||
117 | #ifdef DEBUG | ||
118 | dev_err(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | ||
119 | #endif | ||
120 | if (err) { | ||
121 | char tmp[CAAM_ERROR_STR_MAX]; | ||
122 | |||
123 | dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); | ||
124 | } | ||
125 | |||
126 | res->err = err; | ||
127 | |||
128 | complete(&res->completion); | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | get a split ipad/opad key | ||
133 | |||
134 | Split key generation----------------------------------------------- | ||
135 | |||
136 | [00] 0xb0810008 jobdesc: stidx=1 share=never len=8 | ||
137 | [01] 0x04000014 key: class2->keyreg len=20 | ||
138 | @0xffe01000 | ||
139 | [03] 0x84410014 operation: cls2-op sha1 hmac init dec | ||
140 | [04] 0x24940000 fifold: class2 msgdata-last2 len=0 imm | ||
141 | [05] 0xa4000001 jump: class2 local all ->1 [06] | ||
142 | [06] 0x64260028 fifostr: class2 mdsplit-jdk len=40 | ||
143 | @0xffe04000 | ||
144 | */ | ||
145 | static u32 gen_split_key(struct caam_ctx *ctx, const u8 *key_in, u32 authkeylen) | ||
146 | { | ||
147 | struct device *jrdev = ctx->jrdev; | ||
148 | u32 *desc; | ||
149 | struct split_key_result result; | ||
150 | dma_addr_t dma_addr_in, dma_addr_out; | ||
151 | int ret = 0; | ||
152 | |||
153 | desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); | ||
154 | |||
155 | init_job_desc(desc, 0); | ||
156 | |||
157 | dma_addr_in = dma_map_single(jrdev, (void *)key_in, authkeylen, | ||
158 | DMA_TO_DEVICE); | ||
159 | if (dma_mapping_error(jrdev, dma_addr_in)) { | ||
160 | dev_err(jrdev, "unable to map key input memory\n"); | ||
161 | kfree(desc); | ||
162 | return -ENOMEM; | ||
163 | } | ||
164 | append_key(desc, dma_addr_in, authkeylen, CLASS_2 | | ||
165 | KEY_DEST_CLASS_REG); | ||
166 | |||
167 | /* Sets MDHA up into an HMAC-INIT */ | ||
168 | append_operation(desc, ctx->alg_op | OP_ALG_DECRYPT | | ||
169 | OP_ALG_AS_INIT); | ||
170 | |||
171 | /* | ||
172 | * do a FIFO_LOAD of zero, this will trigger the internal key expansion | ||
173 | into both pads inside MDHA | ||
174 | */ | ||
175 | append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB | | ||
176 | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); | ||
177 | |||
178 | /* | ||
179 | * FIFO_STORE with the explicit split-key content store | ||
180 | * (0x26 output type) | ||
181 | */ | ||
182 | dma_addr_out = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len, | ||
183 | DMA_FROM_DEVICE); | ||
184 | if (dma_mapping_error(jrdev, dma_addr_out)) { | ||
185 | dev_err(jrdev, "unable to map key output memory\n"); | ||
186 | kfree(desc); | ||
187 | return -ENOMEM; | ||
188 | } | ||
189 | append_fifo_store(desc, dma_addr_out, ctx->split_key_len, | ||
190 | LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); | ||
191 | |||
192 | #ifdef DEBUG | ||
193 | print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", | ||
194 | DUMP_PREFIX_ADDRESS, 16, 4, key_in, authkeylen, 1); | ||
195 | print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", | ||
196 | DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); | ||
197 | #endif | ||
198 | |||
199 | result.err = 0; | ||
200 | init_completion(&result.completion); | ||
201 | |||
202 | ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); | ||
203 | if (!ret) { | ||
204 | /* in progress */ | ||
205 | wait_for_completion_interruptible(&result.completion); | ||
206 | ret = result.err; | ||
207 | #ifdef DEBUG | ||
208 | print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", | ||
209 | DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, | ||
210 | ctx->split_key_pad_len, 1); | ||
211 | #endif | ||
212 | } | ||
213 | |||
214 | dma_unmap_single(jrdev, dma_addr_out, ctx->split_key_pad_len, | ||
215 | DMA_FROM_DEVICE); | ||
216 | dma_unmap_single(jrdev, dma_addr_in, authkeylen, DMA_TO_DEVICE); | ||
217 | |||
218 | kfree(desc); | ||
219 | |||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int build_sh_desc_ipsec(struct caam_ctx *ctx) | ||
224 | { | ||
225 | struct device *jrdev = ctx->jrdev; | ||
226 | u32 *sh_desc; | ||
227 | u32 *jump_cmd; | ||
228 | bool keys_fit_inline = 0; | ||
229 | |||
230 | /* | ||
231 | * largest Job Descriptor and its Shared Descriptor | ||
232 | * must both fit into the 64-word Descriptor h/w Buffer | ||
233 | */ | ||
234 | if ((DESC_AEAD_GIVENCRYPT_TEXT_LEN + | ||
235 | DESC_AEAD_SHARED_TEXT_LEN) * CAAM_CMD_SZ + | ||
236 | ctx->split_key_pad_len + ctx->enckeylen <= CAAM_DESC_BYTES_MAX) | ||
237 | keys_fit_inline = 1; | ||
238 | |||
239 | /* build shared descriptor for this session */ | ||
240 | sh_desc = kmalloc(CAAM_CMD_SZ * DESC_AEAD_SHARED_TEXT_LEN + | ||
241 | keys_fit_inline ? | ||
242 | ctx->split_key_pad_len + ctx->enckeylen : | ||
243 | CAAM_PTR_SZ * 2, GFP_DMA | GFP_KERNEL); | ||
244 | if (!sh_desc) { | ||
245 | dev_err(jrdev, "could not allocate shared descriptor\n"); | ||
246 | return -ENOMEM; | ||
247 | } | ||
248 | |||
249 | init_sh_desc(sh_desc, HDR_SAVECTX | HDR_SHARE_SERIAL); | ||
250 | |||
251 | jump_cmd = append_jump(sh_desc, CLASS_BOTH | JUMP_TEST_ALL | | ||
252 | JUMP_COND_SHRD | JUMP_COND_SELF); | ||
253 | |||
254 | /* | ||
255 | * process keys, starting with class 2/authentication. | ||
256 | */ | ||
257 | if (keys_fit_inline) { | ||
258 | append_key_as_imm(sh_desc, ctx->key, ctx->split_key_pad_len, | ||
259 | ctx->split_key_len, | ||
260 | CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC); | ||
261 | |||
262 | append_key_as_imm(sh_desc, (void *)ctx->key + | ||
263 | ctx->split_key_pad_len, ctx->enckeylen, | ||
264 | ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); | ||
265 | } else { | ||
266 | append_key(sh_desc, ctx->key_phys, ctx->split_key_len, CLASS_2 | | ||
267 | KEY_DEST_MDHA_SPLIT | KEY_ENC); | ||
268 | append_key(sh_desc, ctx->key_phys + ctx->split_key_pad_len, | ||
269 | ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG); | ||
270 | } | ||
271 | |||
272 | /* update jump cmd now that we are at the jump target */ | ||
273 | set_jump_tgt_here(sh_desc, jump_cmd); | ||
274 | |||
275 | ctx->shared_desc_phys = dma_map_single(jrdev, sh_desc, | ||
276 | desc_bytes(sh_desc), | ||
277 | DMA_TO_DEVICE); | ||
278 | if (dma_mapping_error(jrdev, ctx->shared_desc_phys)) { | ||
279 | dev_err(jrdev, "unable to map shared descriptor\n"); | ||
280 | kfree(sh_desc); | ||
281 | return -ENOMEM; | ||
282 | } | ||
283 | |||
284 | ctx->sh_desc = sh_desc; | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int aead_authenc_setkey(struct crypto_aead *aead, | ||
290 | const u8 *key, unsigned int keylen) | ||
291 | { | ||
292 | /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */ | ||
293 | static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 }; | ||
294 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
295 | struct device *jrdev = ctx->jrdev; | ||
296 | struct rtattr *rta = (void *)key; | ||
297 | struct crypto_authenc_key_param *param; | ||
298 | unsigned int authkeylen; | ||
299 | unsigned int enckeylen; | ||
300 | int ret = 0; | ||
301 | |||
302 | param = RTA_DATA(rta); | ||
303 | enckeylen = be32_to_cpu(param->enckeylen); | ||
304 | |||
305 | key += RTA_ALIGN(rta->rta_len); | ||
306 | keylen -= RTA_ALIGN(rta->rta_len); | ||
307 | |||
308 | if (keylen < enckeylen) | ||
309 | goto badkey; | ||
310 | |||
311 | authkeylen = keylen - enckeylen; | ||
312 | |||
313 | if (keylen > CAAM_MAX_KEY_SIZE) | ||
314 | goto badkey; | ||
315 | |||
316 | /* Pick class 2 key length from algorithm submask */ | ||
317 | ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >> | ||
318 | OP_ALG_ALGSEL_SHIFT] * 2; | ||
319 | ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16); | ||
320 | |||
321 | #ifdef DEBUG | ||
322 | printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n", | ||
323 | keylen, enckeylen, authkeylen); | ||
324 | printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n", | ||
325 | ctx->split_key_len, ctx->split_key_pad_len); | ||
326 | print_hex_dump(KERN_ERR, "key in @"xstr(__LINE__)": ", | ||
327 | DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); | ||
328 | #endif | ||
329 | ctx->key = kmalloc(ctx->split_key_pad_len + enckeylen, | ||
330 | GFP_KERNEL | GFP_DMA); | ||
331 | if (!ctx->key) { | ||
332 | dev_err(jrdev, "could not allocate key output memory\n"); | ||
333 | return -ENOMEM; | ||
334 | } | ||
335 | |||
336 | ret = gen_split_key(ctx, key, authkeylen); | ||
337 | if (ret) { | ||
338 | kfree(ctx->key); | ||
339 | goto badkey; | ||
340 | } | ||
341 | |||
342 | /* postpend encryption key to auth split key */ | ||
343 | memcpy(ctx->key + ctx->split_key_pad_len, key + authkeylen, enckeylen); | ||
344 | |||
345 | ctx->key_phys = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len + | ||
346 | enckeylen, DMA_TO_DEVICE); | ||
347 | if (dma_mapping_error(jrdev, ctx->key_phys)) { | ||
348 | dev_err(jrdev, "unable to map key i/o memory\n"); | ||
349 | kfree(ctx->key); | ||
350 | return -ENOMEM; | ||
351 | } | ||
352 | #ifdef DEBUG | ||
353 | print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", | ||
354 | DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, | ||
355 | ctx->split_key_pad_len + enckeylen, 1); | ||
356 | #endif | ||
357 | |||
358 | ctx->enckeylen = enckeylen; | ||
359 | |||
360 | ret = build_sh_desc_ipsec(ctx); | ||
361 | if (ret) { | ||
362 | dma_unmap_single(jrdev, ctx->key_phys, ctx->split_key_pad_len + | ||
363 | enckeylen, DMA_TO_DEVICE); | ||
364 | kfree(ctx->key); | ||
365 | } | ||
366 | |||
367 | return ret; | ||
368 | badkey: | ||
369 | crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); | ||
370 | return -EINVAL; | ||
371 | } | ||
372 | |||
373 | struct link_tbl_entry { | ||
374 | u64 ptr; | ||
375 | u32 len; | ||
376 | u8 reserved; | ||
377 | u8 buf_pool_id; | ||
378 | u16 offset; | ||
379 | }; | ||
380 | |||
381 | /* | ||
382 | * ipsec_esp_edesc - s/w-extended ipsec_esp descriptor | ||
383 | * @src_nents: number of segments in input scatterlist | ||
384 | * @dst_nents: number of segments in output scatterlist | ||
385 | * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist | ||
386 | * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE) | ||
387 | * @link_tbl_bytes: length of dma mapped link_tbl space | ||
388 | * @link_tbl_dma: bus physical mapped address of h/w link table | ||
389 | * @hw_desc: the h/w job descriptor followed by any referenced link tables | ||
390 | */ | ||
391 | struct ipsec_esp_edesc { | ||
392 | int assoc_nents; | ||
393 | int src_nents; | ||
394 | int dst_nents; | ||
395 | int link_tbl_bytes; | ||
396 | dma_addr_t link_tbl_dma; | ||
397 | struct link_tbl_entry *link_tbl; | ||
398 | u32 hw_desc[0]; | ||
399 | }; | ||
400 | |||
401 | static void ipsec_esp_unmap(struct device *dev, | ||
402 | struct ipsec_esp_edesc *edesc, | ||
403 | struct aead_request *areq) | ||
404 | { | ||
405 | dma_unmap_sg(dev, areq->assoc, edesc->assoc_nents, DMA_TO_DEVICE); | ||
406 | |||
407 | if (unlikely(areq->dst != areq->src)) { | ||
408 | dma_unmap_sg(dev, areq->src, edesc->src_nents, | ||
409 | DMA_TO_DEVICE); | ||
410 | dma_unmap_sg(dev, areq->dst, edesc->dst_nents, | ||
411 | DMA_FROM_DEVICE); | ||
412 | } else { | ||
413 | dma_unmap_sg(dev, areq->src, edesc->src_nents, | ||
414 | DMA_BIDIRECTIONAL); | ||
415 | } | ||
416 | |||
417 | if (edesc->link_tbl_bytes) | ||
418 | dma_unmap_single(dev, edesc->link_tbl_dma, | ||
419 | edesc->link_tbl_bytes, | ||
420 | DMA_TO_DEVICE); | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * ipsec_esp descriptor callbacks | ||
425 | */ | ||
426 | static void ipsec_esp_encrypt_done(struct device *jrdev, u32 *desc, u32 err, | ||
427 | void *context) | ||
428 | { | ||
429 | struct aead_request *areq = context; | ||
430 | struct ipsec_esp_edesc *edesc; | ||
431 | #ifdef DEBUG | ||
432 | struct crypto_aead *aead = crypto_aead_reqtfm(areq); | ||
433 | int ivsize = crypto_aead_ivsize(aead); | ||
434 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
435 | |||
436 | dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | ||
437 | #endif | ||
438 | edesc = (struct ipsec_esp_edesc *)((char *)desc - | ||
439 | offsetof(struct ipsec_esp_edesc, hw_desc)); | ||
440 | |||
441 | if (err) { | ||
442 | char tmp[CAAM_ERROR_STR_MAX]; | ||
443 | |||
444 | dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); | ||
445 | } | ||
446 | |||
447 | ipsec_esp_unmap(jrdev, edesc, areq); | ||
448 | |||
449 | #ifdef DEBUG | ||
450 | print_hex_dump(KERN_ERR, "assoc @"xstr(__LINE__)": ", | ||
451 | DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->assoc), | ||
452 | areq->assoclen , 1); | ||
453 | print_hex_dump(KERN_ERR, "dstiv @"xstr(__LINE__)": ", | ||
454 | DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src) - ivsize, | ||
455 | edesc->src_nents ? 100 : ivsize, 1); | ||
456 | print_hex_dump(KERN_ERR, "dst @"xstr(__LINE__)": ", | ||
457 | DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src), | ||
458 | edesc->src_nents ? 100 : areq->cryptlen + | ||
459 | ctx->authsize + 4, 1); | ||
460 | #endif | ||
461 | |||
462 | kfree(edesc); | ||
463 | |||
464 | aead_request_complete(areq, err); | ||
465 | } | ||
466 | |||
467 | static void ipsec_esp_decrypt_done(struct device *jrdev, u32 *desc, u32 err, | ||
468 | void *context) | ||
469 | { | ||
470 | struct aead_request *areq = context; | ||
471 | struct ipsec_esp_edesc *edesc; | ||
472 | #ifdef DEBUG | ||
473 | struct crypto_aead *aead = crypto_aead_reqtfm(areq); | ||
474 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
475 | |||
476 | dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | ||
477 | #endif | ||
478 | edesc = (struct ipsec_esp_edesc *)((char *)desc - | ||
479 | offsetof(struct ipsec_esp_edesc, hw_desc)); | ||
480 | |||
481 | if (err) { | ||
482 | char tmp[CAAM_ERROR_STR_MAX]; | ||
483 | |||
484 | dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); | ||
485 | } | ||
486 | |||
487 | ipsec_esp_unmap(jrdev, edesc, areq); | ||
488 | |||
489 | /* | ||
490 | * verify hw auth check passed else return -EBADMSG | ||
491 | */ | ||
492 | if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK) | ||
493 | err = -EBADMSG; | ||
494 | |||
495 | #ifdef DEBUG | ||
496 | print_hex_dump(KERN_ERR, "iphdrout@"xstr(__LINE__)": ", | ||
497 | DUMP_PREFIX_ADDRESS, 16, 4, | ||
498 | ((char *)sg_virt(areq->assoc) - sizeof(struct iphdr)), | ||
499 | sizeof(struct iphdr) + areq->assoclen + | ||
500 | ((areq->cryptlen > 1500) ? 1500 : areq->cryptlen) + | ||
501 | ctx->authsize + 36, 1); | ||
502 | if (!err && edesc->link_tbl_bytes) { | ||
503 | struct scatterlist *sg = sg_last(areq->src, edesc->src_nents); | ||
504 | print_hex_dump(KERN_ERR, "sglastout@"xstr(__LINE__)": ", | ||
505 | DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(sg), | ||
506 | sg->length + ctx->authsize + 16, 1); | ||
507 | } | ||
508 | #endif | ||
509 | kfree(edesc); | ||
510 | |||
511 | aead_request_complete(areq, err); | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * convert scatterlist to h/w link table format | ||
516 | * scatterlist must have been previously dma mapped | ||
517 | */ | ||
518 | static void sg_to_link_tbl(struct scatterlist *sg, int sg_count, | ||
519 | struct link_tbl_entry *link_tbl_ptr, u32 offset) | ||
520 | { | ||
521 | while (sg_count) { | ||
522 | link_tbl_ptr->ptr = sg_dma_address(sg); | ||
523 | link_tbl_ptr->len = sg_dma_len(sg); | ||
524 | link_tbl_ptr->reserved = 0; | ||
525 | link_tbl_ptr->buf_pool_id = 0; | ||
526 | link_tbl_ptr->offset = offset; | ||
527 | link_tbl_ptr++; | ||
528 | sg = sg_next(sg); | ||
529 | sg_count--; | ||
530 | } | ||
531 | |||
532 | /* set Final bit (marks end of link table) */ | ||
533 | link_tbl_ptr--; | ||
534 | link_tbl_ptr->len |= 0x40000000; | ||
535 | } | ||
536 | |||
537 | /* | ||
538 | * fill in and submit ipsec_esp job descriptor | ||
539 | */ | ||
540 | static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq, | ||
541 | u32 encrypt, | ||
542 | void (*callback) (struct device *dev, u32 *desc, | ||
543 | u32 err, void *context)) | ||
544 | { | ||
545 | struct crypto_aead *aead = crypto_aead_reqtfm(areq); | ||
546 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
547 | struct device *jrdev = ctx->jrdev; | ||
548 | u32 *desc = edesc->hw_desc, options; | ||
549 | int ret, sg_count, assoc_sg_count; | ||
550 | int ivsize = crypto_aead_ivsize(aead); | ||
551 | int authsize = ctx->authsize; | ||
552 | dma_addr_t ptr, dst_dma, src_dma; | ||
553 | #ifdef DEBUG | ||
554 | u32 *sh_desc = ctx->sh_desc; | ||
555 | |||
556 | debug("assoclen %d cryptlen %d authsize %d\n", | ||
557 | areq->assoclen, areq->cryptlen, authsize); | ||
558 | print_hex_dump(KERN_ERR, "assoc @"xstr(__LINE__)": ", | ||
559 | DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->assoc), | ||
560 | areq->assoclen , 1); | ||
561 | print_hex_dump(KERN_ERR, "presciv@"xstr(__LINE__)": ", | ||
562 | DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src) - ivsize, | ||
563 | edesc->src_nents ? 100 : ivsize, 1); | ||
564 | print_hex_dump(KERN_ERR, "src @"xstr(__LINE__)": ", | ||
565 | DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src), | ||
566 | edesc->src_nents ? 100 : areq->cryptlen + authsize, 1); | ||
567 | print_hex_dump(KERN_ERR, "shrdesc@"xstr(__LINE__)": ", | ||
568 | DUMP_PREFIX_ADDRESS, 16, 4, sh_desc, | ||
569 | desc_bytes(sh_desc), 1); | ||
570 | #endif | ||
571 | assoc_sg_count = dma_map_sg(jrdev, areq->assoc, edesc->assoc_nents ?: 1, | ||
572 | DMA_TO_DEVICE); | ||
573 | if (areq->src == areq->dst) | ||
574 | sg_count = dma_map_sg(jrdev, areq->src, edesc->src_nents ? : 1, | ||
575 | DMA_BIDIRECTIONAL); | ||
576 | else | ||
577 | sg_count = dma_map_sg(jrdev, areq->src, edesc->src_nents ? : 1, | ||
578 | DMA_TO_DEVICE); | ||
579 | |||
580 | /* start auth operation */ | ||
581 | append_operation(desc, ctx->class2_alg_type | OP_ALG_AS_INITFINAL | | ||
582 | (encrypt ? : OP_ALG_ICV_ON)); | ||
583 | |||
584 | /* Load FIFO with data for Class 2 CHA */ | ||
585 | options = FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG; | ||
586 | if (!edesc->assoc_nents) { | ||
587 | ptr = sg_dma_address(areq->assoc); | ||
588 | } else { | ||
589 | sg_to_link_tbl(areq->assoc, edesc->assoc_nents, | ||
590 | edesc->link_tbl, 0); | ||
591 | ptr = edesc->link_tbl_dma; | ||
592 | options |= LDST_SGF; | ||
593 | } | ||
594 | append_fifo_load(desc, ptr, areq->assoclen, options); | ||
595 | |||
596 | /* copy iv from cipher/class1 input context to class2 infifo */ | ||
597 | append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | ivsize); | ||
598 | |||
599 | if (!encrypt) { | ||
600 | u32 *jump_cmd, *uncond_jump_cmd; | ||
601 | |||
602 | /* JUMP if shared */ | ||
603 | jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD); | ||
604 | |||
605 | /* start class 1 (cipher) operation, non-shared version */ | ||
606 | append_operation(desc, ctx->class1_alg_type | | ||
607 | OP_ALG_AS_INITFINAL); | ||
608 | |||
609 | uncond_jump_cmd = append_jump(desc, 0); | ||
610 | |||
611 | set_jump_tgt_here(desc, jump_cmd); | ||
612 | |||
613 | /* start class 1 (cipher) operation, shared version */ | ||
614 | append_operation(desc, ctx->class1_alg_type | | ||
615 | OP_ALG_AS_INITFINAL | OP_ALG_AAI_DK); | ||
616 | set_jump_tgt_here(desc, uncond_jump_cmd); | ||
617 | } else | ||
618 | append_operation(desc, ctx->class1_alg_type | | ||
619 | OP_ALG_AS_INITFINAL | encrypt); | ||
620 | |||
621 | /* load payload & instruct to class2 to snoop class 1 if encrypting */ | ||
622 | options = 0; | ||
623 | if (!edesc->src_nents) { | ||
624 | src_dma = sg_dma_address(areq->src); | ||
625 | } else { | ||
626 | sg_to_link_tbl(areq->src, edesc->src_nents, edesc->link_tbl + | ||
627 | edesc->assoc_nents, 0); | ||
628 | src_dma = edesc->link_tbl_dma + edesc->assoc_nents * | ||
629 | sizeof(struct link_tbl_entry); | ||
630 | options |= LDST_SGF; | ||
631 | } | ||
632 | append_seq_in_ptr(desc, src_dma, areq->cryptlen + authsize, options); | ||
633 | append_seq_fifo_load(desc, areq->cryptlen, FIFOLD_CLASS_BOTH | | ||
634 | FIFOLD_TYPE_LASTBOTH | | ||
635 | (encrypt ? FIFOLD_TYPE_MSG1OUT2 | ||
636 | : FIFOLD_TYPE_MSG)); | ||
637 | |||
638 | /* specify destination */ | ||
639 | if (areq->src == areq->dst) { | ||
640 | dst_dma = src_dma; | ||
641 | } else { | ||
642 | sg_count = dma_map_sg(jrdev, areq->dst, edesc->dst_nents ? : 1, | ||
643 | DMA_FROM_DEVICE); | ||
644 | if (!edesc->dst_nents) { | ||
645 | dst_dma = sg_dma_address(areq->dst); | ||
646 | options = 0; | ||
647 | } else { | ||
648 | sg_to_link_tbl(areq->dst, edesc->dst_nents, | ||
649 | edesc->link_tbl + edesc->assoc_nents + | ||
650 | edesc->src_nents, 0); | ||
651 | dst_dma = edesc->link_tbl_dma + (edesc->assoc_nents + | ||
652 | edesc->src_nents) * | ||
653 | sizeof(struct link_tbl_entry); | ||
654 | options = LDST_SGF; | ||
655 | } | ||
656 | } | ||
657 | append_seq_out_ptr(desc, dst_dma, areq->cryptlen + authsize, options); | ||
658 | append_seq_fifo_store(desc, areq->cryptlen, FIFOST_TYPE_MESSAGE_DATA); | ||
659 | |||
660 | /* ICV */ | ||
661 | if (encrypt) | ||
662 | append_seq_store(desc, authsize, LDST_CLASS_2_CCB | | ||
663 | LDST_SRCDST_BYTE_CONTEXT); | ||
664 | else | ||
665 | append_seq_fifo_load(desc, authsize, FIFOLD_CLASS_CLASS2 | | ||
666 | FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV); | ||
667 | |||
668 | #ifdef DEBUG | ||
669 | debug("job_desc_len %d\n", desc_len(desc)); | ||
670 | print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", | ||
671 | DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc) , 1); | ||
672 | print_hex_dump(KERN_ERR, "jdlinkt@"xstr(__LINE__)": ", | ||
673 | DUMP_PREFIX_ADDRESS, 16, 4, edesc->link_tbl, | ||
674 | edesc->link_tbl_bytes, 1); | ||
675 | #endif | ||
676 | |||
677 | ret = caam_jr_enqueue(jrdev, desc, callback, areq); | ||
678 | if (!ret) | ||
679 | ret = -EINPROGRESS; | ||
680 | else { | ||
681 | ipsec_esp_unmap(jrdev, edesc, areq); | ||
682 | kfree(edesc); | ||
683 | } | ||
684 | |||
685 | return ret; | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * derive number of elements in scatterlist | ||
690 | */ | ||
691 | static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained) | ||
692 | { | ||
693 | struct scatterlist *sg = sg_list; | ||
694 | int sg_nents = 0; | ||
695 | |||
696 | *chained = 0; | ||
697 | while (nbytes > 0) { | ||
698 | sg_nents++; | ||
699 | nbytes -= sg->length; | ||
700 | if (!sg_is_last(sg) && (sg + 1)->length == 0) | ||
701 | *chained = 1; | ||
702 | sg = scatterwalk_sg_next(sg); | ||
703 | } | ||
704 | |||
705 | return sg_nents; | ||
706 | } | ||
707 | |||
708 | /* | ||
709 | * allocate and map the ipsec_esp extended descriptor | ||
710 | */ | ||
711 | static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq, | ||
712 | int desc_bytes) | ||
713 | { | ||
714 | struct crypto_aead *aead = crypto_aead_reqtfm(areq); | ||
715 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
716 | struct device *jrdev = ctx->jrdev; | ||
717 | gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : | ||
718 | GFP_ATOMIC; | ||
719 | int assoc_nents, src_nents, dst_nents = 0, chained, link_tbl_bytes; | ||
720 | struct ipsec_esp_edesc *edesc; | ||
721 | |||
722 | assoc_nents = sg_count(areq->assoc, areq->assoclen, &chained); | ||
723 | BUG_ON(chained); | ||
724 | if (likely(assoc_nents == 1)) | ||
725 | assoc_nents = 0; | ||
726 | |||
727 | src_nents = sg_count(areq->src, areq->cryptlen + ctx->authsize, | ||
728 | &chained); | ||
729 | BUG_ON(chained); | ||
730 | if (src_nents == 1) | ||
731 | src_nents = 0; | ||
732 | |||
733 | if (unlikely(areq->dst != areq->src)) { | ||
734 | dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize, | ||
735 | &chained); | ||
736 | BUG_ON(chained); | ||
737 | if (dst_nents == 1) | ||
738 | dst_nents = 0; | ||
739 | } | ||
740 | |||
741 | link_tbl_bytes = (assoc_nents + src_nents + dst_nents) * | ||
742 | sizeof(struct link_tbl_entry); | ||
743 | debug("link_tbl_bytes %d\n", link_tbl_bytes); | ||
744 | |||
745 | /* allocate space for base edesc and hw desc commands, link tables */ | ||
746 | edesc = kmalloc(sizeof(struct ipsec_esp_edesc) + desc_bytes + | ||
747 | link_tbl_bytes, GFP_DMA | flags); | ||
748 | if (!edesc) { | ||
749 | dev_err(jrdev, "could not allocate extended descriptor\n"); | ||
750 | return ERR_PTR(-ENOMEM); | ||
751 | } | ||
752 | |||
753 | edesc->assoc_nents = assoc_nents; | ||
754 | edesc->src_nents = src_nents; | ||
755 | edesc->dst_nents = dst_nents; | ||
756 | edesc->link_tbl = (void *)edesc + sizeof(struct ipsec_esp_edesc) + | ||
757 | desc_bytes; | ||
758 | edesc->link_tbl_dma = dma_map_single(jrdev, edesc->link_tbl, | ||
759 | link_tbl_bytes, DMA_TO_DEVICE); | ||
760 | edesc->link_tbl_bytes = link_tbl_bytes; | ||
761 | |||
762 | return edesc; | ||
763 | } | ||
764 | |||
765 | static int aead_authenc_encrypt(struct aead_request *areq) | ||
766 | { | ||
767 | struct ipsec_esp_edesc *edesc; | ||
768 | struct crypto_aead *aead = crypto_aead_reqtfm(areq); | ||
769 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
770 | struct device *jrdev = ctx->jrdev; | ||
771 | int ivsize = crypto_aead_ivsize(aead); | ||
772 | u32 *desc; | ||
773 | dma_addr_t iv_dma; | ||
774 | |||
775 | /* allocate extended descriptor */ | ||
776 | edesc = ipsec_esp_edesc_alloc(areq, DESC_AEAD_ENCRYPT_TEXT_LEN * | ||
777 | CAAM_CMD_SZ); | ||
778 | if (IS_ERR(edesc)) | ||
779 | return PTR_ERR(edesc); | ||
780 | |||
781 | desc = edesc->hw_desc; | ||
782 | |||
783 | /* insert shared descriptor pointer */ | ||
784 | init_job_desc_shared(desc, ctx->shared_desc_phys, | ||
785 | desc_len(ctx->sh_desc), HDR_SHARE_DEFER); | ||
786 | |||
787 | iv_dma = dma_map_single(jrdev, areq->iv, ivsize, DMA_TO_DEVICE); | ||
788 | /* check dma error */ | ||
789 | |||
790 | append_load(desc, iv_dma, ivsize, | ||
791 | LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT); | ||
792 | |||
793 | return ipsec_esp(edesc, areq, OP_ALG_ENCRYPT, ipsec_esp_encrypt_done); | ||
794 | } | ||
795 | |||
796 | static int aead_authenc_decrypt(struct aead_request *req) | ||
797 | { | ||
798 | struct crypto_aead *aead = crypto_aead_reqtfm(req); | ||
799 | int ivsize = crypto_aead_ivsize(aead); | ||
800 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
801 | struct device *jrdev = ctx->jrdev; | ||
802 | struct ipsec_esp_edesc *edesc; | ||
803 | u32 *desc; | ||
804 | dma_addr_t iv_dma; | ||
805 | |||
806 | req->cryptlen -= ctx->authsize; | ||
807 | |||
808 | /* allocate extended descriptor */ | ||
809 | edesc = ipsec_esp_edesc_alloc(req, DESC_AEAD_DECRYPT_TEXT_LEN * | ||
810 | CAAM_CMD_SZ); | ||
811 | if (IS_ERR(edesc)) | ||
812 | return PTR_ERR(edesc); | ||
813 | |||
814 | desc = edesc->hw_desc; | ||
815 | |||
816 | /* insert shared descriptor pointer */ | ||
817 | init_job_desc_shared(desc, ctx->shared_desc_phys, | ||
818 | desc_len(ctx->sh_desc), HDR_SHARE_DEFER); | ||
819 | |||
820 | iv_dma = dma_map_single(jrdev, req->iv, ivsize, DMA_TO_DEVICE); | ||
821 | /* check dma error */ | ||
822 | |||
823 | append_load(desc, iv_dma, ivsize, | ||
824 | LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT); | ||
825 | |||
826 | return ipsec_esp(edesc, req, !OP_ALG_ENCRYPT, ipsec_esp_decrypt_done); | ||
827 | } | ||
828 | |||
829 | static int aead_authenc_givencrypt(struct aead_givcrypt_request *req) | ||
830 | { | ||
831 | struct aead_request *areq = &req->areq; | ||
832 | struct ipsec_esp_edesc *edesc; | ||
833 | struct crypto_aead *aead = crypto_aead_reqtfm(areq); | ||
834 | struct caam_ctx *ctx = crypto_aead_ctx(aead); | ||
835 | struct device *jrdev = ctx->jrdev; | ||
836 | int ivsize = crypto_aead_ivsize(aead); | ||
837 | dma_addr_t iv_dma; | ||
838 | u32 *desc; | ||
839 | |||
840 | iv_dma = dma_map_single(jrdev, req->giv, ivsize, DMA_FROM_DEVICE); | ||
841 | |||
842 | debug("%s: giv %p\n", __func__, req->giv); | ||
843 | |||
844 | /* allocate extended descriptor */ | ||
845 | edesc = ipsec_esp_edesc_alloc(areq, DESC_AEAD_GIVENCRYPT_TEXT_LEN * | ||
846 | CAAM_CMD_SZ); | ||
847 | if (IS_ERR(edesc)) | ||
848 | return PTR_ERR(edesc); | ||
849 | |||
850 | desc = edesc->hw_desc; | ||
851 | |||
852 | /* insert shared descriptor pointer */ | ||
853 | init_job_desc_shared(desc, ctx->shared_desc_phys, | ||
854 | desc_len(ctx->sh_desc), HDR_SHARE_DEFER); | ||
855 | |||
856 | /* | ||
857 | * LOAD IMM Info FIFO | ||
858 | * to DECO, Last, Padding, Random, Message, 16 bytes | ||
859 | */ | ||
860 | append_load_imm_u32(desc, NFIFOENTRY_DEST_DECO | NFIFOENTRY_LC1 | | ||
861 | NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DTYPE_MSG | | ||
862 | NFIFOENTRY_PTYPE_RND | ivsize, | ||
863 | LDST_SRCDST_WORD_INFO_FIFO); | ||
864 | |||
865 | /* | ||
866 | * disable info fifo entries since the above serves as the entry | ||
867 | * this way, the MOVE command won't generate an entry. | ||
868 | * Note that this isn't required in more recent versions of | ||
869 | * SEC as a MOVE that doesn't do info FIFO entries is available. | ||
870 | */ | ||
871 | append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO); | ||
872 | |||
873 | /* MOVE DECO Alignment -> C1 Context 16 bytes */ | ||
874 | append_move(desc, MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX | ivsize); | ||
875 | |||
876 | /* re-enable info fifo entries */ | ||
877 | append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO); | ||
878 | |||
879 | /* MOVE C1 Context -> OFIFO 16 bytes */ | ||
880 | append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO | ivsize); | ||
881 | |||
882 | append_fifo_store(desc, iv_dma, ivsize, FIFOST_TYPE_MESSAGE_DATA); | ||
883 | |||
884 | return ipsec_esp(edesc, areq, OP_ALG_ENCRYPT, ipsec_esp_encrypt_done); | ||
885 | } | ||
886 | |||
887 | struct caam_alg_template { | ||
888 | char name[CRYPTO_MAX_ALG_NAME]; | ||
889 | char driver_name[CRYPTO_MAX_ALG_NAME]; | ||
890 | unsigned int blocksize; | ||
891 | struct aead_alg aead; | ||
892 | u32 class1_alg_type; | ||
893 | u32 class2_alg_type; | ||
894 | u32 alg_op; | ||
895 | }; | ||
896 | |||
897 | static struct caam_alg_template driver_algs[] = { | ||
898 | /* single-pass ipsec_esp descriptor */ | ||
899 | { | ||
900 | .name = "authenc(hmac(sha1),cbc(aes))", | ||
901 | .driver_name = "authenc-hmac-sha1-cbc-aes-caam", | ||
902 | .blocksize = AES_BLOCK_SIZE, | ||
903 | .aead = { | ||
904 | .setkey = aead_authenc_setkey, | ||
905 | .setauthsize = aead_authenc_setauthsize, | ||
906 | .encrypt = aead_authenc_encrypt, | ||
907 | .decrypt = aead_authenc_decrypt, | ||
908 | .givencrypt = aead_authenc_givencrypt, | ||
909 | .geniv = "<built-in>", | ||
910 | .ivsize = AES_BLOCK_SIZE, | ||
911 | .maxauthsize = SHA1_DIGEST_SIZE, | ||
912 | }, | ||
913 | .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, | ||
914 | .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, | ||
915 | .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, | ||
916 | }, | ||
917 | { | ||
918 | .name = "authenc(hmac(sha256),cbc(aes))", | ||
919 | .driver_name = "authenc-hmac-sha256-cbc-aes-caam", | ||
920 | .blocksize = AES_BLOCK_SIZE, | ||
921 | .aead = { | ||
922 | .setkey = aead_authenc_setkey, | ||
923 | .setauthsize = aead_authenc_setauthsize, | ||
924 | .encrypt = aead_authenc_encrypt, | ||
925 | .decrypt = aead_authenc_decrypt, | ||
926 | .givencrypt = aead_authenc_givencrypt, | ||
927 | .geniv = "<built-in>", | ||
928 | .ivsize = AES_BLOCK_SIZE, | ||
929 | .maxauthsize = SHA256_DIGEST_SIZE, | ||
930 | }, | ||
931 | .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, | ||
932 | .class2_alg_type = OP_ALG_ALGSEL_SHA256 | | ||
933 | OP_ALG_AAI_HMAC_PRECOMP, | ||
934 | .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, | ||
935 | }, | ||
936 | { | ||
937 | .name = "authenc(hmac(sha512),cbc(aes))", | ||
938 | .driver_name = "authenc-hmac-sha512-cbc-aes-caam", | ||
939 | .blocksize = AES_BLOCK_SIZE, | ||
940 | .aead = { | ||
941 | .setkey = aead_authenc_setkey, | ||
942 | .setauthsize = aead_authenc_setauthsize, | ||
943 | .encrypt = aead_authenc_encrypt, | ||
944 | .decrypt = aead_authenc_decrypt, | ||
945 | .givencrypt = aead_authenc_givencrypt, | ||
946 | .geniv = "<built-in>", | ||
947 | .ivsize = AES_BLOCK_SIZE, | ||
948 | .maxauthsize = SHA512_DIGEST_SIZE, | ||
949 | }, | ||
950 | .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, | ||
951 | .class2_alg_type = OP_ALG_ALGSEL_SHA512 | | ||
952 | OP_ALG_AAI_HMAC_PRECOMP, | ||
953 | .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, | ||
954 | }, | ||
955 | { | ||
956 | .name = "authenc(hmac(sha1),cbc(des3_ede))", | ||
957 | .driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam", | ||
958 | .blocksize = DES3_EDE_BLOCK_SIZE, | ||
959 | .aead = { | ||
960 | .setkey = aead_authenc_setkey, | ||
961 | .setauthsize = aead_authenc_setauthsize, | ||
962 | .encrypt = aead_authenc_encrypt, | ||
963 | .decrypt = aead_authenc_decrypt, | ||
964 | .givencrypt = aead_authenc_givencrypt, | ||
965 | .geniv = "<built-in>", | ||
966 | .ivsize = DES3_EDE_BLOCK_SIZE, | ||
967 | .maxauthsize = SHA1_DIGEST_SIZE, | ||
968 | }, | ||
969 | .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, | ||
970 | .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, | ||
971 | .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, | ||
972 | }, | ||
973 | { | ||
974 | .name = "authenc(hmac(sha256),cbc(des3_ede))", | ||
975 | .driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam", | ||
976 | .blocksize = DES3_EDE_BLOCK_SIZE, | ||
977 | .aead = { | ||
978 | .setkey = aead_authenc_setkey, | ||
979 | .setauthsize = aead_authenc_setauthsize, | ||
980 | .encrypt = aead_authenc_encrypt, | ||
981 | .decrypt = aead_authenc_decrypt, | ||
982 | .givencrypt = aead_authenc_givencrypt, | ||
983 | .geniv = "<built-in>", | ||
984 | .ivsize = DES3_EDE_BLOCK_SIZE, | ||
985 | .maxauthsize = SHA256_DIGEST_SIZE, | ||
986 | }, | ||
987 | .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, | ||
988 | .class2_alg_type = OP_ALG_ALGSEL_SHA256 | | ||
989 | OP_ALG_AAI_HMAC_PRECOMP, | ||
990 | .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, | ||
991 | }, | ||
992 | { | ||
993 | .name = "authenc(hmac(sha512),cbc(des3_ede))", | ||
994 | .driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam", | ||
995 | .blocksize = DES3_EDE_BLOCK_SIZE, | ||
996 | .aead = { | ||
997 | .setkey = aead_authenc_setkey, | ||
998 | .setauthsize = aead_authenc_setauthsize, | ||
999 | .encrypt = aead_authenc_encrypt, | ||
1000 | .decrypt = aead_authenc_decrypt, | ||
1001 | .givencrypt = aead_authenc_givencrypt, | ||
1002 | .geniv = "<built-in>", | ||
1003 | .ivsize = DES3_EDE_BLOCK_SIZE, | ||
1004 | .maxauthsize = SHA512_DIGEST_SIZE, | ||
1005 | }, | ||
1006 | .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, | ||
1007 | .class2_alg_type = OP_ALG_ALGSEL_SHA512 | | ||
1008 | OP_ALG_AAI_HMAC_PRECOMP, | ||
1009 | .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, | ||
1010 | }, | ||
1011 | { | ||
1012 | .name = "authenc(hmac(sha1),cbc(des))", | ||
1013 | .driver_name = "authenc-hmac-sha1-cbc-des-caam", | ||
1014 | .blocksize = DES_BLOCK_SIZE, | ||
1015 | .aead = { | ||
1016 | .setkey = aead_authenc_setkey, | ||
1017 | .setauthsize = aead_authenc_setauthsize, | ||
1018 | .encrypt = aead_authenc_encrypt, | ||
1019 | .decrypt = aead_authenc_decrypt, | ||
1020 | .givencrypt = aead_authenc_givencrypt, | ||
1021 | .geniv = "<built-in>", | ||
1022 | .ivsize = DES_BLOCK_SIZE, | ||
1023 | .maxauthsize = SHA1_DIGEST_SIZE, | ||
1024 | }, | ||
1025 | .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, | ||
1026 | .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, | ||
1027 | .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, | ||
1028 | }, | ||
1029 | { | ||
1030 | .name = "authenc(hmac(sha256),cbc(des))", | ||
1031 | .driver_name = "authenc-hmac-sha256-cbc-des-caam", | ||
1032 | .blocksize = DES_BLOCK_SIZE, | ||
1033 | .aead = { | ||
1034 | .setkey = aead_authenc_setkey, | ||
1035 | .setauthsize = aead_authenc_setauthsize, | ||
1036 | .encrypt = aead_authenc_encrypt, | ||
1037 | .decrypt = aead_authenc_decrypt, | ||
1038 | .givencrypt = aead_authenc_givencrypt, | ||
1039 | .geniv = "<built-in>", | ||
1040 | .ivsize = DES_BLOCK_SIZE, | ||
1041 | .maxauthsize = SHA256_DIGEST_SIZE, | ||
1042 | }, | ||
1043 | .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, | ||
1044 | .class2_alg_type = OP_ALG_ALGSEL_SHA256 | | ||
1045 | OP_ALG_AAI_HMAC_PRECOMP, | ||
1046 | .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, | ||
1047 | }, | ||
1048 | { | ||
1049 | .name = "authenc(hmac(sha512),cbc(des))", | ||
1050 | .driver_name = "authenc-hmac-sha512-cbc-des-caam", | ||
1051 | .blocksize = DES_BLOCK_SIZE, | ||
1052 | .aead = { | ||
1053 | .setkey = aead_authenc_setkey, | ||
1054 | .setauthsize = aead_authenc_setauthsize, | ||
1055 | .encrypt = aead_authenc_encrypt, | ||
1056 | .decrypt = aead_authenc_decrypt, | ||
1057 | .givencrypt = aead_authenc_givencrypt, | ||
1058 | .geniv = "<built-in>", | ||
1059 | .ivsize = DES_BLOCK_SIZE, | ||
1060 | .maxauthsize = SHA512_DIGEST_SIZE, | ||
1061 | }, | ||
1062 | .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, | ||
1063 | .class2_alg_type = OP_ALG_ALGSEL_SHA512 | | ||
1064 | OP_ALG_AAI_HMAC_PRECOMP, | ||
1065 | .alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC, | ||
1066 | }, | ||
1067 | }; | ||
1068 | |||
1069 | struct caam_crypto_alg { | ||
1070 | struct list_head entry; | ||
1071 | struct device *ctrldev; | ||
1072 | int class1_alg_type; | ||
1073 | int class2_alg_type; | ||
1074 | int alg_op; | ||
1075 | struct crypto_alg crypto_alg; | ||
1076 | }; | ||
1077 | |||
1078 | static int caam_cra_init(struct crypto_tfm *tfm) | ||
1079 | { | ||
1080 | struct crypto_alg *alg = tfm->__crt_alg; | ||
1081 | struct caam_crypto_alg *caam_alg = | ||
1082 | container_of(alg, struct caam_crypto_alg, crypto_alg); | ||
1083 | struct caam_ctx *ctx = crypto_tfm_ctx(tfm); | ||
1084 | struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev); | ||
1085 | int tgt_jr = atomic_inc_return(&priv->tfm_count); | ||
1086 | |||
1087 | /* | ||
1088 | * distribute tfms across job rings to ensure in-order | ||
1089 | * crypto request processing per tfm | ||
1090 | */ | ||
1091 | ctx->jrdev = priv->algapi_jr[(tgt_jr / 2) % priv->num_jrs_for_algapi]; | ||
1092 | |||
1093 | /* copy descriptor header template value */ | ||
1094 | ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type; | ||
1095 | ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam_alg->class2_alg_type; | ||
1096 | ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_alg->alg_op; | ||
1097 | |||
1098 | return 0; | ||
1099 | } | ||
1100 | |||
1101 | static void caam_cra_exit(struct crypto_tfm *tfm) | ||
1102 | { | ||
1103 | struct caam_ctx *ctx = crypto_tfm_ctx(tfm); | ||
1104 | |||
1105 | if (!dma_mapping_error(ctx->jrdev, ctx->shared_desc_phys)) | ||
1106 | dma_unmap_single(ctx->jrdev, ctx->shared_desc_phys, | ||
1107 | desc_bytes(ctx->sh_desc), DMA_TO_DEVICE); | ||
1108 | kfree(ctx->sh_desc); | ||
1109 | |||
1110 | if (!dma_mapping_error(ctx->jrdev, ctx->key_phys)) | ||
1111 | dma_unmap_single(ctx->jrdev, ctx->key_phys, | ||
1112 | ctx->split_key_pad_len + ctx->enckeylen, | ||
1113 | DMA_TO_DEVICE); | ||
1114 | kfree(ctx->key); | ||
1115 | } | ||
1116 | |||
1117 | static void __exit caam_algapi_exit(void) | ||
1118 | { | ||
1119 | |||
1120 | struct device_node *dev_node; | ||
1121 | struct platform_device *pdev; | ||
1122 | struct device *ctrldev; | ||
1123 | struct caam_drv_private *priv; | ||
1124 | struct caam_crypto_alg *t_alg, *n; | ||
1125 | int i, err; | ||
1126 | |||
1127 | dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); | ||
1128 | if (!dev_node) | ||
1129 | return; | ||
1130 | |||
1131 | pdev = of_find_device_by_node(dev_node); | ||
1132 | if (!pdev) | ||
1133 | return; | ||
1134 | |||
1135 | ctrldev = &pdev->dev; | ||
1136 | of_node_put(dev_node); | ||
1137 | priv = dev_get_drvdata(ctrldev); | ||
1138 | |||
1139 | if (!priv->alg_list.next) | ||
1140 | return; | ||
1141 | |||
1142 | list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) { | ||
1143 | crypto_unregister_alg(&t_alg->crypto_alg); | ||
1144 | list_del(&t_alg->entry); | ||
1145 | kfree(t_alg); | ||
1146 | } | ||
1147 | |||
1148 | for (i = 0; i < priv->total_jobrs; i++) { | ||
1149 | err = caam_jr_deregister(priv->algapi_jr[i]); | ||
1150 | if (err < 0) | ||
1151 | break; | ||
1152 | } | ||
1153 | kfree(priv->algapi_jr); | ||
1154 | } | ||
1155 | |||
1156 | static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev, | ||
1157 | struct caam_alg_template | ||
1158 | *template) | ||
1159 | { | ||
1160 | struct caam_crypto_alg *t_alg; | ||
1161 | struct crypto_alg *alg; | ||
1162 | |||
1163 | t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL); | ||
1164 | if (!t_alg) { | ||
1165 | dev_err(ctrldev, "failed to allocate t_alg\n"); | ||
1166 | return ERR_PTR(-ENOMEM); | ||
1167 | } | ||
1168 | |||
1169 | alg = &t_alg->crypto_alg; | ||
1170 | |||
1171 | snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); | ||
1172 | snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", | ||
1173 | template->driver_name); | ||
1174 | alg->cra_module = THIS_MODULE; | ||
1175 | alg->cra_init = caam_cra_init; | ||
1176 | alg->cra_exit = caam_cra_exit; | ||
1177 | alg->cra_priority = CAAM_CRA_PRIORITY; | ||
1178 | alg->cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC; | ||
1179 | alg->cra_blocksize = template->blocksize; | ||
1180 | alg->cra_alignmask = 0; | ||
1181 | alg->cra_type = &crypto_aead_type; | ||
1182 | alg->cra_ctxsize = sizeof(struct caam_ctx); | ||
1183 | alg->cra_u.aead = template->aead; | ||
1184 | |||
1185 | t_alg->class1_alg_type = template->class1_alg_type; | ||
1186 | t_alg->class2_alg_type = template->class2_alg_type; | ||
1187 | t_alg->alg_op = template->alg_op; | ||
1188 | t_alg->ctrldev = ctrldev; | ||
1189 | |||
1190 | return t_alg; | ||
1191 | } | ||
1192 | |||
1193 | static int __init caam_algapi_init(void) | ||
1194 | { | ||
1195 | struct device_node *dev_node; | ||
1196 | struct platform_device *pdev; | ||
1197 | struct device *ctrldev, **jrdev; | ||
1198 | struct caam_drv_private *priv; | ||
1199 | int i = 0, err = 0; | ||
1200 | |||
1201 | dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); | ||
1202 | if (!dev_node) | ||
1203 | return -ENODEV; | ||
1204 | |||
1205 | pdev = of_find_device_by_node(dev_node); | ||
1206 | if (!pdev) | ||
1207 | return -ENODEV; | ||
1208 | |||
1209 | ctrldev = &pdev->dev; | ||
1210 | priv = dev_get_drvdata(ctrldev); | ||
1211 | of_node_put(dev_node); | ||
1212 | |||
1213 | INIT_LIST_HEAD(&priv->alg_list); | ||
1214 | |||
1215 | jrdev = kmalloc(sizeof(*jrdev) * priv->total_jobrs, GFP_KERNEL); | ||
1216 | if (!jrdev) | ||
1217 | return -ENOMEM; | ||
1218 | |||
1219 | for (i = 0; i < priv->total_jobrs; i++) { | ||
1220 | err = caam_jr_register(ctrldev, &jrdev[i]); | ||
1221 | if (err < 0) | ||
1222 | break; | ||
1223 | } | ||
1224 | if (err < 0 && i == 0) { | ||
1225 | dev_err(ctrldev, "algapi error in job ring registration: %d\n", | ||
1226 | err); | ||
1227 | kfree(jrdev); | ||
1228 | return err; | ||
1229 | } | ||
1230 | |||
1231 | priv->num_jrs_for_algapi = i; | ||
1232 | priv->algapi_jr = jrdev; | ||
1233 | atomic_set(&priv->tfm_count, -1); | ||
1234 | |||
1235 | /* register crypto algorithms the device supports */ | ||
1236 | for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { | ||
1237 | /* TODO: check if h/w supports alg */ | ||
1238 | struct caam_crypto_alg *t_alg; | ||
1239 | |||
1240 | t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]); | ||
1241 | if (IS_ERR(t_alg)) { | ||
1242 | err = PTR_ERR(t_alg); | ||
1243 | dev_warn(ctrldev, "%s alg allocation failed\n", | ||
1244 | driver_algs[i].driver_name); | ||
1245 | continue; | ||
1246 | } | ||
1247 | |||
1248 | err = crypto_register_alg(&t_alg->crypto_alg); | ||
1249 | if (err) { | ||
1250 | dev_warn(ctrldev, "%s alg registration failed\n", | ||
1251 | t_alg->crypto_alg.cra_driver_name); | ||
1252 | kfree(t_alg); | ||
1253 | } else { | ||
1254 | list_add_tail(&t_alg->entry, &priv->alg_list); | ||
1255 | dev_info(ctrldev, "%s\n", | ||
1256 | t_alg->crypto_alg.cra_driver_name); | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | return err; | ||
1261 | } | ||
1262 | |||
1263 | module_init(caam_algapi_init); | ||
1264 | module_exit(caam_algapi_exit); | ||
1265 | |||
1266 | MODULE_LICENSE("GPL"); | ||
1267 | MODULE_DESCRIPTION("FSL CAAM support for crypto API"); | ||
1268 | MODULE_AUTHOR("Freescale Semiconductor - NMG/STC"); | ||
diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h new file mode 100644 index 000000000000..950450346f70 --- /dev/null +++ b/drivers/crypto/caam/compat.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
3 | */ | ||
4 | |||
5 | #ifndef CAAM_COMPAT_H | ||
6 | #define CAAM_COMPAT_H | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/mod_devicetable.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/crypto.h> | ||
14 | #include <linux/hw_random.h> | ||
15 | #include <linux/of_platform.h> | ||
16 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/rtnetlink.h> | ||
20 | #include <linux/in.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/debugfs.h> | ||
24 | #include <linux/circ_buf.h> | ||
25 | #include <net/xfrm.h> | ||
26 | |||
27 | #include <crypto/algapi.h> | ||
28 | #include <crypto/aes.h> | ||
29 | #include <crypto/des.h> | ||
30 | #include <crypto/sha.h> | ||
31 | #include <crypto/aead.h> | ||
32 | #include <crypto/authenc.h> | ||
33 | #include <crypto/scatterwalk.h> | ||
34 | |||
35 | #endif /* !defined(CAAM_COMPAT_H) */ | ||
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c new file mode 100644 index 000000000000..9009713a3c2e --- /dev/null +++ b/drivers/crypto/caam/ctrl.c | |||
@@ -0,0 +1,269 @@ | |||
1 | /* | ||
2 | * CAAM control-plane driver backend | ||
3 | * Controller-level driver, kernel property detection, initialization | ||
4 | * | ||
5 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
6 | */ | ||
7 | |||
8 | #include "compat.h" | ||
9 | #include "regs.h" | ||
10 | #include "intern.h" | ||
11 | #include "jr.h" | ||
12 | |||
13 | static int caam_remove(struct platform_device *pdev) | ||
14 | { | ||
15 | struct device *ctrldev; | ||
16 | struct caam_drv_private *ctrlpriv; | ||
17 | struct caam_drv_private_jr *jrpriv; | ||
18 | struct caam_full __iomem *topregs; | ||
19 | int ring, ret = 0; | ||
20 | |||
21 | ctrldev = &pdev->dev; | ||
22 | ctrlpriv = dev_get_drvdata(ctrldev); | ||
23 | topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; | ||
24 | |||
25 | /* shut down JobRs */ | ||
26 | for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { | ||
27 | ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]); | ||
28 | jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]); | ||
29 | irq_dispose_mapping(jrpriv->irq); | ||
30 | } | ||
31 | |||
32 | /* Shut down debug views */ | ||
33 | #ifdef CONFIG_DEBUG_FS | ||
34 | debugfs_remove_recursive(ctrlpriv->dfs_root); | ||
35 | #endif | ||
36 | |||
37 | /* Unmap controller region */ | ||
38 | iounmap(&topregs->ctrl); | ||
39 | |||
40 | kfree(ctrlpriv->jrdev); | ||
41 | kfree(ctrlpriv); | ||
42 | |||
43 | return ret; | ||
44 | } | ||
45 | |||
46 | /* Probe routine for CAAM top (controller) level */ | ||
47 | static int caam_probe(struct platform_device *pdev) | ||
48 | { | ||
49 | int d, ring, rspec; | ||
50 | struct device *dev; | ||
51 | struct device_node *nprop, *np; | ||
52 | struct caam_ctrl __iomem *ctrl; | ||
53 | struct caam_full __iomem *topregs; | ||
54 | struct caam_drv_private *ctrlpriv; | ||
55 | struct caam_perfmon *perfmon; | ||
56 | struct caam_deco **deco; | ||
57 | u32 deconum; | ||
58 | |||
59 | ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL); | ||
60 | if (!ctrlpriv) | ||
61 | return -ENOMEM; | ||
62 | |||
63 | dev = &pdev->dev; | ||
64 | dev_set_drvdata(dev, ctrlpriv); | ||
65 | ctrlpriv->pdev = pdev; | ||
66 | nprop = pdev->dev.of_node; | ||
67 | |||
68 | /* Get configuration properties from device tree */ | ||
69 | /* First, get register page */ | ||
70 | ctrl = of_iomap(nprop, 0); | ||
71 | if (ctrl == NULL) { | ||
72 | dev_err(dev, "caam: of_iomap() failed\n"); | ||
73 | return -ENOMEM; | ||
74 | } | ||
75 | ctrlpriv->ctrl = (struct caam_ctrl __force *)ctrl; | ||
76 | |||
77 | /* topregs used to derive pointers to CAAM sub-blocks only */ | ||
78 | topregs = (struct caam_full __iomem *)ctrl; | ||
79 | |||
80 | /* Get the IRQ of the controller (for security violations only) */ | ||
81 | ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL); | ||
82 | |||
83 | /* | ||
84 | * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, | ||
85 | * 36-bit pointers in master configuration register | ||
86 | */ | ||
87 | setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE | | ||
88 | (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0)); | ||
89 | |||
90 | if (sizeof(dma_addr_t) == sizeof(u64)) | ||
91 | dma_set_mask(dev, DMA_BIT_MASK(36)); | ||
92 | |||
93 | /* Find out how many DECOs are present */ | ||
94 | deconum = (rd_reg64(&topregs->ctrl.perfmon.cha_num) & | ||
95 | CHA_NUM_DECONUM_MASK) >> CHA_NUM_DECONUM_SHIFT; | ||
96 | |||
97 | ctrlpriv->deco = kmalloc(deconum * sizeof(struct caam_deco *), | ||
98 | GFP_KERNEL); | ||
99 | |||
100 | deco = (struct caam_deco __force **)&topregs->deco; | ||
101 | for (d = 0; d < deconum; d++) | ||
102 | ctrlpriv->deco[d] = deco[d]; | ||
103 | |||
104 | /* | ||
105 | * Detect and enable JobRs | ||
106 | * First, find out how many ring spec'ed, allocate references | ||
107 | * for all, then go probe each one. | ||
108 | */ | ||
109 | rspec = 0; | ||
110 | for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") | ||
111 | rspec++; | ||
112 | ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL); | ||
113 | if (ctrlpriv->jrdev == NULL) { | ||
114 | iounmap(&topregs->ctrl); | ||
115 | return -ENOMEM; | ||
116 | } | ||
117 | |||
118 | ring = 0; | ||
119 | ctrlpriv->total_jobrs = 0; | ||
120 | for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") { | ||
121 | caam_jr_probe(pdev, np, ring); | ||
122 | ctrlpriv->total_jobrs++; | ||
123 | ring++; | ||
124 | } | ||
125 | |||
126 | /* Check to see if QI present. If so, enable */ | ||
127 | ctrlpriv->qi_present = !!(rd_reg64(&topregs->ctrl.perfmon.comp_parms) & | ||
128 | CTPR_QI_MASK); | ||
129 | if (ctrlpriv->qi_present) { | ||
130 | ctrlpriv->qi = (struct caam_queue_if __force *)&topregs->qi; | ||
131 | /* This is all that's required to physically enable QI */ | ||
132 | wr_reg32(&topregs->qi.qi_control_lo, QICTL_DQEN); | ||
133 | } | ||
134 | |||
135 | /* If no QI and no rings specified, quit and go home */ | ||
136 | if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) { | ||
137 | dev_err(dev, "no queues configured, terminating\n"); | ||
138 | caam_remove(pdev); | ||
139 | return -ENOMEM; | ||
140 | } | ||
141 | |||
142 | /* NOTE: RTIC detection ought to go here, around Si time */ | ||
143 | |||
144 | /* Initialize queue allocator lock */ | ||
145 | spin_lock_init(&ctrlpriv->jr_alloc_lock); | ||
146 | |||
147 | /* Report "alive" for developer to see */ | ||
148 | dev_info(dev, "device ID = 0x%016llx\n", | ||
149 | rd_reg64(&topregs->ctrl.perfmon.caam_id)); | ||
150 | dev_info(dev, "job rings = %d, qi = %d\n", | ||
151 | ctrlpriv->total_jobrs, ctrlpriv->qi_present); | ||
152 | |||
153 | #ifdef CONFIG_DEBUG_FS | ||
154 | /* | ||
155 | * FIXME: needs better naming distinction, as some amalgamation of | ||
156 | * "caam" and nprop->full_name. The OF name isn't distinctive, | ||
157 | * but does separate instances | ||
158 | */ | ||
159 | perfmon = (struct caam_perfmon __force *)&ctrl->perfmon; | ||
160 | |||
161 | ctrlpriv->dfs_root = debugfs_create_dir("caam", NULL); | ||
162 | ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root); | ||
163 | |||
164 | /* Controller-level - performance monitor counters */ | ||
165 | ctrlpriv->ctl_rq_dequeued = | ||
166 | debugfs_create_u64("rq_dequeued", | ||
167 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
168 | ctrlpriv->ctl, &perfmon->req_dequeued); | ||
169 | ctrlpriv->ctl_ob_enc_req = | ||
170 | debugfs_create_u64("ob_rq_encrypted", | ||
171 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
172 | ctrlpriv->ctl, &perfmon->ob_enc_req); | ||
173 | ctrlpriv->ctl_ib_dec_req = | ||
174 | debugfs_create_u64("ib_rq_decrypted", | ||
175 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
176 | ctrlpriv->ctl, &perfmon->ib_dec_req); | ||
177 | ctrlpriv->ctl_ob_enc_bytes = | ||
178 | debugfs_create_u64("ob_bytes_encrypted", | ||
179 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
180 | ctrlpriv->ctl, &perfmon->ob_enc_bytes); | ||
181 | ctrlpriv->ctl_ob_prot_bytes = | ||
182 | debugfs_create_u64("ob_bytes_protected", | ||
183 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
184 | ctrlpriv->ctl, &perfmon->ob_prot_bytes); | ||
185 | ctrlpriv->ctl_ib_dec_bytes = | ||
186 | debugfs_create_u64("ib_bytes_decrypted", | ||
187 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
188 | ctrlpriv->ctl, &perfmon->ib_dec_bytes); | ||
189 | ctrlpriv->ctl_ib_valid_bytes = | ||
190 | debugfs_create_u64("ib_bytes_validated", | ||
191 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
192 | ctrlpriv->ctl, &perfmon->ib_valid_bytes); | ||
193 | |||
194 | /* Controller level - global status values */ | ||
195 | ctrlpriv->ctl_faultaddr = | ||
196 | debugfs_create_u64("fault_addr", | ||
197 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
198 | ctrlpriv->ctl, &perfmon->faultaddr); | ||
199 | ctrlpriv->ctl_faultdetail = | ||
200 | debugfs_create_u32("fault_detail", | ||
201 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
202 | ctrlpriv->ctl, &perfmon->faultdetail); | ||
203 | ctrlpriv->ctl_faultstatus = | ||
204 | debugfs_create_u32("fault_status", | ||
205 | S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, | ||
206 | ctrlpriv->ctl, &perfmon->status); | ||
207 | |||
208 | /* Internal covering keys (useful in non-secure mode only) */ | ||
209 | ctrlpriv->ctl_kek_wrap.data = &ctrlpriv->ctrl->kek[0]; | ||
210 | ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32); | ||
211 | ctrlpriv->ctl_kek = debugfs_create_blob("kek", | ||
212 | S_IFCHR | S_IRUSR | | ||
213 | S_IRGRP | S_IROTH, | ||
214 | ctrlpriv->ctl, | ||
215 | &ctrlpriv->ctl_kek_wrap); | ||
216 | |||
217 | ctrlpriv->ctl_tkek_wrap.data = &ctrlpriv->ctrl->tkek[0]; | ||
218 | ctrlpriv->ctl_tkek_wrap.size = KEK_KEY_SIZE * sizeof(u32); | ||
219 | ctrlpriv->ctl_tkek = debugfs_create_blob("tkek", | ||
220 | S_IFCHR | S_IRUSR | | ||
221 | S_IRGRP | S_IROTH, | ||
222 | ctrlpriv->ctl, | ||
223 | &ctrlpriv->ctl_tkek_wrap); | ||
224 | |||
225 | ctrlpriv->ctl_tdsk_wrap.data = &ctrlpriv->ctrl->tdsk[0]; | ||
226 | ctrlpriv->ctl_tdsk_wrap.size = KEK_KEY_SIZE * sizeof(u32); | ||
227 | ctrlpriv->ctl_tdsk = debugfs_create_blob("tdsk", | ||
228 | S_IFCHR | S_IRUSR | | ||
229 | S_IRGRP | S_IROTH, | ||
230 | ctrlpriv->ctl, | ||
231 | &ctrlpriv->ctl_tdsk_wrap); | ||
232 | #endif | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct of_device_id caam_match[] = { | ||
237 | { | ||
238 | .compatible = "fsl,sec-v4.0", | ||
239 | }, | ||
240 | {}, | ||
241 | }; | ||
242 | MODULE_DEVICE_TABLE(of, caam_match); | ||
243 | |||
244 | static struct platform_driver caam_driver = { | ||
245 | .driver = { | ||
246 | .name = "caam", | ||
247 | .owner = THIS_MODULE, | ||
248 | .of_match_table = caam_match, | ||
249 | }, | ||
250 | .probe = caam_probe, | ||
251 | .remove = __devexit_p(caam_remove), | ||
252 | }; | ||
253 | |||
254 | static int __init caam_base_init(void) | ||
255 | { | ||
256 | return platform_driver_register(&caam_driver); | ||
257 | } | ||
258 | |||
259 | static void __exit caam_base_exit(void) | ||
260 | { | ||
261 | return platform_driver_unregister(&caam_driver); | ||
262 | } | ||
263 | |||
264 | module_init(caam_base_init); | ||
265 | module_exit(caam_base_exit); | ||
266 | |||
267 | MODULE_LICENSE("GPL"); | ||
268 | MODULE_DESCRIPTION("FSL CAAM request backend"); | ||
269 | MODULE_AUTHOR("Freescale Semiconductor - NMG/STC"); | ||
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h new file mode 100644 index 000000000000..974a75842da9 --- /dev/null +++ b/drivers/crypto/caam/desc.h | |||
@@ -0,0 +1,1605 @@ | |||
1 | /* | ||
2 | * CAAM descriptor composition header | ||
3 | * Definitions to support CAAM descriptor instruction generation | ||
4 | * | ||
5 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
6 | */ | ||
7 | |||
8 | #ifndef DESC_H | ||
9 | #define DESC_H | ||
10 | |||
11 | /* Max size of any CAAM descriptor in 32-bit words, inclusive of header */ | ||
12 | #define MAX_CAAM_DESCSIZE 64 | ||
13 | |||
14 | /* Block size of any entity covered/uncovered with a KEK/TKEK */ | ||
15 | #define KEK_BLOCKSIZE 16 | ||
16 | |||
17 | /* | ||
18 | * Supported descriptor command types as they show up | ||
19 | * inside a descriptor command word. | ||
20 | */ | ||
21 | #define CMD_SHIFT 27 | ||
22 | #define CMD_MASK 0xf8000000 | ||
23 | |||
24 | #define CMD_KEY (0x00 << CMD_SHIFT) | ||
25 | #define CMD_SEQ_KEY (0x01 << CMD_SHIFT) | ||
26 | #define CMD_LOAD (0x02 << CMD_SHIFT) | ||
27 | #define CMD_SEQ_LOAD (0x03 << CMD_SHIFT) | ||
28 | #define CMD_FIFO_LOAD (0x04 << CMD_SHIFT) | ||
29 | #define CMD_SEQ_FIFO_LOAD (0x05 << CMD_SHIFT) | ||
30 | #define CMD_STORE (0x0a << CMD_SHIFT) | ||
31 | #define CMD_SEQ_STORE (0x0b << CMD_SHIFT) | ||
32 | #define CMD_FIFO_STORE (0x0c << CMD_SHIFT) | ||
33 | #define CMD_SEQ_FIFO_STORE (0x0d << CMD_SHIFT) | ||
34 | #define CMD_MOVE_LEN (0x0e << CMD_SHIFT) | ||
35 | #define CMD_MOVE (0x0f << CMD_SHIFT) | ||
36 | #define CMD_OPERATION (0x10 << CMD_SHIFT) | ||
37 | #define CMD_SIGNATURE (0x12 << CMD_SHIFT) | ||
38 | #define CMD_JUMP (0x14 << CMD_SHIFT) | ||
39 | #define CMD_MATH (0x15 << CMD_SHIFT) | ||
40 | #define CMD_DESC_HDR (0x16 << CMD_SHIFT) | ||
41 | #define CMD_SHARED_DESC_HDR (0x17 << CMD_SHIFT) | ||
42 | #define CMD_SEQ_IN_PTR (0x1e << CMD_SHIFT) | ||
43 | #define CMD_SEQ_OUT_PTR (0x1f << CMD_SHIFT) | ||
44 | |||
45 | /* General-purpose class selector for all commands */ | ||
46 | #define CLASS_SHIFT 25 | ||
47 | #define CLASS_MASK (0x03 << CLASS_SHIFT) | ||
48 | |||
49 | #define CLASS_NONE (0x00 << CLASS_SHIFT) | ||
50 | #define CLASS_1 (0x01 << CLASS_SHIFT) | ||
51 | #define CLASS_2 (0x02 << CLASS_SHIFT) | ||
52 | #define CLASS_BOTH (0x03 << CLASS_SHIFT) | ||
53 | |||
54 | /* | ||
55 | * Descriptor header command constructs | ||
56 | * Covers shared, job, and trusted descriptor headers | ||
57 | */ | ||
58 | |||
59 | /* | ||
60 | * Do Not Run - marks a descriptor inexecutable if there was | ||
61 | * a preceding error somewhere | ||
62 | */ | ||
63 | #define HDR_DNR 0x01000000 | ||
64 | |||
65 | /* | ||
66 | * ONE - should always be set. Combination of ONE (always | ||
67 | * set) and ZRO (always clear) forms an endianness sanity check | ||
68 | */ | ||
69 | #define HDR_ONE 0x00800000 | ||
70 | #define HDR_ZRO 0x00008000 | ||
71 | |||
72 | /* Start Index or SharedDesc Length */ | ||
73 | #define HDR_START_IDX_MASK 0x3f | ||
74 | #define HDR_START_IDX_SHIFT 16 | ||
75 | |||
76 | /* If shared descriptor header, 6-bit length */ | ||
77 | #define HDR_DESCLEN_SHR_MASK 0x3f | ||
78 | |||
79 | /* If non-shared header, 7-bit length */ | ||
80 | #define HDR_DESCLEN_MASK 0x7f | ||
81 | |||
82 | /* This is a TrustedDesc (if not SharedDesc) */ | ||
83 | #define HDR_TRUSTED 0x00004000 | ||
84 | |||
85 | /* Make into TrustedDesc (if not SharedDesc) */ | ||
86 | #define HDR_MAKE_TRUSTED 0x00002000 | ||
87 | |||
88 | /* Save context if self-shared (if SharedDesc) */ | ||
89 | #define HDR_SAVECTX 0x00001000 | ||
90 | |||
91 | /* Next item points to SharedDesc */ | ||
92 | #define HDR_SHARED 0x00001000 | ||
93 | |||
94 | /* | ||
95 | * Reverse Execution Order - execute JobDesc first, then | ||
96 | * execute SharedDesc (normally SharedDesc goes first). | ||
97 | */ | ||
98 | #define HDR_REVERSE 0x00000800 | ||
99 | |||
100 | /* Propogate DNR property to SharedDesc */ | ||
101 | #define HDR_PROP_DNR 0x00000800 | ||
102 | |||
103 | /* JobDesc/SharedDesc share property */ | ||
104 | #define HDR_SD_SHARE_MASK 0x03 | ||
105 | #define HDR_SD_SHARE_SHIFT 8 | ||
106 | #define HDR_JD_SHARE_MASK 0x07 | ||
107 | #define HDR_JD_SHARE_SHIFT 8 | ||
108 | |||
109 | #define HDR_SHARE_NEVER (0x00 << HDR_SD_SHARE_SHIFT) | ||
110 | #define HDR_SHARE_WAIT (0x01 << HDR_SD_SHARE_SHIFT) | ||
111 | #define HDR_SHARE_SERIAL (0x02 << HDR_SD_SHARE_SHIFT) | ||
112 | #define HDR_SHARE_ALWAYS (0x03 << HDR_SD_SHARE_SHIFT) | ||
113 | #define HDR_SHARE_DEFER (0x04 << HDR_SD_SHARE_SHIFT) | ||
114 | |||
115 | /* JobDesc/SharedDesc descriptor length */ | ||
116 | #define HDR_JD_LENGTH_MASK 0x7f | ||
117 | #define HDR_SD_LENGTH_MASK 0x3f | ||
118 | |||
119 | /* | ||
120 | * KEY/SEQ_KEY Command Constructs | ||
121 | */ | ||
122 | |||
123 | /* Key Destination Class: 01 = Class 1, 02 - Class 2 */ | ||
124 | #define KEY_DEST_CLASS_SHIFT 25 /* use CLASS_1 or CLASS_2 */ | ||
125 | #define KEY_DEST_CLASS_MASK (0x03 << KEY_DEST_CLASS_SHIFT) | ||
126 | |||
127 | /* Scatter-Gather Table/Variable Length Field */ | ||
128 | #define KEY_SGF 0x01000000 | ||
129 | #define KEY_VLF 0x01000000 | ||
130 | |||
131 | /* Immediate - Key follows command in the descriptor */ | ||
132 | #define KEY_IMM 0x00800000 | ||
133 | |||
134 | /* | ||
135 | * Encrypted - Key is encrypted either with the KEK, or | ||
136 | * with the TDKEK if TK is set | ||
137 | */ | ||
138 | #define KEY_ENC 0x00400000 | ||
139 | |||
140 | /* | ||
141 | * No Write Back - Do not allow key to be FIFO STOREd | ||
142 | */ | ||
143 | #define KEY_NWB 0x00200000 | ||
144 | |||
145 | /* | ||
146 | * Enhanced Encryption of Key | ||
147 | */ | ||
148 | #define KEY_EKT 0x00100000 | ||
149 | |||
150 | /* | ||
151 | * Encrypted with Trusted Key | ||
152 | */ | ||
153 | #define KEY_TK 0x00008000 | ||
154 | |||
155 | /* | ||
156 | * KDEST - Key Destination: 0 - class key register, | ||
157 | * 1 - PKHA 'e', 2 - AFHA Sbox, 3 - MDHA split-key | ||
158 | */ | ||
159 | #define KEY_DEST_SHIFT 16 | ||
160 | #define KEY_DEST_MASK (0x03 << KEY_DEST_SHIFT) | ||
161 | |||
162 | #define KEY_DEST_CLASS_REG (0x00 << KEY_DEST_SHIFT) | ||
163 | #define KEY_DEST_PKHA_E (0x01 << KEY_DEST_SHIFT) | ||
164 | #define KEY_DEST_AFHA_SBOX (0x02 << KEY_DEST_SHIFT) | ||
165 | #define KEY_DEST_MDHA_SPLIT (0x03 << KEY_DEST_SHIFT) | ||
166 | |||
167 | /* Length in bytes */ | ||
168 | #define KEY_LENGTH_MASK 0x000003ff | ||
169 | |||
170 | /* | ||
171 | * LOAD/SEQ_LOAD/STORE/SEQ_STORE Command Constructs | ||
172 | */ | ||
173 | |||
174 | /* | ||
175 | * Load/Store Destination: 0 = class independent CCB, | ||
176 | * 1 = class 1 CCB, 2 = class 2 CCB, 3 = DECO | ||
177 | */ | ||
178 | #define LDST_CLASS_SHIFT 25 | ||
179 | #define LDST_CLASS_MASK (0x03 << LDST_CLASS_SHIFT) | ||
180 | #define LDST_CLASS_IND_CCB (0x00 << LDST_CLASS_SHIFT) | ||
181 | #define LDST_CLASS_1_CCB (0x01 << LDST_CLASS_SHIFT) | ||
182 | #define LDST_CLASS_2_CCB (0x02 << LDST_CLASS_SHIFT) | ||
183 | #define LDST_CLASS_DECO (0x03 << LDST_CLASS_SHIFT) | ||
184 | |||
185 | /* Scatter-Gather Table/Variable Length Field */ | ||
186 | #define LDST_SGF 0x01000000 | ||
187 | #define LDST_VLF LDST_SGF | ||
188 | |||
189 | /* Immediate - Key follows this command in descriptor */ | ||
190 | #define LDST_IMM_MASK 1 | ||
191 | #define LDST_IMM_SHIFT 23 | ||
192 | #define LDST_IMM (LDST_IMM_MASK << LDST_IMM_SHIFT) | ||
193 | |||
194 | /* SRC/DST - Destination for LOAD, Source for STORE */ | ||
195 | #define LDST_SRCDST_SHIFT 16 | ||
196 | #define LDST_SRCDST_MASK (0x7f << LDST_SRCDST_SHIFT) | ||
197 | |||
198 | #define LDST_SRCDST_BYTE_CONTEXT (0x20 << LDST_SRCDST_SHIFT) | ||
199 | #define LDST_SRCDST_BYTE_KEY (0x40 << LDST_SRCDST_SHIFT) | ||
200 | #define LDST_SRCDST_BYTE_INFIFO (0x7c << LDST_SRCDST_SHIFT) | ||
201 | #define LDST_SRCDST_BYTE_OUTFIFO (0x7e << LDST_SRCDST_SHIFT) | ||
202 | |||
203 | #define LDST_SRCDST_WORD_MODE_REG (0x00 << LDST_SRCDST_SHIFT) | ||
204 | #define LDST_SRCDST_WORD_KEYSZ_REG (0x01 << LDST_SRCDST_SHIFT) | ||
205 | #define LDST_SRCDST_WORD_DATASZ_REG (0x02 << LDST_SRCDST_SHIFT) | ||
206 | #define LDST_SRCDST_WORD_ICVSZ_REG (0x03 << LDST_SRCDST_SHIFT) | ||
207 | #define LDST_SRCDST_WORD_CHACTRL (0x06 << LDST_SRCDST_SHIFT) | ||
208 | #define LDST_SRCDST_WORD_DECOCTRL (0x06 << LDST_SRCDST_SHIFT) | ||
209 | #define LDST_SRCDST_WORD_IRQCTRL (0x07 << LDST_SRCDST_SHIFT) | ||
210 | #define LDST_SRCDST_WORD_DECO_PCLOVRD (0x07 << LDST_SRCDST_SHIFT) | ||
211 | #define LDST_SRCDST_WORD_CLRW (0x08 << LDST_SRCDST_SHIFT) | ||
212 | #define LDST_SRCDST_WORD_DECO_MATH0 (0x08 << LDST_SRCDST_SHIFT) | ||
213 | #define LDST_SRCDST_WORD_STAT (0x09 << LDST_SRCDST_SHIFT) | ||
214 | #define LDST_SRCDST_WORD_DECO_MATH1 (0x09 << LDST_SRCDST_SHIFT) | ||
215 | #define LDST_SRCDST_WORD_DECO_MATH2 (0x0a << LDST_SRCDST_SHIFT) | ||
216 | #define LDST_SRCDST_WORD_DECO_AAD_SZ (0x0b << LDST_SRCDST_SHIFT) | ||
217 | #define LDST_SRCDST_WORD_DECO_MATH3 (0x0b << LDST_SRCDST_SHIFT) | ||
218 | #define LDST_SRCDST_WORD_CLASS1_ICV_SZ (0x0c << LDST_SRCDST_SHIFT) | ||
219 | #define LDST_SRCDST_WORD_ALTDS_CLASS1 (0x0f << LDST_SRCDST_SHIFT) | ||
220 | #define LDST_SRCDST_WORD_PKHA_A_SZ (0x10 << LDST_SRCDST_SHIFT) | ||
221 | #define LDST_SRCDST_WORD_PKHA_B_SZ (0x11 << LDST_SRCDST_SHIFT) | ||
222 | #define LDST_SRCDST_WORD_PKHA_N_SZ (0x12 << LDST_SRCDST_SHIFT) | ||
223 | #define LDST_SRCDST_WORD_PKHA_E_SZ (0x13 << LDST_SRCDST_SHIFT) | ||
224 | #define LDST_SRCDST_WORD_DESCBUF (0x40 << LDST_SRCDST_SHIFT) | ||
225 | #define LDST_SRCDST_WORD_INFO_FIFO (0x7a << LDST_SRCDST_SHIFT) | ||
226 | |||
227 | /* Offset in source/destination */ | ||
228 | #define LDST_OFFSET_SHIFT 8 | ||
229 | #define LDST_OFFSET_MASK (0xff << LDST_OFFSET_SHIFT) | ||
230 | |||
231 | /* LDOFF definitions used when DST = LDST_SRCDST_WORD_DECOCTRL */ | ||
232 | /* These could also be shifted by LDST_OFFSET_SHIFT - this reads better */ | ||
233 | #define LDOFF_CHG_SHARE_SHIFT 0 | ||
234 | #define LDOFF_CHG_SHARE_MASK (0x3 << LDOFF_CHG_SHARE_SHIFT) | ||
235 | #define LDOFF_CHG_SHARE_NEVER (0x1 << LDOFF_CHG_SHARE_SHIFT) | ||
236 | #define LDOFF_CHG_SHARE_OK_NO_PROP (0x2 << LDOFF_CHG_SHARE_SHIFT) | ||
237 | #define LDOFF_CHG_SHARE_OK_PROP (0x3 << LDOFF_CHG_SHARE_SHIFT) | ||
238 | |||
239 | #define LDOFF_ENABLE_AUTO_NFIFO (1 << 2) | ||
240 | #define LDOFF_DISABLE_AUTO_NFIFO (1 << 3) | ||
241 | |||
242 | #define LDOFF_CHG_NONSEQLIODN_SHIFT 4 | ||
243 | #define LDOFF_CHG_NONSEQLIODN_MASK (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT) | ||
244 | #define LDOFF_CHG_NONSEQLIODN_SEQ (0x1 << LDOFF_CHG_NONSEQLIODN_SHIFT) | ||
245 | #define LDOFF_CHG_NONSEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_NONSEQLIODN_SHIFT) | ||
246 | #define LDOFF_CHG_NONSEQLIODN_TRUSTED (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT) | ||
247 | |||
248 | #define LDOFF_CHG_SEQLIODN_SHIFT 6 | ||
249 | #define LDOFF_CHG_SEQLIODN_MASK (0x3 << LDOFF_CHG_SEQLIODN_SHIFT) | ||
250 | #define LDOFF_CHG_SEQLIODN_SEQ (0x1 << LDOFF_CHG_SEQLIODN_SHIFT) | ||
251 | #define LDOFF_CHG_SEQLIODN_NON_SEQ (0x2 << LDOFF_CHG_SEQLIODN_SHIFT) | ||
252 | #define LDOFF_CHG_SEQLIODN_TRUSTED (0x3 << LDOFF_CHG_SEQLIODN_SHIFT) | ||
253 | |||
254 | /* Data length in bytes */ | ||
255 | #define LDST_LEN_SHIFT 0 | ||
256 | #define LDST_LEN_MASK (0xff << LDST_LEN_SHIFT) | ||
257 | |||
258 | /* Special Length definitions when dst=deco-ctrl */ | ||
259 | #define LDLEN_ENABLE_OSL_COUNT (1 << 7) | ||
260 | #define LDLEN_RST_CHA_OFIFO_PTR (1 << 6) | ||
261 | #define LDLEN_RST_OFIFO (1 << 5) | ||
262 | #define LDLEN_SET_OFIFO_OFF_VALID (1 << 4) | ||
263 | #define LDLEN_SET_OFIFO_OFF_RSVD (1 << 3) | ||
264 | #define LDLEN_SET_OFIFO_OFFSET_SHIFT 0 | ||
265 | #define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT) | ||
266 | |||
267 | /* | ||
268 | * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE | ||
269 | * Command Constructs | ||
270 | */ | ||
271 | |||
272 | /* | ||
273 | * Load Destination: 0 = skip (SEQ_FIFO_LOAD only), | ||
274 | * 1 = Load for Class1, 2 = Load for Class2, 3 = Load both | ||
275 | * Store Source: 0 = normal, 1 = Class1key, 2 = Class2key | ||
276 | */ | ||
277 | #define FIFOLD_CLASS_SHIFT 25 | ||
278 | #define FIFOLD_CLASS_MASK (0x03 << FIFOLD_CLASS_SHIFT) | ||
279 | #define FIFOLD_CLASS_SKIP (0x00 << FIFOLD_CLASS_SHIFT) | ||
280 | #define FIFOLD_CLASS_CLASS1 (0x01 << FIFOLD_CLASS_SHIFT) | ||
281 | #define FIFOLD_CLASS_CLASS2 (0x02 << FIFOLD_CLASS_SHIFT) | ||
282 | #define FIFOLD_CLASS_BOTH (0x03 << FIFOLD_CLASS_SHIFT) | ||
283 | |||
284 | #define FIFOST_CLASS_SHIFT 25 | ||
285 | #define FIFOST_CLASS_MASK (0x03 << FIFOST_CLASS_SHIFT) | ||
286 | #define FIFOST_CLASS_NORMAL (0x00 << FIFOST_CLASS_SHIFT) | ||
287 | #define FIFOST_CLASS_CLASS1KEY (0x01 << FIFOST_CLASS_SHIFT) | ||
288 | #define FIFOST_CLASS_CLASS2KEY (0x02 << FIFOST_CLASS_SHIFT) | ||
289 | |||
290 | /* | ||
291 | * Scatter-Gather Table/Variable Length Field | ||
292 | * If set for FIFO_LOAD, refers to a SG table. Within | ||
293 | * SEQ_FIFO_LOAD, is variable input sequence | ||
294 | */ | ||
295 | #define FIFOLDST_SGF_SHIFT 24 | ||
296 | #define FIFOLDST_SGF_MASK (1 << FIFOLDST_SGF_SHIFT) | ||
297 | #define FIFOLDST_VLF_MASK (1 << FIFOLDST_SGF_SHIFT) | ||
298 | #define FIFOLDST_SGF (1 << FIFOLDST_SGF_SHIFT) | ||
299 | #define FIFOLDST_VLF (1 << FIFOLDST_SGF_SHIFT) | ||
300 | |||
301 | /* Immediate - Data follows command in descriptor */ | ||
302 | #define FIFOLD_IMM_SHIFT 23 | ||
303 | #define FIFOLD_IMM_MASK (1 << FIFOLD_IMM_SHIFT) | ||
304 | #define FIFOLD_IMM (1 << FIFOLD_IMM_SHIFT) | ||
305 | |||
306 | /* Continue - Not the last FIFO store to come */ | ||
307 | #define FIFOST_CONT_SHIFT 23 | ||
308 | #define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT) | ||
309 | #define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT) | ||
310 | |||
311 | /* | ||
312 | * Extended Length - use 32-bit extended length that | ||
313 | * follows the pointer field. Illegal with IMM set | ||
314 | */ | ||
315 | #define FIFOLDST_EXT_SHIFT 22 | ||
316 | #define FIFOLDST_EXT_MASK (1 << FIFOLDST_EXT_SHIFT) | ||
317 | #define FIFOLDST_EXT (1 << FIFOLDST_EXT_SHIFT) | ||
318 | |||
319 | /* Input data type.*/ | ||
320 | #define FIFOLD_TYPE_SHIFT 16 | ||
321 | #define FIFOLD_CONT_TYPE_SHIFT 19 /* shift past last-flush bits */ | ||
322 | #define FIFOLD_TYPE_MASK (0x3f << FIFOLD_TYPE_SHIFT) | ||
323 | |||
324 | /* PK types */ | ||
325 | #define FIFOLD_TYPE_PK (0x00 << FIFOLD_TYPE_SHIFT) | ||
326 | #define FIFOLD_TYPE_PK_MASK (0x30 << FIFOLD_TYPE_SHIFT) | ||
327 | #define FIFOLD_TYPE_PK_TYPEMASK (0x0f << FIFOLD_TYPE_SHIFT) | ||
328 | #define FIFOLD_TYPE_PK_A0 (0x00 << FIFOLD_TYPE_SHIFT) | ||
329 | #define FIFOLD_TYPE_PK_A1 (0x01 << FIFOLD_TYPE_SHIFT) | ||
330 | #define FIFOLD_TYPE_PK_A2 (0x02 << FIFOLD_TYPE_SHIFT) | ||
331 | #define FIFOLD_TYPE_PK_A3 (0x03 << FIFOLD_TYPE_SHIFT) | ||
332 | #define FIFOLD_TYPE_PK_B0 (0x04 << FIFOLD_TYPE_SHIFT) | ||
333 | #define FIFOLD_TYPE_PK_B1 (0x05 << FIFOLD_TYPE_SHIFT) | ||
334 | #define FIFOLD_TYPE_PK_B2 (0x06 << FIFOLD_TYPE_SHIFT) | ||
335 | #define FIFOLD_TYPE_PK_B3 (0x07 << FIFOLD_TYPE_SHIFT) | ||
336 | #define FIFOLD_TYPE_PK_N (0x08 << FIFOLD_TYPE_SHIFT) | ||
337 | #define FIFOLD_TYPE_PK_A (0x0c << FIFOLD_TYPE_SHIFT) | ||
338 | #define FIFOLD_TYPE_PK_B (0x0d << FIFOLD_TYPE_SHIFT) | ||
339 | |||
340 | /* Other types. Need to OR in last/flush bits as desired */ | ||
341 | #define FIFOLD_TYPE_MSG_MASK (0x38 << FIFOLD_TYPE_SHIFT) | ||
342 | #define FIFOLD_TYPE_MSG (0x10 << FIFOLD_TYPE_SHIFT) | ||
343 | #define FIFOLD_TYPE_MSG1OUT2 (0x18 << FIFOLD_TYPE_SHIFT) | ||
344 | #define FIFOLD_TYPE_IV (0x20 << FIFOLD_TYPE_SHIFT) | ||
345 | #define FIFOLD_TYPE_BITDATA (0x28 << FIFOLD_TYPE_SHIFT) | ||
346 | #define FIFOLD_TYPE_AAD (0x30 << FIFOLD_TYPE_SHIFT) | ||
347 | #define FIFOLD_TYPE_ICV (0x38 << FIFOLD_TYPE_SHIFT) | ||
348 | |||
349 | /* Last/Flush bits for use with "other" types above */ | ||
350 | #define FIFOLD_TYPE_ACT_MASK (0x07 << FIFOLD_TYPE_SHIFT) | ||
351 | #define FIFOLD_TYPE_NOACTION (0x00 << FIFOLD_TYPE_SHIFT) | ||
352 | #define FIFOLD_TYPE_FLUSH1 (0x01 << FIFOLD_TYPE_SHIFT) | ||
353 | #define FIFOLD_TYPE_LAST1 (0x02 << FIFOLD_TYPE_SHIFT) | ||
354 | #define FIFOLD_TYPE_LAST2FLUSH (0x03 << FIFOLD_TYPE_SHIFT) | ||
355 | #define FIFOLD_TYPE_LAST2 (0x04 << FIFOLD_TYPE_SHIFT) | ||
356 | #define FIFOLD_TYPE_LAST2FLUSH1 (0x05 << FIFOLD_TYPE_SHIFT) | ||
357 | #define FIFOLD_TYPE_LASTBOTH (0x06 << FIFOLD_TYPE_SHIFT) | ||
358 | #define FIFOLD_TYPE_LASTBOTHFL (0x07 << FIFOLD_TYPE_SHIFT) | ||
359 | |||
360 | #define FIFOLDST_LEN_MASK 0xffff | ||
361 | #define FIFOLDST_EXT_LEN_MASK 0xffffffff | ||
362 | |||
363 | /* Output data types */ | ||
364 | #define FIFOST_TYPE_SHIFT 16 | ||
365 | #define FIFOST_TYPE_MASK (0x3f << FIFOST_TYPE_SHIFT) | ||
366 | |||
367 | #define FIFOST_TYPE_PKHA_A0 (0x00 << FIFOST_TYPE_SHIFT) | ||
368 | #define FIFOST_TYPE_PKHA_A1 (0x01 << FIFOST_TYPE_SHIFT) | ||
369 | #define FIFOST_TYPE_PKHA_A2 (0x02 << FIFOST_TYPE_SHIFT) | ||
370 | #define FIFOST_TYPE_PKHA_A3 (0x03 << FIFOST_TYPE_SHIFT) | ||
371 | #define FIFOST_TYPE_PKHA_B0 (0x04 << FIFOST_TYPE_SHIFT) | ||
372 | #define FIFOST_TYPE_PKHA_B1 (0x05 << FIFOST_TYPE_SHIFT) | ||
373 | #define FIFOST_TYPE_PKHA_B2 (0x06 << FIFOST_TYPE_SHIFT) | ||
374 | #define FIFOST_TYPE_PKHA_B3 (0x07 << FIFOST_TYPE_SHIFT) | ||
375 | #define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT) | ||
376 | #define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT) | ||
377 | #define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT) | ||
378 | #define FIFOST_TYPE_AF_SBOX_JKEK (0x10 << FIFOST_TYPE_SHIFT) | ||
379 | #define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT) | ||
380 | #define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT) | ||
381 | #define FIFOST_TYPE_PKHA_E_TKEK (0x23 << FIFOST_TYPE_SHIFT) | ||
382 | #define FIFOST_TYPE_KEY_KEK (0x24 << FIFOST_TYPE_SHIFT) | ||
383 | #define FIFOST_TYPE_KEY_TKEK (0x25 << FIFOST_TYPE_SHIFT) | ||
384 | #define FIFOST_TYPE_SPLIT_KEK (0x26 << FIFOST_TYPE_SHIFT) | ||
385 | #define FIFOST_TYPE_SPLIT_TKEK (0x27 << FIFOST_TYPE_SHIFT) | ||
386 | #define FIFOST_TYPE_OUTFIFO_KEK (0x28 << FIFOST_TYPE_SHIFT) | ||
387 | #define FIFOST_TYPE_OUTFIFO_TKEK (0x29 << FIFOST_TYPE_SHIFT) | ||
388 | #define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT) | ||
389 | #define FIFOST_TYPE_RNGSTORE (0x34 << FIFOST_TYPE_SHIFT) | ||
390 | #define FIFOST_TYPE_RNGFIFO (0x35 << FIFOST_TYPE_SHIFT) | ||
391 | #define FIFOST_TYPE_SKIP (0x3f << FIFOST_TYPE_SHIFT) | ||
392 | |||
393 | /* | ||
394 | * OPERATION Command Constructs | ||
395 | */ | ||
396 | |||
397 | /* Operation type selectors - OP TYPE */ | ||
398 | #define OP_TYPE_SHIFT 24 | ||
399 | #define OP_TYPE_MASK (0x07 << OP_TYPE_SHIFT) | ||
400 | |||
401 | #define OP_TYPE_UNI_PROTOCOL (0x00 << OP_TYPE_SHIFT) | ||
402 | #define OP_TYPE_PK (0x01 << OP_TYPE_SHIFT) | ||
403 | #define OP_TYPE_CLASS1_ALG (0x02 << OP_TYPE_SHIFT) | ||
404 | #define OP_TYPE_CLASS2_ALG (0x04 << OP_TYPE_SHIFT) | ||
405 | #define OP_TYPE_DECAP_PROTOCOL (0x06 << OP_TYPE_SHIFT) | ||
406 | #define OP_TYPE_ENCAP_PROTOCOL (0x07 << OP_TYPE_SHIFT) | ||
407 | |||
408 | /* ProtocolID selectors - PROTID */ | ||
409 | #define OP_PCLID_SHIFT 16 | ||
410 | #define OP_PCLID_MASK (0xff << 16) | ||
411 | |||
412 | /* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */ | ||
413 | #define OP_PCLID_IKEV1_PRF (0x01 << OP_PCLID_SHIFT) | ||
414 | #define OP_PCLID_IKEV2_PRF (0x02 << OP_PCLID_SHIFT) | ||
415 | #define OP_PCLID_SSL30_PRF (0x08 << OP_PCLID_SHIFT) | ||
416 | #define OP_PCLID_TLS10_PRF (0x09 << OP_PCLID_SHIFT) | ||
417 | #define OP_PCLID_TLS11_PRF (0x0a << OP_PCLID_SHIFT) | ||
418 | #define OP_PCLID_DTLS10_PRF (0x0c << OP_PCLID_SHIFT) | ||
419 | #define OP_PCLID_PRF (0x06 << OP_PCLID_SHIFT) | ||
420 | #define OP_PCLID_BLOB (0x0d << OP_PCLID_SHIFT) | ||
421 | #define OP_PCLID_SECRETKEY (0x11 << OP_PCLID_SHIFT) | ||
422 | #define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT) | ||
423 | #define OP_PCLID_DSASIGN (0x15 << OP_PCLID_SHIFT) | ||
424 | #define OP_PCLID_DSAVERIFY (0x16 << OP_PCLID_SHIFT) | ||
425 | |||
426 | /* Assuming OP_TYPE = OP_TYPE_DECAP_PROTOCOL/ENCAP_PROTOCOL */ | ||
427 | #define OP_PCLID_IPSEC (0x01 << OP_PCLID_SHIFT) | ||
428 | #define OP_PCLID_SRTP (0x02 << OP_PCLID_SHIFT) | ||
429 | #define OP_PCLID_MACSEC (0x03 << OP_PCLID_SHIFT) | ||
430 | #define OP_PCLID_WIFI (0x04 << OP_PCLID_SHIFT) | ||
431 | #define OP_PCLID_WIMAX (0x05 << OP_PCLID_SHIFT) | ||
432 | #define OP_PCLID_SSL30 (0x08 << OP_PCLID_SHIFT) | ||
433 | #define OP_PCLID_TLS10 (0x09 << OP_PCLID_SHIFT) | ||
434 | #define OP_PCLID_TLS11 (0x0a << OP_PCLID_SHIFT) | ||
435 | #define OP_PCLID_TLS12 (0x0b << OP_PCLID_SHIFT) | ||
436 | #define OP_PCLID_DTLS (0x0c << OP_PCLID_SHIFT) | ||
437 | |||
438 | /* | ||
439 | * ProtocolInfo selectors | ||
440 | */ | ||
441 | #define OP_PCLINFO_MASK 0xffff | ||
442 | |||
443 | /* for OP_PCLID_IPSEC */ | ||
444 | #define OP_PCL_IPSEC_CIPHER_MASK 0xff00 | ||
445 | #define OP_PCL_IPSEC_AUTH_MASK 0x00ff | ||
446 | |||
447 | #define OP_PCL_IPSEC_DES_IV64 0x0100 | ||
448 | #define OP_PCL_IPSEC_DES 0x0200 | ||
449 | #define OP_PCL_IPSEC_3DES 0x0300 | ||
450 | #define OP_PCL_IPSEC_AES_CBC 0x0c00 | ||
451 | #define OP_PCL_IPSEC_AES_CTR 0x0d00 | ||
452 | #define OP_PCL_IPSEC_AES_XTS 0x1600 | ||
453 | #define OP_PCL_IPSEC_AES_CCM8 0x0e00 | ||
454 | #define OP_PCL_IPSEC_AES_CCM12 0x0f00 | ||
455 | #define OP_PCL_IPSEC_AES_CCM16 0x1000 | ||
456 | #define OP_PCL_IPSEC_AES_GCM8 0x1200 | ||
457 | #define OP_PCL_IPSEC_AES_GCM12 0x1300 | ||
458 | #define OP_PCL_IPSEC_AES_GCM16 0x1400 | ||
459 | |||
460 | #define OP_PCL_IPSEC_HMAC_NULL 0x0000 | ||
461 | #define OP_PCL_IPSEC_HMAC_MD5_96 0x0001 | ||
462 | #define OP_PCL_IPSEC_HMAC_SHA1_96 0x0002 | ||
463 | #define OP_PCL_IPSEC_AES_XCBC_MAC_96 0x0005 | ||
464 | #define OP_PCL_IPSEC_HMAC_MD5_128 0x0006 | ||
465 | #define OP_PCL_IPSEC_HMAC_SHA1_160 0x0007 | ||
466 | #define OP_PCL_IPSEC_HMAC_SHA2_256_128 0x000c | ||
467 | #define OP_PCL_IPSEC_HMAC_SHA2_384_192 0x000d | ||
468 | #define OP_PCL_IPSEC_HMAC_SHA2_512_256 0x000e | ||
469 | |||
470 | /* For SRTP - OP_PCLID_SRTP */ | ||
471 | #define OP_PCL_SRTP_CIPHER_MASK 0xff00 | ||
472 | #define OP_PCL_SRTP_AUTH_MASK 0x00ff | ||
473 | |||
474 | #define OP_PCL_SRTP_AES_CTR 0x0d00 | ||
475 | |||
476 | #define OP_PCL_SRTP_HMAC_SHA1_160 0x0007 | ||
477 | |||
478 | /* For SSL 3.0 - OP_PCLID_SSL30 */ | ||
479 | #define OP_PCL_SSL30_AES_128_CBC_SHA 0x002f | ||
480 | #define OP_PCL_SSL30_AES_128_CBC_SHA_2 0x0030 | ||
481 | #define OP_PCL_SSL30_AES_128_CBC_SHA_3 0x0031 | ||
482 | #define OP_PCL_SSL30_AES_128_CBC_SHA_4 0x0032 | ||
483 | #define OP_PCL_SSL30_AES_128_CBC_SHA_5 0x0033 | ||
484 | #define OP_PCL_SSL30_AES_128_CBC_SHA_6 0x0034 | ||
485 | #define OP_PCL_SSL30_AES_128_CBC_SHA_7 0x008c | ||
486 | #define OP_PCL_SSL30_AES_128_CBC_SHA_8 0x0090 | ||
487 | #define OP_PCL_SSL30_AES_128_CBC_SHA_9 0x0094 | ||
488 | #define OP_PCL_SSL30_AES_128_CBC_SHA_10 0xc004 | ||
489 | #define OP_PCL_SSL30_AES_128_CBC_SHA_11 0xc009 | ||
490 | #define OP_PCL_SSL30_AES_128_CBC_SHA_12 0xc00e | ||
491 | #define OP_PCL_SSL30_AES_128_CBC_SHA_13 0xc013 | ||
492 | #define OP_PCL_SSL30_AES_128_CBC_SHA_14 0xc018 | ||
493 | #define OP_PCL_SSL30_AES_128_CBC_SHA_15 0xc01d | ||
494 | #define OP_PCL_SSL30_AES_128_CBC_SHA_16 0xc01e | ||
495 | #define OP_PCL_SSL30_AES_128_CBC_SHA_17 0xc01f | ||
496 | |||
497 | #define OP_PCL_SSL30_AES_256_CBC_SHA 0x0035 | ||
498 | #define OP_PCL_SSL30_AES_256_CBC_SHA_2 0x0036 | ||
499 | #define OP_PCL_SSL30_AES_256_CBC_SHA_3 0x0037 | ||
500 | #define OP_PCL_SSL30_AES_256_CBC_SHA_4 0x0038 | ||
501 | #define OP_PCL_SSL30_AES_256_CBC_SHA_5 0x0039 | ||
502 | #define OP_PCL_SSL30_AES_256_CBC_SHA_6 0x003a | ||
503 | #define OP_PCL_SSL30_AES_256_CBC_SHA_7 0x008d | ||
504 | #define OP_PCL_SSL30_AES_256_CBC_SHA_8 0x0091 | ||
505 | #define OP_PCL_SSL30_AES_256_CBC_SHA_9 0x0095 | ||
506 | #define OP_PCL_SSL30_AES_256_CBC_SHA_10 0xc005 | ||
507 | #define OP_PCL_SSL30_AES_256_CBC_SHA_11 0xc00a | ||
508 | #define OP_PCL_SSL30_AES_256_CBC_SHA_12 0xc00f | ||
509 | #define OP_PCL_SSL30_AES_256_CBC_SHA_13 0xc014 | ||
510 | #define OP_PCL_SSL30_AES_256_CBC_SHA_14 0xc019 | ||
511 | #define OP_PCL_SSL30_AES_256_CBC_SHA_15 0xc020 | ||
512 | #define OP_PCL_SSL30_AES_256_CBC_SHA_16 0xc021 | ||
513 | #define OP_PCL_SSL30_AES_256_CBC_SHA_17 0xc022 | ||
514 | |||
515 | #define OP_PCL_SSL30_3DES_EDE_CBC_MD5 0x0023 | ||
516 | |||
517 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA 0x001f | ||
518 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_2 0x008b | ||
519 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_3 0x008f | ||
520 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_4 0x0093 | ||
521 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_5 0x000a | ||
522 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_6 0x000d | ||
523 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_7 0x0010 | ||
524 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_8 0x0013 | ||
525 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_9 0x0016 | ||
526 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_10 0x001b | ||
527 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_11 0xc003 | ||
528 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_12 0xc008 | ||
529 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_13 0xc00d | ||
530 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_14 0xc012 | ||
531 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_15 0xc017 | ||
532 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_16 0xc01a | ||
533 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_17 0xc01b | ||
534 | #define OP_PCL_SSL30_3DES_EDE_CBC_SHA_18 0xc01c | ||
535 | |||
536 | #define OP_PCL_SSL30_DES40_CBC_MD5 0x0029 | ||
537 | |||
538 | #define OP_PCL_SSL30_DES_CBC_MD5 0x0022 | ||
539 | |||
540 | #define OP_PCL_SSL30_DES40_CBC_SHA 0x0008 | ||
541 | #define OP_PCL_SSL30_DES40_CBC_SHA_2 0x000b | ||
542 | #define OP_PCL_SSL30_DES40_CBC_SHA_3 0x000e | ||
543 | #define OP_PCL_SSL30_DES40_CBC_SHA_4 0x0011 | ||
544 | #define OP_PCL_SSL30_DES40_CBC_SHA_5 0x0014 | ||
545 | #define OP_PCL_SSL30_DES40_CBC_SHA_6 0x0019 | ||
546 | #define OP_PCL_SSL30_DES40_CBC_SHA_7 0x0026 | ||
547 | |||
548 | #define OP_PCL_SSL30_DES_CBC_SHA 0x001e | ||
549 | #define OP_PCL_SSL30_DES_CBC_SHA_2 0x0009 | ||
550 | #define OP_PCL_SSL30_DES_CBC_SHA_3 0x000c | ||
551 | #define OP_PCL_SSL30_DES_CBC_SHA_4 0x000f | ||
552 | #define OP_PCL_SSL30_DES_CBC_SHA_5 0x0012 | ||
553 | #define OP_PCL_SSL30_DES_CBC_SHA_6 0x0015 | ||
554 | #define OP_PCL_SSL30_DES_CBC_SHA_7 0x001a | ||
555 | |||
556 | #define OP_PCL_SSL30_RC4_128_MD5 0x0024 | ||
557 | #define OP_PCL_SSL30_RC4_128_MD5_2 0x0004 | ||
558 | #define OP_PCL_SSL30_RC4_128_MD5_3 0x0018 | ||
559 | |||
560 | #define OP_PCL_SSL30_RC4_40_MD5 0x002b | ||
561 | #define OP_PCL_SSL30_RC4_40_MD5_2 0x0003 | ||
562 | #define OP_PCL_SSL30_RC4_40_MD5_3 0x0017 | ||
563 | |||
564 | #define OP_PCL_SSL30_RC4_128_SHA 0x0020 | ||
565 | #define OP_PCL_SSL30_RC4_128_SHA_2 0x008a | ||
566 | #define OP_PCL_SSL30_RC4_128_SHA_3 0x008e | ||
567 | #define OP_PCL_SSL30_RC4_128_SHA_4 0x0092 | ||
568 | #define OP_PCL_SSL30_RC4_128_SHA_5 0x0005 | ||
569 | #define OP_PCL_SSL30_RC4_128_SHA_6 0xc002 | ||
570 | #define OP_PCL_SSL30_RC4_128_SHA_7 0xc007 | ||
571 | #define OP_PCL_SSL30_RC4_128_SHA_8 0xc00c | ||
572 | #define OP_PCL_SSL30_RC4_128_SHA_9 0xc011 | ||
573 | #define OP_PCL_SSL30_RC4_128_SHA_10 0xc016 | ||
574 | |||
575 | #define OP_PCL_SSL30_RC4_40_SHA 0x0028 | ||
576 | |||
577 | |||
578 | /* For TLS 1.0 - OP_PCLID_TLS10 */ | ||
579 | #define OP_PCL_TLS10_AES_128_CBC_SHA 0x002f | ||
580 | #define OP_PCL_TLS10_AES_128_CBC_SHA_2 0x0030 | ||
581 | #define OP_PCL_TLS10_AES_128_CBC_SHA_3 0x0031 | ||
582 | #define OP_PCL_TLS10_AES_128_CBC_SHA_4 0x0032 | ||
583 | #define OP_PCL_TLS10_AES_128_CBC_SHA_5 0x0033 | ||
584 | #define OP_PCL_TLS10_AES_128_CBC_SHA_6 0x0034 | ||
585 | #define OP_PCL_TLS10_AES_128_CBC_SHA_7 0x008c | ||
586 | #define OP_PCL_TLS10_AES_128_CBC_SHA_8 0x0090 | ||
587 | #define OP_PCL_TLS10_AES_128_CBC_SHA_9 0x0094 | ||
588 | #define OP_PCL_TLS10_AES_128_CBC_SHA_10 0xc004 | ||
589 | #define OP_PCL_TLS10_AES_128_CBC_SHA_11 0xc009 | ||
590 | #define OP_PCL_TLS10_AES_128_CBC_SHA_12 0xc00e | ||
591 | #define OP_PCL_TLS10_AES_128_CBC_SHA_13 0xc013 | ||
592 | #define OP_PCL_TLS10_AES_128_CBC_SHA_14 0xc018 | ||
593 | #define OP_PCL_TLS10_AES_128_CBC_SHA_15 0xc01d | ||
594 | #define OP_PCL_TLS10_AES_128_CBC_SHA_16 0xc01e | ||
595 | #define OP_PCL_TLS10_AES_128_CBC_SHA_17 0xc01f | ||
596 | |||
597 | #define OP_PCL_TLS10_AES_256_CBC_SHA 0x0035 | ||
598 | #define OP_PCL_TLS10_AES_256_CBC_SHA_2 0x0036 | ||
599 | #define OP_PCL_TLS10_AES_256_CBC_SHA_3 0x0037 | ||
600 | #define OP_PCL_TLS10_AES_256_CBC_SHA_4 0x0038 | ||
601 | #define OP_PCL_TLS10_AES_256_CBC_SHA_5 0x0039 | ||
602 | #define OP_PCL_TLS10_AES_256_CBC_SHA_6 0x003a | ||
603 | #define OP_PCL_TLS10_AES_256_CBC_SHA_7 0x008d | ||
604 | #define OP_PCL_TLS10_AES_256_CBC_SHA_8 0x0091 | ||
605 | #define OP_PCL_TLS10_AES_256_CBC_SHA_9 0x0095 | ||
606 | #define OP_PCL_TLS10_AES_256_CBC_SHA_10 0xc005 | ||
607 | #define OP_PCL_TLS10_AES_256_CBC_SHA_11 0xc00a | ||
608 | #define OP_PCL_TLS10_AES_256_CBC_SHA_12 0xc00f | ||
609 | #define OP_PCL_TLS10_AES_256_CBC_SHA_13 0xc014 | ||
610 | #define OP_PCL_TLS10_AES_256_CBC_SHA_14 0xc019 | ||
611 | #define OP_PCL_TLS10_AES_256_CBC_SHA_15 0xc020 | ||
612 | #define OP_PCL_TLS10_AES_256_CBC_SHA_16 0xc021 | ||
613 | #define OP_PCL_TLS10_AES_256_CBC_SHA_17 0xc022 | ||
614 | |||
615 | /* #define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0x0023 */ | ||
616 | |||
617 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA 0x001f | ||
618 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_2 0x008b | ||
619 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_3 0x008f | ||
620 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_4 0x0093 | ||
621 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_5 0x000a | ||
622 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_6 0x000d | ||
623 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_7 0x0010 | ||
624 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_8 0x0013 | ||
625 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_9 0x0016 | ||
626 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_10 0x001b | ||
627 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_11 0xc003 | ||
628 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_12 0xc008 | ||
629 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_13 0xc00d | ||
630 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_14 0xc012 | ||
631 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_15 0xc017 | ||
632 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_16 0xc01a | ||
633 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_17 0xc01b | ||
634 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA_18 0xc01c | ||
635 | |||
636 | #define OP_PCL_TLS10_DES40_CBC_MD5 0x0029 | ||
637 | |||
638 | #define OP_PCL_TLS10_DES_CBC_MD5 0x0022 | ||
639 | |||
640 | #define OP_PCL_TLS10_DES40_CBC_SHA 0x0008 | ||
641 | #define OP_PCL_TLS10_DES40_CBC_SHA_2 0x000b | ||
642 | #define OP_PCL_TLS10_DES40_CBC_SHA_3 0x000e | ||
643 | #define OP_PCL_TLS10_DES40_CBC_SHA_4 0x0011 | ||
644 | #define OP_PCL_TLS10_DES40_CBC_SHA_5 0x0014 | ||
645 | #define OP_PCL_TLS10_DES40_CBC_SHA_6 0x0019 | ||
646 | #define OP_PCL_TLS10_DES40_CBC_SHA_7 0x0026 | ||
647 | |||
648 | |||
649 | #define OP_PCL_TLS10_DES_CBC_SHA 0x001e | ||
650 | #define OP_PCL_TLS10_DES_CBC_SHA_2 0x0009 | ||
651 | #define OP_PCL_TLS10_DES_CBC_SHA_3 0x000c | ||
652 | #define OP_PCL_TLS10_DES_CBC_SHA_4 0x000f | ||
653 | #define OP_PCL_TLS10_DES_CBC_SHA_5 0x0012 | ||
654 | #define OP_PCL_TLS10_DES_CBC_SHA_6 0x0015 | ||
655 | #define OP_PCL_TLS10_DES_CBC_SHA_7 0x001a | ||
656 | |||
657 | #define OP_PCL_TLS10_RC4_128_MD5 0x0024 | ||
658 | #define OP_PCL_TLS10_RC4_128_MD5_2 0x0004 | ||
659 | #define OP_PCL_TLS10_RC4_128_MD5_3 0x0018 | ||
660 | |||
661 | #define OP_PCL_TLS10_RC4_40_MD5 0x002b | ||
662 | #define OP_PCL_TLS10_RC4_40_MD5_2 0x0003 | ||
663 | #define OP_PCL_TLS10_RC4_40_MD5_3 0x0017 | ||
664 | |||
665 | #define OP_PCL_TLS10_RC4_128_SHA 0x0020 | ||
666 | #define OP_PCL_TLS10_RC4_128_SHA_2 0x008a | ||
667 | #define OP_PCL_TLS10_RC4_128_SHA_3 0x008e | ||
668 | #define OP_PCL_TLS10_RC4_128_SHA_4 0x0092 | ||
669 | #define OP_PCL_TLS10_RC4_128_SHA_5 0x0005 | ||
670 | #define OP_PCL_TLS10_RC4_128_SHA_6 0xc002 | ||
671 | #define OP_PCL_TLS10_RC4_128_SHA_7 0xc007 | ||
672 | #define OP_PCL_TLS10_RC4_128_SHA_8 0xc00c | ||
673 | #define OP_PCL_TLS10_RC4_128_SHA_9 0xc011 | ||
674 | #define OP_PCL_TLS10_RC4_128_SHA_10 0xc016 | ||
675 | |||
676 | #define OP_PCL_TLS10_RC4_40_SHA 0x0028 | ||
677 | |||
678 | #define OP_PCL_TLS10_3DES_EDE_CBC_MD5 0xff23 | ||
679 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA160 0xff30 | ||
680 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA224 0xff34 | ||
681 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA256 0xff36 | ||
682 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA384 0xff33 | ||
683 | #define OP_PCL_TLS10_3DES_EDE_CBC_SHA512 0xff35 | ||
684 | #define OP_PCL_TLS10_AES_128_CBC_SHA160 0xff80 | ||
685 | #define OP_PCL_TLS10_AES_128_CBC_SHA224 0xff84 | ||
686 | #define OP_PCL_TLS10_AES_128_CBC_SHA256 0xff86 | ||
687 | #define OP_PCL_TLS10_AES_128_CBC_SHA384 0xff83 | ||
688 | #define OP_PCL_TLS10_AES_128_CBC_SHA512 0xff85 | ||
689 | #define OP_PCL_TLS10_AES_192_CBC_SHA160 0xff20 | ||
690 | #define OP_PCL_TLS10_AES_192_CBC_SHA224 0xff24 | ||
691 | #define OP_PCL_TLS10_AES_192_CBC_SHA256 0xff26 | ||
692 | #define OP_PCL_TLS10_AES_192_CBC_SHA384 0xff23 | ||
693 | #define OP_PCL_TLS10_AES_192_CBC_SHA512 0xff25 | ||
694 | #define OP_PCL_TLS10_AES_256_CBC_SHA160 0xff60 | ||
695 | #define OP_PCL_TLS10_AES_256_CBC_SHA224 0xff64 | ||
696 | #define OP_PCL_TLS10_AES_256_CBC_SHA256 0xff66 | ||
697 | #define OP_PCL_TLS10_AES_256_CBC_SHA384 0xff63 | ||
698 | #define OP_PCL_TLS10_AES_256_CBC_SHA512 0xff65 | ||
699 | |||
700 | |||
701 | |||
702 | /* For TLS 1.1 - OP_PCLID_TLS11 */ | ||
703 | #define OP_PCL_TLS11_AES_128_CBC_SHA 0x002f | ||
704 | #define OP_PCL_TLS11_AES_128_CBC_SHA_2 0x0030 | ||
705 | #define OP_PCL_TLS11_AES_128_CBC_SHA_3 0x0031 | ||
706 | #define OP_PCL_TLS11_AES_128_CBC_SHA_4 0x0032 | ||
707 | #define OP_PCL_TLS11_AES_128_CBC_SHA_5 0x0033 | ||
708 | #define OP_PCL_TLS11_AES_128_CBC_SHA_6 0x0034 | ||
709 | #define OP_PCL_TLS11_AES_128_CBC_SHA_7 0x008c | ||
710 | #define OP_PCL_TLS11_AES_128_CBC_SHA_8 0x0090 | ||
711 | #define OP_PCL_TLS11_AES_128_CBC_SHA_9 0x0094 | ||
712 | #define OP_PCL_TLS11_AES_128_CBC_SHA_10 0xc004 | ||
713 | #define OP_PCL_TLS11_AES_128_CBC_SHA_11 0xc009 | ||
714 | #define OP_PCL_TLS11_AES_128_CBC_SHA_12 0xc00e | ||
715 | #define OP_PCL_TLS11_AES_128_CBC_SHA_13 0xc013 | ||
716 | #define OP_PCL_TLS11_AES_128_CBC_SHA_14 0xc018 | ||
717 | #define OP_PCL_TLS11_AES_128_CBC_SHA_15 0xc01d | ||
718 | #define OP_PCL_TLS11_AES_128_CBC_SHA_16 0xc01e | ||
719 | #define OP_PCL_TLS11_AES_128_CBC_SHA_17 0xc01f | ||
720 | |||
721 | #define OP_PCL_TLS11_AES_256_CBC_SHA 0x0035 | ||
722 | #define OP_PCL_TLS11_AES_256_CBC_SHA_2 0x0036 | ||
723 | #define OP_PCL_TLS11_AES_256_CBC_SHA_3 0x0037 | ||
724 | #define OP_PCL_TLS11_AES_256_CBC_SHA_4 0x0038 | ||
725 | #define OP_PCL_TLS11_AES_256_CBC_SHA_5 0x0039 | ||
726 | #define OP_PCL_TLS11_AES_256_CBC_SHA_6 0x003a | ||
727 | #define OP_PCL_TLS11_AES_256_CBC_SHA_7 0x008d | ||
728 | #define OP_PCL_TLS11_AES_256_CBC_SHA_8 0x0091 | ||
729 | #define OP_PCL_TLS11_AES_256_CBC_SHA_9 0x0095 | ||
730 | #define OP_PCL_TLS11_AES_256_CBC_SHA_10 0xc005 | ||
731 | #define OP_PCL_TLS11_AES_256_CBC_SHA_11 0xc00a | ||
732 | #define OP_PCL_TLS11_AES_256_CBC_SHA_12 0xc00f | ||
733 | #define OP_PCL_TLS11_AES_256_CBC_SHA_13 0xc014 | ||
734 | #define OP_PCL_TLS11_AES_256_CBC_SHA_14 0xc019 | ||
735 | #define OP_PCL_TLS11_AES_256_CBC_SHA_15 0xc020 | ||
736 | #define OP_PCL_TLS11_AES_256_CBC_SHA_16 0xc021 | ||
737 | #define OP_PCL_TLS11_AES_256_CBC_SHA_17 0xc022 | ||
738 | |||
739 | /* #define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0x0023 */ | ||
740 | |||
741 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA 0x001f | ||
742 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_2 0x008b | ||
743 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_3 0x008f | ||
744 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_4 0x0093 | ||
745 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_5 0x000a | ||
746 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_6 0x000d | ||
747 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_7 0x0010 | ||
748 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_8 0x0013 | ||
749 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_9 0x0016 | ||
750 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_10 0x001b | ||
751 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_11 0xc003 | ||
752 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_12 0xc008 | ||
753 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_13 0xc00d | ||
754 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_14 0xc012 | ||
755 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_15 0xc017 | ||
756 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_16 0xc01a | ||
757 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_17 0xc01b | ||
758 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA_18 0xc01c | ||
759 | |||
760 | #define OP_PCL_TLS11_DES40_CBC_MD5 0x0029 | ||
761 | |||
762 | #define OP_PCL_TLS11_DES_CBC_MD5 0x0022 | ||
763 | |||
764 | #define OP_PCL_TLS11_DES40_CBC_SHA 0x0008 | ||
765 | #define OP_PCL_TLS11_DES40_CBC_SHA_2 0x000b | ||
766 | #define OP_PCL_TLS11_DES40_CBC_SHA_3 0x000e | ||
767 | #define OP_PCL_TLS11_DES40_CBC_SHA_4 0x0011 | ||
768 | #define OP_PCL_TLS11_DES40_CBC_SHA_5 0x0014 | ||
769 | #define OP_PCL_TLS11_DES40_CBC_SHA_6 0x0019 | ||
770 | #define OP_PCL_TLS11_DES40_CBC_SHA_7 0x0026 | ||
771 | |||
772 | #define OP_PCL_TLS11_DES_CBC_SHA 0x001e | ||
773 | #define OP_PCL_TLS11_DES_CBC_SHA_2 0x0009 | ||
774 | #define OP_PCL_TLS11_DES_CBC_SHA_3 0x000c | ||
775 | #define OP_PCL_TLS11_DES_CBC_SHA_4 0x000f | ||
776 | #define OP_PCL_TLS11_DES_CBC_SHA_5 0x0012 | ||
777 | #define OP_PCL_TLS11_DES_CBC_SHA_6 0x0015 | ||
778 | #define OP_PCL_TLS11_DES_CBC_SHA_7 0x001a | ||
779 | |||
780 | #define OP_PCL_TLS11_RC4_128_MD5 0x0024 | ||
781 | #define OP_PCL_TLS11_RC4_128_MD5_2 0x0004 | ||
782 | #define OP_PCL_TLS11_RC4_128_MD5_3 0x0018 | ||
783 | |||
784 | #define OP_PCL_TLS11_RC4_40_MD5 0x002b | ||
785 | #define OP_PCL_TLS11_RC4_40_MD5_2 0x0003 | ||
786 | #define OP_PCL_TLS11_RC4_40_MD5_3 0x0017 | ||
787 | |||
788 | #define OP_PCL_TLS11_RC4_128_SHA 0x0020 | ||
789 | #define OP_PCL_TLS11_RC4_128_SHA_2 0x008a | ||
790 | #define OP_PCL_TLS11_RC4_128_SHA_3 0x008e | ||
791 | #define OP_PCL_TLS11_RC4_128_SHA_4 0x0092 | ||
792 | #define OP_PCL_TLS11_RC4_128_SHA_5 0x0005 | ||
793 | #define OP_PCL_TLS11_RC4_128_SHA_6 0xc002 | ||
794 | #define OP_PCL_TLS11_RC4_128_SHA_7 0xc007 | ||
795 | #define OP_PCL_TLS11_RC4_128_SHA_8 0xc00c | ||
796 | #define OP_PCL_TLS11_RC4_128_SHA_9 0xc011 | ||
797 | #define OP_PCL_TLS11_RC4_128_SHA_10 0xc016 | ||
798 | |||
799 | #define OP_PCL_TLS11_RC4_40_SHA 0x0028 | ||
800 | |||
801 | #define OP_PCL_TLS11_3DES_EDE_CBC_MD5 0xff23 | ||
802 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA160 0xff30 | ||
803 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA224 0xff34 | ||
804 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA256 0xff36 | ||
805 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA384 0xff33 | ||
806 | #define OP_PCL_TLS11_3DES_EDE_CBC_SHA512 0xff35 | ||
807 | #define OP_PCL_TLS11_AES_128_CBC_SHA160 0xff80 | ||
808 | #define OP_PCL_TLS11_AES_128_CBC_SHA224 0xff84 | ||
809 | #define OP_PCL_TLS11_AES_128_CBC_SHA256 0xff86 | ||
810 | #define OP_PCL_TLS11_AES_128_CBC_SHA384 0xff83 | ||
811 | #define OP_PCL_TLS11_AES_128_CBC_SHA512 0xff85 | ||
812 | #define OP_PCL_TLS11_AES_192_CBC_SHA160 0xff20 | ||
813 | #define OP_PCL_TLS11_AES_192_CBC_SHA224 0xff24 | ||
814 | #define OP_PCL_TLS11_AES_192_CBC_SHA256 0xff26 | ||
815 | #define OP_PCL_TLS11_AES_192_CBC_SHA384 0xff23 | ||
816 | #define OP_PCL_TLS11_AES_192_CBC_SHA512 0xff25 | ||
817 | #define OP_PCL_TLS11_AES_256_CBC_SHA160 0xff60 | ||
818 | #define OP_PCL_TLS11_AES_256_CBC_SHA224 0xff64 | ||
819 | #define OP_PCL_TLS11_AES_256_CBC_SHA256 0xff66 | ||
820 | #define OP_PCL_TLS11_AES_256_CBC_SHA384 0xff63 | ||
821 | #define OP_PCL_TLS11_AES_256_CBC_SHA512 0xff65 | ||
822 | |||
823 | |||
824 | /* For TLS 1.2 - OP_PCLID_TLS12 */ | ||
825 | #define OP_PCL_TLS12_AES_128_CBC_SHA 0x002f | ||
826 | #define OP_PCL_TLS12_AES_128_CBC_SHA_2 0x0030 | ||
827 | #define OP_PCL_TLS12_AES_128_CBC_SHA_3 0x0031 | ||
828 | #define OP_PCL_TLS12_AES_128_CBC_SHA_4 0x0032 | ||
829 | #define OP_PCL_TLS12_AES_128_CBC_SHA_5 0x0033 | ||
830 | #define OP_PCL_TLS12_AES_128_CBC_SHA_6 0x0034 | ||
831 | #define OP_PCL_TLS12_AES_128_CBC_SHA_7 0x008c | ||
832 | #define OP_PCL_TLS12_AES_128_CBC_SHA_8 0x0090 | ||
833 | #define OP_PCL_TLS12_AES_128_CBC_SHA_9 0x0094 | ||
834 | #define OP_PCL_TLS12_AES_128_CBC_SHA_10 0xc004 | ||
835 | #define OP_PCL_TLS12_AES_128_CBC_SHA_11 0xc009 | ||
836 | #define OP_PCL_TLS12_AES_128_CBC_SHA_12 0xc00e | ||
837 | #define OP_PCL_TLS12_AES_128_CBC_SHA_13 0xc013 | ||
838 | #define OP_PCL_TLS12_AES_128_CBC_SHA_14 0xc018 | ||
839 | #define OP_PCL_TLS12_AES_128_CBC_SHA_15 0xc01d | ||
840 | #define OP_PCL_TLS12_AES_128_CBC_SHA_16 0xc01e | ||
841 | #define OP_PCL_TLS12_AES_128_CBC_SHA_17 0xc01f | ||
842 | |||
843 | #define OP_PCL_TLS12_AES_256_CBC_SHA 0x0035 | ||
844 | #define OP_PCL_TLS12_AES_256_CBC_SHA_2 0x0036 | ||
845 | #define OP_PCL_TLS12_AES_256_CBC_SHA_3 0x0037 | ||
846 | #define OP_PCL_TLS12_AES_256_CBC_SHA_4 0x0038 | ||
847 | #define OP_PCL_TLS12_AES_256_CBC_SHA_5 0x0039 | ||
848 | #define OP_PCL_TLS12_AES_256_CBC_SHA_6 0x003a | ||
849 | #define OP_PCL_TLS12_AES_256_CBC_SHA_7 0x008d | ||
850 | #define OP_PCL_TLS12_AES_256_CBC_SHA_8 0x0091 | ||
851 | #define OP_PCL_TLS12_AES_256_CBC_SHA_9 0x0095 | ||
852 | #define OP_PCL_TLS12_AES_256_CBC_SHA_10 0xc005 | ||
853 | #define OP_PCL_TLS12_AES_256_CBC_SHA_11 0xc00a | ||
854 | #define OP_PCL_TLS12_AES_256_CBC_SHA_12 0xc00f | ||
855 | #define OP_PCL_TLS12_AES_256_CBC_SHA_13 0xc014 | ||
856 | #define OP_PCL_TLS12_AES_256_CBC_SHA_14 0xc019 | ||
857 | #define OP_PCL_TLS12_AES_256_CBC_SHA_15 0xc020 | ||
858 | #define OP_PCL_TLS12_AES_256_CBC_SHA_16 0xc021 | ||
859 | #define OP_PCL_TLS12_AES_256_CBC_SHA_17 0xc022 | ||
860 | |||
861 | /* #define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0x0023 */ | ||
862 | |||
863 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA 0x001f | ||
864 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_2 0x008b | ||
865 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_3 0x008f | ||
866 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_4 0x0093 | ||
867 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_5 0x000a | ||
868 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_6 0x000d | ||
869 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_7 0x0010 | ||
870 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_8 0x0013 | ||
871 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_9 0x0016 | ||
872 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_10 0x001b | ||
873 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_11 0xc003 | ||
874 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_12 0xc008 | ||
875 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_13 0xc00d | ||
876 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_14 0xc012 | ||
877 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_15 0xc017 | ||
878 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_16 0xc01a | ||
879 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_17 0xc01b | ||
880 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA_18 0xc01c | ||
881 | |||
882 | #define OP_PCL_TLS12_DES40_CBC_MD5 0x0029 | ||
883 | |||
884 | #define OP_PCL_TLS12_DES_CBC_MD5 0x0022 | ||
885 | |||
886 | #define OP_PCL_TLS12_DES40_CBC_SHA 0x0008 | ||
887 | #define OP_PCL_TLS12_DES40_CBC_SHA_2 0x000b | ||
888 | #define OP_PCL_TLS12_DES40_CBC_SHA_3 0x000e | ||
889 | #define OP_PCL_TLS12_DES40_CBC_SHA_4 0x0011 | ||
890 | #define OP_PCL_TLS12_DES40_CBC_SHA_5 0x0014 | ||
891 | #define OP_PCL_TLS12_DES40_CBC_SHA_6 0x0019 | ||
892 | #define OP_PCL_TLS12_DES40_CBC_SHA_7 0x0026 | ||
893 | |||
894 | #define OP_PCL_TLS12_DES_CBC_SHA 0x001e | ||
895 | #define OP_PCL_TLS12_DES_CBC_SHA_2 0x0009 | ||
896 | #define OP_PCL_TLS12_DES_CBC_SHA_3 0x000c | ||
897 | #define OP_PCL_TLS12_DES_CBC_SHA_4 0x000f | ||
898 | #define OP_PCL_TLS12_DES_CBC_SHA_5 0x0012 | ||
899 | #define OP_PCL_TLS12_DES_CBC_SHA_6 0x0015 | ||
900 | #define OP_PCL_TLS12_DES_CBC_SHA_7 0x001a | ||
901 | |||
902 | #define OP_PCL_TLS12_RC4_128_MD5 0x0024 | ||
903 | #define OP_PCL_TLS12_RC4_128_MD5_2 0x0004 | ||
904 | #define OP_PCL_TLS12_RC4_128_MD5_3 0x0018 | ||
905 | |||
906 | #define OP_PCL_TLS12_RC4_40_MD5 0x002b | ||
907 | #define OP_PCL_TLS12_RC4_40_MD5_2 0x0003 | ||
908 | #define OP_PCL_TLS12_RC4_40_MD5_3 0x0017 | ||
909 | |||
910 | #define OP_PCL_TLS12_RC4_128_SHA 0x0020 | ||
911 | #define OP_PCL_TLS12_RC4_128_SHA_2 0x008a | ||
912 | #define OP_PCL_TLS12_RC4_128_SHA_3 0x008e | ||
913 | #define OP_PCL_TLS12_RC4_128_SHA_4 0x0092 | ||
914 | #define OP_PCL_TLS12_RC4_128_SHA_5 0x0005 | ||
915 | #define OP_PCL_TLS12_RC4_128_SHA_6 0xc002 | ||
916 | #define OP_PCL_TLS12_RC4_128_SHA_7 0xc007 | ||
917 | #define OP_PCL_TLS12_RC4_128_SHA_8 0xc00c | ||
918 | #define OP_PCL_TLS12_RC4_128_SHA_9 0xc011 | ||
919 | #define OP_PCL_TLS12_RC4_128_SHA_10 0xc016 | ||
920 | |||
921 | #define OP_PCL_TLS12_RC4_40_SHA 0x0028 | ||
922 | |||
923 | /* #define OP_PCL_TLS12_AES_128_CBC_SHA256 0x003c */ | ||
924 | #define OP_PCL_TLS12_AES_128_CBC_SHA256_2 0x003e | ||
925 | #define OP_PCL_TLS12_AES_128_CBC_SHA256_3 0x003f | ||
926 | #define OP_PCL_TLS12_AES_128_CBC_SHA256_4 0x0040 | ||
927 | #define OP_PCL_TLS12_AES_128_CBC_SHA256_5 0x0067 | ||
928 | #define OP_PCL_TLS12_AES_128_CBC_SHA256_6 0x006c | ||
929 | |||
930 | /* #define OP_PCL_TLS12_AES_256_CBC_SHA256 0x003d */ | ||
931 | #define OP_PCL_TLS12_AES_256_CBC_SHA256_2 0x0068 | ||
932 | #define OP_PCL_TLS12_AES_256_CBC_SHA256_3 0x0069 | ||
933 | #define OP_PCL_TLS12_AES_256_CBC_SHA256_4 0x006a | ||
934 | #define OP_PCL_TLS12_AES_256_CBC_SHA256_5 0x006b | ||
935 | #define OP_PCL_TLS12_AES_256_CBC_SHA256_6 0x006d | ||
936 | |||
937 | /* AEAD_AES_xxx_CCM/GCM remain to be defined... */ | ||
938 | |||
939 | #define OP_PCL_TLS12_3DES_EDE_CBC_MD5 0xff23 | ||
940 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA160 0xff30 | ||
941 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA224 0xff34 | ||
942 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA256 0xff36 | ||
943 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA384 0xff33 | ||
944 | #define OP_PCL_TLS12_3DES_EDE_CBC_SHA512 0xff35 | ||
945 | #define OP_PCL_TLS12_AES_128_CBC_SHA160 0xff80 | ||
946 | #define OP_PCL_TLS12_AES_128_CBC_SHA224 0xff84 | ||
947 | #define OP_PCL_TLS12_AES_128_CBC_SHA256 0xff86 | ||
948 | #define OP_PCL_TLS12_AES_128_CBC_SHA384 0xff83 | ||
949 | #define OP_PCL_TLS12_AES_128_CBC_SHA512 0xff85 | ||
950 | #define OP_PCL_TLS12_AES_192_CBC_SHA160 0xff20 | ||
951 | #define OP_PCL_TLS12_AES_192_CBC_SHA224 0xff24 | ||
952 | #define OP_PCL_TLS12_AES_192_CBC_SHA256 0xff26 | ||
953 | #define OP_PCL_TLS12_AES_192_CBC_SHA384 0xff23 | ||
954 | #define OP_PCL_TLS12_AES_192_CBC_SHA512 0xff25 | ||
955 | #define OP_PCL_TLS12_AES_256_CBC_SHA160 0xff60 | ||
956 | #define OP_PCL_TLS12_AES_256_CBC_SHA224 0xff64 | ||
957 | #define OP_PCL_TLS12_AES_256_CBC_SHA256 0xff66 | ||
958 | #define OP_PCL_TLS12_AES_256_CBC_SHA384 0xff63 | ||
959 | #define OP_PCL_TLS12_AES_256_CBC_SHA512 0xff65 | ||
960 | |||
961 | /* For DTLS - OP_PCLID_DTLS */ | ||
962 | |||
963 | #define OP_PCL_DTLS_AES_128_CBC_SHA 0x002f | ||
964 | #define OP_PCL_DTLS_AES_128_CBC_SHA_2 0x0030 | ||
965 | #define OP_PCL_DTLS_AES_128_CBC_SHA_3 0x0031 | ||
966 | #define OP_PCL_DTLS_AES_128_CBC_SHA_4 0x0032 | ||
967 | #define OP_PCL_DTLS_AES_128_CBC_SHA_5 0x0033 | ||
968 | #define OP_PCL_DTLS_AES_128_CBC_SHA_6 0x0034 | ||
969 | #define OP_PCL_DTLS_AES_128_CBC_SHA_7 0x008c | ||
970 | #define OP_PCL_DTLS_AES_128_CBC_SHA_8 0x0090 | ||
971 | #define OP_PCL_DTLS_AES_128_CBC_SHA_9 0x0094 | ||
972 | #define OP_PCL_DTLS_AES_128_CBC_SHA_10 0xc004 | ||
973 | #define OP_PCL_DTLS_AES_128_CBC_SHA_11 0xc009 | ||
974 | #define OP_PCL_DTLS_AES_128_CBC_SHA_12 0xc00e | ||
975 | #define OP_PCL_DTLS_AES_128_CBC_SHA_13 0xc013 | ||
976 | #define OP_PCL_DTLS_AES_128_CBC_SHA_14 0xc018 | ||
977 | #define OP_PCL_DTLS_AES_128_CBC_SHA_15 0xc01d | ||
978 | #define OP_PCL_DTLS_AES_128_CBC_SHA_16 0xc01e | ||
979 | #define OP_PCL_DTLS_AES_128_CBC_SHA_17 0xc01f | ||
980 | |||
981 | #define OP_PCL_DTLS_AES_256_CBC_SHA 0x0035 | ||
982 | #define OP_PCL_DTLS_AES_256_CBC_SHA_2 0x0036 | ||
983 | #define OP_PCL_DTLS_AES_256_CBC_SHA_3 0x0037 | ||
984 | #define OP_PCL_DTLS_AES_256_CBC_SHA_4 0x0038 | ||
985 | #define OP_PCL_DTLS_AES_256_CBC_SHA_5 0x0039 | ||
986 | #define OP_PCL_DTLS_AES_256_CBC_SHA_6 0x003a | ||
987 | #define OP_PCL_DTLS_AES_256_CBC_SHA_7 0x008d | ||
988 | #define OP_PCL_DTLS_AES_256_CBC_SHA_8 0x0091 | ||
989 | #define OP_PCL_DTLS_AES_256_CBC_SHA_9 0x0095 | ||
990 | #define OP_PCL_DTLS_AES_256_CBC_SHA_10 0xc005 | ||
991 | #define OP_PCL_DTLS_AES_256_CBC_SHA_11 0xc00a | ||
992 | #define OP_PCL_DTLS_AES_256_CBC_SHA_12 0xc00f | ||
993 | #define OP_PCL_DTLS_AES_256_CBC_SHA_13 0xc014 | ||
994 | #define OP_PCL_DTLS_AES_256_CBC_SHA_14 0xc019 | ||
995 | #define OP_PCL_DTLS_AES_256_CBC_SHA_15 0xc020 | ||
996 | #define OP_PCL_DTLS_AES_256_CBC_SHA_16 0xc021 | ||
997 | #define OP_PCL_DTLS_AES_256_CBC_SHA_17 0xc022 | ||
998 | |||
999 | /* #define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0x0023 */ | ||
1000 | |||
1001 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA 0x001f | ||
1002 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_2 0x008b | ||
1003 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_3 0x008f | ||
1004 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_4 0x0093 | ||
1005 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_5 0x000a | ||
1006 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_6 0x000d | ||
1007 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_7 0x0010 | ||
1008 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_8 0x0013 | ||
1009 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_9 0x0016 | ||
1010 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_10 0x001b | ||
1011 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_11 0xc003 | ||
1012 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_12 0xc008 | ||
1013 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_13 0xc00d | ||
1014 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_14 0xc012 | ||
1015 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_15 0xc017 | ||
1016 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_16 0xc01a | ||
1017 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_17 0xc01b | ||
1018 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA_18 0xc01c | ||
1019 | |||
1020 | #define OP_PCL_DTLS_DES40_CBC_MD5 0x0029 | ||
1021 | |||
1022 | #define OP_PCL_DTLS_DES_CBC_MD5 0x0022 | ||
1023 | |||
1024 | #define OP_PCL_DTLS_DES40_CBC_SHA 0x0008 | ||
1025 | #define OP_PCL_DTLS_DES40_CBC_SHA_2 0x000b | ||
1026 | #define OP_PCL_DTLS_DES40_CBC_SHA_3 0x000e | ||
1027 | #define OP_PCL_DTLS_DES40_CBC_SHA_4 0x0011 | ||
1028 | #define OP_PCL_DTLS_DES40_CBC_SHA_5 0x0014 | ||
1029 | #define OP_PCL_DTLS_DES40_CBC_SHA_6 0x0019 | ||
1030 | #define OP_PCL_DTLS_DES40_CBC_SHA_7 0x0026 | ||
1031 | |||
1032 | |||
1033 | #define OP_PCL_DTLS_DES_CBC_SHA 0x001e | ||
1034 | #define OP_PCL_DTLS_DES_CBC_SHA_2 0x0009 | ||
1035 | #define OP_PCL_DTLS_DES_CBC_SHA_3 0x000c | ||
1036 | #define OP_PCL_DTLS_DES_CBC_SHA_4 0x000f | ||
1037 | #define OP_PCL_DTLS_DES_CBC_SHA_5 0x0012 | ||
1038 | #define OP_PCL_DTLS_DES_CBC_SHA_6 0x0015 | ||
1039 | #define OP_PCL_DTLS_DES_CBC_SHA_7 0x001a | ||
1040 | |||
1041 | |||
1042 | #define OP_PCL_DTLS_3DES_EDE_CBC_MD5 0xff23 | ||
1043 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA160 0xff30 | ||
1044 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA224 0xff34 | ||
1045 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA256 0xff36 | ||
1046 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA384 0xff33 | ||
1047 | #define OP_PCL_DTLS_3DES_EDE_CBC_SHA512 0xff35 | ||
1048 | #define OP_PCL_DTLS_AES_128_CBC_SHA160 0xff80 | ||
1049 | #define OP_PCL_DTLS_AES_128_CBC_SHA224 0xff84 | ||
1050 | #define OP_PCL_DTLS_AES_128_CBC_SHA256 0xff86 | ||
1051 | #define OP_PCL_DTLS_AES_128_CBC_SHA384 0xff83 | ||
1052 | #define OP_PCL_DTLS_AES_128_CBC_SHA512 0xff85 | ||
1053 | #define OP_PCL_DTLS_AES_192_CBC_SHA160 0xff20 | ||
1054 | #define OP_PCL_DTLS_AES_192_CBC_SHA224 0xff24 | ||
1055 | #define OP_PCL_DTLS_AES_192_CBC_SHA256 0xff26 | ||
1056 | #define OP_PCL_DTLS_AES_192_CBC_SHA384 0xff23 | ||
1057 | #define OP_PCL_DTLS_AES_192_CBC_SHA512 0xff25 | ||
1058 | #define OP_PCL_DTLS_AES_256_CBC_SHA160 0xff60 | ||
1059 | #define OP_PCL_DTLS_AES_256_CBC_SHA224 0xff64 | ||
1060 | #define OP_PCL_DTLS_AES_256_CBC_SHA256 0xff66 | ||
1061 | #define OP_PCL_DTLS_AES_256_CBC_SHA384 0xff63 | ||
1062 | #define OP_PCL_DTLS_AES_256_CBC_SHA512 0xff65 | ||
1063 | |||
1064 | /* 802.16 WiMAX protinfos */ | ||
1065 | #define OP_PCL_WIMAX_OFDM 0x0201 | ||
1066 | #define OP_PCL_WIMAX_OFDMA 0x0231 | ||
1067 | |||
1068 | /* 802.11 WiFi protinfos */ | ||
1069 | #define OP_PCL_WIFI 0xac04 | ||
1070 | |||
1071 | /* MacSec protinfos */ | ||
1072 | #define OP_PCL_MACSEC 0x0001 | ||
1073 | |||
1074 | /* PKI unidirectional protocol protinfo bits */ | ||
1075 | #define OP_PCL_PKPROT_TEST 0x0008 | ||
1076 | #define OP_PCL_PKPROT_DECRYPT 0x0004 | ||
1077 | #define OP_PCL_PKPROT_ECC 0x0002 | ||
1078 | #define OP_PCL_PKPROT_F2M 0x0001 | ||
1079 | |||
1080 | /* For non-protocol/alg-only op commands */ | ||
1081 | #define OP_ALG_TYPE_SHIFT 24 | ||
1082 | #define OP_ALG_TYPE_MASK (0x7 << OP_ALG_TYPE_SHIFT) | ||
1083 | #define OP_ALG_TYPE_CLASS1 2 | ||
1084 | #define OP_ALG_TYPE_CLASS2 4 | ||
1085 | |||
1086 | #define OP_ALG_ALGSEL_SHIFT 16 | ||
1087 | #define OP_ALG_ALGSEL_MASK (0xff << OP_ALG_ALGSEL_SHIFT) | ||
1088 | #define OP_ALG_ALGSEL_SUBMASK (0x0f << OP_ALG_ALGSEL_SHIFT) | ||
1089 | #define OP_ALG_ALGSEL_AES (0x10 << OP_ALG_ALGSEL_SHIFT) | ||
1090 | #define OP_ALG_ALGSEL_DES (0x20 << OP_ALG_ALGSEL_SHIFT) | ||
1091 | #define OP_ALG_ALGSEL_3DES (0x21 << OP_ALG_ALGSEL_SHIFT) | ||
1092 | #define OP_ALG_ALGSEL_ARC4 (0x30 << OP_ALG_ALGSEL_SHIFT) | ||
1093 | #define OP_ALG_ALGSEL_MD5 (0x40 << OP_ALG_ALGSEL_SHIFT) | ||
1094 | #define OP_ALG_ALGSEL_SHA1 (0x41 << OP_ALG_ALGSEL_SHIFT) | ||
1095 | #define OP_ALG_ALGSEL_SHA224 (0x42 << OP_ALG_ALGSEL_SHIFT) | ||
1096 | #define OP_ALG_ALGSEL_SHA256 (0x43 << OP_ALG_ALGSEL_SHIFT) | ||
1097 | #define OP_ALG_ALGSEL_SHA384 (0x44 << OP_ALG_ALGSEL_SHIFT) | ||
1098 | #define OP_ALG_ALGSEL_SHA512 (0x45 << OP_ALG_ALGSEL_SHIFT) | ||
1099 | #define OP_ALG_ALGSEL_RNG (0x50 << OP_ALG_ALGSEL_SHIFT) | ||
1100 | #define OP_ALG_ALGSEL_SNOW (0x60 << OP_ALG_ALGSEL_SHIFT) | ||
1101 | #define OP_ALG_ALGSEL_SNOW_F8 (0x60 << OP_ALG_ALGSEL_SHIFT) | ||
1102 | #define OP_ALG_ALGSEL_KASUMI (0x70 << OP_ALG_ALGSEL_SHIFT) | ||
1103 | #define OP_ALG_ALGSEL_CRC (0x90 << OP_ALG_ALGSEL_SHIFT) | ||
1104 | #define OP_ALG_ALGSEL_SNOW_F9 (0xA0 << OP_ALG_ALGSEL_SHIFT) | ||
1105 | |||
1106 | #define OP_ALG_AAI_SHIFT 4 | ||
1107 | #define OP_ALG_AAI_MASK (0x1ff << OP_ALG_AAI_SHIFT) | ||
1108 | |||
1109 | /* blockcipher AAI set */ | ||
1110 | #define OP_ALG_AAI_CTR_MOD128 (0x00 << OP_ALG_AAI_SHIFT) | ||
1111 | #define OP_ALG_AAI_CTR_MOD8 (0x01 << OP_ALG_AAI_SHIFT) | ||
1112 | #define OP_ALG_AAI_CTR_MOD16 (0x02 << OP_ALG_AAI_SHIFT) | ||
1113 | #define OP_ALG_AAI_CTR_MOD24 (0x03 << OP_ALG_AAI_SHIFT) | ||
1114 | #define OP_ALG_AAI_CTR_MOD32 (0x04 << OP_ALG_AAI_SHIFT) | ||
1115 | #define OP_ALG_AAI_CTR_MOD40 (0x05 << OP_ALG_AAI_SHIFT) | ||
1116 | #define OP_ALG_AAI_CTR_MOD48 (0x06 << OP_ALG_AAI_SHIFT) | ||
1117 | #define OP_ALG_AAI_CTR_MOD56 (0x07 << OP_ALG_AAI_SHIFT) | ||
1118 | #define OP_ALG_AAI_CTR_MOD64 (0x08 << OP_ALG_AAI_SHIFT) | ||
1119 | #define OP_ALG_AAI_CTR_MOD72 (0x09 << OP_ALG_AAI_SHIFT) | ||
1120 | #define OP_ALG_AAI_CTR_MOD80 (0x0a << OP_ALG_AAI_SHIFT) | ||
1121 | #define OP_ALG_AAI_CTR_MOD88 (0x0b << OP_ALG_AAI_SHIFT) | ||
1122 | #define OP_ALG_AAI_CTR_MOD96 (0x0c << OP_ALG_AAI_SHIFT) | ||
1123 | #define OP_ALG_AAI_CTR_MOD104 (0x0d << OP_ALG_AAI_SHIFT) | ||
1124 | #define OP_ALG_AAI_CTR_MOD112 (0x0e << OP_ALG_AAI_SHIFT) | ||
1125 | #define OP_ALG_AAI_CTR_MOD120 (0x0f << OP_ALG_AAI_SHIFT) | ||
1126 | #define OP_ALG_AAI_CBC (0x10 << OP_ALG_AAI_SHIFT) | ||
1127 | #define OP_ALG_AAI_ECB (0x20 << OP_ALG_AAI_SHIFT) | ||
1128 | #define OP_ALG_AAI_CFB (0x30 << OP_ALG_AAI_SHIFT) | ||
1129 | #define OP_ALG_AAI_OFB (0x40 << OP_ALG_AAI_SHIFT) | ||
1130 | #define OP_ALG_AAI_XTS (0x50 << OP_ALG_AAI_SHIFT) | ||
1131 | #define OP_ALG_AAI_CMAC (0x60 << OP_ALG_AAI_SHIFT) | ||
1132 | #define OP_ALG_AAI_XCBC_MAC (0x70 << OP_ALG_AAI_SHIFT) | ||
1133 | #define OP_ALG_AAI_CCM (0x80 << OP_ALG_AAI_SHIFT) | ||
1134 | #define OP_ALG_AAI_GCM (0x90 << OP_ALG_AAI_SHIFT) | ||
1135 | #define OP_ALG_AAI_CBC_XCBCMAC (0xa0 << OP_ALG_AAI_SHIFT) | ||
1136 | #define OP_ALG_AAI_CTR_XCBCMAC (0xb0 << OP_ALG_AAI_SHIFT) | ||
1137 | #define OP_ALG_AAI_CHECKODD (0x80 << OP_ALG_AAI_SHIFT) | ||
1138 | #define OP_ALG_AAI_DK (0x100 << OP_ALG_AAI_SHIFT) | ||
1139 | |||
1140 | /* randomizer AAI set */ | ||
1141 | #define OP_ALG_AAI_RNG (0x00 << OP_ALG_AAI_SHIFT) | ||
1142 | #define OP_ALG_AAI_RNG_NOZERO (0x10 << OP_ALG_AAI_SHIFT) | ||
1143 | #define OP_ALG_AAI_RNG_ODD (0x20 << OP_ALG_AAI_SHIFT) | ||
1144 | |||
1145 | /* hmac/smac AAI set */ | ||
1146 | #define OP_ALG_AAI_HASH (0x00 << OP_ALG_AAI_SHIFT) | ||
1147 | #define OP_ALG_AAI_HMAC (0x01 << OP_ALG_AAI_SHIFT) | ||
1148 | #define OP_ALG_AAI_SMAC (0x02 << OP_ALG_AAI_SHIFT) | ||
1149 | #define OP_ALG_AAI_HMAC_PRECOMP (0x04 << OP_ALG_AAI_SHIFT) | ||
1150 | |||
1151 | /* CRC AAI set*/ | ||
1152 | #define OP_ALG_AAI_802 (0x01 << OP_ALG_AAI_SHIFT) | ||
1153 | #define OP_ALG_AAI_3385 (0x02 << OP_ALG_AAI_SHIFT) | ||
1154 | #define OP_ALG_AAI_CUST_POLY (0x04 << OP_ALG_AAI_SHIFT) | ||
1155 | #define OP_ALG_AAI_DIS (0x10 << OP_ALG_AAI_SHIFT) | ||
1156 | #define OP_ALG_AAI_DOS (0x20 << OP_ALG_AAI_SHIFT) | ||
1157 | #define OP_ALG_AAI_DOC (0x40 << OP_ALG_AAI_SHIFT) | ||
1158 | |||
1159 | /* Kasumi/SNOW AAI set */ | ||
1160 | #define OP_ALG_AAI_F8 (0xc0 << OP_ALG_AAI_SHIFT) | ||
1161 | #define OP_ALG_AAI_F9 (0xc8 << OP_ALG_AAI_SHIFT) | ||
1162 | #define OP_ALG_AAI_GSM (0x10 << OP_ALG_AAI_SHIFT) | ||
1163 | #define OP_ALG_AAI_EDGE (0x20 << OP_ALG_AAI_SHIFT) | ||
1164 | |||
1165 | |||
1166 | #define OP_ALG_AS_SHIFT 2 | ||
1167 | #define OP_ALG_AS_MASK (0x3 << OP_ALG_AS_SHIFT) | ||
1168 | #define OP_ALG_AS_UPDATE (0 << OP_ALG_AS_SHIFT) | ||
1169 | #define OP_ALG_AS_INIT (1 << OP_ALG_AS_SHIFT) | ||
1170 | #define OP_ALG_AS_FINALIZE (2 << OP_ALG_AS_SHIFT) | ||
1171 | #define OP_ALG_AS_INITFINAL (3 << OP_ALG_AS_SHIFT) | ||
1172 | |||
1173 | #define OP_ALG_ICV_SHIFT 1 | ||
1174 | #define OP_ALG_ICV_MASK (1 << OP_ALG_ICV_SHIFT) | ||
1175 | #define OP_ALG_ICV_OFF (0 << OP_ALG_ICV_SHIFT) | ||
1176 | #define OP_ALG_ICV_ON (1 << OP_ALG_ICV_SHIFT) | ||
1177 | |||
1178 | #define OP_ALG_DIR_SHIFT 0 | ||
1179 | #define OP_ALG_DIR_MASK 1 | ||
1180 | #define OP_ALG_DECRYPT 0 | ||
1181 | #define OP_ALG_ENCRYPT 1 | ||
1182 | |||
1183 | /* PKHA algorithm type set */ | ||
1184 | #define OP_ALG_PK 0x00800000 | ||
1185 | #define OP_ALG_PK_FUN_MASK 0x3f /* clrmem, modmath, or cpymem */ | ||
1186 | |||
1187 | /* PKHA mode clear memory functions */ | ||
1188 | #define OP_ALG_PKMODE_A_RAM 0x80000 | ||
1189 | #define OP_ALG_PKMODE_B_RAM 0x40000 | ||
1190 | #define OP_ALG_PKMODE_E_RAM 0x20000 | ||
1191 | #define OP_ALG_PKMODE_N_RAM 0x10000 | ||
1192 | #define OP_ALG_PKMODE_CLEARMEM 0x00001 | ||
1193 | |||
1194 | /* PKHA mode modular-arithmetic functions */ | ||
1195 | #define OP_ALG_PKMODE_MOD_IN_MONTY 0x80000 | ||
1196 | #define OP_ALG_PKMODE_MOD_OUT_MONTY 0x40000 | ||
1197 | #define OP_ALG_PKMODE_MOD_F2M 0x20000 | ||
1198 | #define OP_ALG_PKMODE_MOD_R2_IN 0x10000 | ||
1199 | #define OP_ALG_PKMODE_PRJECTV 0x00800 | ||
1200 | #define OP_ALG_PKMODE_TIME_EQ 0x400 | ||
1201 | #define OP_ALG_PKMODE_OUT_B 0x000 | ||
1202 | #define OP_ALG_PKMODE_OUT_A 0x100 | ||
1203 | #define OP_ALG_PKMODE_MOD_ADD 0x002 | ||
1204 | #define OP_ALG_PKMODE_MOD_SUB_AB 0x003 | ||
1205 | #define OP_ALG_PKMODE_MOD_SUB_BA 0x004 | ||
1206 | #define OP_ALG_PKMODE_MOD_MULT 0x005 | ||
1207 | #define OP_ALG_PKMODE_MOD_EXPO 0x006 | ||
1208 | #define OP_ALG_PKMODE_MOD_REDUCT 0x007 | ||
1209 | #define OP_ALG_PKMODE_MOD_INV 0x008 | ||
1210 | #define OP_ALG_PKMODE_MOD_ECC_ADD 0x009 | ||
1211 | #define OP_ALG_PKMODE_MOD_ECC_DBL 0x00a | ||
1212 | #define OP_ALG_PKMODE_MOD_ECC_MULT 0x00b | ||
1213 | #define OP_ALG_PKMODE_MOD_MONT_CNST 0x00c | ||
1214 | #define OP_ALG_PKMODE_MOD_CRT_CNST 0x00d | ||
1215 | #define OP_ALG_PKMODE_MOD_GCD 0x00e | ||
1216 | #define OP_ALG_PKMODE_MOD_PRIMALITY 0x00f | ||
1217 | |||
1218 | /* PKHA mode copy-memory functions */ | ||
1219 | #define OP_ALG_PKMODE_SRC_REG_SHIFT 13 | ||
1220 | #define OP_ALG_PKMODE_SRC_REG_MASK (7 << OP_ALG_PKMODE_SRC_REG_SHIFT) | ||
1221 | #define OP_ALG_PKMODE_DST_REG_SHIFT 10 | ||
1222 | #define OP_ALG_PKMODE_DST_REG_MASK (7 << OP_ALG_PKMODE_DST_REG_SHIFT) | ||
1223 | #define OP_ALG_PKMODE_SRC_SEG_SHIFT 8 | ||
1224 | #define OP_ALG_PKMODE_SRC_SEG_MASK (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT) | ||
1225 | #define OP_ALG_PKMODE_DST_SEG_SHIFT 6 | ||
1226 | #define OP_ALG_PKMODE_DST_SEG_MASK (3 << OP_ALG_PKMODE_DST_SEG_SHIFT) | ||
1227 | |||
1228 | #define OP_ALG_PKMODE_SRC_REG_A (0 << OP_ALG_PKMODE_SRC_REG_SHIFT) | ||
1229 | #define OP_ALG_PKMODE_SRC_REG_B (1 << OP_ALG_PKMODE_SRC_REG_SHIFT) | ||
1230 | #define OP_ALG_PKMODE_SRC_REG_N (3 << OP_ALG_PKMODE_SRC_REG_SHIFT) | ||
1231 | #define OP_ALG_PKMODE_DST_REG_A (0 << OP_ALG_PKMODE_DST_REG_SHIFT) | ||
1232 | #define OP_ALG_PKMODE_DST_REG_B (1 << OP_ALG_PKMODE_DST_REG_SHIFT) | ||
1233 | #define OP_ALG_PKMODE_DST_REG_E (2 << OP_ALG_PKMODE_DST_REG_SHIFT) | ||
1234 | #define OP_ALG_PKMODE_DST_REG_N (3 << OP_ALG_PKMODE_DST_REG_SHIFT) | ||
1235 | #define OP_ALG_PKMODE_SRC_SEG_0 (0 << OP_ALG_PKMODE_SRC_SEG_SHIFT) | ||
1236 | #define OP_ALG_PKMODE_SRC_SEG_1 (1 << OP_ALG_PKMODE_SRC_SEG_SHIFT) | ||
1237 | #define OP_ALG_PKMODE_SRC_SEG_2 (2 << OP_ALG_PKMODE_SRC_SEG_SHIFT) | ||
1238 | #define OP_ALG_PKMODE_SRC_SEG_3 (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT) | ||
1239 | #define OP_ALG_PKMODE_DST_SEG_0 (0 << OP_ALG_PKMODE_DST_SEG_SHIFT) | ||
1240 | #define OP_ALG_PKMODE_DST_SEG_1 (1 << OP_ALG_PKMODE_DST_SEG_SHIFT) | ||
1241 | #define OP_ALG_PKMODE_DST_SEG_2 (2 << OP_ALG_PKMODE_DST_SEG_SHIFT) | ||
1242 | #define OP_ALG_PKMODE_DST_SEG_3 (3 << OP_ALG_PKMODE_DST_SEG_SHIFT) | ||
1243 | #define OP_ALG_PKMODE_CPYMEM_N_SZ 0x80 | ||
1244 | #define OP_ALG_PKMODE_CPYMEM_SRC_SZ 0x81 | ||
1245 | |||
1246 | /* | ||
1247 | * SEQ_IN_PTR Command Constructs | ||
1248 | */ | ||
1249 | |||
1250 | /* Release Buffers */ | ||
1251 | #define SQIN_RBS 0x04000000 | ||
1252 | |||
1253 | /* Sequence pointer is really a descriptor */ | ||
1254 | #define SQIN_INL 0x02000000 | ||
1255 | |||
1256 | /* Sequence pointer is a scatter-gather table */ | ||
1257 | #define SQIN_SGF 0x01000000 | ||
1258 | |||
1259 | /* Appends to a previous pointer */ | ||
1260 | #define SQIN_PRE 0x00800000 | ||
1261 | |||
1262 | /* Use extended length following pointer */ | ||
1263 | #define SQIN_EXT 0x00400000 | ||
1264 | |||
1265 | /* Restore sequence with pointer/length */ | ||
1266 | #define SQIN_RTO 0x00200000 | ||
1267 | |||
1268 | /* Replace job descriptor */ | ||
1269 | #define SQIN_RJD 0x00100000 | ||
1270 | |||
1271 | #define SQIN_LEN_SHIFT 0 | ||
1272 | #define SQIN_LEN_MASK (0xffff << SQIN_LEN_SHIFT) | ||
1273 | |||
1274 | /* | ||
1275 | * SEQ_OUT_PTR Command Constructs | ||
1276 | */ | ||
1277 | |||
1278 | /* Sequence pointer is a scatter-gather table */ | ||
1279 | #define SQOUT_SGF 0x01000000 | ||
1280 | |||
1281 | /* Appends to a previous pointer */ | ||
1282 | #define SQOUT_PRE 0x00800000 | ||
1283 | |||
1284 | /* Restore sequence with pointer/length */ | ||
1285 | #define SQOUT_RTO 0x00200000 | ||
1286 | |||
1287 | /* Use extended length following pointer */ | ||
1288 | #define SQOUT_EXT 0x00400000 | ||
1289 | |||
1290 | #define SQOUT_LEN_SHIFT 0 | ||
1291 | #define SQOUT_LEN_MASK (0xffff << SQOUT_LEN_SHIFT) | ||
1292 | |||
1293 | |||
1294 | /* | ||
1295 | * SIGNATURE Command Constructs | ||
1296 | */ | ||
1297 | |||
1298 | /* TYPE field is all that's relevant */ | ||
1299 | #define SIGN_TYPE_SHIFT 16 | ||
1300 | #define SIGN_TYPE_MASK (0x0f << SIGN_TYPE_SHIFT) | ||
1301 | |||
1302 | #define SIGN_TYPE_FINAL (0x00 << SIGN_TYPE_SHIFT) | ||
1303 | #define SIGN_TYPE_FINAL_RESTORE (0x01 << SIGN_TYPE_SHIFT) | ||
1304 | #define SIGN_TYPE_FINAL_NONZERO (0x02 << SIGN_TYPE_SHIFT) | ||
1305 | #define SIGN_TYPE_IMM_2 (0x0a << SIGN_TYPE_SHIFT) | ||
1306 | #define SIGN_TYPE_IMM_3 (0x0b << SIGN_TYPE_SHIFT) | ||
1307 | #define SIGN_TYPE_IMM_4 (0x0c << SIGN_TYPE_SHIFT) | ||
1308 | |||
1309 | /* | ||
1310 | * MOVE Command Constructs | ||
1311 | */ | ||
1312 | |||
1313 | #define MOVE_AUX_SHIFT 25 | ||
1314 | #define MOVE_AUX_MASK (3 << MOVE_AUX_SHIFT) | ||
1315 | #define MOVE_AUX_MS (2 << MOVE_AUX_SHIFT) | ||
1316 | #define MOVE_AUX_LS (1 << MOVE_AUX_SHIFT) | ||
1317 | |||
1318 | #define MOVE_WAITCOMP_SHIFT 24 | ||
1319 | #define MOVE_WAITCOMP_MASK (1 << MOVE_WAITCOMP_SHIFT) | ||
1320 | #define MOVE_WAITCOMP (1 << MOVE_WAITCOMP_SHIFT) | ||
1321 | |||
1322 | #define MOVE_SRC_SHIFT 20 | ||
1323 | #define MOVE_SRC_MASK (0x0f << MOVE_SRC_SHIFT) | ||
1324 | #define MOVE_SRC_CLASS1CTX (0x00 << MOVE_SRC_SHIFT) | ||
1325 | #define MOVE_SRC_CLASS2CTX (0x01 << MOVE_SRC_SHIFT) | ||
1326 | #define MOVE_SRC_OUTFIFO (0x02 << MOVE_SRC_SHIFT) | ||
1327 | #define MOVE_SRC_DESCBUF (0x03 << MOVE_SRC_SHIFT) | ||
1328 | #define MOVE_SRC_MATH0 (0x04 << MOVE_SRC_SHIFT) | ||
1329 | #define MOVE_SRC_MATH1 (0x05 << MOVE_SRC_SHIFT) | ||
1330 | #define MOVE_SRC_MATH2 (0x06 << MOVE_SRC_SHIFT) | ||
1331 | #define MOVE_SRC_MATH3 (0x07 << MOVE_SRC_SHIFT) | ||
1332 | #define MOVE_SRC_INFIFO (0x08 << MOVE_SRC_SHIFT) | ||
1333 | #define MOVE_SRC_INFIFO_CL (0x09 << MOVE_SRC_SHIFT) | ||
1334 | |||
1335 | #define MOVE_DEST_SHIFT 16 | ||
1336 | #define MOVE_DEST_MASK (0x0f << MOVE_DEST_SHIFT) | ||
1337 | #define MOVE_DEST_CLASS1CTX (0x00 << MOVE_DEST_SHIFT) | ||
1338 | #define MOVE_DEST_CLASS2CTX (0x01 << MOVE_DEST_SHIFT) | ||
1339 | #define MOVE_DEST_OUTFIFO (0x02 << MOVE_DEST_SHIFT) | ||
1340 | #define MOVE_DEST_DESCBUF (0x03 << MOVE_DEST_SHIFT) | ||
1341 | #define MOVE_DEST_MATH0 (0x04 << MOVE_DEST_SHIFT) | ||
1342 | #define MOVE_DEST_MATH1 (0x05 << MOVE_DEST_SHIFT) | ||
1343 | #define MOVE_DEST_MATH2 (0x06 << MOVE_DEST_SHIFT) | ||
1344 | #define MOVE_DEST_MATH3 (0x07 << MOVE_DEST_SHIFT) | ||
1345 | #define MOVE_DEST_CLASS1INFIFO (0x08 << MOVE_DEST_SHIFT) | ||
1346 | #define MOVE_DEST_CLASS2INFIFO (0x09 << MOVE_DEST_SHIFT) | ||
1347 | #define MOVE_DEST_PK_A (0x0c << MOVE_DEST_SHIFT) | ||
1348 | #define MOVE_DEST_CLASS1KEY (0x0d << MOVE_DEST_SHIFT) | ||
1349 | #define MOVE_DEST_CLASS2KEY (0x0e << MOVE_DEST_SHIFT) | ||
1350 | |||
1351 | #define MOVE_OFFSET_SHIFT 8 | ||
1352 | #define MOVE_OFFSET_MASK (0xff << MOVE_OFFSET_SHIFT) | ||
1353 | |||
1354 | #define MOVE_LEN_SHIFT 0 | ||
1355 | #define MOVE_LEN_MASK (0xff << MOVE_LEN_SHIFT) | ||
1356 | |||
1357 | #define MOVELEN_MRSEL_SHIFT 0 | ||
1358 | #define MOVELEN_MRSEL_MASK (0x3 << MOVE_LEN_SHIFT) | ||
1359 | |||
1360 | /* | ||
1361 | * MATH Command Constructs | ||
1362 | */ | ||
1363 | |||
1364 | #define MATH_IFB_SHIFT 26 | ||
1365 | #define MATH_IFB_MASK (1 << MATH_IFB_SHIFT) | ||
1366 | #define MATH_IFB (1 << MATH_IFB_SHIFT) | ||
1367 | |||
1368 | #define MATH_NFU_SHIFT 25 | ||
1369 | #define MATH_NFU_MASK (1 << MATH_NFU_SHIFT) | ||
1370 | #define MATH_NFU (1 << MATH_NFU_SHIFT) | ||
1371 | |||
1372 | #define MATH_STL_SHIFT 24 | ||
1373 | #define MATH_STL_MASK (1 << MATH_STL_SHIFT) | ||
1374 | #define MATH_STL (1 << MATH_STL_SHIFT) | ||
1375 | |||
1376 | /* Function selectors */ | ||
1377 | #define MATH_FUN_SHIFT 20 | ||
1378 | #define MATH_FUN_MASK (0x0f << MATH_FUN_SHIFT) | ||
1379 | #define MATH_FUN_ADD (0x00 << MATH_FUN_SHIFT) | ||
1380 | #define MATH_FUN_ADDC (0x01 << MATH_FUN_SHIFT) | ||
1381 | #define MATH_FUN_SUB (0x02 << MATH_FUN_SHIFT) | ||
1382 | #define MATH_FUN_SUBB (0x03 << MATH_FUN_SHIFT) | ||
1383 | #define MATH_FUN_OR (0x04 << MATH_FUN_SHIFT) | ||
1384 | #define MATH_FUN_AND (0x05 << MATH_FUN_SHIFT) | ||
1385 | #define MATH_FUN_XOR (0x06 << MATH_FUN_SHIFT) | ||
1386 | #define MATH_FUN_LSHIFT (0x07 << MATH_FUN_SHIFT) | ||
1387 | #define MATH_FUN_RSHIFT (0x08 << MATH_FUN_SHIFT) | ||
1388 | #define MATH_FUN_SHLD (0x09 << MATH_FUN_SHIFT) | ||
1389 | #define MATH_FUN_ZBYT (0x0a << MATH_FUN_SHIFT) | ||
1390 | |||
1391 | /* Source 0 selectors */ | ||
1392 | #define MATH_SRC0_SHIFT 16 | ||
1393 | #define MATH_SRC0_MASK (0x0f << MATH_SRC0_SHIFT) | ||
1394 | #define MATH_SRC0_REG0 (0x00 << MATH_SRC0_SHIFT) | ||
1395 | #define MATH_SRC0_REG1 (0x01 << MATH_SRC0_SHIFT) | ||
1396 | #define MATH_SRC0_REG2 (0x02 << MATH_SRC0_SHIFT) | ||
1397 | #define MATH_SRC0_REG3 (0x03 << MATH_SRC0_SHIFT) | ||
1398 | #define MATH_SRC0_IMM (0x04 << MATH_SRC0_SHIFT) | ||
1399 | #define MATH_SRC0_SEQINLEN (0x08 << MATH_SRC0_SHIFT) | ||
1400 | #define MATH_SRC0_SEQOUTLEN (0x09 << MATH_SRC0_SHIFT) | ||
1401 | #define MATH_SRC0_VARSEQINLEN (0x0a << MATH_SRC0_SHIFT) | ||
1402 | #define MATH_SRC0_VARSEQOUTLEN (0x0b << MATH_SRC0_SHIFT) | ||
1403 | #define MATH_SRC0_ZERO (0x0c << MATH_SRC0_SHIFT) | ||
1404 | |||
1405 | /* Source 1 selectors */ | ||
1406 | #define MATH_SRC1_SHIFT 12 | ||
1407 | #define MATH_SRC1_MASK (0x0f << MATH_SRC1_SHIFT) | ||
1408 | #define MATH_SRC1_REG0 (0x00 << MATH_SRC1_SHIFT) | ||
1409 | #define MATH_SRC1_REG1 (0x01 << MATH_SRC1_SHIFT) | ||
1410 | #define MATH_SRC1_REG2 (0x02 << MATH_SRC1_SHIFT) | ||
1411 | #define MATH_SRC1_REG3 (0x03 << MATH_SRC1_SHIFT) | ||
1412 | #define MATH_SRC1_IMM (0x04 << MATH_SRC1_SHIFT) | ||
1413 | #define MATH_SRC1_INFIFO (0x0a << MATH_SRC1_SHIFT) | ||
1414 | #define MATH_SRC1_OUTFIFO (0x0b << MATH_SRC1_SHIFT) | ||
1415 | #define MATH_SRC1_ONE (0x0c << MATH_SRC1_SHIFT) | ||
1416 | |||
1417 | /* Destination selectors */ | ||
1418 | #define MATH_DEST_SHIFT 8 | ||
1419 | #define MATH_DEST_MASK (0x0f << MATH_DEST_SHIFT) | ||
1420 | #define MATH_DEST_REG0 (0x00 << MATH_DEST_SHIFT) | ||
1421 | #define MATH_DEST_REG1 (0x01 << MATH_DEST_SHIFT) | ||
1422 | #define MATH_DEST_REG2 (0x02 << MATH_DEST_SHIFT) | ||
1423 | #define MATH_DEST_REG3 (0x03 << MATH_DEST_SHIFT) | ||
1424 | #define MATH_DEST_SEQINLEN (0x08 << MATH_DEST_SHIFT) | ||
1425 | #define MATH_DEST_SEQOUTLEN (0x09 << MATH_DEST_SHIFT) | ||
1426 | #define MATH_DEST_VARSEQINLEN (0x0a << MATH_DEST_SHIFT) | ||
1427 | #define MATH_DEST_VARSEQOUTLEN (0x0b << MATH_DEST_SHIFT) | ||
1428 | #define MATH_DEST_NONE (0x0f << MATH_DEST_SHIFT) | ||
1429 | |||
1430 | /* Length selectors */ | ||
1431 | #define MATH_LEN_SHIFT 0 | ||
1432 | #define MATH_LEN_MASK (0x0f << MATH_LEN_SHIFT) | ||
1433 | #define MATH_LEN_1BYTE 0x01 | ||
1434 | #define MATH_LEN_2BYTE 0x02 | ||
1435 | #define MATH_LEN_4BYTE 0x04 | ||
1436 | #define MATH_LEN_8BYTE 0x08 | ||
1437 | |||
1438 | /* | ||
1439 | * JUMP Command Constructs | ||
1440 | */ | ||
1441 | |||
1442 | #define JUMP_CLASS_SHIFT 25 | ||
1443 | #define JUMP_CLASS_MASK (3 << JUMP_CLASS_SHIFT) | ||
1444 | #define JUMP_CLASS_NONE 0 | ||
1445 | #define JUMP_CLASS_CLASS1 (1 << JUMP_CLASS_SHIFT) | ||
1446 | #define JUMP_CLASS_CLASS2 (2 << JUMP_CLASS_SHIFT) | ||
1447 | #define JUMP_CLASS_BOTH (3 << JUMP_CLASS_SHIFT) | ||
1448 | |||
1449 | #define JUMP_JSL_SHIFT 24 | ||
1450 | #define JUMP_JSL_MASK (1 << JUMP_JSL_SHIFT) | ||
1451 | #define JUMP_JSL (1 << JUMP_JSL_SHIFT) | ||
1452 | |||
1453 | #define JUMP_TYPE_SHIFT 22 | ||
1454 | #define JUMP_TYPE_MASK (0x03 << JUMP_TYPE_SHIFT) | ||
1455 | #define JUMP_TYPE_LOCAL (0x00 << JUMP_TYPE_SHIFT) | ||
1456 | #define JUMP_TYPE_NONLOCAL (0x01 << JUMP_TYPE_SHIFT) | ||
1457 | #define JUMP_TYPE_HALT (0x02 << JUMP_TYPE_SHIFT) | ||
1458 | #define JUMP_TYPE_HALT_USER (0x03 << JUMP_TYPE_SHIFT) | ||
1459 | |||
1460 | #define JUMP_TEST_SHIFT 16 | ||
1461 | #define JUMP_TEST_MASK (0x03 << JUMP_TEST_SHIFT) | ||
1462 | #define JUMP_TEST_ALL (0x00 << JUMP_TEST_SHIFT) | ||
1463 | #define JUMP_TEST_INVALL (0x01 << JUMP_TEST_SHIFT) | ||
1464 | #define JUMP_TEST_ANY (0x02 << JUMP_TEST_SHIFT) | ||
1465 | #define JUMP_TEST_INVANY (0x03 << JUMP_TEST_SHIFT) | ||
1466 | |||
1467 | /* Condition codes. JSL bit is factored in */ | ||
1468 | #define JUMP_COND_SHIFT 8 | ||
1469 | #define JUMP_COND_MASK (0x100ff << JUMP_COND_SHIFT) | ||
1470 | #define JUMP_COND_PK_0 (0x80 << JUMP_COND_SHIFT) | ||
1471 | #define JUMP_COND_PK_GCD_1 (0x40 << JUMP_COND_SHIFT) | ||
1472 | #define JUMP_COND_PK_PRIME (0x20 << JUMP_COND_SHIFT) | ||
1473 | #define JUMP_COND_MATH_N (0x08 << JUMP_COND_SHIFT) | ||
1474 | #define JUMP_COND_MATH_Z (0x04 << JUMP_COND_SHIFT) | ||
1475 | #define JUMP_COND_MATH_C (0x02 << JUMP_COND_SHIFT) | ||
1476 | #define JUMP_COND_MATH_NV (0x01 << JUMP_COND_SHIFT) | ||
1477 | |||
1478 | #define JUMP_COND_JRP ((0x80 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1479 | #define JUMP_COND_SHRD ((0x40 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1480 | #define JUMP_COND_SELF ((0x20 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1481 | #define JUMP_COND_CALM ((0x10 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1482 | #define JUMP_COND_NIP ((0x08 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1483 | #define JUMP_COND_NIFP ((0x04 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1484 | #define JUMP_COND_NOP ((0x02 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1485 | #define JUMP_COND_NCP ((0x01 << JUMP_COND_SHIFT) | JUMP_JSL) | ||
1486 | |||
1487 | #define JUMP_OFFSET_SHIFT 0 | ||
1488 | #define JUMP_OFFSET_MASK (0xff << JUMP_OFFSET_SHIFT) | ||
1489 | |||
1490 | /* | ||
1491 | * NFIFO ENTRY | ||
1492 | * Data Constructs | ||
1493 | * | ||
1494 | */ | ||
1495 | #define NFIFOENTRY_DEST_SHIFT 30 | ||
1496 | #define NFIFOENTRY_DEST_MASK (3 << NFIFOENTRY_DEST_SHIFT) | ||
1497 | #define NFIFOENTRY_DEST_DECO (0 << NFIFOENTRY_DEST_SHIFT) | ||
1498 | #define NFIFOENTRY_DEST_CLASS1 (1 << NFIFOENTRY_DEST_SHIFT) | ||
1499 | #define NFIFOENTRY_DEST_CLASS2 (2 << NFIFOENTRY_DEST_SHIFT) | ||
1500 | #define NFIFOENTRY_DEST_BOTH (3 << NFIFOENTRY_DEST_SHIFT) | ||
1501 | |||
1502 | #define NFIFOENTRY_LC2_SHIFT 29 | ||
1503 | #define NFIFOENTRY_LC2_MASK (1 << NFIFOENTRY_LC2_SHIFT) | ||
1504 | #define NFIFOENTRY_LC2 (1 << NFIFOENTRY_LC2_SHIFT) | ||
1505 | |||
1506 | #define NFIFOENTRY_LC1_SHIFT 28 | ||
1507 | #define NFIFOENTRY_LC1_MASK (1 << NFIFOENTRY_LC1_SHIFT) | ||
1508 | #define NFIFOENTRY_LC1 (1 << NFIFOENTRY_LC1_SHIFT) | ||
1509 | |||
1510 | #define NFIFOENTRY_FC2_SHIFT 27 | ||
1511 | #define NFIFOENTRY_FC2_MASK (1 << NFIFOENTRY_FC2_SHIFT) | ||
1512 | #define NFIFOENTRY_FC2 (1 << NFIFOENTRY_FC2_SHIFT) | ||
1513 | |||
1514 | #define NFIFOENTRY_FC1_SHIFT 26 | ||
1515 | #define NFIFOENTRY_FC1_MASK (1 << NFIFOENTRY_FC1_SHIFT) | ||
1516 | #define NFIFOENTRY_FC1 (1 << NFIFOENTRY_FC1_SHIFT) | ||
1517 | |||
1518 | #define NFIFOENTRY_STYPE_SHIFT 24 | ||
1519 | #define NFIFOENTRY_STYPE_MASK (3 << NFIFOENTRY_STYPE_SHIFT) | ||
1520 | #define NFIFOENTRY_STYPE_DFIFO (0 << NFIFOENTRY_STYPE_SHIFT) | ||
1521 | #define NFIFOENTRY_STYPE_OFIFO (1 << NFIFOENTRY_STYPE_SHIFT) | ||
1522 | #define NFIFOENTRY_STYPE_PAD (2 << NFIFOENTRY_STYPE_SHIFT) | ||
1523 | #define NFIFOENTRY_STYPE_SNOOP (3 << NFIFOENTRY_STYPE_SHIFT) | ||
1524 | |||
1525 | #define NFIFOENTRY_DTYPE_SHIFT 20 | ||
1526 | #define NFIFOENTRY_DTYPE_MASK (0xF << NFIFOENTRY_DTYPE_SHIFT) | ||
1527 | |||
1528 | #define NFIFOENTRY_DTYPE_SBOX (0x0 << NFIFOENTRY_DTYPE_SHIFT) | ||
1529 | #define NFIFOENTRY_DTYPE_AAD (0x1 << NFIFOENTRY_DTYPE_SHIFT) | ||
1530 | #define NFIFOENTRY_DTYPE_IV (0x2 << NFIFOENTRY_DTYPE_SHIFT) | ||
1531 | #define NFIFOENTRY_DTYPE_SAD (0x3 << NFIFOENTRY_DTYPE_SHIFT) | ||
1532 | #define NFIFOENTRY_DTYPE_ICV (0xA << NFIFOENTRY_DTYPE_SHIFT) | ||
1533 | #define NFIFOENTRY_DTYPE_SKIP (0xE << NFIFOENTRY_DTYPE_SHIFT) | ||
1534 | #define NFIFOENTRY_DTYPE_MSG (0xF << NFIFOENTRY_DTYPE_SHIFT) | ||
1535 | |||
1536 | #define NFIFOENTRY_DTYPE_PK_A0 (0x0 << NFIFOENTRY_DTYPE_SHIFT) | ||
1537 | #define NFIFOENTRY_DTYPE_PK_A1 (0x1 << NFIFOENTRY_DTYPE_SHIFT) | ||
1538 | #define NFIFOENTRY_DTYPE_PK_A2 (0x2 << NFIFOENTRY_DTYPE_SHIFT) | ||
1539 | #define NFIFOENTRY_DTYPE_PK_A3 (0x3 << NFIFOENTRY_DTYPE_SHIFT) | ||
1540 | #define NFIFOENTRY_DTYPE_PK_B0 (0x4 << NFIFOENTRY_DTYPE_SHIFT) | ||
1541 | #define NFIFOENTRY_DTYPE_PK_B1 (0x5 << NFIFOENTRY_DTYPE_SHIFT) | ||
1542 | #define NFIFOENTRY_DTYPE_PK_B2 (0x6 << NFIFOENTRY_DTYPE_SHIFT) | ||
1543 | #define NFIFOENTRY_DTYPE_PK_B3 (0x7 << NFIFOENTRY_DTYPE_SHIFT) | ||
1544 | #define NFIFOENTRY_DTYPE_PK_N (0x8 << NFIFOENTRY_DTYPE_SHIFT) | ||
1545 | #define NFIFOENTRY_DTYPE_PK_E (0x9 << NFIFOENTRY_DTYPE_SHIFT) | ||
1546 | #define NFIFOENTRY_DTYPE_PK_A (0xC << NFIFOENTRY_DTYPE_SHIFT) | ||
1547 | #define NFIFOENTRY_DTYPE_PK_B (0xD << NFIFOENTRY_DTYPE_SHIFT) | ||
1548 | |||
1549 | |||
1550 | #define NFIFOENTRY_BND_SHIFT 19 | ||
1551 | #define NFIFOENTRY_BND_MASK (1 << NFIFOENTRY_BND_SHIFT) | ||
1552 | #define NFIFOENTRY_BND (1 << NFIFOENTRY_BND_SHIFT) | ||
1553 | |||
1554 | #define NFIFOENTRY_PTYPE_SHIFT 16 | ||
1555 | #define NFIFOENTRY_PTYPE_MASK (0x7 << NFIFOENTRY_PTYPE_SHIFT) | ||
1556 | |||
1557 | #define NFIFOENTRY_PTYPE_ZEROS (0x0 << NFIFOENTRY_PTYPE_SHIFT) | ||
1558 | #define NFIFOENTRY_PTYPE_RND_NOZEROS (0x1 << NFIFOENTRY_PTYPE_SHIFT) | ||
1559 | #define NFIFOENTRY_PTYPE_INCREMENT (0x2 << NFIFOENTRY_PTYPE_SHIFT) | ||
1560 | #define NFIFOENTRY_PTYPE_RND (0x3 << NFIFOENTRY_PTYPE_SHIFT) | ||
1561 | #define NFIFOENTRY_PTYPE_ZEROS_NZ (0x4 << NFIFOENTRY_PTYPE_SHIFT) | ||
1562 | #define NFIFOENTRY_PTYPE_RND_NZ_LZ (0x5 << NFIFOENTRY_PTYPE_SHIFT) | ||
1563 | #define NFIFOENTRY_PTYPE_N (0x6 << NFIFOENTRY_PTYPE_SHIFT) | ||
1564 | #define NFIFOENTRY_PTYPE_RND_NZ_N (0x7 << NFIFOENTRY_PTYPE_SHIFT) | ||
1565 | |||
1566 | #define NFIFOENTRY_OC_SHIFT 15 | ||
1567 | #define NFIFOENTRY_OC_MASK (1 << NFIFOENTRY_OC_SHIFT) | ||
1568 | #define NFIFOENTRY_OC (1 << NFIFOENTRY_OC_SHIFT) | ||
1569 | |||
1570 | #define NFIFOENTRY_AST_SHIFT 14 | ||
1571 | #define NFIFOENTRY_AST_MASK (1 << NFIFOENTRY_OC_SHIFT) | ||
1572 | #define NFIFOENTRY_AST (1 << NFIFOENTRY_OC_SHIFT) | ||
1573 | |||
1574 | #define NFIFOENTRY_BM_SHIFT 11 | ||
1575 | #define NFIFOENTRY_BM_MASK (1 << NFIFOENTRY_BM_SHIFT) | ||
1576 | #define NFIFOENTRY_BM (1 << NFIFOENTRY_BM_SHIFT) | ||
1577 | |||
1578 | #define NFIFOENTRY_PS_SHIFT 10 | ||
1579 | #define NFIFOENTRY_PS_MASK (1 << NFIFOENTRY_PS_SHIFT) | ||
1580 | #define NFIFOENTRY_PS (1 << NFIFOENTRY_PS_SHIFT) | ||
1581 | |||
1582 | |||
1583 | #define NFIFOENTRY_DLEN_SHIFT 0 | ||
1584 | #define NFIFOENTRY_DLEN_MASK (0xFFF << NFIFOENTRY_DLEN_SHIFT) | ||
1585 | |||
1586 | #define NFIFOENTRY_PLEN_SHIFT 0 | ||
1587 | #define NFIFOENTRY_PLEN_MASK (0xFF << NFIFOENTRY_PLEN_SHIFT) | ||
1588 | |||
1589 | /* | ||
1590 | * PDB internal definitions | ||
1591 | */ | ||
1592 | |||
1593 | /* IPSec ESP CBC Encap/Decap Options */ | ||
1594 | #define PDBOPTS_ESPCBC_ARSNONE 0x00 /* no antireplay window */ | ||
1595 | #define PDBOPTS_ESPCBC_ARS32 0x40 /* 32-entry antireplay window */ | ||
1596 | #define PDBOPTS_ESPCBC_ARS64 0xc0 /* 64-entry antireplay window */ | ||
1597 | #define PDBOPTS_ESPCBC_IVSRC 0x20 /* IV comes from internal random gen */ | ||
1598 | #define PDBOPTS_ESPCBC_ESN 0x10 /* extended sequence included */ | ||
1599 | #define PDBOPTS_ESPCBC_OUTFMT 0x08 /* output only decapsulation (decap) */ | ||
1600 | #define PDBOPTS_ESPCBC_IPHDRSRC 0x08 /* IP header comes from PDB (encap) */ | ||
1601 | #define PDBOPTS_ESPCBC_INCIPHDR 0x04 /* Prepend IP header to output frame */ | ||
1602 | #define PDBOPTS_ESPCBC_IPVSN 0x02 /* process IPv6 header */ | ||
1603 | #define PDBOPTS_ESPCBC_TUNNEL 0x01 /* tunnel mode next-header byte */ | ||
1604 | |||
1605 | #endif /* DESC_H */ | ||
diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h new file mode 100644 index 000000000000..46915800c26f --- /dev/null +++ b/drivers/crypto/caam/desc_constr.h | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * caam descriptor construction helper functions | ||
3 | * | ||
4 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
5 | */ | ||
6 | |||
7 | #include "desc.h" | ||
8 | |||
9 | #define IMMEDIATE (1 << 23) | ||
10 | #define CAAM_CMD_SZ sizeof(u32) | ||
11 | #define CAAM_PTR_SZ sizeof(dma_addr_t) | ||
12 | #define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * 64) | ||
13 | |||
14 | #ifdef DEBUG | ||
15 | #define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\ | ||
16 | &__func__[sizeof("append")]); } while (0) | ||
17 | #else | ||
18 | #define PRINT_POS | ||
19 | #endif | ||
20 | |||
21 | #define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \ | ||
22 | LDST_SRCDST_WORD_DECOCTRL | \ | ||
23 | (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT)) | ||
24 | #define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \ | ||
25 | LDST_SRCDST_WORD_DECOCTRL | \ | ||
26 | (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT)) | ||
27 | |||
28 | static inline int desc_len(u32 *desc) | ||
29 | { | ||
30 | return *desc & HDR_DESCLEN_MASK; | ||
31 | } | ||
32 | |||
33 | static inline int desc_bytes(void *desc) | ||
34 | { | ||
35 | return desc_len(desc) * CAAM_CMD_SZ; | ||
36 | } | ||
37 | |||
38 | static inline u32 *desc_end(u32 *desc) | ||
39 | { | ||
40 | return desc + desc_len(desc); | ||
41 | } | ||
42 | |||
43 | static inline void *sh_desc_pdb(u32 *desc) | ||
44 | { | ||
45 | return desc + 1; | ||
46 | } | ||
47 | |||
48 | static inline void init_desc(u32 *desc, u32 options) | ||
49 | { | ||
50 | *desc = options | HDR_ONE | 1; | ||
51 | } | ||
52 | |||
53 | static inline void init_sh_desc(u32 *desc, u32 options) | ||
54 | { | ||
55 | PRINT_POS; | ||
56 | init_desc(desc, CMD_SHARED_DESC_HDR | options); | ||
57 | } | ||
58 | |||
59 | static inline void init_sh_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes) | ||
60 | { | ||
61 | u32 pdb_len = pdb_bytes / CAAM_CMD_SZ + 1; | ||
62 | |||
63 | init_sh_desc(desc, ((pdb_len << HDR_START_IDX_SHIFT) + pdb_len) | | ||
64 | options); | ||
65 | } | ||
66 | |||
67 | static inline void init_job_desc(u32 *desc, u32 options) | ||
68 | { | ||
69 | init_desc(desc, CMD_DESC_HDR | options); | ||
70 | } | ||
71 | |||
72 | static inline void append_ptr(u32 *desc, dma_addr_t ptr) | ||
73 | { | ||
74 | dma_addr_t *offset = (dma_addr_t *)desc_end(desc); | ||
75 | |||
76 | *offset = ptr; | ||
77 | |||
78 | (*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ; | ||
79 | } | ||
80 | |||
81 | static inline void init_job_desc_shared(u32 *desc, dma_addr_t ptr, int len, | ||
82 | u32 options) | ||
83 | { | ||
84 | PRINT_POS; | ||
85 | init_job_desc(desc, HDR_SHARED | options | | ||
86 | (len << HDR_START_IDX_SHIFT)); | ||
87 | append_ptr(desc, ptr); | ||
88 | } | ||
89 | |||
90 | static inline void append_data(u32 *desc, void *data, int len) | ||
91 | { | ||
92 | u32 *offset = desc_end(desc); | ||
93 | |||
94 | if (len) /* avoid sparse warning: memcpy with byte count of 0 */ | ||
95 | memcpy(offset, data, len); | ||
96 | |||
97 | (*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ; | ||
98 | } | ||
99 | |||
100 | static inline void append_cmd(u32 *desc, u32 command) | ||
101 | { | ||
102 | u32 *cmd = desc_end(desc); | ||
103 | |||
104 | *cmd = command; | ||
105 | |||
106 | (*desc)++; | ||
107 | } | ||
108 | |||
109 | static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len, | ||
110 | u32 command) | ||
111 | { | ||
112 | append_cmd(desc, command | len); | ||
113 | append_ptr(desc, ptr); | ||
114 | } | ||
115 | |||
116 | static inline void append_cmd_data(u32 *desc, void *data, int len, | ||
117 | u32 command) | ||
118 | { | ||
119 | append_cmd(desc, command | IMMEDIATE | len); | ||
120 | append_data(desc, data, len); | ||
121 | } | ||
122 | |||
123 | static inline u32 *append_jump(u32 *desc, u32 options) | ||
124 | { | ||
125 | u32 *cmd = desc_end(desc); | ||
126 | |||
127 | PRINT_POS; | ||
128 | append_cmd(desc, CMD_JUMP | options); | ||
129 | |||
130 | return cmd; | ||
131 | } | ||
132 | |||
133 | static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd) | ||
134 | { | ||
135 | *jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc)); | ||
136 | } | ||
137 | |||
138 | #define APPEND_CMD(cmd, op) \ | ||
139 | static inline void append_##cmd(u32 *desc, u32 options) \ | ||
140 | { \ | ||
141 | PRINT_POS; \ | ||
142 | append_cmd(desc, CMD_##op | options); \ | ||
143 | } | ||
144 | APPEND_CMD(operation, OPERATION) | ||
145 | APPEND_CMD(move, MOVE) | ||
146 | |||
147 | #define APPEND_CMD_LEN(cmd, op) \ | ||
148 | static inline void append_##cmd(u32 *desc, unsigned int len, u32 options) \ | ||
149 | { \ | ||
150 | PRINT_POS; \ | ||
151 | append_cmd(desc, CMD_##op | len | options); \ | ||
152 | } | ||
153 | APPEND_CMD_LEN(seq_store, SEQ_STORE) | ||
154 | APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD) | ||
155 | APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE) | ||
156 | |||
157 | #define APPEND_CMD_PTR(cmd, op) \ | ||
158 | static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \ | ||
159 | u32 options) \ | ||
160 | { \ | ||
161 | PRINT_POS; \ | ||
162 | append_cmd_ptr(desc, ptr, len, CMD_##op | options); \ | ||
163 | } | ||
164 | APPEND_CMD_PTR(key, KEY) | ||
165 | APPEND_CMD_PTR(seq_in_ptr, SEQ_IN_PTR) | ||
166 | APPEND_CMD_PTR(seq_out_ptr, SEQ_OUT_PTR) | ||
167 | APPEND_CMD_PTR(load, LOAD) | ||
168 | APPEND_CMD_PTR(store, STORE) | ||
169 | APPEND_CMD_PTR(fifo_load, FIFO_LOAD) | ||
170 | APPEND_CMD_PTR(fifo_store, FIFO_STORE) | ||
171 | |||
172 | #define APPEND_CMD_PTR_TO_IMM(cmd, op) \ | ||
173 | static inline void append_##cmd##_as_imm(u32 *desc, void *data, \ | ||
174 | unsigned int len, u32 options) \ | ||
175 | { \ | ||
176 | PRINT_POS; \ | ||
177 | append_cmd_data(desc, data, len, CMD_##op | options); \ | ||
178 | } | ||
179 | APPEND_CMD_PTR_TO_IMM(load, LOAD); | ||
180 | APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD); | ||
181 | |||
182 | /* | ||
183 | * 2nd variant for commands whose specified immediate length differs | ||
184 | * from length of immediate data provided, e.g., split keys | ||
185 | */ | ||
186 | #define APPEND_CMD_PTR_TO_IMM2(cmd, op) \ | ||
187 | static inline void append_##cmd##_as_imm(u32 *desc, void *data, \ | ||
188 | unsigned int data_len, \ | ||
189 | unsigned int len, u32 options) \ | ||
190 | { \ | ||
191 | PRINT_POS; \ | ||
192 | append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \ | ||
193 | append_data(desc, data, data_len); \ | ||
194 | } | ||
195 | APPEND_CMD_PTR_TO_IMM2(key, KEY); | ||
196 | |||
197 | #define APPEND_CMD_RAW_IMM(cmd, op, type) \ | ||
198 | static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \ | ||
199 | u32 options) \ | ||
200 | { \ | ||
201 | PRINT_POS; \ | ||
202 | append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \ | ||
203 | append_cmd(desc, immediate); \ | ||
204 | } | ||
205 | APPEND_CMD_RAW_IMM(load, LOAD, u32); | ||
diff --git a/drivers/crypto/caam/error.c b/drivers/crypto/caam/error.c new file mode 100644 index 000000000000..7e2d54bffad6 --- /dev/null +++ b/drivers/crypto/caam/error.c | |||
@@ -0,0 +1,248 @@ | |||
1 | /* | ||
2 | * CAAM Error Reporting | ||
3 | * | ||
4 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | ||
5 | */ | ||
6 | |||
7 | #include "compat.h" | ||
8 | #include "regs.h" | ||
9 | #include "intern.h" | ||
10 | #include "desc.h" | ||
11 | #include "jr.h" | ||
12 | #include "error.h" | ||
13 | |||
14 | #define SPRINTFCAT(str, format, param, max_alloc) \ | ||
15 | { \ | ||
16 | char *tmp; \ | ||
17 | \ | ||
18 | tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC); \ | ||
19 | sprintf(tmp, format, param); \ | ||
20 | strcat(str, tmp); \ | ||
21 | kfree(tmp); \ | ||
22 | } | ||
23 | |||
24 | static void report_jump_idx(u32 status, char *outstr) | ||
25 | { | ||
26 | u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >> | ||
27 | JRSTA_DECOERR_INDEX_SHIFT; | ||
28 | |||
29 | if (status & JRSTA_DECOERR_JUMP) | ||
30 | strcat(outstr, "jump tgt desc idx "); | ||
31 | else | ||
32 | strcat(outstr, "desc idx "); | ||
33 | |||
34 | SPRINTFCAT(outstr, "%d: ", idx, sizeof("255")); | ||
35 | } | ||
36 | |||
37 | static void report_ccb_status(u32 status, char *outstr) | ||
38 | { | ||
39 | char *cha_id_list[] = { | ||
40 | "", | ||
41 | "AES", | ||
42 | "DES, 3DES", | ||
43 | "ARC4", | ||
44 | "MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512", | ||
45 | "RNG", | ||
46 | "SNOW f8", | ||
47 | "Kasumi f8, f9", | ||
48 | "All Public Key Algorithms", | ||
49 | "CRC", | ||
50 | "SNOW f9", | ||
51 | }; | ||
52 | char *err_id_list[] = { | ||
53 | "None. No error.", | ||
54 | "Mode error.", | ||
55 | "Data size error.", | ||
56 | "Key size error.", | ||
57 | "PKHA A memory size error.", | ||
58 | "PKHA B memory size error.", | ||
59 | "Data arrived out of sequence error.", | ||
60 | "PKHA divide-by-zero error.", | ||
61 | "PKHA modulus even error.", | ||
62 | "DES key parity error.", | ||
63 | "ICV check failed.", | ||
64 | "Hardware error.", | ||
65 | "Unsupported CCM AAD size.", | ||
66 | "Class 1 CHA is not reset", | ||
67 | "Invalid CHA combination was selected", | ||
68 | "Invalid CHA selected.", | ||
69 | }; | ||
70 | u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >> | ||
71 | JRSTA_CCBERR_CHAID_SHIFT; | ||
72 | u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; | ||
73 | |||
74 | report_jump_idx(status, outstr); | ||
75 | |||
76 | if (cha_id < ARRAY_SIZE(cha_id_list)) { | ||
77 | SPRINTFCAT(outstr, "%s: ", cha_id_list[cha_id], | ||
78 | strlen(cha_id_list[cha_id])); | ||
79 | } else { | ||
80 | SPRINTFCAT(outstr, "unidentified cha_id value 0x%02x: ", | ||
81 | cha_id, sizeof("ff")); | ||
82 | } | ||
83 | |||
84 | if (err_id < ARRAY_SIZE(err_id_list)) { | ||
85 | SPRINTFCAT(outstr, "%s", err_id_list[err_id], | ||
86 | strlen(err_id_list[err_id])); | ||
87 | } else { | ||
88 | SPRINTFCAT(outstr, "unidentified err_id value 0x%02x", | ||
89 | err_id, sizeof("ff")); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | static void report_jump_status(u32 status, char *outstr) | ||
94 | { | ||
95 | SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); | ||
96 | } | ||
97 | |||
98 | static void report_deco_status(u32 status, char *outstr) | ||
99 | { | ||
100 | const struct { | ||
101 | u8 value; | ||
102 | char *error_text; | ||
103 | } desc_error_list[] = { | ||
104 | { 0x00, "None. No error." }, | ||
105 | { 0x01, "SGT Length Error. The descriptor is trying to read " | ||
106 | "more data than is contained in the SGT table." }, | ||
107 | { 0x02, "Reserved." }, | ||
108 | { 0x03, "Job Ring Control Error. There is a bad value in the " | ||
109 | "Job Ring Control register." }, | ||
110 | { 0x04, "Invalid Descriptor Command. The Descriptor Command " | ||
111 | "field is invalid." }, | ||
112 | { 0x05, "Reserved." }, | ||
113 | { 0x06, "Invalid KEY Command" }, | ||
114 | { 0x07, "Invalid LOAD Command" }, | ||
115 | { 0x08, "Invalid STORE Command" }, | ||
116 | { 0x09, "Invalid OPERATION Command" }, | ||
117 | { 0x0A, "Invalid FIFO LOAD Command" }, | ||
118 | { 0x0B, "Invalid FIFO STORE Command" }, | ||
119 | { 0x0C, "Invalid MOVE Command" }, | ||
120 | { 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is " | ||
121 | "invalid because the target is not a Job Header " | ||
122 | "Command, or the jump is from a Trusted Descriptor to " | ||
123 | "a Job Descriptor, or because the target Descriptor " | ||
124 | "contains a Shared Descriptor." }, | ||
125 | { 0x0E, "Invalid MATH Command" }, | ||
126 | { 0x0F, "Invalid SIGNATURE Command" }, | ||
127 | { 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR " | ||
128 | "Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO " | ||
129 | "LOAD, or SEQ FIFO STORE decremented the input or " | ||
130 | "output sequence length below 0. This error may result " | ||
131 | "if a built-in PROTOCOL Command has encountered a " | ||
132 | "malformed PDU." }, | ||
133 | { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."}, | ||
134 | { 0x12, "Shared Descriptor Header Error" }, | ||
135 | { 0x13, "Header Error. Invalid length or parity, or certain " | ||
136 | "other problems." }, | ||
137 | { 0x14, "Burster Error. Burster has gotten to an illegal " | ||
138 | "state" }, | ||
139 | { 0x15, "Context Register Length Error. The descriptor is " | ||
140 | "trying to read or write past the end of the Context " | ||
141 | "Register. A SEQ LOAD or SEQ STORE with the VLF bit " | ||
142 | "set was executed with too large a length in the " | ||
143 | "variable length register (VSOL for SEQ STORE or VSIL " | ||
144 | "for SEQ LOAD)." }, | ||
145 | { 0x16, "DMA Error" }, | ||
146 | { 0x17, "Reserved." }, | ||
147 | { 0x1A, "Job failed due to JR reset" }, | ||
148 | { 0x1B, "Job failed due to Fail Mode" }, | ||
149 | { 0x1C, "DECO Watchdog timer timeout error" }, | ||
150 | { 0x1D, "DECO tried to copy a key from another DECO but the " | ||
151 | "other DECO's Key Registers were locked" }, | ||
152 | { 0x1E, "DECO attempted to copy data from a DECO that had an " | ||
153 | "unmasked Descriptor error" }, | ||
154 | { 0x1F, "LIODN error. DECO was trying to share from itself or " | ||
155 | "from another DECO but the two Non-SEQ LIODN values " | ||
156 | "didn't match or the 'shared from' DECO's Descriptor " | ||
157 | "required that the SEQ LIODNs be the same and they " | ||
158 | "aren't." }, | ||
159 | { 0x20, "DECO has completed a reset initiated via the DRR " | ||
160 | "register" }, | ||
161 | { 0x21, "Nonce error. When using EKT (CCM) key encryption " | ||
162 | "option in the FIFO STORE Command, the Nonce counter " | ||
163 | "reached its maximum value and this encryption mode " | ||
164 | "can no longer be used." }, | ||
165 | { 0x22, "Meta data is too large (> 511 bytes) for TLS decap " | ||
166 | "(input frame; block ciphers) and IPsec decap (output " | ||
167 | "frame, when doing the next header byte update) and " | ||
168 | "DCRC (output frame)." }, | ||
169 | { 0x80, "DNR (do not run) error" }, | ||
170 | { 0x81, "undefined protocol command" }, | ||
171 | { 0x82, "invalid setting in PDB" }, | ||
172 | { 0x83, "Anti-replay LATE error" }, | ||
173 | { 0x84, "Anti-replay REPLAY error" }, | ||
174 | { 0x85, "Sequence number overflow" }, | ||
175 | { 0x86, "Sigver invalid signature" }, | ||
176 | { 0x87, "DSA Sign Illegal test descriptor" }, | ||
177 | { 0x88, "Protocol Format Error - A protocol has seen an error " | ||
178 | "in the format of data received. When running RSA, " | ||
179 | "this means that formatting with random padding was " | ||
180 | "used, and did not follow the form: 0x00, 0x02, 8-to-N " | ||
181 | "bytes of non-zero pad, 0x00, F data." }, | ||
182 | { 0x89, "Protocol Size Error - A protocol has seen an error in " | ||
183 | "size. When running RSA, pdb size N < (size of F) when " | ||
184 | "no formatting is used; or pdb size N < (F + 11) when " | ||
185 | "formatting is used." }, | ||
186 | { 0xC1, "Blob Command error: Undefined mode" }, | ||
187 | { 0xC2, "Blob Command error: Secure Memory Blob mode error" }, | ||
188 | { 0xC4, "Blob Command error: Black Blob key or input size " | ||
189 | "error" }, | ||
190 | { 0xC5, "Blob Command error: Invalid key destination" }, | ||
191 | { 0xC8, "Blob Command error: Trusted/Secure mode error" }, | ||
192 | { 0xF0, "IPsec TTL or hop limit field either came in as 0, " | ||
193 | "or was decremented to 0" }, | ||
194 | { 0xF1, "3GPP HFN matches or exceeds the Threshold" }, | ||
195 | }; | ||
196 | u8 desc_error = status & JRSTA_DECOERR_ERROR_MASK; | ||
197 | int i; | ||
198 | |||
199 | report_jump_idx(status, outstr); | ||
200 | |||
201 | for (i = 0; i < ARRAY_SIZE(desc_error_list); i++) | ||
202 | if (desc_error_list[i].value == desc_error) | ||
203 | break; | ||
204 | |||
205 | if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) { | ||
206 | SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text, | ||
207 | strlen(desc_error_list[i].error_text)); | ||
208 | } else { | ||
209 | SPRINTFCAT(outstr, "unidentified error value 0x%02x", | ||
210 | desc_error, sizeof("ff")); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static void report_jr_status(u32 status, char *outstr) | ||
215 | { | ||
216 | SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); | ||
217 | } | ||
218 | |||
219 | static void report_cond_code_status(u32 status, char *outstr) | ||
220 | { | ||
221 | SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__)); | ||
222 | } | ||
223 | |||
224 | char *caam_jr_strstatus(char *outstr, u32 status) | ||
225 | { | ||
226 | struct stat_src { | ||
227 | void (*report_ssed)(u32 status, char *outstr); | ||
228 | char *error; | ||
229 | } status_src[] = { | ||
230 | { NULL, "No error" }, | ||
231 | { NULL, NULL }, | ||
232 | { report_ccb_status, "CCB" }, | ||
233 | { report_jump_status, "Jump" }, | ||
234 | { report_deco_status, "DECO" }, | ||
235 | { NULL, NULL }, | ||
236 | { report_jr_status, "Job Ring" }, | ||
237 | { report_cond_code_status, "Condition Code" }, | ||
238 | }; | ||
239 | u32 ssrc = status >> JRSTA_SSRC_SHIFT; | ||
240 | |||
241 | sprintf(outstr, "%s: ", status_src[ssrc].error); | ||
242 | |||
243 | if (status_src[ssrc].report_ssed) | ||
244 | status_src[ssrc].report_ssed(status, outstr); | ||
245 | |||
246 | return outstr; | ||
247 | } | ||
248 | EXPORT_SYMBOL(caam_jr_strstatus); | ||
diff --git a/drivers/crypto/caam/error.h b/drivers/crypto/caam/error.h new file mode 100644 index 000000000000..02c7baa1748e --- /dev/null +++ b/drivers/crypto/caam/error.h | |||
@@ -0,0 +1,11 @@ | |||
1 | /* | ||
2 | * CAAM Error Reporting code header | ||
3 | * | ||
4 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | ||
5 | */ | ||
6 | |||
7 | #ifndef CAAM_ERROR_H | ||
8 | #define CAAM_ERROR_H | ||
9 | #define CAAM_ERROR_STR_MAX 302 | ||
10 | extern char *caam_jr_strstatus(char *outstr, u32 status); | ||
11 | #endif /* CAAM_ERROR_H */ | ||
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h new file mode 100644 index 000000000000..a34be01b0b29 --- /dev/null +++ b/drivers/crypto/caam/intern.h | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * CAAM/SEC 4.x driver backend | ||
3 | * Private/internal definitions between modules | ||
4 | * | ||
5 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #ifndef INTERN_H | ||
10 | #define INTERN_H | ||
11 | |||
12 | #define JOBR_UNASSIGNED 0 | ||
13 | #define JOBR_ASSIGNED 1 | ||
14 | |||
15 | /* Currently comes from Kconfig param as a ^2 (driver-required) */ | ||
16 | #define JOBR_DEPTH (1 << CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE) | ||
17 | |||
18 | /* Kconfig params for interrupt coalescing if selected (else zero) */ | ||
19 | #ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_INTC | ||
20 | #define JOBR_INTC JRCFG_ICEN | ||
21 | #define JOBR_INTC_TIME_THLD CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD | ||
22 | #define JOBR_INTC_COUNT_THLD CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD | ||
23 | #else | ||
24 | #define JOBR_INTC 0 | ||
25 | #define JOBR_INTC_TIME_THLD 0 | ||
26 | #define JOBR_INTC_COUNT_THLD 0 | ||
27 | #endif | ||
28 | |||
29 | /* | ||
30 | * Storage for tracking each in-process entry moving across a ring | ||
31 | * Each entry on an output ring needs one of these | ||
32 | */ | ||
33 | struct caam_jrentry_info { | ||
34 | void (*callbk)(struct device *dev, u32 *desc, u32 status, void *arg); | ||
35 | void *cbkarg; /* Argument per ring entry */ | ||
36 | u32 *desc_addr_virt; /* Stored virt addr for postprocessing */ | ||
37 | dma_addr_t desc_addr_dma; /* Stored bus addr for done matching */ | ||
38 | u32 desc_size; /* Stored size for postprocessing, header derived */ | ||
39 | }; | ||
40 | |||
41 | /* Private sub-storage for a single JobR */ | ||
42 | struct caam_drv_private_jr { | ||
43 | struct device *parentdev; /* points back to controller dev */ | ||
44 | int ridx; | ||
45 | struct caam_job_ring __iomem *rregs; /* JobR's register space */ | ||
46 | struct tasklet_struct irqtask[NR_CPUS]; | ||
47 | int irq; /* One per queue */ | ||
48 | int assign; /* busy/free */ | ||
49 | |||
50 | /* Job ring info */ | ||
51 | int ringsize; /* Size of rings (assume input = output) */ | ||
52 | struct caam_jrentry_info *entinfo; /* Alloc'ed 1 per ring entry */ | ||
53 | spinlock_t inplock ____cacheline_aligned; /* Input ring index lock */ | ||
54 | int inp_ring_write_index; /* Input index "tail" */ | ||
55 | int head; /* entinfo (s/w ring) head index */ | ||
56 | dma_addr_t *inpring; /* Base of input ring, alloc DMA-safe */ | ||
57 | spinlock_t outlock ____cacheline_aligned; /* Output ring index lock */ | ||
58 | int out_ring_read_index; /* Output index "tail" */ | ||
59 | int tail; /* entinfo (s/w ring) tail index */ | ||
60 | struct jr_outentry *outring; /* Base of output ring, DMA-safe */ | ||
61 | }; | ||
62 | |||
63 | /* | ||
64 | * Driver-private storage for a single CAAM block instance | ||
65 | */ | ||
66 | struct caam_drv_private { | ||
67 | |||
68 | struct device *dev; | ||
69 | struct device **jrdev; /* Alloc'ed array per sub-device */ | ||
70 | spinlock_t jr_alloc_lock; | ||
71 | struct platform_device *pdev; | ||
72 | |||
73 | /* Physical-presence section */ | ||
74 | struct caam_ctrl *ctrl; /* controller region */ | ||
75 | struct caam_deco **deco; /* DECO/CCB views */ | ||
76 | struct caam_assurance *ac; | ||
77 | struct caam_queue_if *qi; /* QI control region */ | ||
78 | |||
79 | /* | ||
80 | * Detected geometry block. Filled in from device tree if powerpc, | ||
81 | * or from register-based version detection code | ||
82 | */ | ||
83 | u8 total_jobrs; /* Total Job Rings in device */ | ||
84 | u8 qi_present; /* Nonzero if QI present in device */ | ||
85 | int secvio_irq; /* Security violation interrupt number */ | ||
86 | |||
87 | /* which jr allocated to scatterlist crypto */ | ||
88 | atomic_t tfm_count ____cacheline_aligned; | ||
89 | int num_jrs_for_algapi; | ||
90 | struct device **algapi_jr; | ||
91 | /* list of registered crypto algorithms (mk generic context handle?) */ | ||
92 | struct list_head alg_list; | ||
93 | |||
94 | /* | ||
95 | * debugfs entries for developer view into driver/device | ||
96 | * variables at runtime. | ||
97 | */ | ||
98 | #ifdef CONFIG_DEBUG_FS | ||
99 | struct dentry *dfs_root; | ||
100 | struct dentry *ctl; /* controller dir */ | ||
101 | struct dentry *ctl_rq_dequeued, *ctl_ob_enc_req, *ctl_ib_dec_req; | ||
102 | struct dentry *ctl_ob_enc_bytes, *ctl_ob_prot_bytes; | ||
103 | struct dentry *ctl_ib_dec_bytes, *ctl_ib_valid_bytes; | ||
104 | struct dentry *ctl_faultaddr, *ctl_faultdetail, *ctl_faultstatus; | ||
105 | |||
106 | struct debugfs_blob_wrapper ctl_kek_wrap, ctl_tkek_wrap, ctl_tdsk_wrap; | ||
107 | struct dentry *ctl_kek, *ctl_tkek, *ctl_tdsk; | ||
108 | #endif | ||
109 | }; | ||
110 | |||
111 | void caam_jr_algapi_init(struct device *dev); | ||
112 | void caam_jr_algapi_remove(struct device *dev); | ||
113 | #endif /* INTERN_H */ | ||
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c new file mode 100644 index 000000000000..340fa322c0f0 --- /dev/null +++ b/drivers/crypto/caam/jr.c | |||
@@ -0,0 +1,517 @@ | |||
1 | /* | ||
2 | * CAAM/SEC 4.x transport/backend driver | ||
3 | * JobR backend functionality | ||
4 | * | ||
5 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
6 | */ | ||
7 | |||
8 | #include "compat.h" | ||
9 | #include "regs.h" | ||
10 | #include "jr.h" | ||
11 | #include "desc.h" | ||
12 | #include "intern.h" | ||
13 | |||
14 | /* Main per-ring interrupt handler */ | ||
15 | static irqreturn_t caam_jr_interrupt(int irq, void *st_dev) | ||
16 | { | ||
17 | struct device *dev = st_dev; | ||
18 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); | ||
19 | u32 irqstate; | ||
20 | |||
21 | /* | ||
22 | * Check the output ring for ready responses, kick | ||
23 | * tasklet if jobs done. | ||
24 | */ | ||
25 | irqstate = rd_reg32(&jrp->rregs->jrintstatus); | ||
26 | if (!irqstate) | ||
27 | return IRQ_NONE; | ||
28 | |||
29 | /* | ||
30 | * If JobR error, we got more development work to do | ||
31 | * Flag a bug now, but we really need to shut down and | ||
32 | * restart the queue (and fix code). | ||
33 | */ | ||
34 | if (irqstate & JRINT_JR_ERROR) { | ||
35 | dev_err(dev, "job ring error: irqstate: %08x\n", irqstate); | ||
36 | BUG(); | ||
37 | } | ||
38 | |||
39 | /* mask valid interrupts */ | ||
40 | setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); | ||
41 | |||
42 | /* Have valid interrupt at this point, just ACK and trigger */ | ||
43 | wr_reg32(&jrp->rregs->jrintstatus, irqstate); | ||
44 | |||
45 | preempt_disable(); | ||
46 | tasklet_schedule(&jrp->irqtask[smp_processor_id()]); | ||
47 | preempt_enable(); | ||
48 | |||
49 | return IRQ_HANDLED; | ||
50 | } | ||
51 | |||
52 | /* Deferred service handler, run as interrupt-fired tasklet */ | ||
53 | static void caam_jr_dequeue(unsigned long devarg) | ||
54 | { | ||
55 | int hw_idx, sw_idx, i, head, tail; | ||
56 | struct device *dev = (struct device *)devarg; | ||
57 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); | ||
58 | void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg); | ||
59 | u32 *userdesc, userstatus; | ||
60 | void *userarg; | ||
61 | unsigned long flags; | ||
62 | |||
63 | spin_lock_irqsave(&jrp->outlock, flags); | ||
64 | |||
65 | head = ACCESS_ONCE(jrp->head); | ||
66 | sw_idx = tail = jrp->tail; | ||
67 | |||
68 | while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 && | ||
69 | rd_reg32(&jrp->rregs->outring_used)) { | ||
70 | |||
71 | hw_idx = jrp->out_ring_read_index; | ||
72 | for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) { | ||
73 | sw_idx = (tail + i) & (JOBR_DEPTH - 1); | ||
74 | |||
75 | smp_read_barrier_depends(); | ||
76 | |||
77 | if (jrp->outring[hw_idx].desc == | ||
78 | jrp->entinfo[sw_idx].desc_addr_dma) | ||
79 | break; /* found */ | ||
80 | } | ||
81 | /* we should never fail to find a matching descriptor */ | ||
82 | BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0); | ||
83 | |||
84 | /* Unmap just-run descriptor so we can post-process */ | ||
85 | dma_unmap_single(dev, jrp->outring[hw_idx].desc, | ||
86 | jrp->entinfo[sw_idx].desc_size, | ||
87 | DMA_TO_DEVICE); | ||
88 | |||
89 | /* mark completed, avoid matching on a recycled desc addr */ | ||
90 | jrp->entinfo[sw_idx].desc_addr_dma = 0; | ||
91 | |||
92 | /* Stash callback params for use outside of lock */ | ||
93 | usercall = jrp->entinfo[sw_idx].callbk; | ||
94 | userarg = jrp->entinfo[sw_idx].cbkarg; | ||
95 | userdesc = jrp->entinfo[sw_idx].desc_addr_virt; | ||
96 | userstatus = jrp->outring[hw_idx].jrstatus; | ||
97 | |||
98 | smp_mb(); | ||
99 | |||
100 | jrp->out_ring_read_index = (jrp->out_ring_read_index + 1) & | ||
101 | (JOBR_DEPTH - 1); | ||
102 | |||
103 | /* | ||
104 | * if this job completed out-of-order, do not increment | ||
105 | * the tail. Otherwise, increment tail by 1 plus the | ||
106 | * number of subsequent jobs already completed out-of-order | ||
107 | */ | ||
108 | if (sw_idx == tail) { | ||
109 | do { | ||
110 | tail = (tail + 1) & (JOBR_DEPTH - 1); | ||
111 | smp_read_barrier_depends(); | ||
112 | } while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 && | ||
113 | jrp->entinfo[tail].desc_addr_dma == 0); | ||
114 | |||
115 | jrp->tail = tail; | ||
116 | } | ||
117 | |||
118 | /* set done */ | ||
119 | wr_reg32(&jrp->rregs->outring_rmvd, 1); | ||
120 | |||
121 | spin_unlock_irqrestore(&jrp->outlock, flags); | ||
122 | |||
123 | /* Finally, execute user's callback */ | ||
124 | usercall(dev, userdesc, userstatus, userarg); | ||
125 | |||
126 | spin_lock_irqsave(&jrp->outlock, flags); | ||
127 | |||
128 | head = ACCESS_ONCE(jrp->head); | ||
129 | sw_idx = tail = jrp->tail; | ||
130 | } | ||
131 | |||
132 | spin_unlock_irqrestore(&jrp->outlock, flags); | ||
133 | |||
134 | /* reenable / unmask IRQs */ | ||
135 | clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * caam_jr_register() - Alloc a ring for someone to use as needed. Returns | ||
140 | * an ordinal of the rings allocated, else returns -ENODEV if no rings | ||
141 | * are available. | ||
142 | * @ctrldev: points to the controller level dev (parent) that | ||
143 | * owns rings available for use. | ||
144 | * @dev: points to where a pointer to the newly allocated queue's | ||
145 | * dev can be written to if successful. | ||
146 | **/ | ||
147 | int caam_jr_register(struct device *ctrldev, struct device **rdev) | ||
148 | { | ||
149 | struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); | ||
150 | struct caam_drv_private_jr *jrpriv = NULL; | ||
151 | unsigned long flags; | ||
152 | int ring; | ||
153 | |||
154 | /* Lock, if free ring - assign, unlock */ | ||
155 | spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags); | ||
156 | for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { | ||
157 | jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]); | ||
158 | if (jrpriv->assign == JOBR_UNASSIGNED) { | ||
159 | jrpriv->assign = JOBR_ASSIGNED; | ||
160 | *rdev = ctrlpriv->jrdev[ring]; | ||
161 | spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); | ||
162 | return ring; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /* If assigned, write dev where caller needs it */ | ||
167 | spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); | ||
168 | *rdev = NULL; | ||
169 | |||
170 | return -ENODEV; | ||
171 | } | ||
172 | EXPORT_SYMBOL(caam_jr_register); | ||
173 | |||
174 | /** | ||
175 | * caam_jr_deregister() - Deregister an API and release the queue. | ||
176 | * Returns 0 if OK, -EBUSY if queue still contains pending entries | ||
177 | * or unprocessed results at the time of the call | ||
178 | * @dev - points to the dev that identifies the queue to | ||
179 | * be released. | ||
180 | **/ | ||
181 | int caam_jr_deregister(struct device *rdev) | ||
182 | { | ||
183 | struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev); | ||
184 | struct caam_drv_private *ctrlpriv; | ||
185 | unsigned long flags; | ||
186 | |||
187 | /* Get the owning controller's private space */ | ||
188 | ctrlpriv = dev_get_drvdata(jrpriv->parentdev); | ||
189 | |||
190 | /* | ||
191 | * Make sure ring empty before release | ||
192 | */ | ||
193 | if (rd_reg32(&jrpriv->rregs->outring_used) || | ||
194 | (rd_reg32(&jrpriv->rregs->inpring_avail) != JOBR_DEPTH)) | ||
195 | return -EBUSY; | ||
196 | |||
197 | /* Release ring */ | ||
198 | spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags); | ||
199 | jrpriv->assign = JOBR_UNASSIGNED; | ||
200 | spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | EXPORT_SYMBOL(caam_jr_deregister); | ||
205 | |||
206 | /** | ||
207 | * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK, | ||
208 | * -EBUSY if the queue is full, -EIO if it cannot map the caller's | ||
209 | * descriptor. | ||
210 | * @dev: device of the job ring to be used. This device should have | ||
211 | * been assigned prior by caam_jr_register(). | ||
212 | * @desc: points to a job descriptor that execute our request. All | ||
213 | * descriptors (and all referenced data) must be in a DMAable | ||
214 | * region, and all data references must be physical addresses | ||
215 | * accessible to CAAM (i.e. within a PAMU window granted | ||
216 | * to it). | ||
217 | * @cbk: pointer to a callback function to be invoked upon completion | ||
218 | * of this request. This has the form: | ||
219 | * callback(struct device *dev, u32 *desc, u32 stat, void *arg) | ||
220 | * where: | ||
221 | * @dev: contains the job ring device that processed this | ||
222 | * response. | ||
223 | * @desc: descriptor that initiated the request, same as | ||
224 | * "desc" being argued to caam_jr_enqueue(). | ||
225 | * @status: untranslated status received from CAAM. See the | ||
226 | * reference manual for a detailed description of | ||
227 | * error meaning, or see the JRSTA definitions in the | ||
228 | * register header file | ||
229 | * @areq: optional pointer to an argument passed with the | ||
230 | * original request | ||
231 | * @areq: optional pointer to a user argument for use at callback | ||
232 | * time. | ||
233 | **/ | ||
234 | int caam_jr_enqueue(struct device *dev, u32 *desc, | ||
235 | void (*cbk)(struct device *dev, u32 *desc, | ||
236 | u32 status, void *areq), | ||
237 | void *areq) | ||
238 | { | ||
239 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); | ||
240 | struct caam_jrentry_info *head_entry; | ||
241 | unsigned long flags; | ||
242 | int head, tail, desc_size; | ||
243 | dma_addr_t desc_dma; | ||
244 | |||
245 | desc_size = (*desc & HDR_JD_LENGTH_MASK) * sizeof(u32); | ||
246 | desc_dma = dma_map_single(dev, desc, desc_size, DMA_TO_DEVICE); | ||
247 | if (dma_mapping_error(dev, desc_dma)) { | ||
248 | dev_err(dev, "caam_jr_enqueue(): can't map jobdesc\n"); | ||
249 | return -EIO; | ||
250 | } | ||
251 | |||
252 | spin_lock_irqsave(&jrp->inplock, flags); | ||
253 | |||
254 | head = jrp->head; | ||
255 | tail = ACCESS_ONCE(jrp->tail); | ||
256 | |||
257 | if (!rd_reg32(&jrp->rregs->inpring_avail) || | ||
258 | CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { | ||
259 | spin_unlock_irqrestore(&jrp->inplock, flags); | ||
260 | dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); | ||
261 | return -EBUSY; | ||
262 | } | ||
263 | |||
264 | head_entry = &jrp->entinfo[head]; | ||
265 | head_entry->desc_addr_virt = desc; | ||
266 | head_entry->desc_size = desc_size; | ||
267 | head_entry->callbk = (void *)cbk; | ||
268 | head_entry->cbkarg = areq; | ||
269 | head_entry->desc_addr_dma = desc_dma; | ||
270 | |||
271 | jrp->inpring[jrp->inp_ring_write_index] = desc_dma; | ||
272 | |||
273 | smp_wmb(); | ||
274 | |||
275 | jrp->inp_ring_write_index = (jrp->inp_ring_write_index + 1) & | ||
276 | (JOBR_DEPTH - 1); | ||
277 | jrp->head = (head + 1) & (JOBR_DEPTH - 1); | ||
278 | |||
279 | wmb(); | ||
280 | |||
281 | wr_reg32(&jrp->rregs->inpring_jobadd, 1); | ||
282 | |||
283 | spin_unlock_irqrestore(&jrp->inplock, flags); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | EXPORT_SYMBOL(caam_jr_enqueue); | ||
288 | |||
289 | static int caam_reset_hw_jr(struct device *dev) | ||
290 | { | ||
291 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); | ||
292 | unsigned int timeout = 100000; | ||
293 | |||
294 | /* | ||
295 | * mask interrupts since we are going to poll | ||
296 | * for reset completion status | ||
297 | */ | ||
298 | setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); | ||
299 | |||
300 | /* initiate flush (required prior to reset) */ | ||
301 | wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); | ||
302 | while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) == | ||
303 | JRINT_ERR_HALT_INPROGRESS) && --timeout) | ||
304 | cpu_relax(); | ||
305 | |||
306 | if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) != | ||
307 | JRINT_ERR_HALT_COMPLETE || timeout == 0) { | ||
308 | dev_err(dev, "failed to flush job ring %d\n", jrp->ridx); | ||
309 | return -EIO; | ||
310 | } | ||
311 | |||
312 | /* initiate reset */ | ||
313 | timeout = 100000; | ||
314 | wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); | ||
315 | while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout) | ||
316 | cpu_relax(); | ||
317 | |||
318 | if (timeout == 0) { | ||
319 | dev_err(dev, "failed to reset job ring %d\n", jrp->ridx); | ||
320 | return -EIO; | ||
321 | } | ||
322 | |||
323 | /* unmask interrupts */ | ||
324 | clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * Init JobR independent of platform property detection | ||
331 | */ | ||
332 | static int caam_jr_init(struct device *dev) | ||
333 | { | ||
334 | struct caam_drv_private_jr *jrp; | ||
335 | dma_addr_t inpbusaddr, outbusaddr; | ||
336 | int i, error; | ||
337 | |||
338 | jrp = dev_get_drvdata(dev); | ||
339 | |||
340 | /* Connect job ring interrupt handler. */ | ||
341 | for_each_possible_cpu(i) | ||
342 | tasklet_init(&jrp->irqtask[i], caam_jr_dequeue, | ||
343 | (unsigned long)dev); | ||
344 | |||
345 | error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED, | ||
346 | "caam-jobr", dev); | ||
347 | if (error) { | ||
348 | dev_err(dev, "can't connect JobR %d interrupt (%d)\n", | ||
349 | jrp->ridx, jrp->irq); | ||
350 | irq_dispose_mapping(jrp->irq); | ||
351 | jrp->irq = 0; | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | error = caam_reset_hw_jr(dev); | ||
356 | if (error) | ||
357 | return error; | ||
358 | |||
359 | jrp->inpring = kzalloc(sizeof(dma_addr_t) * JOBR_DEPTH, | ||
360 | GFP_KERNEL | GFP_DMA); | ||
361 | jrp->outring = kzalloc(sizeof(struct jr_outentry) * | ||
362 | JOBR_DEPTH, GFP_KERNEL | GFP_DMA); | ||
363 | |||
364 | jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH, | ||
365 | GFP_KERNEL); | ||
366 | |||
367 | if ((jrp->inpring == NULL) || (jrp->outring == NULL) || | ||
368 | (jrp->entinfo == NULL)) { | ||
369 | dev_err(dev, "can't allocate job rings for %d\n", | ||
370 | jrp->ridx); | ||
371 | return -ENOMEM; | ||
372 | } | ||
373 | |||
374 | for (i = 0; i < JOBR_DEPTH; i++) | ||
375 | jrp->entinfo[i].desc_addr_dma = !0; | ||
376 | |||
377 | /* Setup rings */ | ||
378 | inpbusaddr = dma_map_single(dev, jrp->inpring, | ||
379 | sizeof(u32 *) * JOBR_DEPTH, | ||
380 | DMA_BIDIRECTIONAL); | ||
381 | if (dma_mapping_error(dev, inpbusaddr)) { | ||
382 | dev_err(dev, "caam_jr_init(): can't map input ring\n"); | ||
383 | kfree(jrp->inpring); | ||
384 | kfree(jrp->outring); | ||
385 | kfree(jrp->entinfo); | ||
386 | return -EIO; | ||
387 | } | ||
388 | |||
389 | outbusaddr = dma_map_single(dev, jrp->outring, | ||
390 | sizeof(struct jr_outentry) * JOBR_DEPTH, | ||
391 | DMA_BIDIRECTIONAL); | ||
392 | if (dma_mapping_error(dev, outbusaddr)) { | ||
393 | dev_err(dev, "caam_jr_init(): can't map output ring\n"); | ||
394 | dma_unmap_single(dev, inpbusaddr, | ||
395 | sizeof(u32 *) * JOBR_DEPTH, | ||
396 | DMA_BIDIRECTIONAL); | ||
397 | kfree(jrp->inpring); | ||
398 | kfree(jrp->outring); | ||
399 | kfree(jrp->entinfo); | ||
400 | return -EIO; | ||
401 | } | ||
402 | |||
403 | jrp->inp_ring_write_index = 0; | ||
404 | jrp->out_ring_read_index = 0; | ||
405 | jrp->head = 0; | ||
406 | jrp->tail = 0; | ||
407 | |||
408 | wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); | ||
409 | wr_reg64(&jrp->rregs->outring_base, outbusaddr); | ||
410 | wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); | ||
411 | wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); | ||
412 | |||
413 | jrp->ringsize = JOBR_DEPTH; | ||
414 | |||
415 | spin_lock_init(&jrp->inplock); | ||
416 | spin_lock_init(&jrp->outlock); | ||
417 | |||
418 | /* Select interrupt coalescing parameters */ | ||
419 | setbits32(&jrp->rregs->rconfig_lo, JOBR_INTC | | ||
420 | (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | | ||
421 | (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); | ||
422 | |||
423 | jrp->assign = JOBR_UNASSIGNED; | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * Shutdown JobR independent of platform property code | ||
429 | */ | ||
430 | int caam_jr_shutdown(struct device *dev) | ||
431 | { | ||
432 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); | ||
433 | dma_addr_t inpbusaddr, outbusaddr; | ||
434 | int ret, i; | ||
435 | |||
436 | ret = caam_reset_hw_jr(dev); | ||
437 | |||
438 | for_each_possible_cpu(i) | ||
439 | tasklet_kill(&jrp->irqtask[i]); | ||
440 | |||
441 | /* Release interrupt */ | ||
442 | free_irq(jrp->irq, dev); | ||
443 | |||
444 | /* Free rings */ | ||
445 | inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); | ||
446 | outbusaddr = rd_reg64(&jrp->rregs->outring_base); | ||
447 | dma_unmap_single(dev, outbusaddr, | ||
448 | sizeof(struct jr_outentry) * JOBR_DEPTH, | ||
449 | DMA_BIDIRECTIONAL); | ||
450 | dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH, | ||
451 | DMA_BIDIRECTIONAL); | ||
452 | kfree(jrp->outring); | ||
453 | kfree(jrp->inpring); | ||
454 | kfree(jrp->entinfo); | ||
455 | |||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Probe routine for each detected JobR subsystem. It assumes that | ||
461 | * property detection was picked up externally. | ||
462 | */ | ||
463 | int caam_jr_probe(struct platform_device *pdev, struct device_node *np, | ||
464 | int ring) | ||
465 | { | ||
466 | struct device *ctrldev, *jrdev; | ||
467 | struct platform_device *jr_pdev; | ||
468 | struct caam_drv_private *ctrlpriv; | ||
469 | struct caam_drv_private_jr *jrpriv; | ||
470 | u32 *jroffset; | ||
471 | int error; | ||
472 | |||
473 | ctrldev = &pdev->dev; | ||
474 | ctrlpriv = dev_get_drvdata(ctrldev); | ||
475 | |||
476 | jrpriv = kmalloc(sizeof(struct caam_drv_private_jr), | ||
477 | GFP_KERNEL); | ||
478 | if (jrpriv == NULL) { | ||
479 | dev_err(ctrldev, "can't alloc private mem for job ring %d\n", | ||
480 | ring); | ||
481 | return -ENOMEM; | ||
482 | } | ||
483 | jrpriv->parentdev = ctrldev; /* point back to parent */ | ||
484 | jrpriv->ridx = ring; /* save ring identity relative to detection */ | ||
485 | |||
486 | /* | ||
487 | * Derive a pointer to the detected JobRs regs | ||
488 | * Driver has already iomapped the entire space, we just | ||
489 | * need to add in the offset to this JobR. Don't know if I | ||
490 | * like this long-term, but it'll run | ||
491 | */ | ||
492 | jroffset = (u32 *)of_get_property(np, "reg", NULL); | ||
493 | jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl | ||
494 | + *jroffset); | ||
495 | |||
496 | /* Build a local dev for each detected queue */ | ||
497 | jr_pdev = of_platform_device_create(np, NULL, ctrldev); | ||
498 | if (jr_pdev == NULL) { | ||
499 | kfree(jrpriv); | ||
500 | return -EINVAL; | ||
501 | } | ||
502 | jrdev = &jr_pdev->dev; | ||
503 | dev_set_drvdata(jrdev, jrpriv); | ||
504 | ctrlpriv->jrdev[ring] = jrdev; | ||
505 | |||
506 | /* Identify the interrupt */ | ||
507 | jrpriv->irq = of_irq_to_resource(np, 0, NULL); | ||
508 | |||
509 | /* Now do the platform independent part */ | ||
510 | error = caam_jr_init(jrdev); /* now turn on hardware */ | ||
511 | if (error) { | ||
512 | kfree(jrpriv); | ||
513 | return error; | ||
514 | } | ||
515 | |||
516 | return error; | ||
517 | } | ||
diff --git a/drivers/crypto/caam/jr.h b/drivers/crypto/caam/jr.h new file mode 100644 index 000000000000..c23df395b622 --- /dev/null +++ b/drivers/crypto/caam/jr.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * CAAM public-level include definitions for the JobR backend | ||
3 | * | ||
4 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
5 | */ | ||
6 | |||
7 | #ifndef JR_H | ||
8 | #define JR_H | ||
9 | |||
10 | /* Prototypes for backend-level services exposed to APIs */ | ||
11 | int caam_jr_register(struct device *ctrldev, struct device **rdev); | ||
12 | int caam_jr_deregister(struct device *rdev); | ||
13 | int caam_jr_enqueue(struct device *dev, u32 *desc, | ||
14 | void (*cbk)(struct device *dev, u32 *desc, u32 status, | ||
15 | void *areq), | ||
16 | void *areq); | ||
17 | |||
18 | extern int caam_jr_probe(struct platform_device *pdev, struct device_node *np, | ||
19 | int ring); | ||
20 | extern int caam_jr_shutdown(struct device *dev); | ||
21 | #endif /* JR_H */ | ||
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h new file mode 100644 index 000000000000..aee394e39056 --- /dev/null +++ b/drivers/crypto/caam/regs.h | |||
@@ -0,0 +1,663 @@ | |||
1 | /* | ||
2 | * CAAM hardware register-level view | ||
3 | * | ||
4 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | ||
5 | */ | ||
6 | |||
7 | #ifndef REGS_H | ||
8 | #define REGS_H | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/io.h> | ||
12 | |||
13 | /* | ||
14 | * Architecture-specific register access methods | ||
15 | * | ||
16 | * CAAM's bus-addressable registers are 64 bits internally. | ||
17 | * They have been wired to be safely accessible on 32-bit | ||
18 | * architectures, however. Registers were organized such | ||
19 | * that (a) they can be contained in 32 bits, (b) if not, then they | ||
20 | * can be treated as two 32-bit entities, or finally (c) if they | ||
21 | * must be treated as a single 64-bit value, then this can safely | ||
22 | * be done with two 32-bit cycles. | ||
23 | * | ||
24 | * For 32-bit operations on 64-bit values, CAAM follows the same | ||
25 | * 64-bit register access conventions as it's predecessors, in that | ||
26 | * writes are "triggered" by a write to the register at the numerically | ||
27 | * higher address, thus, a full 64-bit write cycle requires a write | ||
28 | * to the lower address, followed by a write to the higher address, | ||
29 | * which will latch/execute the write cycle. | ||
30 | * | ||
31 | * For example, let's assume a SW reset of CAAM through the master | ||
32 | * configuration register. | ||
33 | * - SWRST is in bit 31 of MCFG. | ||
34 | * - MCFG begins at base+0x0000. | ||
35 | * - Bits 63-32 are a 32-bit word at base+0x0000 (numerically-lower) | ||
36 | * - Bits 31-0 are a 32-bit word at base+0x0004 (numerically-higher) | ||
37 | * | ||
38 | * (and on Power, the convention is 0-31, 32-63, I know...) | ||
39 | * | ||
40 | * Assuming a 64-bit write to this MCFG to perform a software reset | ||
41 | * would then require a write of 0 to base+0x0000, followed by a | ||
42 | * write of 0x80000000 to base+0x0004, which would "execute" the | ||
43 | * reset. | ||
44 | * | ||
45 | * Of course, since MCFG 63-32 is all zero, we could cheat and simply | ||
46 | * write 0x8000000 to base+0x0004, and the reset would work fine. | ||
47 | * However, since CAAM does contain some write-and-read-intended | ||
48 | * 64-bit registers, this code defines 64-bit access methods for | ||
49 | * the sake of internal consistency and simplicity, and so that a | ||
50 | * clean transition to 64-bit is possible when it becomes necessary. | ||
51 | * | ||
52 | * There are limitations to this that the developer must recognize. | ||
53 | * 32-bit architectures cannot enforce an atomic-64 operation, | ||
54 | * Therefore: | ||
55 | * | ||
56 | * - On writes, since the HW is assumed to latch the cycle on the | ||
57 | * write of the higher-numeric-address word, then ordered | ||
58 | * writes work OK. | ||
59 | * | ||
60 | * - For reads, where a register contains a relevant value of more | ||
61 | * that 32 bits, the hardware employs logic to latch the other | ||
62 | * "half" of the data until read, ensuring an accurate value. | ||
63 | * This is of particular relevance when dealing with CAAM's | ||
64 | * performance counters. | ||
65 | * | ||
66 | */ | ||
67 | |||
68 | #ifdef __BIG_ENDIAN | ||
69 | #define wr_reg32(reg, data) out_be32(reg, data) | ||
70 | #define rd_reg32(reg) in_be32(reg) | ||
71 | #ifdef CONFIG_64BIT | ||
72 | #define wr_reg64(reg, data) out_be64(reg, data) | ||
73 | #define rd_reg64(reg) in_be64(reg) | ||
74 | #endif | ||
75 | #else | ||
76 | #ifdef __LITTLE_ENDIAN | ||
77 | #define wr_reg32(reg, data) __raw_writel(reg, data) | ||
78 | #define rd_reg32(reg) __raw_readl(reg) | ||
79 | #ifdef CONFIG_64BIT | ||
80 | #define wr_reg64(reg, data) __raw_writeq(reg, data) | ||
81 | #define rd_reg64(reg) __raw_readq(reg) | ||
82 | #endif | ||
83 | #endif | ||
84 | #endif | ||
85 | |||
86 | #ifndef CONFIG_64BIT | ||
87 | static inline void wr_reg64(u64 __iomem *reg, u64 data) | ||
88 | { | ||
89 | wr_reg32((u32 __iomem *)reg, (data & 0xffffffff00000000ull) >> 32); | ||
90 | wr_reg32((u32 __iomem *)reg + 1, data & 0x00000000ffffffffull); | ||
91 | } | ||
92 | |||
93 | static inline u64 rd_reg64(u64 __iomem *reg) | ||
94 | { | ||
95 | return (((u64)rd_reg32((u32 __iomem *)reg)) << 32) | | ||
96 | ((u64)rd_reg32((u32 __iomem *)reg + 1)); | ||
97 | } | ||
98 | #endif | ||
99 | |||
100 | /* | ||
101 | * jr_outentry | ||
102 | * Represents each entry in a JobR output ring | ||
103 | */ | ||
104 | struct jr_outentry { | ||
105 | dma_addr_t desc;/* Pointer to completed descriptor */ | ||
106 | u32 jrstatus; /* Status for completed descriptor */ | ||
107 | } __packed; | ||
108 | |||
109 | /* | ||
110 | * caam_perfmon - Performance Monitor/Secure Memory Status/ | ||
111 | * CAAM Global Status/Component Version IDs | ||
112 | * | ||
113 | * Spans f00-fff wherever instantiated | ||
114 | */ | ||
115 | |||
116 | /* Number of DECOs */ | ||
117 | #define CHA_NUM_DECONUM_SHIFT 56 | ||
118 | #define CHA_NUM_DECONUM_MASK (0xfull << CHA_NUM_DECONUM_SHIFT) | ||
119 | |||
120 | struct caam_perfmon { | ||
121 | /* Performance Monitor Registers f00-f9f */ | ||
122 | u64 req_dequeued; /* PC_REQ_DEQ - Dequeued Requests */ | ||
123 | u64 ob_enc_req; /* PC_OB_ENC_REQ - Outbound Encrypt Requests */ | ||
124 | u64 ib_dec_req; /* PC_IB_DEC_REQ - Inbound Decrypt Requests */ | ||
125 | u64 ob_enc_bytes; /* PC_OB_ENCRYPT - Outbound Bytes Encrypted */ | ||
126 | u64 ob_prot_bytes; /* PC_OB_PROTECT - Outbound Bytes Protected */ | ||
127 | u64 ib_dec_bytes; /* PC_IB_DECRYPT - Inbound Bytes Decrypted */ | ||
128 | u64 ib_valid_bytes; /* PC_IB_VALIDATED Inbound Bytes Validated */ | ||
129 | u64 rsvd[13]; | ||
130 | |||
131 | /* CAAM Hardware Instantiation Parameters fa0-fbf */ | ||
132 | u64 cha_rev; /* CRNR - CHA Revision Number */ | ||
133 | #define CTPR_QI_SHIFT 57 | ||
134 | #define CTPR_QI_MASK (0x1ull << CTPR_QI_SHIFT) | ||
135 | u64 comp_parms; /* CTPR - Compile Parameters Register */ | ||
136 | u64 rsvd1[2]; | ||
137 | |||
138 | /* CAAM Global Status fc0-fdf */ | ||
139 | u64 faultaddr; /* FAR - Fault Address */ | ||
140 | u32 faultliodn; /* FALR - Fault Address LIODN */ | ||
141 | u32 faultdetail; /* FADR - Fault Addr Detail */ | ||
142 | u32 rsvd2; | ||
143 | u32 status; /* CSTA - CAAM Status */ | ||
144 | u64 rsvd3; | ||
145 | |||
146 | /* Component Instantiation Parameters fe0-fff */ | ||
147 | u32 rtic_id; /* RVID - RTIC Version ID */ | ||
148 | u32 ccb_id; /* CCBVID - CCB Version ID */ | ||
149 | u64 cha_id; /* CHAVID - CHA Version ID */ | ||
150 | u64 cha_num; /* CHANUM - CHA Number */ | ||
151 | u64 caam_id; /* CAAMVID - CAAM Version ID */ | ||
152 | }; | ||
153 | |||
154 | /* LIODN programming for DMA configuration */ | ||
155 | #define MSTRID_LOCK_LIODN 0x80000000 | ||
156 | #define MSTRID_LOCK_MAKETRUSTED 0x00010000 /* only for JR masterid */ | ||
157 | |||
158 | #define MSTRID_LIODN_MASK 0x0fff | ||
159 | struct masterid { | ||
160 | u32 liodn_ms; /* lock and make-trusted control bits */ | ||
161 | u32 liodn_ls; /* LIODN for non-sequence and seq access */ | ||
162 | }; | ||
163 | |||
164 | /* Partition ID for DMA configuration */ | ||
165 | struct partid { | ||
166 | u32 rsvd1; | ||
167 | u32 pidr; /* partition ID, DECO */ | ||
168 | }; | ||
169 | |||
170 | /* RNG test mode (replicated twice in some configurations) */ | ||
171 | /* Padded out to 0x100 */ | ||
172 | struct rngtst { | ||
173 | u32 mode; /* RTSTMODEx - Test mode */ | ||
174 | u32 rsvd1[3]; | ||
175 | u32 reset; /* RTSTRESETx - Test reset control */ | ||
176 | u32 rsvd2[3]; | ||
177 | u32 status; /* RTSTSSTATUSx - Test status */ | ||
178 | u32 rsvd3; | ||
179 | u32 errstat; /* RTSTERRSTATx - Test error status */ | ||
180 | u32 rsvd4; | ||
181 | u32 errctl; /* RTSTERRCTLx - Test error control */ | ||
182 | u32 rsvd5; | ||
183 | u32 entropy; /* RTSTENTROPYx - Test entropy */ | ||
184 | u32 rsvd6[15]; | ||
185 | u32 verifctl; /* RTSTVERIFCTLx - Test verification control */ | ||
186 | u32 rsvd7; | ||
187 | u32 verifstat; /* RTSTVERIFSTATx - Test verification status */ | ||
188 | u32 rsvd8; | ||
189 | u32 verifdata; /* RTSTVERIFDx - Test verification data */ | ||
190 | u32 rsvd9; | ||
191 | u32 xkey; /* RTSTXKEYx - Test XKEY */ | ||
192 | u32 rsvd10; | ||
193 | u32 oscctctl; /* RTSTOSCCTCTLx - Test osc. counter control */ | ||
194 | u32 rsvd11; | ||
195 | u32 oscct; /* RTSTOSCCTx - Test oscillator counter */ | ||
196 | u32 rsvd12; | ||
197 | u32 oscctstat; /* RTSTODCCTSTATx - Test osc counter status */ | ||
198 | u32 rsvd13[2]; | ||
199 | u32 ofifo[4]; /* RTSTOFIFOx - Test output FIFO */ | ||
200 | u32 rsvd14[15]; | ||
201 | }; | ||
202 | |||
203 | /* | ||
204 | * caam_ctrl - basic core configuration | ||
205 | * starts base + 0x0000 padded out to 0x1000 | ||
206 | */ | ||
207 | |||
208 | #define KEK_KEY_SIZE 8 | ||
209 | #define TKEK_KEY_SIZE 8 | ||
210 | #define TDSK_KEY_SIZE 8 | ||
211 | |||
212 | #define DECO_RESET 1 /* Use with DECO reset/availability regs */ | ||
213 | #define DECO_RESET_0 (DECO_RESET << 0) | ||
214 | #define DECO_RESET_1 (DECO_RESET << 1) | ||
215 | #define DECO_RESET_2 (DECO_RESET << 2) | ||
216 | #define DECO_RESET_3 (DECO_RESET << 3) | ||
217 | #define DECO_RESET_4 (DECO_RESET << 4) | ||
218 | |||
219 | struct caam_ctrl { | ||
220 | /* Basic Configuration Section 000-01f */ | ||
221 | /* Read/Writable */ | ||
222 | u32 rsvd1; | ||
223 | u32 mcr; /* MCFG Master Config Register */ | ||
224 | u32 rsvd2[2]; | ||
225 | |||
226 | /* Bus Access Configuration Section 010-11f */ | ||
227 | /* Read/Writable */ | ||
228 | struct masterid jr_mid[4]; /* JRxLIODNR - JobR LIODN setup */ | ||
229 | u32 rsvd3[12]; | ||
230 | struct masterid rtic_mid[4]; /* RTICxLIODNR - RTIC LIODN setup */ | ||
231 | u32 rsvd4[7]; | ||
232 | u32 deco_rq; /* DECORR - DECO Request */ | ||
233 | struct partid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */ | ||
234 | u32 rsvd5[22]; | ||
235 | |||
236 | /* DECO Availability/Reset Section 120-3ff */ | ||
237 | u32 deco_avail; /* DAR - DECO availability */ | ||
238 | u32 deco_reset; /* DRR - DECO reset */ | ||
239 | u32 rsvd6[182]; | ||
240 | |||
241 | /* Key Encryption/Decryption Configuration 400-5ff */ | ||
242 | /* Read/Writable only while in Non-secure mode */ | ||
243 | u32 kek[KEK_KEY_SIZE]; /* JDKEKR - Key Encryption Key */ | ||
244 | u32 tkek[TKEK_KEY_SIZE]; /* TDKEKR - Trusted Desc KEK */ | ||
245 | u32 tdsk[TDSK_KEY_SIZE]; /* TDSKR - Trusted Desc Signing Key */ | ||
246 | u32 rsvd7[32]; | ||
247 | u64 sknonce; /* SKNR - Secure Key Nonce */ | ||
248 | u32 rsvd8[70]; | ||
249 | |||
250 | /* RNG Test/Verification/Debug Access 600-7ff */ | ||
251 | /* (Useful in Test/Debug modes only...) */ | ||
252 | struct rngtst rtst[2]; | ||
253 | |||
254 | u32 rsvd9[448]; | ||
255 | |||
256 | /* Performance Monitor f00-fff */ | ||
257 | struct caam_perfmon perfmon; | ||
258 | }; | ||
259 | |||
260 | /* | ||
261 | * Controller master config register defs | ||
262 | */ | ||
263 | #define MCFGR_SWRESET 0x80000000 /* software reset */ | ||
264 | #define MCFGR_WDENABLE 0x40000000 /* DECO watchdog enable */ | ||
265 | #define MCFGR_WDFAIL 0x20000000 /* DECO watchdog force-fail */ | ||
266 | #define MCFGR_DMA_RESET 0x10000000 | ||
267 | #define MCFGR_LONG_PTR 0x00010000 /* Use >32-bit desc addressing */ | ||
268 | |||
269 | /* AXI read cache control */ | ||
270 | #define MCFGR_ARCACHE_SHIFT 12 | ||
271 | #define MCFGR_ARCACHE_MASK (0xf << MCFGR_ARCACHE_SHIFT) | ||
272 | |||
273 | /* AXI write cache control */ | ||
274 | #define MCFGR_AWCACHE_SHIFT 8 | ||
275 | #define MCFGR_AWCACHE_MASK (0xf << MCFGR_AWCACHE_SHIFT) | ||
276 | |||
277 | /* AXI pipeline depth */ | ||
278 | #define MCFGR_AXIPIPE_SHIFT 4 | ||
279 | #define MCFGR_AXIPIPE_MASK (0xf << MCFGR_AXIPIPE_SHIFT) | ||
280 | |||
281 | #define MCFGR_AXIPRI 0x00000008 /* Assert AXI priority sideband */ | ||
282 | #define MCFGR_BURST_64 0x00000001 /* Max burst size */ | ||
283 | |||
284 | /* | ||
285 | * caam_job_ring - direct job ring setup | ||
286 | * 1-4 possible per instantiation, base + 1000/2000/3000/4000 | ||
287 | * Padded out to 0x1000 | ||
288 | */ | ||
289 | struct caam_job_ring { | ||
290 | /* Input ring */ | ||
291 | u64 inpring_base; /* IRBAx - Input desc ring baseaddr */ | ||
292 | u32 rsvd1; | ||
293 | u32 inpring_size; /* IRSx - Input ring size */ | ||
294 | u32 rsvd2; | ||
295 | u32 inpring_avail; /* IRSAx - Input ring room remaining */ | ||
296 | u32 rsvd3; | ||
297 | u32 inpring_jobadd; /* IRJAx - Input ring jobs added */ | ||
298 | |||
299 | /* Output Ring */ | ||
300 | u64 outring_base; /* ORBAx - Output status ring base addr */ | ||
301 | u32 rsvd4; | ||
302 | u32 outring_size; /* ORSx - Output ring size */ | ||
303 | u32 rsvd5; | ||
304 | u32 outring_rmvd; /* ORJRx - Output ring jobs removed */ | ||
305 | u32 rsvd6; | ||
306 | u32 outring_used; /* ORSFx - Output ring slots full */ | ||
307 | |||
308 | /* Status/Configuration */ | ||
309 | u32 rsvd7; | ||
310 | u32 jroutstatus; /* JRSTAx - JobR output status */ | ||
311 | u32 rsvd8; | ||
312 | u32 jrintstatus; /* JRINTx - JobR interrupt status */ | ||
313 | u32 rconfig_hi; /* JRxCFG - Ring configuration */ | ||
314 | u32 rconfig_lo; | ||
315 | |||
316 | /* Indices. CAAM maintains as "heads" of each queue */ | ||
317 | u32 rsvd9; | ||
318 | u32 inp_rdidx; /* IRRIx - Input ring read index */ | ||
319 | u32 rsvd10; | ||
320 | u32 out_wtidx; /* ORWIx - Output ring write index */ | ||
321 | |||
322 | /* Command/control */ | ||
323 | u32 rsvd11; | ||
324 | u32 jrcommand; /* JRCRx - JobR command */ | ||
325 | |||
326 | u32 rsvd12[932]; | ||
327 | |||
328 | /* Performance Monitor f00-fff */ | ||
329 | struct caam_perfmon perfmon; | ||
330 | }; | ||
331 | |||
332 | #define JR_RINGSIZE_MASK 0x03ff | ||
333 | /* | ||
334 | * jrstatus - Job Ring Output Status | ||
335 | * All values in lo word | ||
336 | * Also note, same values written out as status through QI | ||
337 | * in the command/status field of a frame descriptor | ||
338 | */ | ||
339 | #define JRSTA_SSRC_SHIFT 28 | ||
340 | #define JRSTA_SSRC_MASK 0xf0000000 | ||
341 | |||
342 | #define JRSTA_SSRC_NONE 0x00000000 | ||
343 | #define JRSTA_SSRC_CCB_ERROR 0x20000000 | ||
344 | #define JRSTA_SSRC_JUMP_HALT_USER 0x30000000 | ||
345 | #define JRSTA_SSRC_DECO 0x40000000 | ||
346 | #define JRSTA_SSRC_JRERROR 0x60000000 | ||
347 | #define JRSTA_SSRC_JUMP_HALT_CC 0x70000000 | ||
348 | |||
349 | #define JRSTA_DECOERR_JUMP 0x08000000 | ||
350 | #define JRSTA_DECOERR_INDEX_SHIFT 8 | ||
351 | #define JRSTA_DECOERR_INDEX_MASK 0xff00 | ||
352 | #define JRSTA_DECOERR_ERROR_MASK 0x00ff | ||
353 | |||
354 | #define JRSTA_DECOERR_NONE 0x00 | ||
355 | #define JRSTA_DECOERR_LINKLEN 0x01 | ||
356 | #define JRSTA_DECOERR_LINKPTR 0x02 | ||
357 | #define JRSTA_DECOERR_JRCTRL 0x03 | ||
358 | #define JRSTA_DECOERR_DESCCMD 0x04 | ||
359 | #define JRSTA_DECOERR_ORDER 0x05 | ||
360 | #define JRSTA_DECOERR_KEYCMD 0x06 | ||
361 | #define JRSTA_DECOERR_LOADCMD 0x07 | ||
362 | #define JRSTA_DECOERR_STORECMD 0x08 | ||
363 | #define JRSTA_DECOERR_OPCMD 0x09 | ||
364 | #define JRSTA_DECOERR_FIFOLDCMD 0x0a | ||
365 | #define JRSTA_DECOERR_FIFOSTCMD 0x0b | ||
366 | #define JRSTA_DECOERR_MOVECMD 0x0c | ||
367 | #define JRSTA_DECOERR_JUMPCMD 0x0d | ||
368 | #define JRSTA_DECOERR_MATHCMD 0x0e | ||
369 | #define JRSTA_DECOERR_SHASHCMD 0x0f | ||
370 | #define JRSTA_DECOERR_SEQCMD 0x10 | ||
371 | #define JRSTA_DECOERR_DECOINTERNAL 0x11 | ||
372 | #define JRSTA_DECOERR_SHDESCHDR 0x12 | ||
373 | #define JRSTA_DECOERR_HDRLEN 0x13 | ||
374 | #define JRSTA_DECOERR_BURSTER 0x14 | ||
375 | #define JRSTA_DECOERR_DESCSIGNATURE 0x15 | ||
376 | #define JRSTA_DECOERR_DMA 0x16 | ||
377 | #define JRSTA_DECOERR_BURSTFIFO 0x17 | ||
378 | #define JRSTA_DECOERR_JRRESET 0x1a | ||
379 | #define JRSTA_DECOERR_JOBFAIL 0x1b | ||
380 | #define JRSTA_DECOERR_DNRERR 0x80 | ||
381 | #define JRSTA_DECOERR_UNDEFPCL 0x81 | ||
382 | #define JRSTA_DECOERR_PDBERR 0x82 | ||
383 | #define JRSTA_DECOERR_ANRPLY_LATE 0x83 | ||
384 | #define JRSTA_DECOERR_ANRPLY_REPLAY 0x84 | ||
385 | #define JRSTA_DECOERR_SEQOVF 0x85 | ||
386 | #define JRSTA_DECOERR_INVSIGN 0x86 | ||
387 | #define JRSTA_DECOERR_DSASIGN 0x87 | ||
388 | |||
389 | #define JRSTA_CCBERR_JUMP 0x08000000 | ||
390 | #define JRSTA_CCBERR_INDEX_MASK 0xff00 | ||
391 | #define JRSTA_CCBERR_INDEX_SHIFT 8 | ||
392 | #define JRSTA_CCBERR_CHAID_MASK 0x00f0 | ||
393 | #define JRSTA_CCBERR_CHAID_SHIFT 4 | ||
394 | #define JRSTA_CCBERR_ERRID_MASK 0x000f | ||
395 | |||
396 | #define JRSTA_CCBERR_CHAID_AES (0x01 << JRSTA_CCBERR_CHAID_SHIFT) | ||
397 | #define JRSTA_CCBERR_CHAID_DES (0x02 << JRSTA_CCBERR_CHAID_SHIFT) | ||
398 | #define JRSTA_CCBERR_CHAID_ARC4 (0x03 << JRSTA_CCBERR_CHAID_SHIFT) | ||
399 | #define JRSTA_CCBERR_CHAID_MD (0x04 << JRSTA_CCBERR_CHAID_SHIFT) | ||
400 | #define JRSTA_CCBERR_CHAID_RNG (0x05 << JRSTA_CCBERR_CHAID_SHIFT) | ||
401 | #define JRSTA_CCBERR_CHAID_SNOW (0x06 << JRSTA_CCBERR_CHAID_SHIFT) | ||
402 | #define JRSTA_CCBERR_CHAID_KASUMI (0x07 << JRSTA_CCBERR_CHAID_SHIFT) | ||
403 | #define JRSTA_CCBERR_CHAID_PK (0x08 << JRSTA_CCBERR_CHAID_SHIFT) | ||
404 | #define JRSTA_CCBERR_CHAID_CRC (0x09 << JRSTA_CCBERR_CHAID_SHIFT) | ||
405 | |||
406 | #define JRSTA_CCBERR_ERRID_NONE 0x00 | ||
407 | #define JRSTA_CCBERR_ERRID_MODE 0x01 | ||
408 | #define JRSTA_CCBERR_ERRID_DATASIZ 0x02 | ||
409 | #define JRSTA_CCBERR_ERRID_KEYSIZ 0x03 | ||
410 | #define JRSTA_CCBERR_ERRID_PKAMEMSZ 0x04 | ||
411 | #define JRSTA_CCBERR_ERRID_PKBMEMSZ 0x05 | ||
412 | #define JRSTA_CCBERR_ERRID_SEQUENCE 0x06 | ||
413 | #define JRSTA_CCBERR_ERRID_PKDIVZRO 0x07 | ||
414 | #define JRSTA_CCBERR_ERRID_PKMODEVN 0x08 | ||
415 | #define JRSTA_CCBERR_ERRID_KEYPARIT 0x09 | ||
416 | #define JRSTA_CCBERR_ERRID_ICVCHK 0x0a | ||
417 | #define JRSTA_CCBERR_ERRID_HARDWARE 0x0b | ||
418 | #define JRSTA_CCBERR_ERRID_CCMAAD 0x0c | ||
419 | #define JRSTA_CCBERR_ERRID_INVCHA 0x0f | ||
420 | |||
421 | #define JRINT_ERR_INDEX_MASK 0x3fff0000 | ||
422 | #define JRINT_ERR_INDEX_SHIFT 16 | ||
423 | #define JRINT_ERR_TYPE_MASK 0xf00 | ||
424 | #define JRINT_ERR_TYPE_SHIFT 8 | ||
425 | #define JRINT_ERR_HALT_MASK 0xc | ||
426 | #define JRINT_ERR_HALT_SHIFT 2 | ||
427 | #define JRINT_ERR_HALT_INPROGRESS 0x4 | ||
428 | #define JRINT_ERR_HALT_COMPLETE 0x8 | ||
429 | #define JRINT_JR_ERROR 0x02 | ||
430 | #define JRINT_JR_INT 0x01 | ||
431 | |||
432 | #define JRINT_ERR_TYPE_WRITE 1 | ||
433 | #define JRINT_ERR_TYPE_BAD_INPADDR 3 | ||
434 | #define JRINT_ERR_TYPE_BAD_OUTADDR 4 | ||
435 | #define JRINT_ERR_TYPE_INV_INPWRT 5 | ||
436 | #define JRINT_ERR_TYPE_INV_OUTWRT 6 | ||
437 | #define JRINT_ERR_TYPE_RESET 7 | ||
438 | #define JRINT_ERR_TYPE_REMOVE_OFL 8 | ||
439 | #define JRINT_ERR_TYPE_ADD_OFL 9 | ||
440 | |||
441 | #define JRCFG_SOE 0x04 | ||
442 | #define JRCFG_ICEN 0x02 | ||
443 | #define JRCFG_IMSK 0x01 | ||
444 | #define JRCFG_ICDCT_SHIFT 8 | ||
445 | #define JRCFG_ICTT_SHIFT 16 | ||
446 | |||
447 | #define JRCR_RESET 0x01 | ||
448 | |||
449 | /* | ||
450 | * caam_assurance - Assurance Controller View | ||
451 | * base + 0x6000 padded out to 0x1000 | ||
452 | */ | ||
453 | |||
454 | struct rtic_element { | ||
455 | u64 address; | ||
456 | u32 rsvd; | ||
457 | u32 length; | ||
458 | }; | ||
459 | |||
460 | struct rtic_block { | ||
461 | struct rtic_element element[2]; | ||
462 | }; | ||
463 | |||
464 | struct rtic_memhash { | ||
465 | u32 memhash_be[32]; | ||
466 | u32 memhash_le[32]; | ||
467 | }; | ||
468 | |||
469 | struct caam_assurance { | ||
470 | /* Status/Command/Watchdog */ | ||
471 | u32 rsvd1; | ||
472 | u32 status; /* RSTA - Status */ | ||
473 | u32 rsvd2; | ||
474 | u32 cmd; /* RCMD - Command */ | ||
475 | u32 rsvd3; | ||
476 | u32 ctrl; /* RCTL - Control */ | ||
477 | u32 rsvd4; | ||
478 | u32 throttle; /* RTHR - Throttle */ | ||
479 | u32 rsvd5[2]; | ||
480 | u64 watchdog; /* RWDOG - Watchdog Timer */ | ||
481 | u32 rsvd6; | ||
482 | u32 rend; /* REND - Endian corrections */ | ||
483 | u32 rsvd7[50]; | ||
484 | |||
485 | /* Block access/configuration @ 100/110/120/130 */ | ||
486 | struct rtic_block memblk[4]; /* Memory Blocks A-D */ | ||
487 | u32 rsvd8[32]; | ||
488 | |||
489 | /* Block hashes @ 200/300/400/500 */ | ||
490 | struct rtic_memhash hash[4]; /* Block hash values A-D */ | ||
491 | u32 rsvd_3[640]; | ||
492 | }; | ||
493 | |||
494 | /* | ||
495 | * caam_queue_if - QI configuration and control | ||
496 | * starts base + 0x7000, padded out to 0x1000 long | ||
497 | */ | ||
498 | |||
499 | struct caam_queue_if { | ||
500 | u32 qi_control_hi; /* QICTL - QI Control */ | ||
501 | u32 qi_control_lo; | ||
502 | u32 rsvd1; | ||
503 | u32 qi_status; /* QISTA - QI Status */ | ||
504 | u32 qi_deq_cfg_hi; /* QIDQC - QI Dequeue Configuration */ | ||
505 | u32 qi_deq_cfg_lo; | ||
506 | u32 qi_enq_cfg_hi; /* QISEQC - QI Enqueue Command */ | ||
507 | u32 qi_enq_cfg_lo; | ||
508 | u32 rsvd2[1016]; | ||
509 | }; | ||
510 | |||
511 | /* QI control bits - low word */ | ||
512 | #define QICTL_DQEN 0x01 /* Enable frame pop */ | ||
513 | #define QICTL_STOP 0x02 /* Stop dequeue/enqueue */ | ||
514 | #define QICTL_SOE 0x04 /* Stop on error */ | ||
515 | |||
516 | /* QI control bits - high word */ | ||
517 | #define QICTL_MBSI 0x01 | ||
518 | #define QICTL_MHWSI 0x02 | ||
519 | #define QICTL_MWSI 0x04 | ||
520 | #define QICTL_MDWSI 0x08 | ||
521 | #define QICTL_CBSI 0x10 /* CtrlDataByteSwapInput */ | ||
522 | #define QICTL_CHWSI 0x20 /* CtrlDataHalfSwapInput */ | ||
523 | #define QICTL_CWSI 0x40 /* CtrlDataWordSwapInput */ | ||
524 | #define QICTL_CDWSI 0x80 /* CtrlDataDWordSwapInput */ | ||
525 | #define QICTL_MBSO 0x0100 | ||
526 | #define QICTL_MHWSO 0x0200 | ||
527 | #define QICTL_MWSO 0x0400 | ||
528 | #define QICTL_MDWSO 0x0800 | ||
529 | #define QICTL_CBSO 0x1000 /* CtrlDataByteSwapOutput */ | ||
530 | #define QICTL_CHWSO 0x2000 /* CtrlDataHalfSwapOutput */ | ||
531 | #define QICTL_CWSO 0x4000 /* CtrlDataWordSwapOutput */ | ||
532 | #define QICTL_CDWSO 0x8000 /* CtrlDataDWordSwapOutput */ | ||
533 | #define QICTL_DMBS 0x010000 | ||
534 | #define QICTL_EPO 0x020000 | ||
535 | |||
536 | /* QI status bits */ | ||
537 | #define QISTA_PHRDERR 0x01 /* PreHeader Read Error */ | ||
538 | #define QISTA_CFRDERR 0x02 /* Compound Frame Read Error */ | ||
539 | #define QISTA_OFWRERR 0x04 /* Output Frame Read Error */ | ||
540 | #define QISTA_BPDERR 0x08 /* Buffer Pool Depleted */ | ||
541 | #define QISTA_BTSERR 0x10 /* Buffer Undersize */ | ||
542 | #define QISTA_CFWRERR 0x20 /* Compound Frame Write Err */ | ||
543 | #define QISTA_STOPD 0x80000000 /* QI Stopped (see QICTL) */ | ||
544 | |||
545 | /* deco_sg_table - DECO view of scatter/gather table */ | ||
546 | struct deco_sg_table { | ||
547 | u64 addr; /* Segment Address */ | ||
548 | u32 elen; /* E, F bits + 30-bit length */ | ||
549 | u32 bpid_offset; /* Buffer Pool ID + 16-bit length */ | ||
550 | }; | ||
551 | |||
552 | /* | ||
553 | * caam_deco - descriptor controller - CHA cluster block | ||
554 | * | ||
555 | * Only accessible when direct DECO access is turned on | ||
556 | * (done in DECORR, via MID programmed in DECOxMID | ||
557 | * | ||
558 | * 5 typical, base + 0x8000/9000/a000/b000 | ||
559 | * Padded out to 0x1000 long | ||
560 | */ | ||
561 | struct caam_deco { | ||
562 | u32 rsvd1; | ||
563 | u32 cls1_mode; /* CxC1MR - Class 1 Mode */ | ||
564 | u32 rsvd2; | ||
565 | u32 cls1_keysize; /* CxC1KSR - Class 1 Key Size */ | ||
566 | u32 cls1_datasize_hi; /* CxC1DSR - Class 1 Data Size */ | ||
567 | u32 cls1_datasize_lo; | ||
568 | u32 rsvd3; | ||
569 | u32 cls1_icvsize; /* CxC1ICVSR - Class 1 ICV size */ | ||
570 | u32 rsvd4[5]; | ||
571 | u32 cha_ctrl; /* CCTLR - CHA control */ | ||
572 | u32 rsvd5; | ||
573 | u32 irq_crtl; /* CxCIRQ - CCB interrupt done/error/clear */ | ||
574 | u32 rsvd6; | ||
575 | u32 clr_written; /* CxCWR - Clear-Written */ | ||
576 | u32 ccb_status_hi; /* CxCSTA - CCB Status/Error */ | ||
577 | u32 ccb_status_lo; | ||
578 | u32 rsvd7[3]; | ||
579 | u32 aad_size; /* CxAADSZR - Current AAD Size */ | ||
580 | u32 rsvd8; | ||
581 | u32 cls1_iv_size; /* CxC1IVSZR - Current Class 1 IV Size */ | ||
582 | u32 rsvd9[7]; | ||
583 | u32 pkha_a_size; /* PKASZRx - Size of PKHA A */ | ||
584 | u32 rsvd10; | ||
585 | u32 pkha_b_size; /* PKBSZRx - Size of PKHA B */ | ||
586 | u32 rsvd11; | ||
587 | u32 pkha_n_size; /* PKNSZRx - Size of PKHA N */ | ||
588 | u32 rsvd12; | ||
589 | u32 pkha_e_size; /* PKESZRx - Size of PKHA E */ | ||
590 | u32 rsvd13[24]; | ||
591 | u32 cls1_ctx[16]; /* CxC1CTXR - Class 1 Context @100 */ | ||
592 | u32 rsvd14[48]; | ||
593 | u32 cls1_key[8]; /* CxC1KEYR - Class 1 Key @200 */ | ||
594 | u32 rsvd15[121]; | ||
595 | u32 cls2_mode; /* CxC2MR - Class 2 Mode */ | ||
596 | u32 rsvd16; | ||
597 | u32 cls2_keysize; /* CxX2KSR - Class 2 Key Size */ | ||
598 | u32 cls2_datasize_hi; /* CxC2DSR - Class 2 Data Size */ | ||
599 | u32 cls2_datasize_lo; | ||
600 | u32 rsvd17; | ||
601 | u32 cls2_icvsize; /* CxC2ICVSZR - Class 2 ICV Size */ | ||
602 | u32 rsvd18[56]; | ||
603 | u32 cls2_ctx[18]; /* CxC2CTXR - Class 2 Context @500 */ | ||
604 | u32 rsvd19[46]; | ||
605 | u32 cls2_key[32]; /* CxC2KEYR - Class2 Key @600 */ | ||
606 | u32 rsvd20[84]; | ||
607 | u32 inp_infofifo_hi; /* CxIFIFO - Input Info FIFO @7d0 */ | ||
608 | u32 inp_infofifo_lo; | ||
609 | u32 rsvd21[2]; | ||
610 | u64 inp_datafifo; /* CxDFIFO - Input Data FIFO */ | ||
611 | u32 rsvd22[2]; | ||
612 | u64 out_datafifo; /* CxOFIFO - Output Data FIFO */ | ||
613 | u32 rsvd23[2]; | ||
614 | u32 jr_ctl_hi; /* CxJRR - JobR Control Register @800 */ | ||
615 | u32 jr_ctl_lo; | ||
616 | u64 jr_descaddr; /* CxDADR - JobR Descriptor Address */ | ||
617 | u32 op_status_hi; /* DxOPSTA - DECO Operation Status */ | ||
618 | u32 op_status_lo; | ||
619 | u32 rsvd24[2]; | ||
620 | u32 liodn; /* DxLSR - DECO LIODN Status - non-seq */ | ||
621 | u32 td_liodn; /* DxLSR - DECO LIODN Status - trustdesc */ | ||
622 | u32 rsvd26[6]; | ||
623 | u64 math[4]; /* DxMTH - Math register */ | ||
624 | u32 rsvd27[8]; | ||
625 | struct deco_sg_table gthr_tbl[4]; /* DxGTR - Gather Tables */ | ||
626 | u32 rsvd28[16]; | ||
627 | struct deco_sg_table sctr_tbl[4]; /* DxSTR - Scatter Tables */ | ||
628 | u32 rsvd29[48]; | ||
629 | u32 descbuf[64]; /* DxDESB - Descriptor buffer */ | ||
630 | u32 rsvd30[320]; | ||
631 | }; | ||
632 | |||
633 | /* | ||
634 | * Current top-level view of memory map is: | ||
635 | * | ||
636 | * 0x0000 - 0x0fff - CAAM Top-Level Control | ||
637 | * 0x1000 - 0x1fff - Job Ring 0 | ||
638 | * 0x2000 - 0x2fff - Job Ring 1 | ||
639 | * 0x3000 - 0x3fff - Job Ring 2 | ||
640 | * 0x4000 - 0x4fff - Job Ring 3 | ||
641 | * 0x5000 - 0x5fff - (unused) | ||
642 | * 0x6000 - 0x6fff - Assurance Controller | ||
643 | * 0x7000 - 0x7fff - Queue Interface | ||
644 | * 0x8000 - 0x8fff - DECO-CCB 0 | ||
645 | * 0x9000 - 0x9fff - DECO-CCB 1 | ||
646 | * 0xa000 - 0xafff - DECO-CCB 2 | ||
647 | * 0xb000 - 0xbfff - DECO-CCB 3 | ||
648 | * 0xc000 - 0xcfff - DECO-CCB 4 | ||
649 | * | ||
650 | * caam_full describes the full register view of CAAM if useful, | ||
651 | * although many configurations may choose to implement parts of | ||
652 | * the register map separately, in differing privilege regions | ||
653 | */ | ||
654 | struct caam_full { | ||
655 | struct caam_ctrl __iomem ctrl; | ||
656 | struct caam_job_ring jr[4]; | ||
657 | u64 rsvd[512]; | ||
658 | struct caam_assurance assure; | ||
659 | struct caam_queue_if qi; | ||
660 | struct caam_deco *deco; | ||
661 | }; | ||
662 | |||
663 | #endif /* REGS_H */ | ||
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index c99305afa58a..3cf303ee3fe3 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c | |||
@@ -133,7 +133,6 @@ struct mv_req_hash_ctx { | |||
133 | int extra_bytes; /* unprocessed bytes in buffer */ | 133 | int extra_bytes; /* unprocessed bytes in buffer */ |
134 | enum hash_op op; | 134 | enum hash_op op; |
135 | int count_add; | 135 | int count_add; |
136 | struct scatterlist dummysg; | ||
137 | }; | 136 | }; |
138 | 137 | ||
139 | static void compute_aes_dec_key(struct mv_ctx *ctx) | 138 | static void compute_aes_dec_key(struct mv_ctx *ctx) |
@@ -187,9 +186,9 @@ static void copy_src_to_buf(struct req_progress *p, char *dbuf, int len) | |||
187 | { | 186 | { |
188 | int ret; | 187 | int ret; |
189 | void *sbuf; | 188 | void *sbuf; |
190 | int copied = 0; | 189 | int copy_len; |
191 | 190 | ||
192 | while (1) { | 191 | while (len) { |
193 | if (!p->sg_src_left) { | 192 | if (!p->sg_src_left) { |
194 | ret = sg_miter_next(&p->src_sg_it); | 193 | ret = sg_miter_next(&p->src_sg_it); |
195 | BUG_ON(!ret); | 194 | BUG_ON(!ret); |
@@ -199,19 +198,14 @@ static void copy_src_to_buf(struct req_progress *p, char *dbuf, int len) | |||
199 | 198 | ||
200 | sbuf = p->src_sg_it.addr + p->src_start; | 199 | sbuf = p->src_sg_it.addr + p->src_start; |
201 | 200 | ||
202 | if (p->sg_src_left <= len - copied) { | 201 | copy_len = min(p->sg_src_left, len); |
203 | memcpy(dbuf + copied, sbuf, p->sg_src_left); | 202 | memcpy(dbuf, sbuf, copy_len); |
204 | copied += p->sg_src_left; | 203 | |
205 | p->sg_src_left = 0; | 204 | p->src_start += copy_len; |
206 | if (copied >= len) | 205 | p->sg_src_left -= copy_len; |
207 | break; | 206 | |
208 | } else { | 207 | len -= copy_len; |
209 | int copy_len = len - copied; | 208 | dbuf += copy_len; |
210 | memcpy(dbuf + copied, sbuf, copy_len); | ||
211 | p->src_start += copy_len; | ||
212 | p->sg_src_left -= copy_len; | ||
213 | break; | ||
214 | } | ||
215 | } | 209 | } |
216 | } | 210 | } |
217 | 211 | ||
@@ -275,7 +269,6 @@ static void mv_process_current_q(int first_block) | |||
275 | memcpy(cpg->sram + SRAM_CONFIG, &op, | 269 | memcpy(cpg->sram + SRAM_CONFIG, &op, |
276 | sizeof(struct sec_accel_config)); | 270 | sizeof(struct sec_accel_config)); |
277 | 271 | ||
278 | writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0); | ||
279 | /* GO */ | 272 | /* GO */ |
280 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); | 273 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); |
281 | 274 | ||
@@ -302,6 +295,7 @@ static void mv_crypto_algo_completion(void) | |||
302 | static void mv_process_hash_current(int first_block) | 295 | static void mv_process_hash_current(int first_block) |
303 | { | 296 | { |
304 | struct ahash_request *req = ahash_request_cast(cpg->cur_req); | 297 | struct ahash_request *req = ahash_request_cast(cpg->cur_req); |
298 | const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm); | ||
305 | struct mv_req_hash_ctx *req_ctx = ahash_request_ctx(req); | 299 | struct mv_req_hash_ctx *req_ctx = ahash_request_ctx(req); |
306 | struct req_progress *p = &cpg->p; | 300 | struct req_progress *p = &cpg->p; |
307 | struct sec_accel_config op = { 0 }; | 301 | struct sec_accel_config op = { 0 }; |
@@ -314,6 +308,8 @@ static void mv_process_hash_current(int first_block) | |||
314 | break; | 308 | break; |
315 | case COP_HMAC_SHA1: | 309 | case COP_HMAC_SHA1: |
316 | op.config = CFG_OP_MAC_ONLY | CFG_MACM_HMAC_SHA1; | 310 | op.config = CFG_OP_MAC_ONLY | CFG_MACM_HMAC_SHA1; |
311 | memcpy(cpg->sram + SRAM_HMAC_IV_IN, | ||
312 | tfm_ctx->ivs, sizeof(tfm_ctx->ivs)); | ||
317 | break; | 313 | break; |
318 | } | 314 | } |
319 | 315 | ||
@@ -345,11 +341,16 @@ static void mv_process_hash_current(int first_block) | |||
345 | op.config |= CFG_LAST_FRAG; | 341 | op.config |= CFG_LAST_FRAG; |
346 | else | 342 | else |
347 | op.config |= CFG_MID_FRAG; | 343 | op.config |= CFG_MID_FRAG; |
344 | |||
345 | writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A); | ||
346 | writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B); | ||
347 | writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C); | ||
348 | writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D); | ||
349 | writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E); | ||
348 | } | 350 | } |
349 | 351 | ||
350 | memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); | 352 | memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); |
351 | 353 | ||
352 | writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0); | ||
353 | /* GO */ | 354 | /* GO */ |
354 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); | 355 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); |
355 | 356 | ||
@@ -409,12 +410,6 @@ static void mv_hash_algo_completion(void) | |||
409 | copy_src_to_buf(&cpg->p, ctx->buffer, ctx->extra_bytes); | 410 | copy_src_to_buf(&cpg->p, ctx->buffer, ctx->extra_bytes); |
410 | sg_miter_stop(&cpg->p.src_sg_it); | 411 | sg_miter_stop(&cpg->p.src_sg_it); |
411 | 412 | ||
412 | ctx->state[0] = readl(cpg->reg + DIGEST_INITIAL_VAL_A); | ||
413 | ctx->state[1] = readl(cpg->reg + DIGEST_INITIAL_VAL_B); | ||
414 | ctx->state[2] = readl(cpg->reg + DIGEST_INITIAL_VAL_C); | ||
415 | ctx->state[3] = readl(cpg->reg + DIGEST_INITIAL_VAL_D); | ||
416 | ctx->state[4] = readl(cpg->reg + DIGEST_INITIAL_VAL_E); | ||
417 | |||
418 | if (likely(ctx->last_chunk)) { | 413 | if (likely(ctx->last_chunk)) { |
419 | if (likely(ctx->count <= MAX_HW_HASH_SIZE)) { | 414 | if (likely(ctx->count <= MAX_HW_HASH_SIZE)) { |
420 | memcpy(req->result, cpg->sram + SRAM_DIGEST_BUF, | 415 | memcpy(req->result, cpg->sram + SRAM_DIGEST_BUF, |
@@ -422,6 +417,12 @@ static void mv_hash_algo_completion(void) | |||
422 | (req))); | 417 | (req))); |
423 | } else | 418 | } else |
424 | mv_hash_final_fallback(req); | 419 | mv_hash_final_fallback(req); |
420 | } else { | ||
421 | ctx->state[0] = readl(cpg->reg + DIGEST_INITIAL_VAL_A); | ||
422 | ctx->state[1] = readl(cpg->reg + DIGEST_INITIAL_VAL_B); | ||
423 | ctx->state[2] = readl(cpg->reg + DIGEST_INITIAL_VAL_C); | ||
424 | ctx->state[3] = readl(cpg->reg + DIGEST_INITIAL_VAL_D); | ||
425 | ctx->state[4] = readl(cpg->reg + DIGEST_INITIAL_VAL_E); | ||
425 | } | 426 | } |
426 | } | 427 | } |
427 | 428 | ||
@@ -480,7 +481,7 @@ static int count_sgs(struct scatterlist *sl, unsigned int total_bytes) | |||
480 | int i = 0; | 481 | int i = 0; |
481 | size_t cur_len; | 482 | size_t cur_len; |
482 | 483 | ||
483 | while (1) { | 484 | while (sl) { |
484 | cur_len = sl[i].length; | 485 | cur_len = sl[i].length; |
485 | ++i; | 486 | ++i; |
486 | if (total_bytes > cur_len) | 487 | if (total_bytes > cur_len) |
@@ -517,29 +518,12 @@ static void mv_start_new_hash_req(struct ahash_request *req) | |||
517 | { | 518 | { |
518 | struct req_progress *p = &cpg->p; | 519 | struct req_progress *p = &cpg->p; |
519 | struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); | 520 | struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); |
520 | const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm); | ||
521 | int num_sgs, hw_bytes, old_extra_bytes, rc; | 521 | int num_sgs, hw_bytes, old_extra_bytes, rc; |
522 | cpg->cur_req = &req->base; | 522 | cpg->cur_req = &req->base; |
523 | memset(p, 0, sizeof(struct req_progress)); | 523 | memset(p, 0, sizeof(struct req_progress)); |
524 | hw_bytes = req->nbytes + ctx->extra_bytes; | 524 | hw_bytes = req->nbytes + ctx->extra_bytes; |
525 | old_extra_bytes = ctx->extra_bytes; | 525 | old_extra_bytes = ctx->extra_bytes; |
526 | 526 | ||
527 | if (unlikely(ctx->extra_bytes)) { | ||
528 | memcpy(cpg->sram + SRAM_DATA_IN_START, ctx->buffer, | ||
529 | ctx->extra_bytes); | ||
530 | p->crypt_len = ctx->extra_bytes; | ||
531 | } | ||
532 | |||
533 | memcpy(cpg->sram + SRAM_HMAC_IV_IN, tfm_ctx->ivs, sizeof(tfm_ctx->ivs)); | ||
534 | |||
535 | if (unlikely(!ctx->first_hash)) { | ||
536 | writel(ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A); | ||
537 | writel(ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B); | ||
538 | writel(ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C); | ||
539 | writel(ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D); | ||
540 | writel(ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E); | ||
541 | } | ||
542 | |||
543 | ctx->extra_bytes = hw_bytes % SHA1_BLOCK_SIZE; | 527 | ctx->extra_bytes = hw_bytes % SHA1_BLOCK_SIZE; |
544 | if (ctx->extra_bytes != 0 | 528 | if (ctx->extra_bytes != 0 |
545 | && (!ctx->last_chunk || ctx->count > MAX_HW_HASH_SIZE)) | 529 | && (!ctx->last_chunk || ctx->count > MAX_HW_HASH_SIZE)) |
@@ -555,6 +539,12 @@ static void mv_start_new_hash_req(struct ahash_request *req) | |||
555 | p->complete = mv_hash_algo_completion; | 539 | p->complete = mv_hash_algo_completion; |
556 | p->process = mv_process_hash_current; | 540 | p->process = mv_process_hash_current; |
557 | 541 | ||
542 | if (unlikely(old_extra_bytes)) { | ||
543 | memcpy(cpg->sram + SRAM_DATA_IN_START, ctx->buffer, | ||
544 | old_extra_bytes); | ||
545 | p->crypt_len = old_extra_bytes; | ||
546 | } | ||
547 | |||
558 | mv_process_hash_current(1); | 548 | mv_process_hash_current(1); |
559 | } else { | 549 | } else { |
560 | copy_src_to_buf(p, ctx->buffer + old_extra_bytes, | 550 | copy_src_to_buf(p, ctx->buffer + old_extra_bytes, |
@@ -603,9 +593,7 @@ static int queue_manag(void *data) | |||
603 | if (async_req->tfm->__crt_alg->cra_type != | 593 | if (async_req->tfm->__crt_alg->cra_type != |
604 | &crypto_ahash_type) { | 594 | &crypto_ahash_type) { |
605 | struct ablkcipher_request *req = | 595 | struct ablkcipher_request *req = |
606 | container_of(async_req, | 596 | ablkcipher_request_cast(async_req); |
607 | struct ablkcipher_request, | ||
608 | base); | ||
609 | mv_start_new_crypt_req(req); | 597 | mv_start_new_crypt_req(req); |
610 | } else { | 598 | } else { |
611 | struct ahash_request *req = | 599 | struct ahash_request *req = |
@@ -722,19 +710,13 @@ static int mv_hash_update(struct ahash_request *req) | |||
722 | static int mv_hash_final(struct ahash_request *req) | 710 | static int mv_hash_final(struct ahash_request *req) |
723 | { | 711 | { |
724 | struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); | 712 | struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); |
725 | /* dummy buffer of 4 bytes */ | 713 | |
726 | sg_init_one(&ctx->dummysg, ctx->buffer, 4); | ||
727 | /* I think I'm allowed to do that... */ | ||
728 | ahash_request_set_crypt(req, &ctx->dummysg, req->result, 0); | ||
729 | mv_update_hash_req_ctx(ctx, 1, 0); | 714 | mv_update_hash_req_ctx(ctx, 1, 0); |
730 | return mv_handle_req(&req->base); | 715 | return mv_handle_req(&req->base); |
731 | } | 716 | } |
732 | 717 | ||
733 | static int mv_hash_finup(struct ahash_request *req) | 718 | static int mv_hash_finup(struct ahash_request *req) |
734 | { | 719 | { |
735 | if (!req->nbytes) | ||
736 | return mv_hash_final(req); | ||
737 | |||
738 | mv_update_hash_req_ctx(ahash_request_ctx(req), 1, req->nbytes); | 720 | mv_update_hash_req_ctx(ahash_request_ctx(req), 1, req->nbytes); |
739 | return mv_handle_req(&req->base); | 721 | return mv_handle_req(&req->base); |
740 | } | 722 | } |
@@ -1065,14 +1047,21 @@ static int mv_probe(struct platform_device *pdev) | |||
1065 | 1047 | ||
1066 | writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK); | 1048 | writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK); |
1067 | writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG); | 1049 | writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG); |
1050 | writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0); | ||
1068 | 1051 | ||
1069 | ret = crypto_register_alg(&mv_aes_alg_ecb); | 1052 | ret = crypto_register_alg(&mv_aes_alg_ecb); |
1070 | if (ret) | 1053 | if (ret) { |
1054 | printk(KERN_WARNING MV_CESA | ||
1055 | "Could not register aes-ecb driver\n"); | ||
1071 | goto err_irq; | 1056 | goto err_irq; |
1057 | } | ||
1072 | 1058 | ||
1073 | ret = crypto_register_alg(&mv_aes_alg_cbc); | 1059 | ret = crypto_register_alg(&mv_aes_alg_cbc); |
1074 | if (ret) | 1060 | if (ret) { |
1061 | printk(KERN_WARNING MV_CESA | ||
1062 | "Could not register aes-cbc driver\n"); | ||
1075 | goto err_unreg_ecb; | 1063 | goto err_unreg_ecb; |
1064 | } | ||
1076 | 1065 | ||
1077 | ret = crypto_register_ahash(&mv_sha1_alg); | 1066 | ret = crypto_register_ahash(&mv_sha1_alg); |
1078 | if (ret == 0) | 1067 | if (ret == 0) |
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 465cde3e4f60..ba8f1ea84c5e 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c | |||
@@ -78,7 +78,6 @@ | |||
78 | #define FLAGS_SHA1 0x0010 | 78 | #define FLAGS_SHA1 0x0010 |
79 | #define FLAGS_DMA_ACTIVE 0x0020 | 79 | #define FLAGS_DMA_ACTIVE 0x0020 |
80 | #define FLAGS_OUTPUT_READY 0x0040 | 80 | #define FLAGS_OUTPUT_READY 0x0040 |
81 | #define FLAGS_CLEAN 0x0080 | ||
82 | #define FLAGS_INIT 0x0100 | 81 | #define FLAGS_INIT 0x0100 |
83 | #define FLAGS_CPU 0x0200 | 82 | #define FLAGS_CPU 0x0200 |
84 | #define FLAGS_HMAC 0x0400 | 83 | #define FLAGS_HMAC 0x0400 |
@@ -511,26 +510,6 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd) | |||
511 | return 0; | 510 | return 0; |
512 | } | 511 | } |
513 | 512 | ||
514 | static void omap_sham_cleanup(struct ahash_request *req) | ||
515 | { | ||
516 | struct omap_sham_reqctx *ctx = ahash_request_ctx(req); | ||
517 | struct omap_sham_dev *dd = ctx->dd; | ||
518 | unsigned long flags; | ||
519 | |||
520 | spin_lock_irqsave(&dd->lock, flags); | ||
521 | if (ctx->flags & FLAGS_CLEAN) { | ||
522 | spin_unlock_irqrestore(&dd->lock, flags); | ||
523 | return; | ||
524 | } | ||
525 | ctx->flags |= FLAGS_CLEAN; | ||
526 | spin_unlock_irqrestore(&dd->lock, flags); | ||
527 | |||
528 | if (ctx->digcnt) | ||
529 | omap_sham_copy_ready_hash(req); | ||
530 | |||
531 | dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt); | ||
532 | } | ||
533 | |||
534 | static int omap_sham_init(struct ahash_request *req) | 513 | static int omap_sham_init(struct ahash_request *req) |
535 | { | 514 | { |
536 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); | 515 | struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); |
@@ -618,9 +597,8 @@ static int omap_sham_final_req(struct omap_sham_dev *dd) | |||
618 | return err; | 597 | return err; |
619 | } | 598 | } |
620 | 599 | ||
621 | static int omap_sham_finish_req_hmac(struct ahash_request *req) | 600 | static int omap_sham_finish_hmac(struct ahash_request *req) |
622 | { | 601 | { |
623 | struct omap_sham_reqctx *ctx = ahash_request_ctx(req); | ||
624 | struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); | 602 | struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); |
625 | struct omap_sham_hmac_ctx *bctx = tctx->base; | 603 | struct omap_sham_hmac_ctx *bctx = tctx->base; |
626 | int bs = crypto_shash_blocksize(bctx->shash); | 604 | int bs = crypto_shash_blocksize(bctx->shash); |
@@ -635,7 +613,24 @@ static int omap_sham_finish_req_hmac(struct ahash_request *req) | |||
635 | 613 | ||
636 | return crypto_shash_init(&desc.shash) ?: | 614 | return crypto_shash_init(&desc.shash) ?: |
637 | crypto_shash_update(&desc.shash, bctx->opad, bs) ?: | 615 | crypto_shash_update(&desc.shash, bctx->opad, bs) ?: |
638 | crypto_shash_finup(&desc.shash, ctx->digest, ds, ctx->digest); | 616 | crypto_shash_finup(&desc.shash, req->result, ds, req->result); |
617 | } | ||
618 | |||
619 | static int omap_sham_finish(struct ahash_request *req) | ||
620 | { | ||
621 | struct omap_sham_reqctx *ctx = ahash_request_ctx(req); | ||
622 | struct omap_sham_dev *dd = ctx->dd; | ||
623 | int err = 0; | ||
624 | |||
625 | if (ctx->digcnt) { | ||
626 | omap_sham_copy_ready_hash(req); | ||
627 | if (ctx->flags & FLAGS_HMAC) | ||
628 | err = omap_sham_finish_hmac(req); | ||
629 | } | ||
630 | |||
631 | dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt); | ||
632 | |||
633 | return err; | ||
639 | } | 634 | } |
640 | 635 | ||
641 | static void omap_sham_finish_req(struct ahash_request *req, int err) | 636 | static void omap_sham_finish_req(struct ahash_request *req, int err) |
@@ -645,15 +640,12 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) | |||
645 | 640 | ||
646 | if (!err) { | 641 | if (!err) { |
647 | omap_sham_copy_hash(ctx->dd->req, 1); | 642 | omap_sham_copy_hash(ctx->dd->req, 1); |
648 | if (ctx->flags & FLAGS_HMAC) | 643 | if (ctx->flags & FLAGS_FINAL) |
649 | err = omap_sham_finish_req_hmac(req); | 644 | err = omap_sham_finish(req); |
650 | } else { | 645 | } else { |
651 | ctx->flags |= FLAGS_ERROR; | 646 | ctx->flags |= FLAGS_ERROR; |
652 | } | 647 | } |
653 | 648 | ||
654 | if ((ctx->flags & FLAGS_FINAL) || err) | ||
655 | omap_sham_cleanup(req); | ||
656 | |||
657 | clk_disable(dd->iclk); | 649 | clk_disable(dd->iclk); |
658 | dd->flags &= ~FLAGS_BUSY; | 650 | dd->flags &= ~FLAGS_BUSY; |
659 | 651 | ||
@@ -809,22 +801,21 @@ static int omap_sham_final_shash(struct ahash_request *req) | |||
809 | static int omap_sham_final(struct ahash_request *req) | 801 | static int omap_sham_final(struct ahash_request *req) |
810 | { | 802 | { |
811 | struct omap_sham_reqctx *ctx = ahash_request_ctx(req); | 803 | struct omap_sham_reqctx *ctx = ahash_request_ctx(req); |
812 | int err = 0; | ||
813 | 804 | ||
814 | ctx->flags |= FLAGS_FINUP; | 805 | ctx->flags |= FLAGS_FINUP; |
815 | 806 | ||
816 | if (!(ctx->flags & FLAGS_ERROR)) { | 807 | if (ctx->flags & FLAGS_ERROR) |
817 | /* OMAP HW accel works only with buffers >= 9 */ | 808 | return 0; /* uncompleted hash is not needed */ |
818 | /* HMAC is always >= 9 because of ipad */ | ||
819 | if ((ctx->digcnt + ctx->bufcnt) < 9) | ||
820 | err = omap_sham_final_shash(req); | ||
821 | else if (ctx->bufcnt) | ||
822 | return omap_sham_enqueue(req, OP_FINAL); | ||
823 | } | ||
824 | 809 | ||
825 | omap_sham_cleanup(req); | 810 | /* OMAP HW accel works only with buffers >= 9 */ |
811 | /* HMAC is always >= 9 because ipad == block size */ | ||
812 | if ((ctx->digcnt + ctx->bufcnt) < 9) | ||
813 | return omap_sham_final_shash(req); | ||
814 | else if (ctx->bufcnt) | ||
815 | return omap_sham_enqueue(req, OP_FINAL); | ||
826 | 816 | ||
827 | return err; | 817 | /* copy ready hash (+ finalize hmac) */ |
818 | return omap_sham_finish(req); | ||
828 | } | 819 | } |
829 | 820 | ||
830 | static int omap_sham_finup(struct ahash_request *req) | 821 | static int omap_sham_finup(struct ahash_request *req) |
@@ -835,7 +826,7 @@ static int omap_sham_finup(struct ahash_request *req) | |||
835 | ctx->flags |= FLAGS_FINUP; | 826 | ctx->flags |= FLAGS_FINUP; |
836 | 827 | ||
837 | err1 = omap_sham_update(req); | 828 | err1 = omap_sham_update(req); |
838 | if (err1 == -EINPROGRESS) | 829 | if (err1 == -EINPROGRESS || err1 == -EBUSY) |
839 | return err1; | 830 | return err1; |
840 | /* | 831 | /* |
841 | * final() has to be always called to cleanup resources | 832 | * final() has to be always called to cleanup resources |
@@ -890,8 +881,6 @@ static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base) | |||
890 | struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm); | 881 | struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm); |
891 | const char *alg_name = crypto_tfm_alg_name(tfm); | 882 | const char *alg_name = crypto_tfm_alg_name(tfm); |
892 | 883 | ||
893 | pr_info("enter\n"); | ||
894 | |||
895 | /* Allocate a fallback and abort if it failed. */ | 884 | /* Allocate a fallback and abort if it failed. */ |
896 | tctx->fallback = crypto_alloc_shash(alg_name, 0, | 885 | tctx->fallback = crypto_alloc_shash(alg_name, 0, |
897 | CRYPTO_ALG_NEED_FALLBACK); | 886 | CRYPTO_ALG_NEED_FALLBACK); |
@@ -1297,7 +1286,8 @@ static int __init omap_sham_mod_init(void) | |||
1297 | pr_info("loading %s driver\n", "omap-sham"); | 1286 | pr_info("loading %s driver\n", "omap-sham"); |
1298 | 1287 | ||
1299 | if (!cpu_class_is_omap2() || | 1288 | if (!cpu_class_is_omap2() || |
1300 | omap_type() != OMAP2_DEVICE_TYPE_SEC) { | 1289 | (omap_type() != OMAP2_DEVICE_TYPE_SEC && |
1290 | omap_type() != OMAP2_DEVICE_TYPE_EMU)) { | ||
1301 | pr_err("Unsupported cpu\n"); | 1291 | pr_err("Unsupported cpu\n"); |
1302 | return -ENODEV; | 1292 | return -ENODEV; |
1303 | } | 1293 | } |
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index adf075b6b9a8..06bdb4b2c6a6 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c | |||
@@ -288,9 +288,250 @@ static struct shash_alg sha256_alg = { | |||
288 | } | 288 | } |
289 | }; | 289 | }; |
290 | 290 | ||
291 | /* Add two shash_alg instance for hardware-implemented * | ||
292 | * multiple-parts hash supported by VIA Nano Processor.*/ | ||
293 | static int padlock_sha1_init_nano(struct shash_desc *desc) | ||
294 | { | ||
295 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
296 | |||
297 | *sctx = (struct sha1_state){ | ||
298 | .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, | ||
299 | }; | ||
300 | |||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static int padlock_sha1_update_nano(struct shash_desc *desc, | ||
305 | const u8 *data, unsigned int len) | ||
306 | { | ||
307 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
308 | unsigned int partial, done; | ||
309 | const u8 *src; | ||
310 | /*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/ | ||
311 | u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__ | ||
312 | ((aligned(STACK_ALIGN))); | ||
313 | u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT); | ||
314 | int ts_state; | ||
315 | |||
316 | partial = sctx->count & 0x3f; | ||
317 | sctx->count += len; | ||
318 | done = 0; | ||
319 | src = data; | ||
320 | memcpy(dst, (u8 *)(sctx->state), SHA1_DIGEST_SIZE); | ||
321 | |||
322 | if ((partial + len) >= SHA1_BLOCK_SIZE) { | ||
323 | |||
324 | /* Append the bytes in state's buffer to a block to handle */ | ||
325 | if (partial) { | ||
326 | done = -partial; | ||
327 | memcpy(sctx->buffer + partial, data, | ||
328 | done + SHA1_BLOCK_SIZE); | ||
329 | src = sctx->buffer; | ||
330 | ts_state = irq_ts_save(); | ||
331 | asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" | ||
332 | : "+S"(src), "+D"(dst) \ | ||
333 | : "a"((long)-1), "c"((unsigned long)1)); | ||
334 | irq_ts_restore(ts_state); | ||
335 | done += SHA1_BLOCK_SIZE; | ||
336 | src = data + done; | ||
337 | } | ||
338 | |||
339 | /* Process the left bytes from the input data */ | ||
340 | if (len - done >= SHA1_BLOCK_SIZE) { | ||
341 | ts_state = irq_ts_save(); | ||
342 | asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" | ||
343 | : "+S"(src), "+D"(dst) | ||
344 | : "a"((long)-1), | ||
345 | "c"((unsigned long)((len - done) / SHA1_BLOCK_SIZE))); | ||
346 | irq_ts_restore(ts_state); | ||
347 | done += ((len - done) - (len - done) % SHA1_BLOCK_SIZE); | ||
348 | src = data + done; | ||
349 | } | ||
350 | partial = 0; | ||
351 | } | ||
352 | memcpy((u8 *)(sctx->state), dst, SHA1_DIGEST_SIZE); | ||
353 | memcpy(sctx->buffer + partial, src, len - done); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int padlock_sha1_final_nano(struct shash_desc *desc, u8 *out) | ||
359 | { | ||
360 | struct sha1_state *state = (struct sha1_state *)shash_desc_ctx(desc); | ||
361 | unsigned int partial, padlen; | ||
362 | __be64 bits; | ||
363 | static const u8 padding[64] = { 0x80, }; | ||
364 | |||
365 | bits = cpu_to_be64(state->count << 3); | ||
366 | |||
367 | /* Pad out to 56 mod 64 */ | ||
368 | partial = state->count & 0x3f; | ||
369 | padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial); | ||
370 | padlock_sha1_update_nano(desc, padding, padlen); | ||
371 | |||
372 | /* Append length field bytes */ | ||
373 | padlock_sha1_update_nano(desc, (const u8 *)&bits, sizeof(bits)); | ||
374 | |||
375 | /* Swap to output */ | ||
376 | padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 5); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int padlock_sha256_init_nano(struct shash_desc *desc) | ||
382 | { | ||
383 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
384 | |||
385 | *sctx = (struct sha256_state){ | ||
386 | .state = { SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3, \ | ||
387 | SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7}, | ||
388 | }; | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int padlock_sha256_update_nano(struct shash_desc *desc, const u8 *data, | ||
394 | unsigned int len) | ||
395 | { | ||
396 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
397 | unsigned int partial, done; | ||
398 | const u8 *src; | ||
399 | /*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/ | ||
400 | u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__ | ||
401 | ((aligned(STACK_ALIGN))); | ||
402 | u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT); | ||
403 | int ts_state; | ||
404 | |||
405 | partial = sctx->count & 0x3f; | ||
406 | sctx->count += len; | ||
407 | done = 0; | ||
408 | src = data; | ||
409 | memcpy(dst, (u8 *)(sctx->state), SHA256_DIGEST_SIZE); | ||
410 | |||
411 | if ((partial + len) >= SHA256_BLOCK_SIZE) { | ||
412 | |||
413 | /* Append the bytes in state's buffer to a block to handle */ | ||
414 | if (partial) { | ||
415 | done = -partial; | ||
416 | memcpy(sctx->buf + partial, data, | ||
417 | done + SHA256_BLOCK_SIZE); | ||
418 | src = sctx->buf; | ||
419 | ts_state = irq_ts_save(); | ||
420 | asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" | ||
421 | : "+S"(src), "+D"(dst) | ||
422 | : "a"((long)-1), "c"((unsigned long)1)); | ||
423 | irq_ts_restore(ts_state); | ||
424 | done += SHA256_BLOCK_SIZE; | ||
425 | src = data + done; | ||
426 | } | ||
427 | |||
428 | /* Process the left bytes from input data*/ | ||
429 | if (len - done >= SHA256_BLOCK_SIZE) { | ||
430 | ts_state = irq_ts_save(); | ||
431 | asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" | ||
432 | : "+S"(src), "+D"(dst) | ||
433 | : "a"((long)-1), | ||
434 | "c"((unsigned long)((len - done) / 64))); | ||
435 | irq_ts_restore(ts_state); | ||
436 | done += ((len - done) - (len - done) % 64); | ||
437 | src = data + done; | ||
438 | } | ||
439 | partial = 0; | ||
440 | } | ||
441 | memcpy((u8 *)(sctx->state), dst, SHA256_DIGEST_SIZE); | ||
442 | memcpy(sctx->buf + partial, src, len - done); | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static int padlock_sha256_final_nano(struct shash_desc *desc, u8 *out) | ||
448 | { | ||
449 | struct sha256_state *state = | ||
450 | (struct sha256_state *)shash_desc_ctx(desc); | ||
451 | unsigned int partial, padlen; | ||
452 | __be64 bits; | ||
453 | static const u8 padding[64] = { 0x80, }; | ||
454 | |||
455 | bits = cpu_to_be64(state->count << 3); | ||
456 | |||
457 | /* Pad out to 56 mod 64 */ | ||
458 | partial = state->count & 0x3f; | ||
459 | padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial); | ||
460 | padlock_sha256_update_nano(desc, padding, padlen); | ||
461 | |||
462 | /* Append length field bytes */ | ||
463 | padlock_sha256_update_nano(desc, (const u8 *)&bits, sizeof(bits)); | ||
464 | |||
465 | /* Swap to output */ | ||
466 | padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 8); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int padlock_sha_export_nano(struct shash_desc *desc, | ||
472 | void *out) | ||
473 | { | ||
474 | int statesize = crypto_shash_statesize(desc->tfm); | ||
475 | void *sctx = shash_desc_ctx(desc); | ||
476 | |||
477 | memcpy(out, sctx, statesize); | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static int padlock_sha_import_nano(struct shash_desc *desc, | ||
482 | const void *in) | ||
483 | { | ||
484 | int statesize = crypto_shash_statesize(desc->tfm); | ||
485 | void *sctx = shash_desc_ctx(desc); | ||
486 | |||
487 | memcpy(sctx, in, statesize); | ||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | static struct shash_alg sha1_alg_nano = { | ||
492 | .digestsize = SHA1_DIGEST_SIZE, | ||
493 | .init = padlock_sha1_init_nano, | ||
494 | .update = padlock_sha1_update_nano, | ||
495 | .final = padlock_sha1_final_nano, | ||
496 | .export = padlock_sha_export_nano, | ||
497 | .import = padlock_sha_import_nano, | ||
498 | .descsize = sizeof(struct sha1_state), | ||
499 | .statesize = sizeof(struct sha1_state), | ||
500 | .base = { | ||
501 | .cra_name = "sha1", | ||
502 | .cra_driver_name = "sha1-padlock-nano", | ||
503 | .cra_priority = PADLOCK_CRA_PRIORITY, | ||
504 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
505 | .cra_blocksize = SHA1_BLOCK_SIZE, | ||
506 | .cra_module = THIS_MODULE, | ||
507 | } | ||
508 | }; | ||
509 | |||
510 | static struct shash_alg sha256_alg_nano = { | ||
511 | .digestsize = SHA256_DIGEST_SIZE, | ||
512 | .init = padlock_sha256_init_nano, | ||
513 | .update = padlock_sha256_update_nano, | ||
514 | .final = padlock_sha256_final_nano, | ||
515 | .export = padlock_sha_export_nano, | ||
516 | .import = padlock_sha_import_nano, | ||
517 | .descsize = sizeof(struct sha256_state), | ||
518 | .statesize = sizeof(struct sha256_state), | ||
519 | .base = { | ||
520 | .cra_name = "sha256", | ||
521 | .cra_driver_name = "sha256-padlock-nano", | ||
522 | .cra_priority = PADLOCK_CRA_PRIORITY, | ||
523 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
524 | .cra_blocksize = SHA256_BLOCK_SIZE, | ||
525 | .cra_module = THIS_MODULE, | ||
526 | } | ||
527 | }; | ||
528 | |||
291 | static int __init padlock_init(void) | 529 | static int __init padlock_init(void) |
292 | { | 530 | { |
293 | int rc = -ENODEV; | 531 | int rc = -ENODEV; |
532 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
533 | struct shash_alg *sha1; | ||
534 | struct shash_alg *sha256; | ||
294 | 535 | ||
295 | if (!cpu_has_phe) { | 536 | if (!cpu_has_phe) { |
296 | printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); | 537 | printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); |
@@ -302,11 +543,21 @@ static int __init padlock_init(void) | |||
302 | return -ENODEV; | 543 | return -ENODEV; |
303 | } | 544 | } |
304 | 545 | ||
305 | rc = crypto_register_shash(&sha1_alg); | 546 | /* Register the newly added algorithm module if on * |
547 | * VIA Nano processor, or else just do as before */ | ||
548 | if (c->x86_model < 0x0f) { | ||
549 | sha1 = &sha1_alg; | ||
550 | sha256 = &sha256_alg; | ||
551 | } else { | ||
552 | sha1 = &sha1_alg_nano; | ||
553 | sha256 = &sha256_alg_nano; | ||
554 | } | ||
555 | |||
556 | rc = crypto_register_shash(sha1); | ||
306 | if (rc) | 557 | if (rc) |
307 | goto out; | 558 | goto out; |
308 | 559 | ||
309 | rc = crypto_register_shash(&sha256_alg); | 560 | rc = crypto_register_shash(sha256); |
310 | if (rc) | 561 | if (rc) |
311 | goto out_unreg1; | 562 | goto out_unreg1; |
312 | 563 | ||
@@ -315,7 +566,8 @@ static int __init padlock_init(void) | |||
315 | return 0; | 566 | return 0; |
316 | 567 | ||
317 | out_unreg1: | 568 | out_unreg1: |
318 | crypto_unregister_shash(&sha1_alg); | 569 | crypto_unregister_shash(sha1); |
570 | |||
319 | out: | 571 | out: |
320 | printk(KERN_ERR PFX "VIA PadLock SHA1/SHA256 initialization failed.\n"); | 572 | printk(KERN_ERR PFX "VIA PadLock SHA1/SHA256 initialization failed.\n"); |
321 | return rc; | 573 | return rc; |
@@ -323,8 +575,15 @@ out: | |||
323 | 575 | ||
324 | static void __exit padlock_fini(void) | 576 | static void __exit padlock_fini(void) |
325 | { | 577 | { |
326 | crypto_unregister_shash(&sha1_alg); | 578 | struct cpuinfo_x86 *c = &cpu_data(0); |
327 | crypto_unregister_shash(&sha256_alg); | 579 | |
580 | if (c->x86_model >= 0x0f) { | ||
581 | crypto_unregister_shash(&sha1_alg_nano); | ||
582 | crypto_unregister_shash(&sha256_alg_nano); | ||
583 | } else { | ||
584 | crypto_unregister_shash(&sha1_alg); | ||
585 | crypto_unregister_shash(&sha256_alg); | ||
586 | } | ||
328 | } | 587 | } |
329 | 588 | ||
330 | module_init(padlock_init); | 589 | module_init(padlock_init); |
diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c index b092d0a65837..230b5b8cda1f 100644 --- a/drivers/crypto/picoxcell_crypto.c +++ b/drivers/crypto/picoxcell_crypto.c | |||
@@ -176,6 +176,8 @@ struct spacc_aead_ctx { | |||
176 | u8 salt[AES_BLOCK_SIZE]; | 176 | u8 salt[AES_BLOCK_SIZE]; |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static int spacc_ablk_submit(struct spacc_req *req); | ||
180 | |||
179 | static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg) | 181 | static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg) |
180 | { | 182 | { |
181 | return alg ? container_of(alg, struct spacc_alg, alg) : NULL; | 183 | return alg ? container_of(alg, struct spacc_alg, alg) : NULL; |
@@ -666,6 +668,24 @@ static int spacc_aead_submit(struct spacc_req *req) | |||
666 | return -EINPROGRESS; | 668 | return -EINPROGRESS; |
667 | } | 669 | } |
668 | 670 | ||
671 | static int spacc_req_submit(struct spacc_req *req); | ||
672 | |||
673 | static void spacc_push(struct spacc_engine *engine) | ||
674 | { | ||
675 | struct spacc_req *req; | ||
676 | |||
677 | while (!list_empty(&engine->pending) && | ||
678 | engine->in_flight + 1 <= engine->fifo_sz) { | ||
679 | |||
680 | ++engine->in_flight; | ||
681 | req = list_first_entry(&engine->pending, struct spacc_req, | ||
682 | list); | ||
683 | list_move_tail(&req->list, &engine->in_progress); | ||
684 | |||
685 | req->result = spacc_req_submit(req); | ||
686 | } | ||
687 | } | ||
688 | |||
669 | /* | 689 | /* |
670 | * Setup an AEAD request for processing. This will configure the engine, load | 690 | * Setup an AEAD request for processing. This will configure the engine, load |
671 | * the context and then start the packet processing. | 691 | * the context and then start the packet processing. |
@@ -698,7 +718,8 @@ static int spacc_aead_setup(struct aead_request *req, u8 *giv, | |||
698 | 718 | ||
699 | err = -EINPROGRESS; | 719 | err = -EINPROGRESS; |
700 | spin_lock_irqsave(&engine->hw_lock, flags); | 720 | spin_lock_irqsave(&engine->hw_lock, flags); |
701 | if (unlikely(spacc_fifo_cmd_full(engine))) { | 721 | if (unlikely(spacc_fifo_cmd_full(engine)) || |
722 | engine->in_flight + 1 > engine->fifo_sz) { | ||
702 | if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { | 723 | if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { |
703 | err = -EBUSY; | 724 | err = -EBUSY; |
704 | spin_unlock_irqrestore(&engine->hw_lock, flags); | 725 | spin_unlock_irqrestore(&engine->hw_lock, flags); |
@@ -706,9 +727,8 @@ static int spacc_aead_setup(struct aead_request *req, u8 *giv, | |||
706 | } | 727 | } |
707 | list_add_tail(&dev_req->list, &engine->pending); | 728 | list_add_tail(&dev_req->list, &engine->pending); |
708 | } else { | 729 | } else { |
709 | ++engine->in_flight; | 730 | list_add_tail(&dev_req->list, &engine->pending); |
710 | list_add_tail(&dev_req->list, &engine->in_progress); | 731 | spacc_push(engine); |
711 | spacc_aead_submit(dev_req); | ||
712 | } | 732 | } |
713 | spin_unlock_irqrestore(&engine->hw_lock, flags); | 733 | spin_unlock_irqrestore(&engine->hw_lock, flags); |
714 | 734 | ||
@@ -1041,7 +1061,8 @@ static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type, | |||
1041 | * we either stick it on the end of a pending list if we can backlog, | 1061 | * we either stick it on the end of a pending list if we can backlog, |
1042 | * or bailout with an error if not. | 1062 | * or bailout with an error if not. |
1043 | */ | 1063 | */ |
1044 | if (unlikely(spacc_fifo_cmd_full(engine))) { | 1064 | if (unlikely(spacc_fifo_cmd_full(engine)) || |
1065 | engine->in_flight + 1 > engine->fifo_sz) { | ||
1045 | if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { | 1066 | if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { |
1046 | err = -EBUSY; | 1067 | err = -EBUSY; |
1047 | spin_unlock_irqrestore(&engine->hw_lock, flags); | 1068 | spin_unlock_irqrestore(&engine->hw_lock, flags); |
@@ -1049,9 +1070,8 @@ static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type, | |||
1049 | } | 1070 | } |
1050 | list_add_tail(&dev_req->list, &engine->pending); | 1071 | list_add_tail(&dev_req->list, &engine->pending); |
1051 | } else { | 1072 | } else { |
1052 | ++engine->in_flight; | 1073 | list_add_tail(&dev_req->list, &engine->pending); |
1053 | list_add_tail(&dev_req->list, &engine->in_progress); | 1074 | spacc_push(engine); |
1054 | spacc_ablk_submit(dev_req); | ||
1055 | } | 1075 | } |
1056 | spin_unlock_irqrestore(&engine->hw_lock, flags); | 1076 | spin_unlock_irqrestore(&engine->hw_lock, flags); |
1057 | 1077 | ||
@@ -1139,6 +1159,7 @@ static void spacc_process_done(struct spacc_engine *engine) | |||
1139 | req = list_first_entry(&engine->in_progress, struct spacc_req, | 1159 | req = list_first_entry(&engine->in_progress, struct spacc_req, |
1140 | list); | 1160 | list); |
1141 | list_move_tail(&req->list, &engine->completed); | 1161 | list_move_tail(&req->list, &engine->completed); |
1162 | --engine->in_flight; | ||
1142 | 1163 | ||
1143 | /* POP the status register. */ | 1164 | /* POP the status register. */ |
1144 | writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET); | 1165 | writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET); |
@@ -1208,36 +1229,21 @@ static void spacc_spacc_complete(unsigned long data) | |||
1208 | struct spacc_engine *engine = (struct spacc_engine *)data; | 1229 | struct spacc_engine *engine = (struct spacc_engine *)data; |
1209 | struct spacc_req *req, *tmp; | 1230 | struct spacc_req *req, *tmp; |
1210 | unsigned long flags; | 1231 | unsigned long flags; |
1211 | int num_removed = 0; | ||
1212 | LIST_HEAD(completed); | 1232 | LIST_HEAD(completed); |
1213 | 1233 | ||
1214 | spin_lock_irqsave(&engine->hw_lock, flags); | 1234 | spin_lock_irqsave(&engine->hw_lock, flags); |
1235 | |||
1215 | list_splice_init(&engine->completed, &completed); | 1236 | list_splice_init(&engine->completed, &completed); |
1237 | spacc_push(engine); | ||
1238 | if (engine->in_flight) | ||
1239 | mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT); | ||
1240 | |||
1216 | spin_unlock_irqrestore(&engine->hw_lock, flags); | 1241 | spin_unlock_irqrestore(&engine->hw_lock, flags); |
1217 | 1242 | ||
1218 | list_for_each_entry_safe(req, tmp, &completed, list) { | 1243 | list_for_each_entry_safe(req, tmp, &completed, list) { |
1219 | ++num_removed; | ||
1220 | req->complete(req); | 1244 | req->complete(req); |
1245 | list_del(&req->list); | ||
1221 | } | 1246 | } |
1222 | |||
1223 | /* Try and fill the engine back up again. */ | ||
1224 | spin_lock_irqsave(&engine->hw_lock, flags); | ||
1225 | |||
1226 | engine->in_flight -= num_removed; | ||
1227 | |||
1228 | list_for_each_entry_safe(req, tmp, &engine->pending, list) { | ||
1229 | if (spacc_fifo_cmd_full(engine)) | ||
1230 | break; | ||
1231 | |||
1232 | list_move_tail(&req->list, &engine->in_progress); | ||
1233 | ++engine->in_flight; | ||
1234 | req->result = spacc_req_submit(req); | ||
1235 | } | ||
1236 | |||
1237 | if (engine->in_flight) | ||
1238 | mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT); | ||
1239 | |||
1240 | spin_unlock_irqrestore(&engine->hw_lock, flags); | ||
1241 | } | 1247 | } |
1242 | 1248 | ||
1243 | #ifdef CONFIG_PM | 1249 | #ifdef CONFIG_PM |
diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c new file mode 100644 index 000000000000..8115417a1c93 --- /dev/null +++ b/drivers/crypto/s5p-sss.c | |||
@@ -0,0 +1,701 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * Support for Samsung S5PV210 HW acceleration. | ||
5 | * | ||
6 | * Copyright (C) 2011 NetUP Inc. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/scatterlist.h> | ||
23 | #include <linux/dma-mapping.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/crypto.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | |||
28 | #include <crypto/algapi.h> | ||
29 | #include <crypto/aes.h> | ||
30 | #include <crypto/ctr.h> | ||
31 | |||
32 | #include <plat/cpu.h> | ||
33 | #include <plat/dma.h> | ||
34 | |||
35 | #define _SBF(s, v) ((v) << (s)) | ||
36 | #define _BIT(b) _SBF(b, 1) | ||
37 | |||
38 | /* Feed control registers */ | ||
39 | #define SSS_REG_FCINTSTAT 0x0000 | ||
40 | #define SSS_FCINTSTAT_BRDMAINT _BIT(3) | ||
41 | #define SSS_FCINTSTAT_BTDMAINT _BIT(2) | ||
42 | #define SSS_FCINTSTAT_HRDMAINT _BIT(1) | ||
43 | #define SSS_FCINTSTAT_PKDMAINT _BIT(0) | ||
44 | |||
45 | #define SSS_REG_FCINTENSET 0x0004 | ||
46 | #define SSS_FCINTENSET_BRDMAINTENSET _BIT(3) | ||
47 | #define SSS_FCINTENSET_BTDMAINTENSET _BIT(2) | ||
48 | #define SSS_FCINTENSET_HRDMAINTENSET _BIT(1) | ||
49 | #define SSS_FCINTENSET_PKDMAINTENSET _BIT(0) | ||
50 | |||
51 | #define SSS_REG_FCINTENCLR 0x0008 | ||
52 | #define SSS_FCINTENCLR_BRDMAINTENCLR _BIT(3) | ||
53 | #define SSS_FCINTENCLR_BTDMAINTENCLR _BIT(2) | ||
54 | #define SSS_FCINTENCLR_HRDMAINTENCLR _BIT(1) | ||
55 | #define SSS_FCINTENCLR_PKDMAINTENCLR _BIT(0) | ||
56 | |||
57 | #define SSS_REG_FCINTPEND 0x000C | ||
58 | #define SSS_FCINTPEND_BRDMAINTP _BIT(3) | ||
59 | #define SSS_FCINTPEND_BTDMAINTP _BIT(2) | ||
60 | #define SSS_FCINTPEND_HRDMAINTP _BIT(1) | ||
61 | #define SSS_FCINTPEND_PKDMAINTP _BIT(0) | ||
62 | |||
63 | #define SSS_REG_FCFIFOSTAT 0x0010 | ||
64 | #define SSS_FCFIFOSTAT_BRFIFOFUL _BIT(7) | ||
65 | #define SSS_FCFIFOSTAT_BRFIFOEMP _BIT(6) | ||
66 | #define SSS_FCFIFOSTAT_BTFIFOFUL _BIT(5) | ||
67 | #define SSS_FCFIFOSTAT_BTFIFOEMP _BIT(4) | ||
68 | #define SSS_FCFIFOSTAT_HRFIFOFUL _BIT(3) | ||
69 | #define SSS_FCFIFOSTAT_HRFIFOEMP _BIT(2) | ||
70 | #define SSS_FCFIFOSTAT_PKFIFOFUL _BIT(1) | ||
71 | #define SSS_FCFIFOSTAT_PKFIFOEMP _BIT(0) | ||
72 | |||
73 | #define SSS_REG_FCFIFOCTRL 0x0014 | ||
74 | #define SSS_FCFIFOCTRL_DESSEL _BIT(2) | ||
75 | #define SSS_HASHIN_INDEPENDENT _SBF(0, 0x00) | ||
76 | #define SSS_HASHIN_CIPHER_INPUT _SBF(0, 0x01) | ||
77 | #define SSS_HASHIN_CIPHER_OUTPUT _SBF(0, 0x02) | ||
78 | |||
79 | #define SSS_REG_FCBRDMAS 0x0020 | ||
80 | #define SSS_REG_FCBRDMAL 0x0024 | ||
81 | #define SSS_REG_FCBRDMAC 0x0028 | ||
82 | #define SSS_FCBRDMAC_BYTESWAP _BIT(1) | ||
83 | #define SSS_FCBRDMAC_FLUSH _BIT(0) | ||
84 | |||
85 | #define SSS_REG_FCBTDMAS 0x0030 | ||
86 | #define SSS_REG_FCBTDMAL 0x0034 | ||
87 | #define SSS_REG_FCBTDMAC 0x0038 | ||
88 | #define SSS_FCBTDMAC_BYTESWAP _BIT(1) | ||
89 | #define SSS_FCBTDMAC_FLUSH _BIT(0) | ||
90 | |||
91 | #define SSS_REG_FCHRDMAS 0x0040 | ||
92 | #define SSS_REG_FCHRDMAL 0x0044 | ||
93 | #define SSS_REG_FCHRDMAC 0x0048 | ||
94 | #define SSS_FCHRDMAC_BYTESWAP _BIT(1) | ||
95 | #define SSS_FCHRDMAC_FLUSH _BIT(0) | ||
96 | |||
97 | #define SSS_REG_FCPKDMAS 0x0050 | ||
98 | #define SSS_REG_FCPKDMAL 0x0054 | ||
99 | #define SSS_REG_FCPKDMAC 0x0058 | ||
100 | #define SSS_FCPKDMAC_BYTESWAP _BIT(3) | ||
101 | #define SSS_FCPKDMAC_DESCEND _BIT(2) | ||
102 | #define SSS_FCPKDMAC_TRANSMIT _BIT(1) | ||
103 | #define SSS_FCPKDMAC_FLUSH _BIT(0) | ||
104 | |||
105 | #define SSS_REG_FCPKDMAO 0x005C | ||
106 | |||
107 | /* AES registers */ | ||
108 | #define SSS_REG_AES_CONTROL 0x4000 | ||
109 | #define SSS_AES_BYTESWAP_DI _BIT(11) | ||
110 | #define SSS_AES_BYTESWAP_DO _BIT(10) | ||
111 | #define SSS_AES_BYTESWAP_IV _BIT(9) | ||
112 | #define SSS_AES_BYTESWAP_CNT _BIT(8) | ||
113 | #define SSS_AES_BYTESWAP_KEY _BIT(7) | ||
114 | #define SSS_AES_KEY_CHANGE_MODE _BIT(6) | ||
115 | #define SSS_AES_KEY_SIZE_128 _SBF(4, 0x00) | ||
116 | #define SSS_AES_KEY_SIZE_192 _SBF(4, 0x01) | ||
117 | #define SSS_AES_KEY_SIZE_256 _SBF(4, 0x02) | ||
118 | #define SSS_AES_FIFO_MODE _BIT(3) | ||
119 | #define SSS_AES_CHAIN_MODE_ECB _SBF(1, 0x00) | ||
120 | #define SSS_AES_CHAIN_MODE_CBC _SBF(1, 0x01) | ||
121 | #define SSS_AES_CHAIN_MODE_CTR _SBF(1, 0x02) | ||
122 | #define SSS_AES_MODE_DECRYPT _BIT(0) | ||
123 | |||
124 | #define SSS_REG_AES_STATUS 0x4004 | ||
125 | #define SSS_AES_BUSY _BIT(2) | ||
126 | #define SSS_AES_INPUT_READY _BIT(1) | ||
127 | #define SSS_AES_OUTPUT_READY _BIT(0) | ||
128 | |||
129 | #define SSS_REG_AES_IN_DATA(s) (0x4010 + (s << 2)) | ||
130 | #define SSS_REG_AES_OUT_DATA(s) (0x4020 + (s << 2)) | ||
131 | #define SSS_REG_AES_IV_DATA(s) (0x4030 + (s << 2)) | ||
132 | #define SSS_REG_AES_CNT_DATA(s) (0x4040 + (s << 2)) | ||
133 | #define SSS_REG_AES_KEY_DATA(s) (0x4080 + (s << 2)) | ||
134 | |||
135 | #define SSS_REG(dev, reg) ((dev)->ioaddr + (SSS_REG_##reg)) | ||
136 | #define SSS_READ(dev, reg) __raw_readl(SSS_REG(dev, reg)) | ||
137 | #define SSS_WRITE(dev, reg, val) __raw_writel((val), SSS_REG(dev, reg)) | ||
138 | |||
139 | /* HW engine modes */ | ||
140 | #define FLAGS_AES_DECRYPT _BIT(0) | ||
141 | #define FLAGS_AES_MODE_MASK _SBF(1, 0x03) | ||
142 | #define FLAGS_AES_CBC _SBF(1, 0x01) | ||
143 | #define FLAGS_AES_CTR _SBF(1, 0x02) | ||
144 | |||
145 | #define AES_KEY_LEN 16 | ||
146 | #define CRYPTO_QUEUE_LEN 1 | ||
147 | |||
148 | struct s5p_aes_reqctx { | ||
149 | unsigned long mode; | ||
150 | }; | ||
151 | |||
152 | struct s5p_aes_ctx { | ||
153 | struct s5p_aes_dev *dev; | ||
154 | |||
155 | uint8_t aes_key[AES_MAX_KEY_SIZE]; | ||
156 | uint8_t nonce[CTR_RFC3686_NONCE_SIZE]; | ||
157 | int keylen; | ||
158 | }; | ||
159 | |||
160 | struct s5p_aes_dev { | ||
161 | struct device *dev; | ||
162 | struct clk *clk; | ||
163 | void __iomem *ioaddr; | ||
164 | int irq_hash; | ||
165 | int irq_fc; | ||
166 | |||
167 | struct ablkcipher_request *req; | ||
168 | struct s5p_aes_ctx *ctx; | ||
169 | struct scatterlist *sg_src; | ||
170 | struct scatterlist *sg_dst; | ||
171 | |||
172 | struct tasklet_struct tasklet; | ||
173 | struct crypto_queue queue; | ||
174 | bool busy; | ||
175 | spinlock_t lock; | ||
176 | }; | ||
177 | |||
178 | static struct s5p_aes_dev *s5p_dev; | ||
179 | |||
180 | static void s5p_set_dma_indata(struct s5p_aes_dev *dev, struct scatterlist *sg) | ||
181 | { | ||
182 | SSS_WRITE(dev, FCBRDMAS, sg_dma_address(sg)); | ||
183 | SSS_WRITE(dev, FCBRDMAL, sg_dma_len(sg)); | ||
184 | } | ||
185 | |||
186 | static void s5p_set_dma_outdata(struct s5p_aes_dev *dev, struct scatterlist *sg) | ||
187 | { | ||
188 | SSS_WRITE(dev, FCBTDMAS, sg_dma_address(sg)); | ||
189 | SSS_WRITE(dev, FCBTDMAL, sg_dma_len(sg)); | ||
190 | } | ||
191 | |||
192 | static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) | ||
193 | { | ||
194 | /* holding a lock outside */ | ||
195 | dev->req->base.complete(&dev->req->base, err); | ||
196 | dev->busy = false; | ||
197 | } | ||
198 | |||
199 | static void s5p_unset_outdata(struct s5p_aes_dev *dev) | ||
200 | { | ||
201 | dma_unmap_sg(dev->dev, dev->sg_dst, 1, DMA_FROM_DEVICE); | ||
202 | } | ||
203 | |||
204 | static void s5p_unset_indata(struct s5p_aes_dev *dev) | ||
205 | { | ||
206 | dma_unmap_sg(dev->dev, dev->sg_src, 1, DMA_TO_DEVICE); | ||
207 | } | ||
208 | |||
209 | static int s5p_set_outdata(struct s5p_aes_dev *dev, struct scatterlist *sg) | ||
210 | { | ||
211 | int err; | ||
212 | |||
213 | if (!IS_ALIGNED(sg_dma_len(sg), AES_BLOCK_SIZE)) { | ||
214 | err = -EINVAL; | ||
215 | goto exit; | ||
216 | } | ||
217 | if (!sg_dma_len(sg)) { | ||
218 | err = -EINVAL; | ||
219 | goto exit; | ||
220 | } | ||
221 | |||
222 | err = dma_map_sg(dev->dev, sg, 1, DMA_FROM_DEVICE); | ||
223 | if (!err) { | ||
224 | err = -ENOMEM; | ||
225 | goto exit; | ||
226 | } | ||
227 | |||
228 | dev->sg_dst = sg; | ||
229 | err = 0; | ||
230 | |||
231 | exit: | ||
232 | return err; | ||
233 | } | ||
234 | |||
235 | static int s5p_set_indata(struct s5p_aes_dev *dev, struct scatterlist *sg) | ||
236 | { | ||
237 | int err; | ||
238 | |||
239 | if (!IS_ALIGNED(sg_dma_len(sg), AES_BLOCK_SIZE)) { | ||
240 | err = -EINVAL; | ||
241 | goto exit; | ||
242 | } | ||
243 | if (!sg_dma_len(sg)) { | ||
244 | err = -EINVAL; | ||
245 | goto exit; | ||
246 | } | ||
247 | |||
248 | err = dma_map_sg(dev->dev, sg, 1, DMA_TO_DEVICE); | ||
249 | if (!err) { | ||
250 | err = -ENOMEM; | ||
251 | goto exit; | ||
252 | } | ||
253 | |||
254 | dev->sg_src = sg; | ||
255 | err = 0; | ||
256 | |||
257 | exit: | ||
258 | return err; | ||
259 | } | ||
260 | |||
261 | static void s5p_aes_tx(struct s5p_aes_dev *dev) | ||
262 | { | ||
263 | int err = 0; | ||
264 | |||
265 | s5p_unset_outdata(dev); | ||
266 | |||
267 | if (!sg_is_last(dev->sg_dst)) { | ||
268 | err = s5p_set_outdata(dev, sg_next(dev->sg_dst)); | ||
269 | if (err) { | ||
270 | s5p_aes_complete(dev, err); | ||
271 | return; | ||
272 | } | ||
273 | |||
274 | s5p_set_dma_outdata(dev, dev->sg_dst); | ||
275 | } else | ||
276 | s5p_aes_complete(dev, err); | ||
277 | } | ||
278 | |||
279 | static void s5p_aes_rx(struct s5p_aes_dev *dev) | ||
280 | { | ||
281 | int err; | ||
282 | |||
283 | s5p_unset_indata(dev); | ||
284 | |||
285 | if (!sg_is_last(dev->sg_src)) { | ||
286 | err = s5p_set_indata(dev, sg_next(dev->sg_src)); | ||
287 | if (err) { | ||
288 | s5p_aes_complete(dev, err); | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | s5p_set_dma_indata(dev, dev->sg_src); | ||
293 | } | ||
294 | } | ||
295 | |||
296 | static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id) | ||
297 | { | ||
298 | struct platform_device *pdev = dev_id; | ||
299 | struct s5p_aes_dev *dev = platform_get_drvdata(pdev); | ||
300 | uint32_t status; | ||
301 | unsigned long flags; | ||
302 | |||
303 | spin_lock_irqsave(&dev->lock, flags); | ||
304 | |||
305 | if (irq == dev->irq_fc) { | ||
306 | status = SSS_READ(dev, FCINTSTAT); | ||
307 | if (status & SSS_FCINTSTAT_BRDMAINT) | ||
308 | s5p_aes_rx(dev); | ||
309 | if (status & SSS_FCINTSTAT_BTDMAINT) | ||
310 | s5p_aes_tx(dev); | ||
311 | |||
312 | SSS_WRITE(dev, FCINTPEND, status); | ||
313 | } | ||
314 | |||
315 | spin_unlock_irqrestore(&dev->lock, flags); | ||
316 | |||
317 | return IRQ_HANDLED; | ||
318 | } | ||
319 | |||
320 | static void s5p_set_aes(struct s5p_aes_dev *dev, | ||
321 | uint8_t *key, uint8_t *iv, unsigned int keylen) | ||
322 | { | ||
323 | void __iomem *keystart; | ||
324 | |||
325 | memcpy(dev->ioaddr + SSS_REG_AES_IV_DATA(0), iv, 0x10); | ||
326 | |||
327 | if (keylen == AES_KEYSIZE_256) | ||
328 | keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(0); | ||
329 | else if (keylen == AES_KEYSIZE_192) | ||
330 | keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(2); | ||
331 | else | ||
332 | keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(4); | ||
333 | |||
334 | memcpy(keystart, key, keylen); | ||
335 | } | ||
336 | |||
337 | static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode) | ||
338 | { | ||
339 | struct ablkcipher_request *req = dev->req; | ||
340 | |||
341 | uint32_t aes_control; | ||
342 | int err; | ||
343 | unsigned long flags; | ||
344 | |||
345 | aes_control = SSS_AES_KEY_CHANGE_MODE; | ||
346 | if (mode & FLAGS_AES_DECRYPT) | ||
347 | aes_control |= SSS_AES_MODE_DECRYPT; | ||
348 | |||
349 | if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC) | ||
350 | aes_control |= SSS_AES_CHAIN_MODE_CBC; | ||
351 | else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR) | ||
352 | aes_control |= SSS_AES_CHAIN_MODE_CTR; | ||
353 | |||
354 | if (dev->ctx->keylen == AES_KEYSIZE_192) | ||
355 | aes_control |= SSS_AES_KEY_SIZE_192; | ||
356 | else if (dev->ctx->keylen == AES_KEYSIZE_256) | ||
357 | aes_control |= SSS_AES_KEY_SIZE_256; | ||
358 | |||
359 | aes_control |= SSS_AES_FIFO_MODE; | ||
360 | |||
361 | /* as a variant it is possible to use byte swapping on DMA side */ | ||
362 | aes_control |= SSS_AES_BYTESWAP_DI | ||
363 | | SSS_AES_BYTESWAP_DO | ||
364 | | SSS_AES_BYTESWAP_IV | ||
365 | | SSS_AES_BYTESWAP_KEY | ||
366 | | SSS_AES_BYTESWAP_CNT; | ||
367 | |||
368 | spin_lock_irqsave(&dev->lock, flags); | ||
369 | |||
370 | SSS_WRITE(dev, FCINTENCLR, | ||
371 | SSS_FCINTENCLR_BTDMAINTENCLR | SSS_FCINTENCLR_BRDMAINTENCLR); | ||
372 | SSS_WRITE(dev, FCFIFOCTRL, 0x00); | ||
373 | |||
374 | err = s5p_set_indata(dev, req->src); | ||
375 | if (err) | ||
376 | goto indata_error; | ||
377 | |||
378 | err = s5p_set_outdata(dev, req->dst); | ||
379 | if (err) | ||
380 | goto outdata_error; | ||
381 | |||
382 | SSS_WRITE(dev, AES_CONTROL, aes_control); | ||
383 | s5p_set_aes(dev, dev->ctx->aes_key, req->info, dev->ctx->keylen); | ||
384 | |||
385 | s5p_set_dma_indata(dev, req->src); | ||
386 | s5p_set_dma_outdata(dev, req->dst); | ||
387 | |||
388 | SSS_WRITE(dev, FCINTENSET, | ||
389 | SSS_FCINTENSET_BTDMAINTENSET | SSS_FCINTENSET_BRDMAINTENSET); | ||
390 | |||
391 | spin_unlock_irqrestore(&dev->lock, flags); | ||
392 | |||
393 | return; | ||
394 | |||
395 | outdata_error: | ||
396 | s5p_unset_indata(dev); | ||
397 | |||
398 | indata_error: | ||
399 | s5p_aes_complete(dev, err); | ||
400 | spin_unlock_irqrestore(&dev->lock, flags); | ||
401 | } | ||
402 | |||
403 | static void s5p_tasklet_cb(unsigned long data) | ||
404 | { | ||
405 | struct s5p_aes_dev *dev = (struct s5p_aes_dev *)data; | ||
406 | struct crypto_async_request *async_req, *backlog; | ||
407 | struct s5p_aes_reqctx *reqctx; | ||
408 | unsigned long flags; | ||
409 | |||
410 | spin_lock_irqsave(&dev->lock, flags); | ||
411 | backlog = crypto_get_backlog(&dev->queue); | ||
412 | async_req = crypto_dequeue_request(&dev->queue); | ||
413 | spin_unlock_irqrestore(&dev->lock, flags); | ||
414 | |||
415 | if (!async_req) | ||
416 | return; | ||
417 | |||
418 | if (backlog) | ||
419 | backlog->complete(backlog, -EINPROGRESS); | ||
420 | |||
421 | dev->req = ablkcipher_request_cast(async_req); | ||
422 | dev->ctx = crypto_tfm_ctx(dev->req->base.tfm); | ||
423 | reqctx = ablkcipher_request_ctx(dev->req); | ||
424 | |||
425 | s5p_aes_crypt_start(dev, reqctx->mode); | ||
426 | } | ||
427 | |||
428 | static int s5p_aes_handle_req(struct s5p_aes_dev *dev, | ||
429 | struct ablkcipher_request *req) | ||
430 | { | ||
431 | unsigned long flags; | ||
432 | int err; | ||
433 | |||
434 | spin_lock_irqsave(&dev->lock, flags); | ||
435 | if (dev->busy) { | ||
436 | err = -EAGAIN; | ||
437 | spin_unlock_irqrestore(&dev->lock, flags); | ||
438 | goto exit; | ||
439 | } | ||
440 | dev->busy = true; | ||
441 | |||
442 | err = ablkcipher_enqueue_request(&dev->queue, req); | ||
443 | spin_unlock_irqrestore(&dev->lock, flags); | ||
444 | |||
445 | tasklet_schedule(&dev->tasklet); | ||
446 | |||
447 | exit: | ||
448 | return err; | ||
449 | } | ||
450 | |||
451 | static int s5p_aes_crypt(struct ablkcipher_request *req, unsigned long mode) | ||
452 | { | ||
453 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | ||
454 | struct s5p_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); | ||
455 | struct s5p_aes_reqctx *reqctx = ablkcipher_request_ctx(req); | ||
456 | struct s5p_aes_dev *dev = ctx->dev; | ||
457 | |||
458 | if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { | ||
459 | pr_err("request size is not exact amount of AES blocks\n"); | ||
460 | return -EINVAL; | ||
461 | } | ||
462 | |||
463 | reqctx->mode = mode; | ||
464 | |||
465 | return s5p_aes_handle_req(dev, req); | ||
466 | } | ||
467 | |||
468 | static int s5p_aes_setkey(struct crypto_ablkcipher *cipher, | ||
469 | const uint8_t *key, unsigned int keylen) | ||
470 | { | ||
471 | struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); | ||
472 | struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
473 | |||
474 | if (keylen != AES_KEYSIZE_128 && | ||
475 | keylen != AES_KEYSIZE_192 && | ||
476 | keylen != AES_KEYSIZE_256) | ||
477 | return -EINVAL; | ||
478 | |||
479 | memcpy(ctx->aes_key, key, keylen); | ||
480 | ctx->keylen = keylen; | ||
481 | |||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | static int s5p_aes_ecb_encrypt(struct ablkcipher_request *req) | ||
486 | { | ||
487 | return s5p_aes_crypt(req, 0); | ||
488 | } | ||
489 | |||
490 | static int s5p_aes_ecb_decrypt(struct ablkcipher_request *req) | ||
491 | { | ||
492 | return s5p_aes_crypt(req, FLAGS_AES_DECRYPT); | ||
493 | } | ||
494 | |||
495 | static int s5p_aes_cbc_encrypt(struct ablkcipher_request *req) | ||
496 | { | ||
497 | return s5p_aes_crypt(req, FLAGS_AES_CBC); | ||
498 | } | ||
499 | |||
500 | static int s5p_aes_cbc_decrypt(struct ablkcipher_request *req) | ||
501 | { | ||
502 | return s5p_aes_crypt(req, FLAGS_AES_DECRYPT | FLAGS_AES_CBC); | ||
503 | } | ||
504 | |||
505 | static int s5p_aes_cra_init(struct crypto_tfm *tfm) | ||
506 | { | ||
507 | struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
508 | |||
509 | ctx->dev = s5p_dev; | ||
510 | tfm->crt_ablkcipher.reqsize = sizeof(struct s5p_aes_reqctx); | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | static struct crypto_alg algs[] = { | ||
516 | { | ||
517 | .cra_name = "ecb(aes)", | ||
518 | .cra_driver_name = "ecb-aes-s5p", | ||
519 | .cra_priority = 100, | ||
520 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | | ||
521 | CRYPTO_ALG_ASYNC, | ||
522 | .cra_blocksize = AES_BLOCK_SIZE, | ||
523 | .cra_ctxsize = sizeof(struct s5p_aes_ctx), | ||
524 | .cra_alignmask = 0x0f, | ||
525 | .cra_type = &crypto_ablkcipher_type, | ||
526 | .cra_module = THIS_MODULE, | ||
527 | .cra_init = s5p_aes_cra_init, | ||
528 | .cra_u.ablkcipher = { | ||
529 | .min_keysize = AES_MIN_KEY_SIZE, | ||
530 | .max_keysize = AES_MAX_KEY_SIZE, | ||
531 | .setkey = s5p_aes_setkey, | ||
532 | .encrypt = s5p_aes_ecb_encrypt, | ||
533 | .decrypt = s5p_aes_ecb_decrypt, | ||
534 | } | ||
535 | }, | ||
536 | { | ||
537 | .cra_name = "cbc(aes)", | ||
538 | .cra_driver_name = "cbc-aes-s5p", | ||
539 | .cra_priority = 100, | ||
540 | .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | | ||
541 | CRYPTO_ALG_ASYNC, | ||
542 | .cra_blocksize = AES_BLOCK_SIZE, | ||
543 | .cra_ctxsize = sizeof(struct s5p_aes_ctx), | ||
544 | .cra_alignmask = 0x0f, | ||
545 | .cra_type = &crypto_ablkcipher_type, | ||
546 | .cra_module = THIS_MODULE, | ||
547 | .cra_init = s5p_aes_cra_init, | ||
548 | .cra_u.ablkcipher = { | ||
549 | .min_keysize = AES_MIN_KEY_SIZE, | ||
550 | .max_keysize = AES_MAX_KEY_SIZE, | ||
551 | .ivsize = AES_BLOCK_SIZE, | ||
552 | .setkey = s5p_aes_setkey, | ||
553 | .encrypt = s5p_aes_cbc_encrypt, | ||
554 | .decrypt = s5p_aes_cbc_decrypt, | ||
555 | } | ||
556 | }, | ||
557 | }; | ||
558 | |||
559 | static int s5p_aes_probe(struct platform_device *pdev) | ||
560 | { | ||
561 | int i, j, err = -ENODEV; | ||
562 | struct s5p_aes_dev *pdata; | ||
563 | struct device *dev = &pdev->dev; | ||
564 | struct resource *res; | ||
565 | |||
566 | if (s5p_dev) | ||
567 | return -EEXIST; | ||
568 | |||
569 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
570 | if (!res) | ||
571 | return -ENODEV; | ||
572 | |||
573 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
574 | if (!pdata) | ||
575 | return -ENOMEM; | ||
576 | |||
577 | if (!devm_request_mem_region(dev, res->start, | ||
578 | resource_size(res), pdev->name)) | ||
579 | return -EBUSY; | ||
580 | |||
581 | pdata->clk = clk_get(dev, "secss"); | ||
582 | if (IS_ERR(pdata->clk)) { | ||
583 | dev_err(dev, "failed to find secss clock source\n"); | ||
584 | return -ENOENT; | ||
585 | } | ||
586 | |||
587 | clk_enable(pdata->clk); | ||
588 | |||
589 | spin_lock_init(&pdata->lock); | ||
590 | pdata->ioaddr = devm_ioremap(dev, res->start, | ||
591 | resource_size(res)); | ||
592 | |||
593 | pdata->irq_hash = platform_get_irq_byname(pdev, "hash"); | ||
594 | if (pdata->irq_hash < 0) { | ||
595 | err = pdata->irq_hash; | ||
596 | dev_warn(dev, "hash interrupt is not available.\n"); | ||
597 | goto err_irq; | ||
598 | } | ||
599 | err = devm_request_irq(dev, pdata->irq_hash, s5p_aes_interrupt, | ||
600 | IRQF_SHARED, pdev->name, pdev); | ||
601 | if (err < 0) { | ||
602 | dev_warn(dev, "hash interrupt is not available.\n"); | ||
603 | goto err_irq; | ||
604 | } | ||
605 | |||
606 | pdata->irq_fc = platform_get_irq_byname(pdev, "feed control"); | ||
607 | if (pdata->irq_fc < 0) { | ||
608 | err = pdata->irq_fc; | ||
609 | dev_warn(dev, "feed control interrupt is not available.\n"); | ||
610 | goto err_irq; | ||
611 | } | ||
612 | err = devm_request_irq(dev, pdata->irq_fc, s5p_aes_interrupt, | ||
613 | IRQF_SHARED, pdev->name, pdev); | ||
614 | if (err < 0) { | ||
615 | dev_warn(dev, "feed control interrupt is not available.\n"); | ||
616 | goto err_irq; | ||
617 | } | ||
618 | |||
619 | pdata->dev = dev; | ||
620 | platform_set_drvdata(pdev, pdata); | ||
621 | s5p_dev = pdata; | ||
622 | |||
623 | tasklet_init(&pdata->tasklet, s5p_tasklet_cb, (unsigned long)pdata); | ||
624 | crypto_init_queue(&pdata->queue, CRYPTO_QUEUE_LEN); | ||
625 | |||
626 | for (i = 0; i < ARRAY_SIZE(algs); i++) { | ||
627 | INIT_LIST_HEAD(&algs[i].cra_list); | ||
628 | err = crypto_register_alg(&algs[i]); | ||
629 | if (err) | ||
630 | goto err_algs; | ||
631 | } | ||
632 | |||
633 | pr_info("s5p-sss driver registered\n"); | ||
634 | |||
635 | return 0; | ||
636 | |||
637 | err_algs: | ||
638 | dev_err(dev, "can't register '%s': %d\n", algs[i].cra_name, err); | ||
639 | |||
640 | for (j = 0; j < i; j++) | ||
641 | crypto_unregister_alg(&algs[j]); | ||
642 | |||
643 | tasklet_kill(&pdata->tasklet); | ||
644 | |||
645 | err_irq: | ||
646 | clk_disable(pdata->clk); | ||
647 | clk_put(pdata->clk); | ||
648 | |||
649 | s5p_dev = NULL; | ||
650 | platform_set_drvdata(pdev, NULL); | ||
651 | |||
652 | return err; | ||
653 | } | ||
654 | |||
655 | static int s5p_aes_remove(struct platform_device *pdev) | ||
656 | { | ||
657 | struct s5p_aes_dev *pdata = platform_get_drvdata(pdev); | ||
658 | int i; | ||
659 | |||
660 | if (!pdata) | ||
661 | return -ENODEV; | ||
662 | |||
663 | for (i = 0; i < ARRAY_SIZE(algs); i++) | ||
664 | crypto_unregister_alg(&algs[i]); | ||
665 | |||
666 | tasklet_kill(&pdata->tasklet); | ||
667 | |||
668 | clk_disable(pdata->clk); | ||
669 | clk_put(pdata->clk); | ||
670 | |||
671 | s5p_dev = NULL; | ||
672 | platform_set_drvdata(pdev, NULL); | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static struct platform_driver s5p_aes_crypto = { | ||
678 | .probe = s5p_aes_probe, | ||
679 | .remove = s5p_aes_remove, | ||
680 | .driver = { | ||
681 | .owner = THIS_MODULE, | ||
682 | .name = "s5p-secss", | ||
683 | }, | ||
684 | }; | ||
685 | |||
686 | static int __init s5p_aes_mod_init(void) | ||
687 | { | ||
688 | return platform_driver_register(&s5p_aes_crypto); | ||
689 | } | ||
690 | |||
691 | static void __exit s5p_aes_mod_exit(void) | ||
692 | { | ||
693 | platform_driver_unregister(&s5p_aes_crypto); | ||
694 | } | ||
695 | |||
696 | module_init(s5p_aes_mod_init); | ||
697 | module_exit(s5p_aes_mod_exit); | ||
698 | |||
699 | MODULE_DESCRIPTION("S5PV210 AES hw acceleration support."); | ||
700 | MODULE_LICENSE("GPL v2"); | ||
701 | MODULE_AUTHOR("Vladimir Zapolskiy <vzapolskiy@gmail.com>"); | ||