blob: d87267885634e8aeea744a694f26f6eeb28ebfb1 [file] [log] [blame]
Martin Rothc7acf162020-05-28 00:44:50 -06001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <2crypto.h>
4#include <2return_codes.h>
5#include <bl_uapp/bl_syscall_public.h>
6#include <commonlib/bsd/helpers.h>
7#include <console/console.h>
8#include "psp_verstage.h"
9#include <stddef.h>
10#include <string.h>
Kangheui Won362ec8d2020-10-02 16:12:02 +100011#include <swab.h>
Martin Rothc7acf162020-05-28 00:44:50 -060012#include <vb2_api.h>
13
Jason Glenesk90f71912020-10-13 04:35:09 -070014static struct sha_generic_data sha_op;
Martin Rothc7acf162020-05-28 00:44:50 -060015static uint32_t sha_op_size_remaining;
16static uint8_t __attribute__((aligned(32))) sha_hash[64];
17
18vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, uint32_t data_size)
19{
20 printk(BIOS_DEBUG, "Calculating hash of %d bytes\n", data_size);
21
22 sha_op_size_remaining = data_size;
23
Kangheui Wonce0fad52021-06-25 16:03:05 +100024 if (platform_set_sha_op(hash_alg, &sha_op) != 0) {
Martin Rothc7acf162020-05-28 00:44:50 -060025 printk(BIOS_INFO, "Unsupported hash_alg %d!\n", hash_alg);
26 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
27 }
28
29 /* Set init flag for first operation */
30 sha_op.Init = 1;
31
32 /* Clear eom flag until last operation */
33 sha_op.Eom = 0;
34
35 /* Need documentation on this b:157610147 */
36 sha_op.DataMemType = 2;
37
38 sha_op.Digest = sha_hash;
39
40 sha_op.IntermediateDigest = NULL;
41
42 sha_op.IntermediateMsgLen = 0;
43
44 return VB2_SUCCESS;
45}
46
47vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
48{
49 uint32_t retval;
50 sha_op.Data = (uint8_t *) buf;
51
52 if (!sha_op_size_remaining) {
Julius Wernere9665952022-01-21 17:06:20 -080053 printk(BIOS_ERR, "got more data than expected.\n");
Martin Rothc7acf162020-05-28 00:44:50 -060054 return VB2_ERROR_UNKNOWN;
55 }
56
57 while (size) {
58 sha_op.DataLen = size;
59
60 sha_op_size_remaining -= sha_op.DataLen;
61
62 /* Set eom flag for final operation */
63 if (sha_op_size_remaining == 0)
64 sha_op.Eom = 1;
65
66 retval = svc_crypto_sha(&sha_op, SHA_GENERIC);
67 if (retval) {
Julius Wernere9665952022-01-21 17:06:20 -080068 printk(BIOS_ERR, "HW crypto failed - errorcode: %#x\n",
Martin Rothc7acf162020-05-28 00:44:50 -060069 retval);
70 return VB2_ERROR_UNKNOWN;
71 }
72
73 /* Clear init flag after first operation */
74 if (sha_op.Init == 1)
75 sha_op.Init = 0;
76
77 size -= sha_op.DataLen;
78 }
79
80 return VB2_SUCCESS;
81}
82
83/* Copy the hash back to verstage */
84vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
85{
86 if (sha_op.Eom == 0) {
Julius Wernere9665952022-01-21 17:06:20 -080087 printk(BIOS_ERR, "Got less data than expected.\n");
Martin Rothc7acf162020-05-28 00:44:50 -060088 return VB2_ERROR_UNKNOWN;
89 }
90
91 if (digest_size != sha_op.DigestLen) {
Julius Wernere9665952022-01-21 17:06:20 -080092 printk(BIOS_ERR, "Digest size does not match expected length.\n");
Martin Rothc7acf162020-05-28 00:44:50 -060093 return VB2_ERROR_UNKNOWN;
94 }
95
96 memcpy(digest, sha_hash, digest_size);
97
98 return VB2_SUCCESS;
99}
Kangheui Won07de9082020-08-14 14:37:53 +1000100
Kangheui Won362ec8d2020-10-02 16:12:02 +1000101vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key,
102 uint8_t *inout,
103 uint32_t *workbuf32, int exp)
Kangheui Won07de9082020-08-14 14:37:53 +1000104{
Kangheui Won362ec8d2020-10-02 16:12:02 +1000105 /* workbuf32 is guaranteed to be a length of
106 * 3 * key->arrsize * sizeof(uint32_t).
107 * Since PSP expects everything in LE and *inout is BE array,
108 * we'll use workbuf for temporary buffer for endian conversion.
109 */
Jason Glenesk90f71912020-10-13 04:35:09 -0700110 struct mod_exp_params mod_exp_param;
Kangheui Won362ec8d2020-10-02 16:12:02 +1000111 unsigned int key_bytes = key->arrsize * sizeof(uint32_t);
112 uint32_t *sig_swapped = workbuf32;
113 uint32_t *output_buffer = &workbuf32[key->arrsize];
114 uint32_t *inout_32 = (uint32_t *)inout;
Kangheui Won07de9082020-08-14 14:37:53 +1000115 uint32_t retval;
Kangheui Won362ec8d2020-10-02 16:12:02 +1000116 uint32_t i;
Kangheui Won07de9082020-08-14 14:37:53 +1000117
Kangheui Won362ec8d2020-10-02 16:12:02 +1000118 /* PSP only supports 2K and 4K moduli */
Kangheui Won07de9082020-08-14 14:37:53 +1000119 if (key->sig_alg != VB2_SIG_RSA2048 &&
120 key->sig_alg != VB2_SIG_RSA2048_EXP3 &&
121 key->sig_alg != VB2_SIG_RSA4096) {
122 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
123 }
124
Kangheui Won362ec8d2020-10-02 16:12:02 +1000125 for (i = 0; i < key->arrsize; i++)
126 sig_swapped[i] = swab32(inout_32[key->arrsize - i - 1]);
Kangheui Won07de9082020-08-14 14:37:53 +1000127
Kangheui Won362ec8d2020-10-02 16:12:02 +1000128 mod_exp_param.pExponent = (char *)&exp;
129 mod_exp_param.ExpSize = sizeof(exp);
130 mod_exp_param.pModulus = (char *)key->n;
131 mod_exp_param.ModulusSize = key_bytes;
132 mod_exp_param.pMessage = (char *)sig_swapped;
133 mod_exp_param.pOutput = (char *)output_buffer;
Kangheui Won07de9082020-08-14 14:37:53 +1000134
Kangheui Won362ec8d2020-10-02 16:12:02 +1000135 retval = svc_modexp(&mod_exp_param);
Kangheui Won07de9082020-08-14 14:37:53 +1000136 if (retval) {
Julius Wernere9665952022-01-21 17:06:20 -0800137 printk(BIOS_ERR, "HW crypto failed - errorcode: %#x\n",
Kangheui Won07de9082020-08-14 14:37:53 +1000138 retval);
Kangheui Won362ec8d2020-10-02 16:12:02 +1000139 return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
Kangheui Won07de9082020-08-14 14:37:53 +1000140 }
141
Kangheui Won362ec8d2020-10-02 16:12:02 +1000142 /* vboot expects results in *inout with BE, so copy & convert. */
143 for (i = 0; i < key->arrsize; i++)
144 inout_32[i] = swab32(output_buffer[key->arrsize - i - 1]);
145
Kangheui Won07de9082020-08-14 14:37:53 +1000146 return VB2_SUCCESS;
147}