101b2a7fcSCarlo Caione /* 201b2a7fcSCarlo Caione * Copyright (c) 2019, Remi Pommarel <repk@triplefau.lt> 301b2a7fcSCarlo Caione * 401b2a7fcSCarlo Caione * SPDX-License-Identifier: BSD-3-Clause 501b2a7fcSCarlo Caione */ 601b2a7fcSCarlo Caione 701b2a7fcSCarlo Caione #include <arch_helpers.h> 801b2a7fcSCarlo Caione #include <assert.h> 901b2a7fcSCarlo Caione #include <crypto/sha_dma.h> 1001b2a7fcSCarlo Caione #include <lib/mmio.h> 11*885e2683SClaus Pedersen #include <platform_def.h> 1201b2a7fcSCarlo Caione 1326d94393SCarlo Caione #include "aml_private.h" 1401b2a7fcSCarlo Caione 1501b2a7fcSCarlo Caione #define ASD_MODE_SHA224 0x7 1601b2a7fcSCarlo Caione #define ASD_MODE_SHA256 0x6 1701b2a7fcSCarlo Caione 1801b2a7fcSCarlo Caione /* SHA DMA descriptor */ 1901b2a7fcSCarlo Caione struct asd_desc { 2001b2a7fcSCarlo Caione uint32_t cfg; 2101b2a7fcSCarlo Caione uint32_t src; 2201b2a7fcSCarlo Caione uint32_t dst; 2301b2a7fcSCarlo Caione }; 2401b2a7fcSCarlo Caione #define ASD_DESC_GET(x, msk, off) (((x) >> (off)) & (msk)) 2501b2a7fcSCarlo Caione #define ASD_DESC_SET(x, v, msk, off) \ 2601b2a7fcSCarlo Caione ((x) = ((x) & ~((msk) << (off))) | (((v) & (msk)) << (off))) 2701b2a7fcSCarlo Caione 2801b2a7fcSCarlo Caione #define ASD_DESC_LEN_OFF 0 2901b2a7fcSCarlo Caione #define ASD_DESC_LEN_MASK 0x1ffff 3001b2a7fcSCarlo Caione #define ASD_DESC_LEN(d) \ 3101b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF)) 3201b2a7fcSCarlo Caione #define ASD_DESC_LEN_SET(d, v) \ 3301b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LEN_MASK, ASD_DESC_LEN_OFF)) 3401b2a7fcSCarlo Caione 3501b2a7fcSCarlo Caione #define ASD_DESC_IRQ_OFF 17 3601b2a7fcSCarlo Caione #define ASD_DESC_IRQ_MASK 0x1 3701b2a7fcSCarlo Caione #define ASD_DESC_IRQ(d) \ 3801b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF)) 3901b2a7fcSCarlo Caione #define ASD_DESC_IRQ_SET(d, v) \ 4001b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_IRQ_MASK, ASD_DESC_IRQ_OFF)) 4101b2a7fcSCarlo Caione 4201b2a7fcSCarlo Caione #define ASD_DESC_EOD_OFF 18 4301b2a7fcSCarlo Caione #define ASD_DESC_EOD_MASK 0x1 4401b2a7fcSCarlo Caione #define ASD_DESC_EOD(d) \ 4501b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF)) 4601b2a7fcSCarlo Caione #define ASD_DESC_EOD_SET(d, v) \ 4701b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_EOD_MASK, ASD_DESC_EOD_OFF)) 4801b2a7fcSCarlo Caione 4901b2a7fcSCarlo Caione #define ASD_DESC_LOOP_OFF 19 5001b2a7fcSCarlo Caione #define ASD_DESC_LOOP_MASK 0x1 5101b2a7fcSCarlo Caione #define ASD_DESC_LOOP(d) \ 5201b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF)) 5301b2a7fcSCarlo Caione #define ASD_DESC_LOOP_SET(d, v) \ 5401b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_LOOP_MASK, ASD_DESC_LOOP_OFF)) 5501b2a7fcSCarlo Caione 5601b2a7fcSCarlo Caione #define ASD_DESC_MODE_OFF 20 5701b2a7fcSCarlo Caione #define ASD_DESC_MODE_MASK 0xf 5801b2a7fcSCarlo Caione #define ASD_DESC_MODE(d) \ 5901b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF)) 6001b2a7fcSCarlo Caione #define ASD_DESC_MODE_SET(d, v) \ 6101b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_MODE_MASK, ASD_DESC_MODE_OFF)) 6201b2a7fcSCarlo Caione 6301b2a7fcSCarlo Caione #define ASD_DESC_BEGIN_OFF 24 6401b2a7fcSCarlo Caione #define ASD_DESC_BEGIN_MASK 0x1 6501b2a7fcSCarlo Caione #define ASD_DESC_BEGIN(d) \ 6601b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF)) 6701b2a7fcSCarlo Caione #define ASD_DESC_BEGIN_SET(d, v) \ 6801b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BEGIN_MASK, ASD_DESC_BEGIN_OFF)) 6901b2a7fcSCarlo Caione 7001b2a7fcSCarlo Caione #define ASD_DESC_END_OFF 25 7101b2a7fcSCarlo Caione #define ASD_DESC_END_MASK 0x1 7201b2a7fcSCarlo Caione #define ASD_DESC_END(d) \ 7301b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_END_MASK, ASD_DESC_END_OFF)) 7401b2a7fcSCarlo Caione #define ASD_DESC_END_SET(d, v) \ 7501b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_END_MASK, ASD_DESC_END_OFF)) 7601b2a7fcSCarlo Caione 7701b2a7fcSCarlo Caione #define ASD_DESC_OP_OFF 26 7801b2a7fcSCarlo Caione #define ASD_DESC_OP_MASK 0x2 7901b2a7fcSCarlo Caione #define ASD_DESC_OP(d) \ 8001b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF)) 8101b2a7fcSCarlo Caione #define ASD_DESC_OP_SET(d, v) \ 8201b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OP_MASK, ASD_DESC_OP_OFF)) 8301b2a7fcSCarlo Caione 8401b2a7fcSCarlo Caione #define ASD_DESC_ENCONLY_OFF 28 8501b2a7fcSCarlo Caione #define ASD_DESC_ENCONLY_MASK 0x1 8601b2a7fcSCarlo Caione #define ASD_DESC_ENCONLY(d) \ 8701b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF)) 8801b2a7fcSCarlo Caione #define ASD_DESC_ENCONLY_SET(d, v) \ 8901b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ENCONLY_MASK, ASD_DESC_ENCONLY_OFF)) 9001b2a7fcSCarlo Caione 9101b2a7fcSCarlo Caione #define ASD_DESC_BLOCK_OFF 29 9201b2a7fcSCarlo Caione #define ASD_DESC_BLOCK_MASK 0x1 9301b2a7fcSCarlo Caione #define ASD_DESC_BLOCK(d) \ 9401b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF)) 9501b2a7fcSCarlo Caione #define ASD_DESC_BLOCK_SET(d, v) \ 9601b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_BLOCK_MASK, ASD_DESC_BLOCK_OFF)) 9701b2a7fcSCarlo Caione 9801b2a7fcSCarlo Caione #define ASD_DESC_ERR_OFF 30 9901b2a7fcSCarlo Caione #define ASD_DESC_ERR_MASK 0x1 10001b2a7fcSCarlo Caione #define ASD_DESC_ERR(d) \ 10101b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF)) 10201b2a7fcSCarlo Caione #define ASD_DESC_ERR_SET(d, v) \ 10301b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_ERR_MASK, ASD_DESC_ERR_OFF)) 10401b2a7fcSCarlo Caione 10501b2a7fcSCarlo Caione #define ASD_DESC_OWNER_OFF 31u 10601b2a7fcSCarlo Caione #define ASD_DESC_OWNER_MASK 0x1u 10701b2a7fcSCarlo Caione #define ASD_DESC_OWNER(d) \ 10801b2a7fcSCarlo Caione (ASD_DESC_GET((d)->cfg, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF)) 10901b2a7fcSCarlo Caione #define ASD_DESC_OWNER_SET(d, v) \ 11001b2a7fcSCarlo Caione (ASD_DESC_SET((d)->cfg, v, ASD_DESC_OWNER_MASK, ASD_DESC_OWNER_OFF)) 11101b2a7fcSCarlo Caione 11201b2a7fcSCarlo Caione static void asd_compute_sha(struct asd_ctx *ctx, void *data, size_t len, 11301b2a7fcSCarlo Caione int finalize) 11401b2a7fcSCarlo Caione { 11501b2a7fcSCarlo Caione /* Make it cache line size aligned ? */ 11601b2a7fcSCarlo Caione struct asd_desc desc = { 11701b2a7fcSCarlo Caione .src = (uint32_t)(uintptr_t)data, 11801b2a7fcSCarlo Caione .dst = (uint32_t)(uintptr_t)ctx->digest, 11901b2a7fcSCarlo Caione }; 12001b2a7fcSCarlo Caione 12101b2a7fcSCarlo Caione /* Check data address is 32bit compatible */ 12201b2a7fcSCarlo Caione assert((uintptr_t)data == (uintptr_t)desc.src); 12301b2a7fcSCarlo Caione assert((uintptr_t)ctx->digest == (uintptr_t)desc.dst); 12401b2a7fcSCarlo Caione assert((uintptr_t)&desc == (uintptr_t)&desc); 12501b2a7fcSCarlo Caione 12601b2a7fcSCarlo Caione ASD_DESC_LEN_SET(&desc, len); 12701b2a7fcSCarlo Caione ASD_DESC_OWNER_SET(&desc, 1u); 12801b2a7fcSCarlo Caione ASD_DESC_ENCONLY_SET(&desc, 1); 12901b2a7fcSCarlo Caione ASD_DESC_EOD_SET(&desc, 1); 13001b2a7fcSCarlo Caione if (ctx->started == 0) { 13101b2a7fcSCarlo Caione ASD_DESC_BEGIN_SET(&desc, 1); 13201b2a7fcSCarlo Caione ctx->started = 1; 13301b2a7fcSCarlo Caione } 13401b2a7fcSCarlo Caione if (finalize) { 13501b2a7fcSCarlo Caione ASD_DESC_END_SET(&desc, 1); 13601b2a7fcSCarlo Caione ctx->started = 0; 13701b2a7fcSCarlo Caione } 13801b2a7fcSCarlo Caione if (ctx->mode == ASM_SHA224) 13901b2a7fcSCarlo Caione ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA224); 14001b2a7fcSCarlo Caione else 14101b2a7fcSCarlo Caione ASD_DESC_MODE_SET(&desc, ASD_MODE_SHA256); 14201b2a7fcSCarlo Caione 14301b2a7fcSCarlo Caione flush_dcache_range((uintptr_t)&desc, sizeof(desc)); 14401b2a7fcSCarlo Caione flush_dcache_range((uintptr_t)data, len); 14501b2a7fcSCarlo Caione 14601b2a7fcSCarlo Caione mmio_write_32(AML_SHA_DMA_STATUS, 0xf); 14701b2a7fcSCarlo Caione mmio_write_32(AML_SHA_DMA_DESC, ((uintptr_t)&desc) | 2); 14801b2a7fcSCarlo Caione while (mmio_read_32(AML_SHA_DMA_STATUS) == 0) 14901b2a7fcSCarlo Caione continue; 15001b2a7fcSCarlo Caione flush_dcache_range((uintptr_t)ctx->digest, SHA256_HASHSZ); 15101b2a7fcSCarlo Caione } 15201b2a7fcSCarlo Caione 15301b2a7fcSCarlo Caione void asd_sha_update(struct asd_ctx *ctx, void *data, size_t len) 15401b2a7fcSCarlo Caione { 15501b2a7fcSCarlo Caione size_t nr; 15601b2a7fcSCarlo Caione 15701b2a7fcSCarlo Caione if (ctx->blocksz) { 15801b2a7fcSCarlo Caione nr = MIN(len, SHA256_BLOCKSZ - ctx->blocksz); 15901b2a7fcSCarlo Caione memcpy(ctx->block + ctx->blocksz, data, nr); 16001b2a7fcSCarlo Caione ctx->blocksz += nr; 16101b2a7fcSCarlo Caione len -= nr; 16201b2a7fcSCarlo Caione data += nr; 16301b2a7fcSCarlo Caione } 16401b2a7fcSCarlo Caione 16501b2a7fcSCarlo Caione if (ctx->blocksz == SHA256_BLOCKSZ) { 16601b2a7fcSCarlo Caione asd_compute_sha(ctx, ctx->block, SHA256_BLOCKSZ, 0); 16701b2a7fcSCarlo Caione ctx->blocksz = 0; 16801b2a7fcSCarlo Caione } 16901b2a7fcSCarlo Caione 17001b2a7fcSCarlo Caione asd_compute_sha(ctx, data, len & ~(SHA256_BLOCKSZ - 1), 0); 17101b2a7fcSCarlo Caione data += len & ~(SHA256_BLOCKSZ - 1); 17201b2a7fcSCarlo Caione 17301b2a7fcSCarlo Caione if (len & (SHA256_BLOCKSZ - 1)) { 17401b2a7fcSCarlo Caione nr = len & (SHA256_BLOCKSZ - 1); 17501b2a7fcSCarlo Caione memcpy(ctx->block + ctx->blocksz, data, nr); 17601b2a7fcSCarlo Caione ctx->blocksz += nr; 17701b2a7fcSCarlo Caione } 17801b2a7fcSCarlo Caione } 17901b2a7fcSCarlo Caione 18001b2a7fcSCarlo Caione void asd_sha_finalize(struct asd_ctx *ctx) 18101b2a7fcSCarlo Caione { 18201b2a7fcSCarlo Caione asd_compute_sha(ctx, ctx->block, ctx->blocksz, 1); 18301b2a7fcSCarlo Caione } 184