/** * @brief Calculate the Endpoint Secondary Signing Key (ESSK) * * @param y2 A pointer to the Y2 term used by all * @param essk A pointer to the output ESSK variable * @param ims_sample_compatibility If true, generate IMS values that are * compatible with the original (incorrect) 100 sample values sent * to Toshiba 2016/01/14. If false, generate the IMS value using * the correct form. */ void calc_essk(uint8_t * y2, mcl_octet * essk, bool ims_sample_compatibility) { uint8_t z2[SHA256_HASH_DIGEST_SIZE]; uint8_t scratch_hash[SHA256_HASH_DIGEST_SIZE]; int status; if (ims_sample_compatibility) { /** * Y2 = sha256(IMS[0:31] xor copy(0x5a, 32)) // (provided) * EPSK[0:31] = sha256(Y2 || copy(0x01, 32)) */ sha256_concat(essk->val, y2, 0x01, 32); } else { /** * Y2 = sha256(IMS[0:31] xor copy(0x5a, 32)) // (provided) * Z2 = sha256(Y2 || copy(0x02, 32)) * ESSK[0:31] = sha256(Z2 || copy(0x01, 32)) */ sha256_concat(z2, y2, 0x02, 32); sha256_concat(scratch_hash, z2, 0x01, 32); memcpy(essk->val, scratch_hash, SHA256_HASH_DIGEST_SIZE); essk->len = SHA256_HASH_DIGEST_SIZE; } essk->len = SHA256_HASH_DIGEST_SIZE; #ifdef IMS_DEBUGMSG display_binary_data(essk->val, essk->len, true, "essk "); #endif }
/** * @brief Calculate the Endpoint Primary Signing Key (EPSK) * * @param y2 A pointer to the Y2 term used by all * @param epsk A pointer to the output EPSK variable */ void calc_epsk(uint8_t * y2, mcl_octet * epsk) { uint8_t z1[SHA256_HASH_DIGEST_SIZE]; uint8_t scratch_hash[SHA256_HASH_DIGEST_SIZE]; int status; /** * Y2 = sha256(IMS[0:31] xor copy(0x5a, 32)) // (provided) * Z1 = sha256(Y2 || copy(0x01, 32)) * EPSK[0:31] = sha256(Z1 || copy(0x01, 32)) * EPSK[32:55] = sha256(Z1 || copy(0x02, 32))[0:23] */ sha256_concat(z1, y2, 0x01, 32); sha256_concat(scratch_hash, z1, 0x01, 32); memcpy(&epsk->val[0], scratch_hash, SHA256_HASH_DIGEST_SIZE); sha256_concat(scratch_hash, z1, 0x02, 32); memcpy(&epsk->val[SHA256_HASH_DIGEST_SIZE], scratch_hash, (EPSK_SIZE - SHA256_HASH_DIGEST_SIZE)); epsk->len = EPSK_SIZE; #ifdef IMS_DEBUGMSG display_binary_data(epsk->val, epsk->len, true, "epsk "); #endif }
/** * @brief Calculate the Endpoint Secondary Verification Key (ESVK) * * @param essk A pointer to the input ESSK variable * @param esvk A pointer to the output ESVK variable * * @returns Zero if successful, MIRACL status otherwise (ESVK didn't validate) */ int calc_esvk(mcl_octet * essk, mcl_octet * esvk) { int status = 0; /* Generate the corresponding EPVK public key, a djb25519 ECC */ MCL_ECP_KEY_PAIR_GENERATE_C25519(NULL, essk, esvk); status = MCL_ECP_PUBLIC_KEY_VALIDATE_C25519(1, esvk); if (status != 0) { printf("EPVK is invalid!\r\n"); } #ifdef IMS_DEBUGMSG display_binary_data(esvk->val, esvk->len, true, "esvk "); #endif return status; }
void print_ff(char * title, mcl_chunk ff[][MCL_BS], int n) { static uint8_t buf[2048]; static mcl_octet temp = {0, sizeof(buf), buf}; if (!title) { title = ""; } MCL_FF_toOctet_C25519(&temp, ff, n); #ifdef MSB_FIRST printf("%s\n", title); MCL_OCT_output(&temp); printf("\n"); #else display_binary_data(temp.val, temp.len, true, title); #endif }
/** * @brief Print out the data/payload associated with the FTF header element table * * @param romimage Pointer to the FFFF to display * @param header Pointer to the FFFF header element descriptor to display * @param title_string Optional title string * @param indent Optional prefix string * * @returns Nothing */ static void print_ffff_element_data(const struct ffff *romimage, const ffff_header * ffff_hdr, const char * title_string, const char * indent) { int index; const ffff_element_descriptor * element; const tftf_header * tftf_hdr; bool data_is_tftf; char indent_buf[256]; char indent_data_buf[256]; if (ffff_hdr) { int index; const ffff_element_descriptor * element = ffff_hdr->elements; uint8_t * pdata = NULL; /* Format the indent for the binary data */ if (!indent) { indent = ""; } snprintf(indent_buf, sizeof(indent_buf), "%s ", indent); snprintf(indent_data_buf, sizeof(indent_buf), "%s ", indent); /* 1. Print the title line */ if (title_string) { printf("%s%s:\n", indent, title_string); } else { printf("%sFFFF contents:\n", indent); } /* 2. Print the associated data blobs */ for (index = 0, element = ffff_hdr->elements; ((index < ffff_max_elements) && (element->element_type != FFFF_ELEMENT_END)); index++, element++) { /* Print a generic element header */ printf("%selement [%d] (%s) (%d bytes):\n", indent_buf, index, ffff_element_type_name(element->element_type), element->element_length); /* Print the element data proper */ tftf_hdr = (const tftf_header *)&romimage->blob[element->element_location]; if (sniff_tftf_header(tftf_hdr)) { /* We know how to print TFTF elements */ print_tftf(tftf_hdr, ffff_element_type_name(element->element_type), indent_data_buf); } else { /* No idea what format it has, use a data dump */ display_binary_data(&romimage->blob[element->element_location], element->element_length, false, indent_data_buf); } } } printf("\n"); }