blob: e16610ca23f0448e743345f41cd38452533e1ee7 [file] [log] [blame]
Jit Loon Lim7768a662023-05-17 12:26:11 +08001/*
2 * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <assert.h>
9#include <errno.h>
10
11#include <arch_helpers.h>
12#include <common/debug.h>
13#include <common/tbbr/tbbr_img_def.h>
14#include <drivers/delay_timer.h>
15#include <lib/mmio.h>
16#include <lib/utils.h>
17#include <tools_share/firmware_image_package.h>
18
19#include "socfpga_mailbox.h"
20#include "socfpga_vab.h"
21
22static size_t get_img_size(uint8_t *img_buf, size_t img_buf_sz)
23{
24 uint8_t *img_buf_end = img_buf + img_buf_sz;
25 uint32_t cert_sz = get_unaligned_le32(img_buf_end - sizeof(uint32_t));
26 uint8_t *p = img_buf_end - cert_sz - sizeof(uint32_t);
27
28 /* Ensure p is pointing within the img_buf */
29 if (p < img_buf || p > (img_buf_end - VAB_CERT_HEADER_SIZE))
30 return 0;
31
32 if (get_unaligned_le32(p) == SDM_CERT_MAGIC_NUM)
33 return (size_t)(p - img_buf);
34
35 return 0;
36}
37
38
39
40int socfpga_vendor_authentication(void **p_image, size_t *p_size)
41{
42 int retry_count = 20;
43 uint8_t hash384[FCS_SHA384_WORD_SIZE];
44 uint64_t img_addr, mbox_data_addr;
45 uint32_t img_sz, mbox_data_sz;
46 uint8_t *cert_hash_ptr, *mbox_relocate_data_addr;
47 uint32_t resp = 0, resp_len = 1;
48 int ret = 0;
49
50 img_addr = (uintptr_t)*p_image;
51 img_sz = get_img_size((uint8_t *)img_addr, *p_size);
52
53 if (!img_sz) {
54 NOTICE("VAB certificate not found in image!\n");
55 return -ENOVABIMG;
56 }
57
58 if (!IS_BYTE_ALIGNED(img_sz, sizeof(uint32_t))) {
59 NOTICE("Image size (%d bytes) not aliged to 4 bytes!\n", img_sz);
60 return -EIMGERR;
61 }
62
63 /* Generate HASH384 from the image */
64 /* TODO: This part need to cross check !!!!!! */
65 sha384_csum_wd((uint8_t *)img_addr, img_sz, hash384, CHUNKSZ_PER_WD_RESET);
66 cert_hash_ptr = (uint8_t *)(img_addr + img_sz +
67 VAB_CERT_MAGIC_OFFSET + VAB_CERT_FIT_SHA384_OFFSET);
68
69 /*
70 * Compare the SHA384 found in certificate against the SHA384
71 * calculated from image
72 */
73 if (memcmp(hash384, cert_hash_ptr, FCS_SHA384_WORD_SIZE)) {
74 NOTICE("SHA384 does not match!\n");
75 return -EKEYREJECTED;
76 }
77
78
79 mbox_data_addr = img_addr + img_sz - sizeof(uint32_t);
80 /* Size in word (32bits) */
81 mbox_data_sz = (BYTE_ALIGN(*p_size - img_sz, sizeof(uint32_t))) >> 2;
82
83 NOTICE("mbox_data_addr = %lx mbox_data_sz = %d\n", mbox_data_addr, mbox_data_sz);
84
85 /* TODO: This part need to cross check !!!!!! */
86 // mbox_relocate_data_addr = (uint8_t *)malloc(mbox_data_sz * sizeof(uint32_t));
87 // if (!mbox_relocate_data_addr) {
88 // NOTICE("Cannot allocate memory for VAB certificate relocation!\n");
89 // return -ENOMEM;
90 // }
91
92 memcpy(mbox_relocate_data_addr, (uint8_t *)mbox_data_addr, mbox_data_sz * sizeof(uint32_t));
93 *(uint32_t *)mbox_relocate_data_addr = 0;
94
95 do {
96 /* Invoke SMC call to ATF to send the VAB certificate to SDM */
97 ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_VAB_SRC_CERT,
98(uint32_t *)mbox_relocate_data_addr, mbox_data_sz, 0, &resp, &resp_len);
99
100 /* If SDM is not available, just delay 50ms and retry again */
101 /* 0x1FF = The device is busy */
102 if (ret == MBOX_RESP_ERR(0x1FF)) {
103 mdelay(50);
104 } else {
105 break;
106 }
107 } while (--retry_count);
108
109 /* Free the relocate certificate memory space */
110 zeromem((void *)&mbox_relocate_data_addr, sizeof(uint32_t));
111
112
113 /* Exclude the size of the VAB certificate from image size */
114 *p_size = img_sz;
115
116 if (ret) {
117 /*
118 * Unsupported mailbox command or device not in the
119 * owned/secure state
120 */
121 /* 0x85 = Not allowed under current security setting */
122 if (ret == MBOX_RESP_ERR(0x85)) {
123 /* SDM bypass authentication */
124 NOTICE("Image Authentication bypassed at address\n");
125 return 0;
126 }
127 NOTICE("VAB certificate authentication failed in SDM\n");
128 /* 0x1FF = The device is busy */
129 if (ret == MBOX_RESP_ERR(0x1FF)) {
130 NOTICE("Operation timed out\n");
131 return -ETIMEOUT;
132 } else if (ret == MBOX_WRONG_ID) {
133 NOTICE("No such process\n");
134 return -EPROCESS;
135 }
136 } else {
137 /* If Certificate Process Status has error */
138 if (resp) {
139 NOTICE("VAB certificate execution format error\n");
140 return -EIMGERR;
141 }
142 }
143
144 NOTICE("Image Authentication bypassed at address\n");
145 return ret;
146
147}
148
149static uint32_t get_unaligned_le32(const void *p)
150{
151 /* TODO: Temp for testing */
152 //return le32_to_cpup((__le32 *)p);
153 return 0;
154}
155
156void sha384_csum_wd(const unsigned char *input, unsigned int ilen,
157 unsigned char *output, unsigned int chunk_sz)
158{
159 /* TODO: Update sha384 start, update and finish */
160}