Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
4c1ec1f9 YK |
2 | /* |
3 | * CAAM/SEC 4.x functions for handling key-generation jobs | |
4 | * | |
5 | * Copyright 2008-2011 Freescale Semiconductor, Inc. | |
6 | * | |
7 | */ | |
8 | #include "compat.h" | |
9 | #include "jr.h" | |
10 | #include "error.h" | |
11 | #include "desc_constr.h" | |
12 | #include "key_gen.h" | |
13 | ||
6655cb8e HG |
14 | /** |
15 | * split_key_len - Compute MDHA split key length for a given algorithm | |
16 | * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1, | |
17 | * SHA224, SHA384, SHA512. | |
18 | * | |
19 | * Return: MDHA split key length | |
20 | */ | |
21 | static inline u32 split_key_len(u32 hash) | |
22 | { | |
23 | /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */ | |
24 | static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 }; | |
25 | u32 idx; | |
26 | ||
27 | idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT; | |
28 | ||
29 | return (u32)(mdpadlen[idx] * 2); | |
30 | } | |
31 | ||
32 | /** | |
33 | * split_key_pad_len - Compute MDHA split key pad length for a given algorithm | |
34 | * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1, | |
35 | * SHA224, SHA384, SHA512. | |
36 | * | |
37 | * Return: MDHA split key pad length | |
38 | */ | |
39 | static inline u32 split_key_pad_len(u32 hash) | |
40 | { | |
41 | return ALIGN(split_key_len(hash), 16); | |
42 | } | |
43 | ||
4c1ec1f9 YK |
44 | void split_key_done(struct device *dev, u32 *desc, u32 err, |
45 | void *context) | |
46 | { | |
47 | struct split_key_result *res = context; | |
48 | ||
49 | #ifdef DEBUG | |
50 | dev_err(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | |
51 | #endif | |
52 | ||
fa9659cd MV |
53 | if (err) |
54 | caam_jr_strstatus(dev, err); | |
4c1ec1f9 YK |
55 | |
56 | res->err = err; | |
57 | ||
58 | complete(&res->completion); | |
59 | } | |
60 | EXPORT_SYMBOL(split_key_done); | |
61 | /* | |
62 | get a split ipad/opad key | |
63 | ||
64 | Split key generation----------------------------------------------- | |
65 | ||
66 | [00] 0xb0810008 jobdesc: stidx=1 share=never len=8 | |
67 | [01] 0x04000014 key: class2->keyreg len=20 | |
68 | @0xffe01000 | |
69 | [03] 0x84410014 operation: cls2-op sha1 hmac init dec | |
70 | [04] 0x24940000 fifold: class2 msgdata-last2 len=0 imm | |
71 | [05] 0xa4000001 jump: class2 local all ->1 [06] | |
72 | [06] 0x64260028 fifostr: class2 mdsplit-jdk len=40 | |
73 | @0xffe04000 | |
74 | */ | |
db57656b | 75 | int gen_split_key(struct device *jrdev, u8 *key_out, |
6655cb8e HG |
76 | struct alginfo * const adata, const u8 *key_in, u32 keylen, |
77 | int max_keylen) | |
4c1ec1f9 YK |
78 | { |
79 | u32 *desc; | |
80 | struct split_key_result result; | |
81 | dma_addr_t dma_addr_in, dma_addr_out; | |
738459e3 | 82 | int ret = -ENOMEM; |
4c1ec1f9 | 83 | |
6655cb8e HG |
84 | adata->keylen = split_key_len(adata->algtype & OP_ALG_ALGSEL_MASK); |
85 | adata->keylen_pad = split_key_pad_len(adata->algtype & | |
86 | OP_ALG_ALGSEL_MASK); | |
87 | ||
88 | #ifdef DEBUG | |
89 | dev_err(jrdev, "split keylen %d split keylen padded %d\n", | |
90 | adata->keylen, adata->keylen_pad); | |
91 | print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ", | |
92 | DUMP_PREFIX_ADDRESS, 16, 4, key_in, keylen, 1); | |
93 | #endif | |
94 | ||
95 | if (adata->keylen_pad > max_keylen) | |
96 | return -EINVAL; | |
97 | ||
4c1ec1f9 | 98 | desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); |
2af8f4a2 KP |
99 | if (!desc) { |
100 | dev_err(jrdev, "unable to allocate key input memory\n"); | |
738459e3 | 101 | return ret; |
2af8f4a2 | 102 | } |
4c1ec1f9 | 103 | |
4c1ec1f9 YK |
104 | dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen, |
105 | DMA_TO_DEVICE); | |
106 | if (dma_mapping_error(jrdev, dma_addr_in)) { | |
107 | dev_err(jrdev, "unable to map key input memory\n"); | |
738459e3 | 108 | goto out_free; |
4c1ec1f9 | 109 | } |
738459e3 | 110 | |
db57656b | 111 | dma_addr_out = dma_map_single(jrdev, key_out, adata->keylen_pad, |
738459e3 CS |
112 | DMA_FROM_DEVICE); |
113 | if (dma_mapping_error(jrdev, dma_addr_out)) { | |
114 | dev_err(jrdev, "unable to map key output memory\n"); | |
115 | goto out_unmap_in; | |
116 | } | |
117 | ||
118 | init_job_desc(desc, 0); | |
4c1ec1f9 YK |
119 | append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG); |
120 | ||
121 | /* Sets MDHA up into an HMAC-INIT */ | |
488ebc3a HG |
122 | append_operation(desc, (adata->algtype & OP_ALG_ALGSEL_MASK) | |
123 | OP_ALG_AAI_HMAC | OP_TYPE_CLASS2_ALG | OP_ALG_DECRYPT | | |
124 | OP_ALG_AS_INIT); | |
4c1ec1f9 YK |
125 | |
126 | /* | |
127 | * do a FIFO_LOAD of zero, this will trigger the internal key expansion | |
128 | * into both pads inside MDHA | |
129 | */ | |
130 | append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB | | |
131 | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); | |
132 | ||
133 | /* | |
134 | * FIFO_STORE with the explicit split-key content store | |
135 | * (0x26 output type) | |
136 | */ | |
db57656b | 137 | append_fifo_store(desc, dma_addr_out, adata->keylen, |
4c1ec1f9 YK |
138 | LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); |
139 | ||
140 | #ifdef DEBUG | |
514df281 | 141 | print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ", |
4c1ec1f9 | 142 | DUMP_PREFIX_ADDRESS, 16, 4, key_in, keylen, 1); |
514df281 | 143 | print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ", |
4c1ec1f9 YK |
144 | DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); |
145 | #endif | |
146 | ||
147 | result.err = 0; | |
148 | init_completion(&result.completion); | |
149 | ||
150 | ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); | |
151 | if (!ret) { | |
152 | /* in progress */ | |
7459e1d2 | 153 | wait_for_completion(&result.completion); |
4c1ec1f9 YK |
154 | ret = result.err; |
155 | #ifdef DEBUG | |
514df281 | 156 | print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ", |
4c1ec1f9 | 157 | DUMP_PREFIX_ADDRESS, 16, 4, key_out, |
db57656b | 158 | adata->keylen_pad, 1); |
4c1ec1f9 YK |
159 | #endif |
160 | } | |
161 | ||
db57656b | 162 | dma_unmap_single(jrdev, dma_addr_out, adata->keylen_pad, |
4c1ec1f9 | 163 | DMA_FROM_DEVICE); |
738459e3 | 164 | out_unmap_in: |
4c1ec1f9 | 165 | dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE); |
738459e3 | 166 | out_free: |
4c1ec1f9 | 167 | kfree(desc); |
4c1ec1f9 YK |
168 | return ret; |
169 | } | |
3b75a2c1 | 170 | EXPORT_SYMBOL(gen_split_key); |