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