1*2be57b86SSumit Garg /* 2*2be57b86SSumit Garg * Copyright (c) 2020, Linaro Limited. All rights reserved. 3*2be57b86SSumit Garg * Author: Sumit Garg <sumit.garg@linaro.org> 4*2be57b86SSumit Garg * 5*2be57b86SSumit Garg * SPDX-License-Identifier: BSD-3-Clause 6*2be57b86SSumit Garg */ 7*2be57b86SSumit Garg 8*2be57b86SSumit Garg #include <assert.h> 9*2be57b86SSumit Garg #include <errno.h> 10*2be57b86SSumit Garg #include <stdint.h> 11*2be57b86SSumit Garg #include <string.h> 12*2be57b86SSumit Garg 13*2be57b86SSumit Garg #include <platform_def.h> 14*2be57b86SSumit Garg 15*2be57b86SSumit Garg #include <common/bl_common.h> 16*2be57b86SSumit Garg #include <common/debug.h> 17*2be57b86SSumit Garg #include <drivers/auth/crypto_mod.h> 18*2be57b86SSumit Garg #include <drivers/io/io_driver.h> 19*2be57b86SSumit Garg #include <drivers/io/io_encrypted.h> 20*2be57b86SSumit Garg #include <drivers/io/io_storage.h> 21*2be57b86SSumit Garg #include <lib/utils.h> 22*2be57b86SSumit Garg #include <plat/common/platform.h> 23*2be57b86SSumit Garg #include <tools_share/firmware_encrypted.h> 24*2be57b86SSumit Garg #include <tools_share/uuid.h> 25*2be57b86SSumit Garg 26*2be57b86SSumit Garg static uintptr_t backend_dev_handle; 27*2be57b86SSumit Garg static uintptr_t backend_dev_spec; 28*2be57b86SSumit Garg static uintptr_t backend_handle; 29*2be57b86SSumit Garg static uintptr_t backend_image_spec; 30*2be57b86SSumit Garg 31*2be57b86SSumit Garg static io_dev_info_t enc_dev_info; 32*2be57b86SSumit Garg 33*2be57b86SSumit Garg /* Encrypted firmware driver functions */ 34*2be57b86SSumit Garg static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info); 35*2be57b86SSumit Garg static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec, 36*2be57b86SSumit Garg io_entity_t *entity); 37*2be57b86SSumit Garg static int enc_file_len(io_entity_t *entity, size_t *length); 38*2be57b86SSumit Garg static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, 39*2be57b86SSumit Garg size_t *length_read); 40*2be57b86SSumit Garg static int enc_file_close(io_entity_t *entity); 41*2be57b86SSumit Garg static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params); 42*2be57b86SSumit Garg static int enc_dev_close(io_dev_info_t *dev_info); 43*2be57b86SSumit Garg 44*2be57b86SSumit Garg static inline int is_valid_header(struct fw_enc_hdr *header) 45*2be57b86SSumit Garg { 46*2be57b86SSumit Garg if (header->magic == ENC_HEADER_MAGIC) 47*2be57b86SSumit Garg return 1; 48*2be57b86SSumit Garg else 49*2be57b86SSumit Garg return 0; 50*2be57b86SSumit Garg } 51*2be57b86SSumit Garg 52*2be57b86SSumit Garg static io_type_t device_type_enc(void) 53*2be57b86SSumit Garg { 54*2be57b86SSumit Garg return IO_TYPE_ENCRYPTED; 55*2be57b86SSumit Garg } 56*2be57b86SSumit Garg 57*2be57b86SSumit Garg static const io_dev_connector_t enc_dev_connector = { 58*2be57b86SSumit Garg .dev_open = enc_dev_open 59*2be57b86SSumit Garg }; 60*2be57b86SSumit Garg 61*2be57b86SSumit Garg static const io_dev_funcs_t enc_dev_funcs = { 62*2be57b86SSumit Garg .type = device_type_enc, 63*2be57b86SSumit Garg .open = enc_file_open, 64*2be57b86SSumit Garg .seek = NULL, 65*2be57b86SSumit Garg .size = enc_file_len, 66*2be57b86SSumit Garg .read = enc_file_read, 67*2be57b86SSumit Garg .write = NULL, 68*2be57b86SSumit Garg .close = enc_file_close, 69*2be57b86SSumit Garg .dev_init = enc_dev_init, 70*2be57b86SSumit Garg .dev_close = enc_dev_close, 71*2be57b86SSumit Garg }; 72*2be57b86SSumit Garg 73*2be57b86SSumit Garg static int enc_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info) 74*2be57b86SSumit Garg { 75*2be57b86SSumit Garg assert(dev_info != NULL); 76*2be57b86SSumit Garg 77*2be57b86SSumit Garg enc_dev_info.funcs = &enc_dev_funcs; 78*2be57b86SSumit Garg *dev_info = &enc_dev_info; 79*2be57b86SSumit Garg 80*2be57b86SSumit Garg return 0; 81*2be57b86SSumit Garg } 82*2be57b86SSumit Garg 83*2be57b86SSumit Garg static int enc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params) 84*2be57b86SSumit Garg { 85*2be57b86SSumit Garg int result; 86*2be57b86SSumit Garg unsigned int image_id = (unsigned int)init_params; 87*2be57b86SSumit Garg 88*2be57b86SSumit Garg /* Obtain a reference to the image by querying the platform layer */ 89*2be57b86SSumit Garg result = plat_get_image_source(image_id, &backend_dev_handle, 90*2be57b86SSumit Garg &backend_dev_spec); 91*2be57b86SSumit Garg if (result != 0) { 92*2be57b86SSumit Garg WARN("Failed to obtain reference to image id=%u (%i)\n", 93*2be57b86SSumit Garg image_id, result); 94*2be57b86SSumit Garg return -ENOENT; 95*2be57b86SSumit Garg } 96*2be57b86SSumit Garg 97*2be57b86SSumit Garg return result; 98*2be57b86SSumit Garg } 99*2be57b86SSumit Garg 100*2be57b86SSumit Garg static int enc_dev_close(io_dev_info_t *dev_info) 101*2be57b86SSumit Garg { 102*2be57b86SSumit Garg backend_dev_handle = (uintptr_t)NULL; 103*2be57b86SSumit Garg backend_dev_spec = (uintptr_t)NULL; 104*2be57b86SSumit Garg 105*2be57b86SSumit Garg return 0; 106*2be57b86SSumit Garg } 107*2be57b86SSumit Garg 108*2be57b86SSumit Garg static int enc_file_open(io_dev_info_t *dev_info, const uintptr_t spec, 109*2be57b86SSumit Garg io_entity_t *entity) 110*2be57b86SSumit Garg { 111*2be57b86SSumit Garg int result; 112*2be57b86SSumit Garg 113*2be57b86SSumit Garg assert(spec != 0); 114*2be57b86SSumit Garg assert(entity != NULL); 115*2be57b86SSumit Garg 116*2be57b86SSumit Garg backend_image_spec = spec; 117*2be57b86SSumit Garg 118*2be57b86SSumit Garg result = io_open(backend_dev_handle, backend_image_spec, 119*2be57b86SSumit Garg &backend_handle); 120*2be57b86SSumit Garg if (result != 0) { 121*2be57b86SSumit Garg WARN("Failed to open backend device (%i)\n", result); 122*2be57b86SSumit Garg result = -ENOENT; 123*2be57b86SSumit Garg } 124*2be57b86SSumit Garg 125*2be57b86SSumit Garg return result; 126*2be57b86SSumit Garg } 127*2be57b86SSumit Garg 128*2be57b86SSumit Garg static int enc_file_len(io_entity_t *entity, size_t *length) 129*2be57b86SSumit Garg { 130*2be57b86SSumit Garg int result; 131*2be57b86SSumit Garg 132*2be57b86SSumit Garg assert(entity != NULL); 133*2be57b86SSumit Garg assert(length != NULL); 134*2be57b86SSumit Garg 135*2be57b86SSumit Garg result = io_size(backend_handle, length); 136*2be57b86SSumit Garg if (result != 0) { 137*2be57b86SSumit Garg WARN("Failed to read blob length (%i)\n", result); 138*2be57b86SSumit Garg return -ENOENT; 139*2be57b86SSumit Garg } 140*2be57b86SSumit Garg 141*2be57b86SSumit Garg /* 142*2be57b86SSumit Garg * Encryption header is attached at the beginning of the encrypted file 143*2be57b86SSumit Garg * and is not considered a part of the payload. 144*2be57b86SSumit Garg */ 145*2be57b86SSumit Garg if (*length < sizeof(struct fw_enc_hdr)) 146*2be57b86SSumit Garg return -EIO; 147*2be57b86SSumit Garg 148*2be57b86SSumit Garg *length -= sizeof(struct fw_enc_hdr); 149*2be57b86SSumit Garg 150*2be57b86SSumit Garg return result; 151*2be57b86SSumit Garg } 152*2be57b86SSumit Garg 153*2be57b86SSumit Garg static int enc_file_read(io_entity_t *entity, uintptr_t buffer, size_t length, 154*2be57b86SSumit Garg size_t *length_read) 155*2be57b86SSumit Garg { 156*2be57b86SSumit Garg int result; 157*2be57b86SSumit Garg struct fw_enc_hdr header; 158*2be57b86SSumit Garg enum fw_enc_status_t fw_enc_status; 159*2be57b86SSumit Garg size_t bytes_read; 160*2be57b86SSumit Garg uint8_t key[ENC_MAX_KEY_SIZE]; 161*2be57b86SSumit Garg size_t key_len = sizeof(key); 162*2be57b86SSumit Garg unsigned int key_flags = 0; 163*2be57b86SSumit Garg const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)backend_image_spec; 164*2be57b86SSumit Garg 165*2be57b86SSumit Garg assert(entity != NULL); 166*2be57b86SSumit Garg assert(length_read != NULL); 167*2be57b86SSumit Garg 168*2be57b86SSumit Garg result = io_read(backend_handle, (uintptr_t)&header, sizeof(header), 169*2be57b86SSumit Garg &bytes_read); 170*2be57b86SSumit Garg if (result != 0) { 171*2be57b86SSumit Garg WARN("Failed to read encryption header (%i)\n", result); 172*2be57b86SSumit Garg return -ENOENT; 173*2be57b86SSumit Garg } 174*2be57b86SSumit Garg 175*2be57b86SSumit Garg if (!is_valid_header(&header)) { 176*2be57b86SSumit Garg WARN("Encryption header check failed.\n"); 177*2be57b86SSumit Garg return -ENOENT; 178*2be57b86SSumit Garg } 179*2be57b86SSumit Garg 180*2be57b86SSumit Garg VERBOSE("Encryption header looks OK.\n"); 181*2be57b86SSumit Garg fw_enc_status = header.flags & FW_ENC_STATUS_FLAG_MASK; 182*2be57b86SSumit Garg 183*2be57b86SSumit Garg if ((header.iv_len > ENC_MAX_IV_SIZE) || 184*2be57b86SSumit Garg (header.tag_len > ENC_MAX_TAG_SIZE)) { 185*2be57b86SSumit Garg WARN("Incorrect IV or tag length\n"); 186*2be57b86SSumit Garg return -ENOENT; 187*2be57b86SSumit Garg } 188*2be57b86SSumit Garg 189*2be57b86SSumit Garg result = io_read(backend_handle, buffer, length, &bytes_read); 190*2be57b86SSumit Garg if (result != 0) { 191*2be57b86SSumit Garg WARN("Failed to read encrypted payload (%i)\n", result); 192*2be57b86SSumit Garg return -ENOENT; 193*2be57b86SSumit Garg } 194*2be57b86SSumit Garg 195*2be57b86SSumit Garg *length_read = bytes_read; 196*2be57b86SSumit Garg 197*2be57b86SSumit Garg result = plat_get_enc_key_info(fw_enc_status, key, &key_len, &key_flags, 198*2be57b86SSumit Garg (uint8_t *)&uuid_spec->uuid, 199*2be57b86SSumit Garg sizeof(uuid_t)); 200*2be57b86SSumit Garg if (result != 0) { 201*2be57b86SSumit Garg WARN("Failed to obtain encryption key (%i)\n", result); 202*2be57b86SSumit Garg return -ENOENT; 203*2be57b86SSumit Garg } 204*2be57b86SSumit Garg 205*2be57b86SSumit Garg result = crypto_mod_auth_decrypt(header.dec_algo, 206*2be57b86SSumit Garg (void *)buffer, *length_read, key, 207*2be57b86SSumit Garg key_len, key_flags, header.iv, 208*2be57b86SSumit Garg header.iv_len, header.tag, 209*2be57b86SSumit Garg header.tag_len); 210*2be57b86SSumit Garg memset(key, 0, key_len); 211*2be57b86SSumit Garg 212*2be57b86SSumit Garg if (result != 0) { 213*2be57b86SSumit Garg ERROR("File decryption failed (%i)\n", result); 214*2be57b86SSumit Garg return -ENOENT; 215*2be57b86SSumit Garg } 216*2be57b86SSumit Garg 217*2be57b86SSumit Garg return result; 218*2be57b86SSumit Garg } 219*2be57b86SSumit Garg 220*2be57b86SSumit Garg static int enc_file_close(io_entity_t *entity) 221*2be57b86SSumit Garg { 222*2be57b86SSumit Garg io_close(backend_handle); 223*2be57b86SSumit Garg 224*2be57b86SSumit Garg backend_image_spec = (uintptr_t)NULL; 225*2be57b86SSumit Garg entity->info = 0; 226*2be57b86SSumit Garg 227*2be57b86SSumit Garg return 0; 228*2be57b86SSumit Garg } 229*2be57b86SSumit Garg 230*2be57b86SSumit Garg /* Exported functions */ 231*2be57b86SSumit Garg 232*2be57b86SSumit Garg /* Register the Encrypted Firmware driver with the IO abstraction */ 233*2be57b86SSumit Garg int register_io_dev_enc(const io_dev_connector_t **dev_con) 234*2be57b86SSumit Garg { 235*2be57b86SSumit Garg int result; 236*2be57b86SSumit Garg 237*2be57b86SSumit Garg assert(dev_con != NULL); 238*2be57b86SSumit Garg 239*2be57b86SSumit Garg result = io_register_device(&enc_dev_info); 240*2be57b86SSumit Garg if (result == 0) 241*2be57b86SSumit Garg *dev_con = &enc_dev_connector; 242*2be57b86SSumit Garg 243*2be57b86SSumit Garg return result; 244*2be57b86SSumit Garg } 245