/* * SPDX-License-Identifier: LicenseRef-Unisoc-General-1.0 * * Copyright 2016-2024 Unisoc (Shanghai) Technologies Co., Ltd * * Licensed under the Unisoc General Software License, version 1.0 (the License); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.unisoc.com/en_us/license/UNISOC_GENERAL_LICENSE_V1.0-EN_US * * Software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * See the Unisoc General Software License, version 1.0 for more details. */ #include #include #include #include #include #include #include #include #include #include "log.h" #include "anti-rollback.h" #define SYS_HEADER_SIZE 0x200 #define MAX_CERT_SIZE 2048 const char* v_file="/mnt/etc/anti-rollback/version"; const char* s_file="/mnt/etc/anti-rollback/signature"; char boot_dev[15]={0}; uint8_t signature[4096]={0}; char cert[MAX_CERT_SIZE] = {0}; #define MAX_HASH_BITS_LEN (256) #define MAX_HASH_BYTES_LEN (MAX_HASH_BITS_LEN >> 3) #define IV_BYTE_LEN 16 #define MAGIC_SIZE 8 #define MAX_RSA4096_KEY_BITS_LEN (4096) #define MAX_RSA_KEY_BITS_LEN (MAX_RSA4096_KEY_BITS_LEN) #define MAX_RSA_KEY_BYTES_LEN (MAX_RSA_KEY_BITS_LEN>>3) typedef struct sys_img_header { uint32_t magic_num; // "BTHD"=="0x42544844"=="boothead" uint32_t version; // 1 uint8_t payload_hash[MAX_HASH_BYTES_LEN]; // sha256 hash value uint64_t imgaddr; // image loaded address uint32_t imgsize; // image size uint8_t iv_data[IV_BYTE_LEN]; // the parameter of AES crypto uint32_t is_packed; // packed image flag 0:false 1:true uint32_t firmware_size; // runtime firmware size uint32_t img_real_size; //image real size before sign uint32_t size_after_sign; //image all size after sign uint8_t reserved[424]; // 424 + 17*4 + 16 + 4= 512 uint32_t slot; // spl double slot: slota or slotb } sys_img_header; typedef struct sprdsignedimageheader { /* Magic number */ uint8_t magic[MAGIC_SIZE]; /* Version of this header format */ uint32_t header_version_major; /* Version of this header format */ uint32_t header_version_minor; /*image body, plain or cipher text */ uint64_t payload_size; uint64_t payload_offset; /*offset from itself start */ /*content certification size,if 0,ignore */ uint64_t cert_size; uint64_t cert_offset; /*(opt)private content size,if 0,ignore */ uint64_t priv_size; uint64_t priv_offset; /*(opt)debug/rma certification primary size,if 0,ignore */ uint64_t cert_dbg_prim_size; uint64_t cert_dbg_prim_offset; /*(opt)debug/rma certification second size,if 0,ignore */ uint64_t cert_dbg_developer_size; uint64_t cert_dbg_developer_offset; } sprdsignedimageheader; bool is_little_endian(void) { uint16_t data = 1; return *(uint8_t*)(&data); } void write32(uint8_t* buffer, uint32_t value) { if (is_little_endian()) { buffer[0] = value & 0xFF; buffer[1] = (value >> 8) & 0xFF; buffer[2] = (value >> 16) & 0xFF; buffer[3] = (value >> 24) & 0xFF; } else { buffer[3] = value & 0xFF; buffer[2] = (value >> 8) & 0xFF; buffer[1] = (value >> 16) & 0xFF; buffer[0] = (value >> 24) & 0xFF; } } void hexdump(const unsigned char *s, int l) { int n=0; for( ; n < l ; ++n) { if((n%16) == 0) printf("\n%04x",n); printf(" %02x",s[n]); } printf("\n"); } static int get_verison_and_signature(uint32_t* size) { std::ifstream file(v_file); std::ifstream file1(s_file, std::ios::binary); if (file.is_open() && file1.is_open()) { std::string line; std::getline(file, line); std::cout << "int version:" << atoi(line.c_str()) << std::endl; write32(signature + *size, line.length()); *size += 4; memcpy(signature + *size, line.c_str(), line.length()); *size += line.length(); std::getline(file, line); std::cout << "algorithm:" << line << std::endl; //write32(signature + size, line.length()); //size += 4; //memcpy(signature + size, line.c_str(), line.length()); //size += line.length(); std::getline(file, line); //std::cout << "hash:" << line << std::endl; write32(signature + *size, line.length()); *size += 4; memcpy(signature + *size, line.c_str(), line.length()); //hexdump(signature + *size, line.length()); *size += line.length(); write32(signature + *size, MAX_CERT_SIZE); *size += 4; memcpy(signature + *size, cert, MAX_CERT_SIZE); //std::cout << "pub key:" <= 0) ret = result; failed: return ret; }