Greg Kroah-Hartman | b244131 | 2017-11-01 15:07:57 +0100 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 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 | |
| 14 | void split_key_done(struct device *dev, u32 *desc, u32 err, |
| 15 | void *context) |
| 16 | { |
| 17 | struct split_key_result *res = context; |
Horia Geantă | 1984aae | 2019-07-31 16:08:03 +0300 | [diff] [blame] | 18 | int ecode = 0; |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 19 | |
Sascha Hauer | 6e00550 | 2019-05-23 10:50:29 +0200 | [diff] [blame] | 20 | dev_dbg(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 21 | |
Marek Vasut | fa9659c | 2014-04-24 20:05:12 +0200 | [diff] [blame] | 22 | if (err) |
Horia Geantă | 1984aae | 2019-07-31 16:08:03 +0300 | [diff] [blame] | 23 | ecode = caam_jr_strstatus(dev, err); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 24 | |
Horia Geantă | 1984aae | 2019-07-31 16:08:03 +0300 | [diff] [blame] | 25 | res->err = ecode; |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 26 | |
| 27 | complete(&res->completion); |
| 28 | } |
| 29 | EXPORT_SYMBOL(split_key_done); |
| 30 | /* |
| 31 | get a split ipad/opad key |
| 32 | |
| 33 | Split key generation----------------------------------------------- |
| 34 | |
| 35 | [00] 0xb0810008 jobdesc: stidx=1 share=never len=8 |
| 36 | [01] 0x04000014 key: class2->keyreg len=20 |
| 37 | @0xffe01000 |
| 38 | [03] 0x84410014 operation: cls2-op sha1 hmac init dec |
| 39 | [04] 0x24940000 fifold: class2 msgdata-last2 len=0 imm |
| 40 | [05] 0xa4000001 jump: class2 local all ->1 [06] |
| 41 | [06] 0x64260028 fifostr: class2 mdsplit-jdk len=40 |
| 42 | @0xffe04000 |
| 43 | */ |
Horia Geantă | db57656 | 2016-11-22 15:44:04 +0200 | [diff] [blame] | 44 | int gen_split_key(struct device *jrdev, u8 *key_out, |
Horia Geantă | 6655cb8e5 | 2016-11-22 15:44:10 +0200 | [diff] [blame] | 45 | struct alginfo * const adata, const u8 *key_in, u32 keylen, |
| 46 | int max_keylen) |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 47 | { |
| 48 | u32 *desc; |
| 49 | struct split_key_result result; |
Horia Geantă | 3072444 | 2019-02-19 16:56:57 +0200 | [diff] [blame] | 50 | dma_addr_t dma_addr; |
Horia Geantă | e9b4913 | 2019-07-31 16:08:11 +0300 | [diff] [blame] | 51 | unsigned int local_max; |
Cristian Stoica | 738459e | 2014-10-30 14:40:22 +0200 | [diff] [blame] | 52 | int ret = -ENOMEM; |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 53 | |
Horia Geantă | 6655cb8e5 | 2016-11-22 15:44:10 +0200 | [diff] [blame] | 54 | adata->keylen = split_key_len(adata->algtype & OP_ALG_ALGSEL_MASK); |
| 55 | adata->keylen_pad = split_key_pad_len(adata->algtype & |
| 56 | OP_ALG_ALGSEL_MASK); |
Horia Geantă | e9b4913 | 2019-07-31 16:08:11 +0300 | [diff] [blame] | 57 | local_max = max(keylen, adata->keylen_pad); |
Horia Geantă | 6655cb8e5 | 2016-11-22 15:44:10 +0200 | [diff] [blame] | 58 | |
Sascha Hauer | 6e00550 | 2019-05-23 10:50:29 +0200 | [diff] [blame] | 59 | dev_dbg(jrdev, "split keylen %d split keylen padded %d\n", |
Horia Geantă | 6655cb8e5 | 2016-11-22 15:44:10 +0200 | [diff] [blame] | 60 | adata->keylen, adata->keylen_pad); |
Sascha Hauer | 6e00550 | 2019-05-23 10:50:29 +0200 | [diff] [blame] | 61 | print_hex_dump_debug("ctx.key@" __stringify(__LINE__)": ", |
| 62 | DUMP_PREFIX_ADDRESS, 16, 4, key_in, keylen, 1); |
Horia Geantă | 6655cb8e5 | 2016-11-22 15:44:10 +0200 | [diff] [blame] | 63 | |
Horia Geantă | e9b4913 | 2019-07-31 16:08:11 +0300 | [diff] [blame] | 64 | if (local_max > max_keylen) |
Horia Geantă | 6655cb8e5 | 2016-11-22 15:44:10 +0200 | [diff] [blame] | 65 | return -EINVAL; |
| 66 | |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 67 | desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); |
Kim Phillips | 2af8f4a | 2012-09-07 04:17:03 +0800 | [diff] [blame] | 68 | if (!desc) { |
| 69 | dev_err(jrdev, "unable to allocate key input memory\n"); |
Cristian Stoica | 738459e | 2014-10-30 14:40:22 +0200 | [diff] [blame] | 70 | return ret; |
Kim Phillips | 2af8f4a | 2012-09-07 04:17:03 +0800 | [diff] [blame] | 71 | } |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 72 | |
Horia Geantă | 3072444 | 2019-02-19 16:56:57 +0200 | [diff] [blame] | 73 | memcpy(key_out, key_in, keylen); |
| 74 | |
Horia Geantă | e9b4913 | 2019-07-31 16:08:11 +0300 | [diff] [blame] | 75 | dma_addr = dma_map_single(jrdev, key_out, local_max, DMA_BIDIRECTIONAL); |
Horia Geantă | 3072444 | 2019-02-19 16:56:57 +0200 | [diff] [blame] | 76 | if (dma_mapping_error(jrdev, dma_addr)) { |
| 77 | dev_err(jrdev, "unable to map key memory\n"); |
Cristian Stoica | 738459e | 2014-10-30 14:40:22 +0200 | [diff] [blame] | 78 | goto out_free; |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 79 | } |
Cristian Stoica | 738459e | 2014-10-30 14:40:22 +0200 | [diff] [blame] | 80 | |
Cristian Stoica | 738459e | 2014-10-30 14:40:22 +0200 | [diff] [blame] | 81 | init_job_desc(desc, 0); |
Horia Geantă | 3072444 | 2019-02-19 16:56:57 +0200 | [diff] [blame] | 82 | append_key(desc, dma_addr, keylen, CLASS_2 | KEY_DEST_CLASS_REG); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 83 | |
| 84 | /* Sets MDHA up into an HMAC-INIT */ |
Horia Geantă | 488ebc3 | 2016-11-22 15:44:05 +0200 | [diff] [blame] | 85 | append_operation(desc, (adata->algtype & OP_ALG_ALGSEL_MASK) | |
| 86 | OP_ALG_AAI_HMAC | OP_TYPE_CLASS2_ALG | OP_ALG_DECRYPT | |
| 87 | OP_ALG_AS_INIT); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 88 | |
| 89 | /* |
| 90 | * do a FIFO_LOAD of zero, this will trigger the internal key expansion |
| 91 | * into both pads inside MDHA |
| 92 | */ |
| 93 | append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB | |
| 94 | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); |
| 95 | |
| 96 | /* |
| 97 | * FIFO_STORE with the explicit split-key content store |
| 98 | * (0x26 output type) |
| 99 | */ |
Horia Geantă | 3072444 | 2019-02-19 16:56:57 +0200 | [diff] [blame] | 100 | append_fifo_store(desc, dma_addr, adata->keylen, |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 101 | LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); |
| 102 | |
Sascha Hauer | 6e00550 | 2019-05-23 10:50:29 +0200 | [diff] [blame] | 103 | print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ", |
| 104 | DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), |
| 105 | 1); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 106 | |
| 107 | result.err = 0; |
| 108 | init_completion(&result.completion); |
| 109 | |
| 110 | ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); |
Iuliana Prodan | 4d370a1 | 2020-02-12 19:55:20 +0200 | [diff] [blame] | 111 | if (ret == -EINPROGRESS) { |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 112 | /* in progress */ |
Horia Geantă | 7459e1d | 2017-07-07 16:57:06 +0300 | [diff] [blame] | 113 | wait_for_completion(&result.completion); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 114 | ret = result.err; |
Sascha Hauer | 6e00550 | 2019-05-23 10:50:29 +0200 | [diff] [blame] | 115 | |
| 116 | print_hex_dump_debug("ctx.key@"__stringify(__LINE__)": ", |
| 117 | DUMP_PREFIX_ADDRESS, 16, 4, key_out, |
| 118 | adata->keylen_pad, 1); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 119 | } |
| 120 | |
Horia Geantă | e9b4913 | 2019-07-31 16:08:11 +0300 | [diff] [blame] | 121 | dma_unmap_single(jrdev, dma_addr, local_max, DMA_BIDIRECTIONAL); |
Cristian Stoica | 738459e | 2014-10-30 14:40:22 +0200 | [diff] [blame] | 122 | out_free: |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 123 | kfree(desc); |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 124 | return ret; |
| 125 | } |
Ben Collins | 3b75a2c | 2012-08-23 18:39:57 -0400 | [diff] [blame] | 126 | EXPORT_SYMBOL(gen_split_key); |