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