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