11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */ 2bc420748SJens Wiklander /* 3bc420748SJens Wiklander * Copyright (c) 2015, Linaro Limited 4bc420748SJens Wiklander */ 5bc420748SJens Wiklander #ifndef SIGNED_HDR_H 6bc420748SJens Wiklander #define SIGNED_HDR_H 7bc420748SJens Wiklander 892ea2867SJens Wiklander #include <inttypes.h> 9064663e8SJens Wiklander #include <stdlib.h> 1040bb4a98SJens Wiklander #include <tee_api_types.h> 1140bb4a98SJens Wiklander #include <util.h> 12bc420748SJens Wiklander 13bc420748SJens Wiklander enum shdr_img_type { 14bc420748SJens Wiklander SHDR_TA = 0, 1582b5346dSJens Wiklander SHDR_BOOTSTRAP_TA = 1, 16e1afc439SSumit Garg SHDR_ENCRYPTED_TA = 2, 17bc420748SJens Wiklander }; 18bc420748SJens Wiklander 19bc420748SJens Wiklander #define SHDR_MAGIC 0x4f545348 20bc420748SJens Wiklander 21bc420748SJens Wiklander /** 22bc420748SJens Wiklander * struct shdr - signed header 23bc420748SJens Wiklander * @magic: magic number must match SHDR_MAGIC 24bc420748SJens Wiklander * @img_type: image type, values defined by enum shdr_img_type 25bc420748SJens Wiklander * @img_size: image size in bytes 26bc420748SJens Wiklander * @algo: algorithm, defined by public key algorithms TEE_ALG_* 27bc420748SJens Wiklander * from TEE Internal API specification 28bc420748SJens Wiklander * @hash_size: size of the signed hash 29bc420748SJens Wiklander * @sig_size: size of the signature 30bc420748SJens Wiklander * @hash: hash of an image 31bc420748SJens Wiklander * @sig: signature of @hash 32bc420748SJens Wiklander */ 33bc420748SJens Wiklander struct shdr { 34bc420748SJens Wiklander uint32_t magic; 35bc420748SJens Wiklander uint32_t img_type; 36bc420748SJens Wiklander uint32_t img_size; 37bc420748SJens Wiklander uint32_t algo; 38bc420748SJens Wiklander uint16_t hash_size; 39bc420748SJens Wiklander uint16_t sig_size; 40bc420748SJens Wiklander /* 41bc420748SJens Wiklander * Commented out element used to visualize the layout dynamic part 42bc420748SJens Wiklander * of the struct. 43bc420748SJens Wiklander * 44bc420748SJens Wiklander * hash is accessed through the macro SHDR_GET_HASH and 45bc420748SJens Wiklander * signature is accessed through the macro SHDR_GET_SIG 46bc420748SJens Wiklander * 47bc420748SJens Wiklander * uint8_t hash[hash_size]; 48bc420748SJens Wiklander * uint8_t sig[sig_size]; 49bc420748SJens Wiklander */ 50bc420748SJens Wiklander }; 51bc420748SJens Wiklander 5240bb4a98SJens Wiklander static inline size_t shdr_get_size(const struct shdr *shdr) 5340bb4a98SJens Wiklander { 5440bb4a98SJens Wiklander size_t s = sizeof(*shdr); 5540bb4a98SJens Wiklander 5640bb4a98SJens Wiklander if (ADD_OVERFLOW(s, shdr->hash_size, &s) || 5740bb4a98SJens Wiklander ADD_OVERFLOW(s, shdr->sig_size, &s)) 5840bb4a98SJens Wiklander return 0; 5940bb4a98SJens Wiklander 6040bb4a98SJens Wiklander return s; 6140bb4a98SJens Wiklander } 6240bb4a98SJens Wiklander 6340bb4a98SJens Wiklander #define SHDR_GET_SIZE(x) shdr_get_size((x)) 64bc420748SJens Wiklander #define SHDR_GET_HASH(x) (uint8_t *)(((struct shdr *)(x)) + 1) 65bc420748SJens Wiklander #define SHDR_GET_SIG(x) (SHDR_GET_HASH(x) + (x)->hash_size) 66bc420748SJens Wiklander 67b19db423SJens Wiklander /** 68b19db423SJens Wiklander * struct shdr_bootstrap_ta - bootstrap TA subheader 69b19db423SJens Wiklander * @uuid: UUID of the TA 70b19db423SJens Wiklander * @ta_version: Version of the TA 71b19db423SJens Wiklander */ 7282b5346dSJens Wiklander struct shdr_bootstrap_ta { 7382b5346dSJens Wiklander uint8_t uuid[sizeof(TEE_UUID)]; 74a8f769f3SEtienne Carriere uint32_t ta_version; 7582b5346dSJens Wiklander }; 7682b5346dSJens Wiklander 77e1afc439SSumit Garg /** 78e1afc439SSumit Garg * struct shdr_encrypted_ta - encrypted TA header 79e1afc439SSumit Garg * @enc_algo: authenticated encyption algorithm, defined by symmetric key 80e1afc439SSumit Garg * algorithms TEE_ALG_* from TEE Internal API 81e1afc439SSumit Garg * specification 82e1afc439SSumit Garg * @flags: authenticated encyption flags 83e1afc439SSumit Garg * @iv_size: size of the initialization vector 84e1afc439SSumit Garg * @tag_size: size of the authentication tag 85e1afc439SSumit Garg * @iv: initialization vector 86e1afc439SSumit Garg * @tag: authentication tag 87e1afc439SSumit Garg */ 88e1afc439SSumit Garg struct shdr_encrypted_ta { 89e1afc439SSumit Garg uint32_t enc_algo; 90e1afc439SSumit Garg uint32_t flags; 91e1afc439SSumit Garg uint16_t iv_size; 92e1afc439SSumit Garg uint16_t tag_size; 93e1afc439SSumit Garg /* 94e1afc439SSumit Garg * Commented out element used to visualize the layout dynamic part 95e1afc439SSumit Garg * of the struct. 96e1afc439SSumit Garg * 97e1afc439SSumit Garg * iv is accessed through the macro SHDR_ENC_GET_IV and 98e1afc439SSumit Garg * tag is accessed through the macro SHDR_ENC_GET_TAG 99e1afc439SSumit Garg * 100e1afc439SSumit Garg * uint8_t iv[iv_size]; 101e1afc439SSumit Garg * uint8_t tag[tag_size]; 102e1afc439SSumit Garg */ 103e1afc439SSumit Garg }; 104e1afc439SSumit Garg 105e1afc439SSumit Garg #define SHDR_ENC_KEY_TYPE_MASK 0x1 106e1afc439SSumit Garg 107e1afc439SSumit Garg enum shdr_enc_key_type { 108e1afc439SSumit Garg SHDR_ENC_KEY_DEV_SPECIFIC = 0, 109e1afc439SSumit Garg SHDR_ENC_KEY_CLASS_WIDE = 1, 110e1afc439SSumit Garg }; 111e1afc439SSumit Garg 1121b02ce1dSJens Wiklander static inline size_t shdr_enc_get_size(const struct shdr_encrypted_ta *ehdr) 1131b02ce1dSJens Wiklander { 1141b02ce1dSJens Wiklander size_t s = sizeof(*ehdr); 1151b02ce1dSJens Wiklander 1161b02ce1dSJens Wiklander if (ADD_OVERFLOW(s, ehdr->iv_size, &s) || 1171b02ce1dSJens Wiklander ADD_OVERFLOW(s, ehdr->tag_size, &s)) 1181b02ce1dSJens Wiklander return 0; 1191b02ce1dSJens Wiklander 1201b02ce1dSJens Wiklander return s; 1211b02ce1dSJens Wiklander } 1221b02ce1dSJens Wiklander 1231b02ce1dSJens Wiklander #define SHDR_ENC_GET_SIZE(x) shdr_enc_get_size((x)) 124e1afc439SSumit Garg #define SHDR_ENC_GET_IV(x) ((uint8_t *) \ 125e1afc439SSumit Garg (((struct shdr_encrypted_ta *)(x)) + 1)) 126e1afc439SSumit Garg #define SHDR_ENC_GET_TAG(x) ({ typeof(x) _x = (x); \ 127e1afc439SSumit Garg (SHDR_ENC_GET_IV(_x) + _x->iv_size); }) 128e1afc439SSumit Garg 129064663e8SJens Wiklander /* 130064663e8SJens Wiklander * Allocates a struct shdr large enough to hold the entire header, 131064663e8SJens Wiklander * excluding a subheader like struct shdr_bootstrap_ta. 132064663e8SJens Wiklander */ 133*ec1aa4faSJens Wiklander struct shdr *shdr_alloc_and_copy(size_t offs, const void *img, size_t img_size); 134bc420748SJens Wiklander 135064663e8SJens Wiklander /* Frees a previously allocated struct shdr */ 136064663e8SJens Wiklander static inline void shdr_free(struct shdr *shdr) 137064663e8SJens Wiklander { 138064663e8SJens Wiklander free(shdr); 139064663e8SJens Wiklander } 140064663e8SJens Wiklander 141064663e8SJens Wiklander /* 142064663e8SJens Wiklander * Verifies the signature in the @shdr. 143064663e8SJens Wiklander * 144064663e8SJens Wiklander * Note that the static part of struct shdr and payload still need to be 145064663e8SJens Wiklander * checked against the hash contained in the header. 146064663e8SJens Wiklander * 147064663e8SJens Wiklander * Returns TEE_SUCCESS on success or TEE_ERROR_SECURITY on failure 148064663e8SJens Wiklander */ 149064663e8SJens Wiklander TEE_Result shdr_verify_signature(const struct shdr *shdr); 150064663e8SJens Wiklander 151064663e8SJens Wiklander #endif /*SIGNED_HDR_H*/ 152