1 /* 2 * Copyright (c) 2019, Remi Pommarel <repk@triplefau.lt> 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 #include <assert.h> 9 #include <crypto/sha_dma.h> 10 #include <lib/mmio.h> 11 12 #define AML_SHA_DMA_BASE 0xc883e000 13 14 #define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08) 15 #define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x18) 16 17 #define ASD_MODE_SHA224 0x7 18 #define ASD_MODE_SHA256 0x6 19 20 /* SHA DMA descriptor */ 21 struct asd_desc { 22 uint32_t cfg; 23 uint32_t src; 24 uint32_t dst; 25 }; 26 #define ASD_DESC_GET(x, msk, off) (((x) >> (off)) & (msk)) 27 #define ASD_DESC_SET(x, v, msk, off) \ 28 ((x) = ((x) & ~((msk) << (off))) | (((v) & (msk)) << (off))) 29 30 #define ASD_DESC_LEN_OFF 0 31 #define ASD_DESC_LEN_MASK 0x1ffff 32 #define ASD_DESC_LEN(d) \ 33 (ASD_DESC_GET((d)->cfg, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF)) 34 #define ASD_DESC_LEN_SET(d, v) \ 35 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF)) 36 37 #define ASD_DESC_IRQ_OFF 17 38 #define ASD_DESC_IRQ_MASK 0x1 39 #define ASD_DESC_IRQ(d) \ 40 (ASD_DESC_GET((d)->cfg, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF)) 41 #define ASD_DESC_IRQ_SET(d, v) \ 42 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF)) 43 44 #define ASD_DESC_EOD_OFF 18 45 #define ASD_DESC_EOD_MASK 0x1 46 #define ASD_DESC_EOD(d) \ 47 (ASD_DESC_GET((d)->cfg, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF)) 48 #define ASD_DESC_EOD_SET(d, v) \ 49 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF)) 50 51 #define ASD_DESC_LOOP_OFF 19 52 #define ASD_DESC_LOOP_MASK 0x1 53 #define ASD_DESC_LOOP(d) \ 54 (ASD_DESC_GET((d)->cfg, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF)) 55 #define ASD_DESC_LOOP_SET(d, v) \ 56 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF)) 57 58 #define ASD_DESC_MODE_OFF 20 59 #define ASD_DESC_MODE_MASK 0xf 60 #define ASD_DESC_MODE(d) \ 61 (ASD_DESC_GET((d)->cfg, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF)) 62 #define ASD_DESC_MODE_SET(d, v) \ 63 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF)) 64 65 #define ASD_DESC_BEGIN_OFF 24 66 #define ASD_DESC_BEGIN_MASK 0x1 67 #define ASD_DESC_BEGIN(d) \ 68 (ASD_DESC_GET((d)->cfg, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF)) 69 #define ASD_DESC_BEGIN_SET(d, v) \ 70 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF)) 71 72 #define ASD_DESC_END_OFF 25 73 #define ASD_DESC_END_MASK 0x1 74 #define ASD_DESC_END(d) \ 75 (ASD_DESC_GET((d)->cfg, ASD_DESC_END_MASK, ASD_DESC_END_OFF)) 76 #define ASD_DESC_END_SET(d, v) \ 77 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_END_MASK, ASD_DESC_END_OFF)) 78 79 #define ASD_DESC_OP_OFF 26 80 #define ASD_DESC_OP_MASK 0x2 81 #define ASD_DESC_OP(d) \ 82 (ASD_DESC_GET((d)->cfg, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF)) 83 #define ASD_DESC_OP_SET(d, v) \ 84 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF)) 85 86 #define ASD_DESC_ENCONLY_OFF 28 87 #define ASD_DESC_ENCONLY_MASK 0x1 88 #define ASD_DESC_ENCONLY(d) \ 89 (ASD_DESC_GET((d)->cfg, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF)) 90 #define ASD_DESC_ENCONLY_SET(d, v) \ 91 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF)) 92 93 #define ASD_DESC_BLOCK_OFF 29 94 #define ASD_DESC_BLOCK_MASK 0x1 95 #define ASD_DESC_BLOCK(d) \ 96 (ASD_DESC_GET((d)->cfg, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF)) 97 #define ASD_DESC_BLOCK_SET(d, v) \ 98 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF)) 99 100 #define ASD_DESC_ERR_OFF 30 101 #define ASD_DESC_ERR_MASK 0x1 102 #define ASD_DESC_ERR(d) \ 103 (ASD_DESC_GET((d)->cfg, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF)) 104 #define ASD_DESC_ERR_SET(d, v) \ 105 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF)) 106 107 #define ASD_DESC_OWNER_OFF 31u 108 #define ASD_DESC_OWNER_MASK 0x1u 109 #define ASD_DESC_OWNER(d) \ 110 (ASD_DESC_GET((d)->cfg, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF)) 111 #define ASD_DESC_OWNER_SET(d, v) \ 112 (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF)) 113 114 static void asd_compute_sha(struct asd_ctx *ctx, void *data, size_t len, 115 int finalize) 116 { 117 /* Make it cache line size aligned ? */ 118 struct asd_desc desc = { 119 .src = (uint32_t)(uintptr_t)data, 120 .dst = (uint32_t)(uintptr_t)ctx->digest, 121 }; 122 123 /* Check data address is 32bit compatible */ 124 assert((uintptr_t)data == (uintptr_t)desc.src); 125 assert((uintptr_t)ctx->digest == (uintptr_t)desc.dst); 126 assert((uintptr_t)&desc == (uintptr_t)&desc); 127 128 ASD_DESC_LEN_SET(&desc, len); 129 ASD_DESC_OWNER_SET(&desc, 1u); 130 ASD_DESC_ENCONLY_SET(&desc, 1); 131 ASD_DESC_EOD_SET(&desc, 1); 132 if (ctx->started == 0) { 133 ASD_DESC_BEGIN_SET(&desc, 1); 134 ctx->started = 1; 135 } 136 if (finalize) { 137 ASD_DESC_END_SET(&desc, 1); 138 ctx->started = 0; 139 } 140 if (ctx->mode == ASM_SHA224) 141 ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA224); 142 else 143 ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA256); 144 145 flush_dcache_range((uintptr_t)&desc, sizeof(desc)); 146 flush_dcache_range((uintptr_t)data, len); 147 148 mmio_write_32(AML_SHA_DMA_STATUS, 0xf); 149 mmio_write_32(AML_SHA_DMA_DESC, ((uintptr_t)&desc) | 2); 150 while (mmio_read_32(AML_SHA_DMA_STATUS) == 0) 151 continue; 152 flush_dcache_range((uintptr_t)ctx->digest, SHA256_HASHSZ); 153 } 154 155 void asd_sha_update(struct asd_ctx *ctx, void *data, size_t len) 156 { 157 size_t nr; 158 159 if (ctx->blocksz) { 160 nr = MIN(len, SHA256_BLOCKSZ - ctx->blocksz); 161 memcpy(ctx->block + ctx->blocksz, data, nr); 162 ctx->blocksz += nr; 163 len -= nr; 164 data += nr; 165 } 166 167 if (ctx->blocksz == SHA256_BLOCKSZ) { 168 asd_compute_sha(ctx, ctx->block, SHA256_BLOCKSZ, 0); 169 ctx->blocksz = 0; 170 } 171 172 asd_compute_sha(ctx, data, len & ~(SHA256_BLOCKSZ - 1), 0); 173 data += len & ~(SHA256_BLOCKSZ - 1); 174 175 if (len & (SHA256_BLOCKSZ - 1)) { 176 nr = len & (SHA256_BLOCKSZ - 1); 177 memcpy(ctx->block + ctx->blocksz, data, nr); 178 ctx->blocksz += nr; 179 } 180 } 181 182 void asd_sha_finalize(struct asd_ctx *ctx) 183 { 184 asd_compute_sha(ctx, ctx->block, ctx->blocksz, 1); 185 } 186