1e752c173SChia-Wei Wang // SPDX-License-Identifier: BSD-2-Clause
2e752c173SChia-Wei Wang /*
3e752c173SChia-Wei Wang * Copyright (c) 2022, Aspeed Technology Inc.
4e752c173SChia-Wei Wang */
5e752c173SChia-Wei Wang #include <stdint.h>
6e752c173SChia-Wei Wang #include <stddef.h>
7e752c173SChia-Wei Wang #include <string.h>
8e752c173SChia-Wei Wang #include <io.h>
9e752c173SChia-Wei Wang #include <util.h>
10e752c173SChia-Wei Wang #include <drvcrypt_hash.h>
11e752c173SChia-Wei Wang #include <mm/core_mmu.h>
12e752c173SChia-Wei Wang #include <mm/core_memprot.h>
13e752c173SChia-Wei Wang #include <kernel/delay.h>
14e752c173SChia-Wei Wang #include <tee/cache.h>
15e752c173SChia-Wei Wang
16e752c173SChia-Wei Wang #include "hace_ast2600.h"
17e752c173SChia-Wei Wang
18e752c173SChia-Wei Wang #define HACE_BASE 0x1e6d0000
19e752c173SChia-Wei Wang
20e752c173SChia-Wei Wang /* register offsets and bit fields */
21e752c173SChia-Wei Wang #define HACE_STS 0x1C
22e752c173SChia-Wei Wang #define HACE_STS_HASH_INT BIT(9)
23e752c173SChia-Wei Wang #define HACE_STS_HASH_BUSY BIT(0)
24e752c173SChia-Wei Wang #define HACE_HASH_DATA 0x20
25e752c173SChia-Wei Wang #define HACE_HASH_DIGEST 0x24
26e752c173SChia-Wei Wang #define HACE_HASH_HMAC_KEY 0x28
27e752c173SChia-Wei Wang #define HACE_HASH_DATA_LEN 0x2C
28e752c173SChia-Wei Wang #define HACE_HASH_CMD 0x30
29e752c173SChia-Wei Wang #define HACE_HASH_CMD_ACCUM BIT(8)
30e752c173SChia-Wei Wang #define HACE_HASH_CMD_ALG_SHA1 BIT(5)
31e752c173SChia-Wei Wang #define HACE_HASH_CMD_ALG_SHA256 (BIT(6) | BIT(4))
32e752c173SChia-Wei Wang #define HACE_HASH_CMD_ALG_SHA384 (BIT(10) | BIT(6) | BIT(5))
33e752c173SChia-Wei Wang #define HACE_HASH_CMD_ALG_SHA512 (BIT(6) | BIT(5))
34e752c173SChia-Wei Wang #define HACE_HASH_CMD_SHA_BE BIT(3)
35e752c173SChia-Wei Wang
36e752c173SChia-Wei Wang /* buffer size based on SHA-512 need */
37e752c173SChia-Wei Wang #define HASH_BLK_BUFSZ 128
38e752c173SChia-Wei Wang #define HASH_DGT_BUFSZ 64
39e752c173SChia-Wei Wang
40e752c173SChia-Wei Wang register_phys_mem(MEM_AREA_IO_SEC, HACE_BASE, SMALL_PAGE_SIZE);
41e752c173SChia-Wei Wang
42e752c173SChia-Wei Wang struct ast2600_hace_ctx {
43e752c173SChia-Wei Wang struct crypto_hash_ctx hash_ctx;
44e752c173SChia-Wei Wang uint32_t cmd;
45e752c173SChia-Wei Wang uint32_t algo;
46e752c173SChia-Wei Wang uint32_t dgt_size;
47e752c173SChia-Wei Wang uint32_t blk_size;
48e752c173SChia-Wei Wang uint32_t pad_size;
49e752c173SChia-Wei Wang uint64_t total[2];
50e752c173SChia-Wei Wang
51e752c173SChia-Wei Wang /* DMA memory to interact with HACE */
52*ca1d8e13SNeal Liu uint8_t *buf;
53*ca1d8e13SNeal Liu uint8_t *digest;
54e752c173SChia-Wei Wang };
55e752c173SChia-Wei Wang
56e752c173SChia-Wei Wang static vaddr_t hace_virt;
57e752c173SChia-Wei Wang struct mutex hace_mtx = MUTEX_INITIALIZER;
58e752c173SChia-Wei Wang
59e752c173SChia-Wei Wang static const uint32_t iv_sha1[8] = {
60e752c173SChia-Wei Wang 0x01234567, 0x89abcdef, 0xfedcba98, 0x76543210,
61e752c173SChia-Wei Wang 0xf0e1d2c3, 0, 0, 0
62e752c173SChia-Wei Wang };
63e752c173SChia-Wei Wang
64e752c173SChia-Wei Wang static const uint32_t iv_sha256[8] = {
65e752c173SChia-Wei Wang 0x67e6096a, 0x85ae67bb, 0x72f36e3c, 0x3af54fa5,
66e752c173SChia-Wei Wang 0x7f520e51, 0x8c68059b, 0xabd9831f, 0x19cde05b
67e752c173SChia-Wei Wang };
68e752c173SChia-Wei Wang
69e752c173SChia-Wei Wang static const uint32_t iv_sha384[16] = {
70e752c173SChia-Wei Wang 0x5d9dbbcb, 0xd89e05c1, 0x2a299a62, 0x07d57c36,
71e752c173SChia-Wei Wang 0x5a015991, 0x17dd7030, 0xd8ec2f15, 0x39590ef7,
72e752c173SChia-Wei Wang 0x67263367, 0x310bc0ff, 0x874ab48e, 0x11155868,
73e752c173SChia-Wei Wang 0x0d2e0cdb, 0xa78ff964, 0x1d48b547, 0xa44ffabe
74e752c173SChia-Wei Wang };
75e752c173SChia-Wei Wang
76e752c173SChia-Wei Wang static const uint32_t iv_sha512[16] = {
77e752c173SChia-Wei Wang 0x67e6096a, 0x08c9bcf3, 0x85ae67bb, 0x3ba7ca84,
78e752c173SChia-Wei Wang 0x72f36e3c, 0x2bf894fe, 0x3af54fa5, 0xf1361d5f,
79e752c173SChia-Wei Wang 0x7f520e51, 0xd182e6ad, 0x8c68059b, 0x1f6c3e2b,
80e752c173SChia-Wei Wang 0xabd9831f, 0x6bbd41fb, 0x19cde05b, 0x79217e13
81e752c173SChia-Wei Wang };
82e752c173SChia-Wei Wang
ast2600_hace_process(struct crypto_hash_ctx * ctx,const uint8_t * data,size_t len)83e752c173SChia-Wei Wang static TEE_Result ast2600_hace_process(struct crypto_hash_ctx *ctx,
84e752c173SChia-Wei Wang const uint8_t *data, size_t len)
85e752c173SChia-Wei Wang {
86e752c173SChia-Wei Wang TEE_Result rc = TEE_ERROR_GENERIC;
87e752c173SChia-Wei Wang uint32_t sts = 0;
88e752c173SChia-Wei Wang uint64_t tref = 0;
89e752c173SChia-Wei Wang paddr_t data_phys = 0;
90e752c173SChia-Wei Wang paddr_t digest_phys = 0;
91e752c173SChia-Wei Wang struct ast2600_hace_ctx *hctx = NULL;
92e752c173SChia-Wei Wang
93*ca1d8e13SNeal Liu mutex_lock(&hace_mtx);
94*ca1d8e13SNeal Liu
95e752c173SChia-Wei Wang hctx = container_of(ctx, struct ast2600_hace_ctx, hash_ctx);
96e752c173SChia-Wei Wang
97e752c173SChia-Wei Wang sts = io_read32(hace_virt + HACE_STS);
98*ca1d8e13SNeal Liu if (sts & HACE_STS_HASH_BUSY) {
99*ca1d8e13SNeal Liu rc = TEE_ERROR_BUSY;
100*ca1d8e13SNeal Liu goto out;
101*ca1d8e13SNeal Liu }
102e752c173SChia-Wei Wang
103e752c173SChia-Wei Wang cache_operation(TEE_CACHEFLUSH, (void *)data, len);
104e752c173SChia-Wei Wang
105e752c173SChia-Wei Wang data_phys = virt_to_phys((void *)data);
106e752c173SChia-Wei Wang digest_phys = virt_to_phys(hctx->digest);
107e752c173SChia-Wei Wang
108e752c173SChia-Wei Wang io_write32(hace_virt + HACE_HASH_DATA, (uint32_t)data_phys);
109e752c173SChia-Wei Wang io_write32(hace_virt + HACE_HASH_DIGEST, (uint32_t)digest_phys);
110e752c173SChia-Wei Wang io_write32(hace_virt + HACE_HASH_HMAC_KEY, (uint32_t)digest_phys);
111e752c173SChia-Wei Wang
112e752c173SChia-Wei Wang io_write32(hace_virt + HACE_HASH_DATA_LEN, len);
113e752c173SChia-Wei Wang io_write32(hace_virt + HACE_HASH_CMD, hctx->cmd);
114e752c173SChia-Wei Wang
115e752c173SChia-Wei Wang /* poll for completion */
116e752c173SChia-Wei Wang tref = timeout_init_us(1000 + (len >> 3));
117e752c173SChia-Wei Wang
118e752c173SChia-Wei Wang do {
119e752c173SChia-Wei Wang sts = io_read32(hace_virt + HACE_STS);
120e752c173SChia-Wei Wang if (timeout_elapsed(tref)) {
121e752c173SChia-Wei Wang rc = TEE_ERROR_TARGET_DEAD;
122e752c173SChia-Wei Wang goto out;
123e752c173SChia-Wei Wang }
124e752c173SChia-Wei Wang } while (!(sts & HACE_STS_HASH_INT));
125e752c173SChia-Wei Wang
126*ca1d8e13SNeal Liu io_write32(hace_virt + HACE_STS, HACE_STS_HASH_INT);
127*ca1d8e13SNeal Liu
128*ca1d8e13SNeal Liu rc = TEE_SUCCESS;
129e752c173SChia-Wei Wang out:
130e752c173SChia-Wei Wang mutex_unlock(&hace_mtx);
131e752c173SChia-Wei Wang
132e752c173SChia-Wei Wang return rc;
133e752c173SChia-Wei Wang }
134e752c173SChia-Wei Wang
ast2600_hace_init(struct crypto_hash_ctx * ctx)135e752c173SChia-Wei Wang static TEE_Result ast2600_hace_init(struct crypto_hash_ctx *ctx)
136e752c173SChia-Wei Wang {
137e752c173SChia-Wei Wang struct ast2600_hace_ctx *hctx = NULL;
138e752c173SChia-Wei Wang
139e752c173SChia-Wei Wang hctx = container_of(ctx, struct ast2600_hace_ctx, hash_ctx);
140e752c173SChia-Wei Wang
141e752c173SChia-Wei Wang switch (hctx->algo) {
142e752c173SChia-Wei Wang case TEE_ALG_SHA1:
143e752c173SChia-Wei Wang memcpy(hctx->digest, iv_sha1, sizeof(iv_sha1));
144e752c173SChia-Wei Wang break;
145e752c173SChia-Wei Wang case TEE_ALG_SHA256:
146e752c173SChia-Wei Wang memcpy(hctx->digest, iv_sha256, sizeof(iv_sha256));
147e752c173SChia-Wei Wang break;
148e752c173SChia-Wei Wang case TEE_ALG_SHA384:
149e752c173SChia-Wei Wang memcpy(hctx->digest, iv_sha384, sizeof(iv_sha384));
150e752c173SChia-Wei Wang break;
151e752c173SChia-Wei Wang case TEE_ALG_SHA512:
152e752c173SChia-Wei Wang memcpy(hctx->digest, iv_sha512, sizeof(iv_sha512));
153e752c173SChia-Wei Wang break;
154e752c173SChia-Wei Wang default:
155e752c173SChia-Wei Wang return TEE_ERROR_NOT_SUPPORTED;
156e752c173SChia-Wei Wang }
157e752c173SChia-Wei Wang
1580c2a8f2fSNeal Liu hctx->total[0] = 0;
1590c2a8f2fSNeal Liu hctx->total[1] = 0;
160e752c173SChia-Wei Wang
161*ca1d8e13SNeal Liu cache_operation(TEE_CACHEFLUSH, hctx->digest, HASH_DGT_BUFSZ);
162e752c173SChia-Wei Wang
163e752c173SChia-Wei Wang return TEE_SUCCESS;
164e752c173SChia-Wei Wang }
165e752c173SChia-Wei Wang
ast2600_hace_update(struct crypto_hash_ctx * ctx,const uint8_t * data,size_t len)166e752c173SChia-Wei Wang static TEE_Result ast2600_hace_update(struct crypto_hash_ctx *ctx,
167e752c173SChia-Wei Wang const uint8_t *data, size_t len)
168e752c173SChia-Wei Wang {
169e752c173SChia-Wei Wang TEE_Result rc = TEE_ERROR_GENERIC;
170e752c173SChia-Wei Wang uint32_t left = 0;
171e752c173SChia-Wei Wang uint32_t fill = 0;
172e752c173SChia-Wei Wang size_t blk_size = 0;
173e752c173SChia-Wei Wang struct ast2600_hace_ctx *hctx = NULL;
174e752c173SChia-Wei Wang
175*ca1d8e13SNeal Liu if (!ctx || !data || !len)
176*ca1d8e13SNeal Liu return TEE_ERROR_BAD_PARAMETERS;
177*ca1d8e13SNeal Liu
178e752c173SChia-Wei Wang hctx = container_of(ctx, struct ast2600_hace_ctx, hash_ctx);
179e752c173SChia-Wei Wang
180e752c173SChia-Wei Wang blk_size = hctx->blk_size;
181e752c173SChia-Wei Wang
182e752c173SChia-Wei Wang left = hctx->total[0] & (blk_size - 1);
183e752c173SChia-Wei Wang fill = blk_size - left;
184e752c173SChia-Wei Wang
185e752c173SChia-Wei Wang hctx->total[0] += len;
186e752c173SChia-Wei Wang if (hctx->total[0] < len)
187e752c173SChia-Wei Wang hctx->total[1]++;
188e752c173SChia-Wei Wang
189e752c173SChia-Wei Wang if (left && len >= fill) {
190e752c173SChia-Wei Wang memcpy(hctx->buf + left, data, fill);
191e752c173SChia-Wei Wang rc = ast2600_hace_process(ctx, hctx->buf, blk_size);
192e752c173SChia-Wei Wang if (rc)
193e752c173SChia-Wei Wang return rc;
194e752c173SChia-Wei Wang
195e752c173SChia-Wei Wang data += fill;
196e752c173SChia-Wei Wang len -= fill;
197e752c173SChia-Wei Wang left = 0;
198e752c173SChia-Wei Wang }
199e752c173SChia-Wei Wang
200e752c173SChia-Wei Wang while (len >= blk_size) {
201*ca1d8e13SNeal Liu memcpy(hctx->buf, data, blk_size);
202*ca1d8e13SNeal Liu rc = ast2600_hace_process(ctx, hctx->buf, blk_size);
203e752c173SChia-Wei Wang if (rc)
204e752c173SChia-Wei Wang return rc;
205e752c173SChia-Wei Wang
206e752c173SChia-Wei Wang data += blk_size;
207e752c173SChia-Wei Wang len -= blk_size;
208e752c173SChia-Wei Wang }
209e752c173SChia-Wei Wang
210e752c173SChia-Wei Wang if (len)
211e752c173SChia-Wei Wang memcpy(hctx->buf + left, data, len);
212e752c173SChia-Wei Wang
213e752c173SChia-Wei Wang return TEE_SUCCESS;
214e752c173SChia-Wei Wang }
215e752c173SChia-Wei Wang
ast2600_hace_final(struct crypto_hash_ctx * ctx,uint8_t * digest,size_t len)216e752c173SChia-Wei Wang static TEE_Result ast2600_hace_final(struct crypto_hash_ctx *ctx,
217e752c173SChia-Wei Wang uint8_t *digest, size_t len)
218e752c173SChia-Wei Wang {
219e752c173SChia-Wei Wang TEE_Result rc = TEE_ERROR_GENERIC;
220e752c173SChia-Wei Wang uint32_t last = 0;
221e752c173SChia-Wei Wang uint32_t padn = 0;
222e752c173SChia-Wei Wang uint8_t pad[HASH_BLK_BUFSZ * 2] = { };
223e752c173SChia-Wei Wang uint64_t dbits[2] = { };
224e752c173SChia-Wei Wang uint64_t dbits_be[2] = { };
225e752c173SChia-Wei Wang struct ast2600_hace_ctx *hctx = NULL;
226*ca1d8e13SNeal Liu size_t length = 0;
227e752c173SChia-Wei Wang
228e752c173SChia-Wei Wang hctx = container_of(ctx, struct ast2600_hace_ctx, hash_ctx);
229*ca1d8e13SNeal Liu length = MIN(len, hctx->dgt_size);
230e752c173SChia-Wei Wang
231e752c173SChia-Wei Wang memset(pad, 0, sizeof(pad));
232e752c173SChia-Wei Wang pad[0] = 0x80;
233e752c173SChia-Wei Wang
234e752c173SChia-Wei Wang dbits[0] = (hctx->total[0] << 3);
235e752c173SChia-Wei Wang dbits_be[0] = get_be64(&dbits[0]);
236e752c173SChia-Wei Wang
237e752c173SChia-Wei Wang dbits[1] = (hctx->total[0] >> 61) | (hctx->total[1] << 3);
238e752c173SChia-Wei Wang dbits_be[1] = get_be64(&dbits[1]);
239e752c173SChia-Wei Wang
240e752c173SChia-Wei Wang last = hctx->total[0] & (hctx->blk_size - 1);
241e752c173SChia-Wei Wang
2420c2a8f2fSNeal Liu switch (hctx->algo) {
243e752c173SChia-Wei Wang case TEE_ALG_SHA1:
244e752c173SChia-Wei Wang case TEE_ALG_SHA256:
245e752c173SChia-Wei Wang if (last < 56)
246e752c173SChia-Wei Wang padn = 56 - last;
247e752c173SChia-Wei Wang else
248e752c173SChia-Wei Wang padn = 120 - last;
249e752c173SChia-Wei Wang
250e752c173SChia-Wei Wang rc = ast2600_hace_update(ctx, pad, padn);
251e752c173SChia-Wei Wang if (rc)
252e752c173SChia-Wei Wang return rc;
253e752c173SChia-Wei Wang
254e752c173SChia-Wei Wang rc = ast2600_hace_update(ctx, (uint8_t *)&dbits_be[0],
255e752c173SChia-Wei Wang sizeof(dbits_be[0]));
256e752c173SChia-Wei Wang if (rc)
257e752c173SChia-Wei Wang return rc;
258e752c173SChia-Wei Wang break;
259e752c173SChia-Wei Wang case TEE_ALG_SHA384:
260e752c173SChia-Wei Wang case TEE_ALG_SHA512:
261e752c173SChia-Wei Wang if (last < 112)
262e752c173SChia-Wei Wang padn = 112 - last;
263e752c173SChia-Wei Wang else
264e752c173SChia-Wei Wang padn = 240 - last;
265e752c173SChia-Wei Wang
266e752c173SChia-Wei Wang rc = ast2600_hace_update(ctx, pad, padn);
267e752c173SChia-Wei Wang if (rc)
268e752c173SChia-Wei Wang return rc;
269e752c173SChia-Wei Wang
270e752c173SChia-Wei Wang rc = ast2600_hace_update(ctx, (uint8_t *)&dbits_be[1],
271e752c173SChia-Wei Wang sizeof(dbits_be[1]));
272e752c173SChia-Wei Wang if (rc)
273e752c173SChia-Wei Wang return rc;
274e752c173SChia-Wei Wang
275e752c173SChia-Wei Wang rc = ast2600_hace_update(ctx, (uint8_t *)&dbits_be[0],
276e752c173SChia-Wei Wang sizeof(dbits_be[0]));
277e752c173SChia-Wei Wang if (rc)
278e752c173SChia-Wei Wang return rc;
279e752c173SChia-Wei Wang break;
280e752c173SChia-Wei Wang default:
281e752c173SChia-Wei Wang return TEE_ERROR_NOT_SUPPORTED;
282e752c173SChia-Wei Wang }
283e752c173SChia-Wei Wang
284*ca1d8e13SNeal Liu cache_operation(TEE_CACHEINVALIDATE, hctx->digest, HASH_DGT_BUFSZ);
285e752c173SChia-Wei Wang
286*ca1d8e13SNeal Liu memcpy(digest, hctx->digest, length);
287e752c173SChia-Wei Wang
288e752c173SChia-Wei Wang return TEE_SUCCESS;
289e752c173SChia-Wei Wang }
290e752c173SChia-Wei Wang
ast2600_hace_free(struct crypto_hash_ctx * ctx)291e752c173SChia-Wei Wang static void ast2600_hace_free(struct crypto_hash_ctx *ctx)
292e752c173SChia-Wei Wang {
293e752c173SChia-Wei Wang struct ast2600_hace_ctx *hctx = NULL;
294e752c173SChia-Wei Wang
295e752c173SChia-Wei Wang hctx = container_of(ctx, struct ast2600_hace_ctx, hash_ctx);
296e752c173SChia-Wei Wang
297*ca1d8e13SNeal Liu free(hctx->buf);
298*ca1d8e13SNeal Liu free(hctx->digest);
299e752c173SChia-Wei Wang free(hctx);
300e752c173SChia-Wei Wang }
301e752c173SChia-Wei Wang
ast2600_hace_copy_state(struct crypto_hash_ctx * dst_ctx,struct crypto_hash_ctx * src_ctx)302e752c173SChia-Wei Wang static void ast2600_hace_copy_state(struct crypto_hash_ctx *dst_ctx,
303e752c173SChia-Wei Wang struct crypto_hash_ctx *src_ctx)
304e752c173SChia-Wei Wang {
305e752c173SChia-Wei Wang struct ast2600_hace_ctx *src_hctx = NULL;
306e752c173SChia-Wei Wang struct ast2600_hace_ctx *dst_hctx = NULL;
307e752c173SChia-Wei Wang
308e752c173SChia-Wei Wang src_hctx = container_of(src_ctx, struct ast2600_hace_ctx, hash_ctx);
309e752c173SChia-Wei Wang dst_hctx = container_of(dst_ctx, struct ast2600_hace_ctx, hash_ctx);
310e752c173SChia-Wei Wang
311*ca1d8e13SNeal Liu dst_hctx->hash_ctx = src_hctx->hash_ctx;
312*ca1d8e13SNeal Liu dst_hctx->cmd = src_hctx->cmd;
313*ca1d8e13SNeal Liu dst_hctx->dgt_size = src_hctx->dgt_size;
314*ca1d8e13SNeal Liu dst_hctx->blk_size = src_hctx->blk_size;
315*ca1d8e13SNeal Liu dst_hctx->pad_size = src_hctx->pad_size;
316*ca1d8e13SNeal Liu dst_hctx->total[0] = src_hctx->total[0];
317*ca1d8e13SNeal Liu dst_hctx->total[1] = src_hctx->total[1];
318e752c173SChia-Wei Wang
319*ca1d8e13SNeal Liu cache_operation(TEE_CACHEINVALIDATE, src_hctx->buf, HASH_BLK_BUFSZ);
320*ca1d8e13SNeal Liu memcpy(dst_hctx->buf, src_hctx->buf, HASH_BLK_BUFSZ);
321*ca1d8e13SNeal Liu cache_operation(TEE_CACHEFLUSH, dst_hctx->buf, HASH_BLK_BUFSZ);
322e752c173SChia-Wei Wang
323*ca1d8e13SNeal Liu cache_operation(TEE_CACHEINVALIDATE, src_hctx->digest, HASH_DGT_BUFSZ);
324*ca1d8e13SNeal Liu memcpy(dst_hctx->digest, src_hctx->digest, HASH_DGT_BUFSZ);
325*ca1d8e13SNeal Liu cache_operation(TEE_CACHEFLUSH, dst_hctx->digest, HASH_DGT_BUFSZ);
326e752c173SChia-Wei Wang }
327e752c173SChia-Wei Wang
328e752c173SChia-Wei Wang static const struct crypto_hash_ops ast2600_hace_ops = {
329e752c173SChia-Wei Wang .init = ast2600_hace_init,
330e752c173SChia-Wei Wang .update = ast2600_hace_update,
331e752c173SChia-Wei Wang .final = ast2600_hace_final,
332e752c173SChia-Wei Wang .free_ctx = ast2600_hace_free,
333e752c173SChia-Wei Wang .copy_state = ast2600_hace_copy_state,
334e752c173SChia-Wei Wang };
335e752c173SChia-Wei Wang
ast2600_hace_alloc(struct crypto_hash_ctx ** pctx,uint32_t algo)336e752c173SChia-Wei Wang static TEE_Result ast2600_hace_alloc(struct crypto_hash_ctx **pctx,
337e752c173SChia-Wei Wang uint32_t algo)
338e752c173SChia-Wei Wang {
339e752c173SChia-Wei Wang struct ast2600_hace_ctx *hctx = calloc(1, sizeof(*hctx));
340e752c173SChia-Wei Wang
341e752c173SChia-Wei Wang if (!hctx)
342e752c173SChia-Wei Wang return TEE_ERROR_OUT_OF_MEMORY;
343*ca1d8e13SNeal Liu hctx->buf = memalign(HASH_BLK_BUFSZ, HASH_BLK_BUFSZ);
344*ca1d8e13SNeal Liu if (!hctx->buf)
345*ca1d8e13SNeal Liu return TEE_ERROR_OUT_OF_MEMORY;
346*ca1d8e13SNeal Liu
347*ca1d8e13SNeal Liu hctx->digest = memalign(HASH_DGT_BUFSZ, HASH_DGT_BUFSZ);
348*ca1d8e13SNeal Liu if (!hctx->digest)
349*ca1d8e13SNeal Liu return TEE_ERROR_OUT_OF_MEMORY;
350e752c173SChia-Wei Wang
3510c2a8f2fSNeal Liu hctx->hash_ctx.ops = &ast2600_hace_ops;
3520c2a8f2fSNeal Liu hctx->algo = algo;
3530c2a8f2fSNeal Liu hctx->cmd = HACE_HASH_CMD_ACCUM | HACE_HASH_CMD_SHA_BE;
354e752c173SChia-Wei Wang
355e752c173SChia-Wei Wang switch (algo) {
356e752c173SChia-Wei Wang case TEE_ALG_SHA1:
357e752c173SChia-Wei Wang hctx->dgt_size = 20;
358e752c173SChia-Wei Wang hctx->blk_size = 64;
359e752c173SChia-Wei Wang hctx->pad_size = 8;
360e752c173SChia-Wei Wang hctx->cmd |= HACE_HASH_CMD_ALG_SHA1;
361e752c173SChia-Wei Wang break;
362e752c173SChia-Wei Wang case TEE_ALG_SHA256:
363e752c173SChia-Wei Wang hctx->dgt_size = 32;
364e752c173SChia-Wei Wang hctx->blk_size = 64;
365e752c173SChia-Wei Wang hctx->pad_size = 8;
366e752c173SChia-Wei Wang hctx->cmd |= HACE_HASH_CMD_ALG_SHA256;
367e752c173SChia-Wei Wang break;
368e752c173SChia-Wei Wang case TEE_ALG_SHA384:
369e752c173SChia-Wei Wang hctx->dgt_size = 48;
370e752c173SChia-Wei Wang hctx->blk_size = 128;
371e752c173SChia-Wei Wang hctx->pad_size = 16;
372e752c173SChia-Wei Wang hctx->cmd |= HACE_HASH_CMD_ALG_SHA384;
373e752c173SChia-Wei Wang break;
374e752c173SChia-Wei Wang case TEE_ALG_SHA512:
375e752c173SChia-Wei Wang hctx->dgt_size = 64;
376e752c173SChia-Wei Wang hctx->blk_size = 128;
377e752c173SChia-Wei Wang hctx->pad_size = 16;
378e752c173SChia-Wei Wang hctx->cmd |= HACE_HASH_CMD_ALG_SHA512;
379e752c173SChia-Wei Wang break;
380e752c173SChia-Wei Wang default:
381e752c173SChia-Wei Wang free(hctx);
382e752c173SChia-Wei Wang return TEE_ERROR_NOT_IMPLEMENTED;
383e752c173SChia-Wei Wang }
384e752c173SChia-Wei Wang
385e752c173SChia-Wei Wang *pctx = &hctx->hash_ctx;
386e752c173SChia-Wei Wang
387e752c173SChia-Wei Wang return TEE_SUCCESS;
388e752c173SChia-Wei Wang }
389e752c173SChia-Wei Wang
ast2600_drvcrypt_register_hash(void)390e752c173SChia-Wei Wang TEE_Result ast2600_drvcrypt_register_hash(void)
391e752c173SChia-Wei Wang {
392e752c173SChia-Wei Wang hace_virt = core_mmu_get_va(HACE_BASE, MEM_AREA_IO_SEC,
393e752c173SChia-Wei Wang SMALL_PAGE_SIZE);
394e752c173SChia-Wei Wang if (!hace_virt) {
395e752c173SChia-Wei Wang EMSG("cannot get HACE virtual address");
396e752c173SChia-Wei Wang return TEE_ERROR_GENERIC;
397e752c173SChia-Wei Wang }
398e752c173SChia-Wei Wang
399e752c173SChia-Wei Wang return drvcrypt_register_hash(ast2600_hace_alloc);
400e752c173SChia-Wei Wang }
401