Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 1 | /* |
| 2 | * CAAM/SEC 4.x functions for handling key-generation jobs |
| 3 | * |
| 4 | * Copyright 2008-2011 Freescale Semiconductor, Inc. |
| 5 | * |
| 6 | */ |
| 7 | #include "compat.h" |
| 8 | #include "jr.h" |
| 9 | #include "error.h" |
| 10 | #include "desc_constr.h" |
| 11 | #include "key_gen.h" |
| 12 | |
| 13 | void split_key_done(struct device *dev, u32 *desc, u32 err, |
| 14 | void *context) |
| 15 | { |
| 16 | struct split_key_result *res = context; |
| 17 | |
| 18 | #ifdef DEBUG |
| 19 | dev_err(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 20 | #endif |
| 21 | |
| 22 | if (err) { |
| 23 | char tmp[CAAM_ERROR_STR_MAX]; |
| 24 | |
| 25 | dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err)); |
| 26 | } |
| 27 | |
| 28 | res->err = err; |
| 29 | |
| 30 | complete(&res->completion); |
| 31 | } |
| 32 | EXPORT_SYMBOL(split_key_done); |
| 33 | /* |
| 34 | get a split ipad/opad key |
| 35 | |
| 36 | Split key generation----------------------------------------------- |
| 37 | |
| 38 | [00] 0xb0810008 jobdesc: stidx=1 share=never len=8 |
| 39 | [01] 0x04000014 key: class2->keyreg len=20 |
| 40 | @0xffe01000 |
| 41 | [03] 0x84410014 operation: cls2-op sha1 hmac init dec |
| 42 | [04] 0x24940000 fifold: class2 msgdata-last2 len=0 imm |
| 43 | [05] 0xa4000001 jump: class2 local all ->1 [06] |
| 44 | [06] 0x64260028 fifostr: class2 mdsplit-jdk len=40 |
| 45 | @0xffe04000 |
| 46 | */ |
| 47 | u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, |
| 48 | int split_key_pad_len, const u8 *key_in, u32 keylen, |
| 49 | u32 alg_op) |
| 50 | { |
| 51 | u32 *desc; |
| 52 | struct split_key_result result; |
| 53 | dma_addr_t dma_addr_in, dma_addr_out; |
| 54 | int ret = 0; |
| 55 | |
| 56 | 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] | 57 | if (!desc) { |
| 58 | dev_err(jrdev, "unable to allocate key input memory\n"); |
| 59 | return -ENOMEM; |
| 60 | } |
Yuan Kang | 4c1ec1f | 2012-06-22 19:48:45 -0500 | [diff] [blame] | 61 | |
| 62 | init_job_desc(desc, 0); |
| 63 | |
| 64 | dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen, |
| 65 | DMA_TO_DEVICE); |
| 66 | if (dma_mapping_error(jrdev, dma_addr_in)) { |
| 67 | dev_err(jrdev, "unable to map key input memory\n"); |
| 68 | kfree(desc); |
| 69 | return -ENOMEM; |
| 70 | } |
| 71 | append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG); |
| 72 | |
| 73 | /* Sets MDHA up into an HMAC-INIT */ |
| 74 | append_operation(desc, alg_op | OP_ALG_DECRYPT | OP_ALG_AS_INIT); |
| 75 | |
| 76 | /* |
| 77 | * do a FIFO_LOAD of zero, this will trigger the internal key expansion |
| 78 | * into both pads inside MDHA |
| 79 | */ |
| 80 | append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB | |
| 81 | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); |
| 82 | |
| 83 | /* |
| 84 | * FIFO_STORE with the explicit split-key content store |
| 85 | * (0x26 output type) |
| 86 | */ |
| 87 | dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len, |
| 88 | DMA_FROM_DEVICE); |
| 89 | if (dma_mapping_error(jrdev, dma_addr_out)) { |
| 90 | dev_err(jrdev, "unable to map key output memory\n"); |
| 91 | kfree(desc); |
| 92 | return -ENOMEM; |
| 93 | } |
| 94 | append_fifo_store(desc, dma_addr_out, split_key_len, |
| 95 | LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); |
| 96 | |
| 97 | #ifdef DEBUG |
| 98 | print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", |
| 99 | DUMP_PREFIX_ADDRESS, 16, 4, key_in, keylen, 1); |
| 100 | print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ", |
| 101 | DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1); |
| 102 | #endif |
| 103 | |
| 104 | result.err = 0; |
| 105 | init_completion(&result.completion); |
| 106 | |
| 107 | ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result); |
| 108 | if (!ret) { |
| 109 | /* in progress */ |
| 110 | wait_for_completion_interruptible(&result.completion); |
| 111 | ret = result.err; |
| 112 | #ifdef DEBUG |
| 113 | print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ", |
| 114 | DUMP_PREFIX_ADDRESS, 16, 4, key_out, |
| 115 | split_key_pad_len, 1); |
| 116 | #endif |
| 117 | } |
| 118 | |
| 119 | dma_unmap_single(jrdev, dma_addr_out, split_key_pad_len, |
| 120 | DMA_FROM_DEVICE); |
| 121 | dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE); |
| 122 | |
| 123 | kfree(desc); |
| 124 | |
| 125 | return ret; |
| 126 | } |
Ben Collins | 3b75a2c | 2012-08-23 18:39:57 -0400 | [diff] [blame] | 127 | EXPORT_SYMBOL(gen_split_key); |