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