/** * @brief Stage 2 loader "C" entry point. Started from Stage 1 * bootloader. Primary function is to load, validate, and start * executing a stage 3 image. Also will (when fully implemented) * perform startup negotiations with AP, cryptographic initialzations * and tests, module authentication, flash update, and other housekeeping. * Image load and validation are essntially identical to the crresponding * functions in stage 1, although different keys are used for signature * validation. * * @param none * * @returns Nothing. Will launch/restart image if successful, halt if not. */ void bootrom_main(void) { int rc; /* TA-20 R/W data in bufRAM */ uint32_t boot_status = INIT_STATUS_OPERATING; bool boot_from_spi = true; bool fallback_boot_unipro = false; uint32_t is_secure_image; secondstage_cfgdata *cfgdata; chip_init(); dbginit(); /* Ensure that we start each boot with an assumption of success */ init_last_error(); crypto_init(); dbgprint("\nHello world from s2fw\n"); if (!get_2ndstage_cfgdata(&cfgdata)) { dbgprint("found valid config data\n"); if (cfgdata->use_fake_ims) { /** * We don't really need to handle all the efuses as boot ROM * does. But we do want to update the EPUID according to the * fake IMS. And the rest of the efuse handling do no harm * anyway. */ if (efuse_init() != 0) { halt_and_catch_fire(boot_status); } } } uint8_t ims[TSB_ISAA_NUM_IMS_BYTES]; tsb_get_ims(ims, TSB_ISAA_NUM_IMS_BYTES); key_generation(ims); chip_unipro_init(); boot_control(&boot_from_spi); /* Advertise our boot status */ chip_advertise_boot_status(boot_status); /* Advertise our initialization type */ rc = chip_advertise_boot_type(); if (rc) { halt_and_catch_fire(boot_status); } if (boot_from_spi) { dbgprint("Boot from SPIROM\n"); spi_ops.init(); /** * Call locate_ffff_element_on_storage to locate next stage FW. * Do not care about the image length here so pass NULL. */ if (locate_ffff_element_on_storage(&spi_ops, FFFF_ELEMENT_STAGE_3_FW, NULL) == 0) { boot_status = INIT_STATUS_SPI_BOOT_STARTED; chip_advertise_boot_status(boot_status); if (!load_tftf_image(&spi_ops, &is_secure_image)) { spi_ops.finish(true, is_secure_image); if (is_secure_image) { boot_status = INIT_STATUS_TRUSTED_SPI_FLASH_BOOT_FINISHED; dbgprintx32("SPI Trusted: (", merge_errno_with_boot_status(boot_status), ")\n"); } else { boot_status = INIT_STATUS_UNTRUSTED_SPI_FLASH_BOOT_FINISHED; dbgprintx32("SPI Untrusted: (", merge_errno_with_boot_status(boot_status), ")\n"); /* * Disable IMS, CMS access before starting untrusted image. * NB. JTAG continues to be not enabled at this point */ efuse_rig_for_untrusted(); } /* Log that we're starting the boot-from-SPIROM */ chip_advertise_boot_status(merge_errno_with_boot_status(boot_status)); /* TA-16 jump to SPI code (BOOTRET_o = 0 && SPIBOOT_N = 0) */ jump_to_image(); } } spi_ops.finish(false, false); /* Fallback to UniPro boot */ boot_from_spi = false; fallback_boot_unipro = true; chip_clear_image_loading_ram(); } else { /* (Not boot-from-spi, */ fallback_boot_unipro = false; } if (greybus_init()) { set_last_error(BRE_BOU_GBCTRL_CPORT); halt_and_catch_fire(boot_status); } /* Boot-Over-UniPro... * We get here if directed to do so by the bootselector, or as a fallback * for a failed SPIROM boot. */ if (!boot_from_spi) { /* Boot over Unipro */ if (fallback_boot_unipro) { boot_status = merge_errno_with_boot_status( INIT_STATUS_FALLLBACK_UNIPRO_BOOT_STARTED); dbgprintx32("Spi boot failed (", boot_status, "), "); } else { boot_status = INIT_STATUS_UNIPRO_BOOT_STARTED; } chip_advertise_boot_status(boot_status); dbgprintx32("Boot over UniPro (", merge_errno_with_boot_status(boot_status), ")\n"); advertise_ready(); #if RUN_SPI_TEST spi_gb_init(); dbgprint("Running in loop to perform as SPI over Greybus\n"); while (1) { if (greybus_loop()) { dbgprint("ERROR in greuybus loop\n"); halt_and_catch_fire(boot_status); } } #endif dbgprint("Ready-poked; download-ready\n"); if (greybus_ops.init() != 0) { halt_and_catch_fire(boot_status); } if (!load_tftf_image(&greybus_ops, &is_secure_image)) { if (greybus_ops.finish(true, is_secure_image) != 0) { halt_and_catch_fire(boot_status); } if (is_secure_image) { boot_status = fallback_boot_unipro ? INIT_STATUS_FALLLBACK_TRUSTED_UNIPRO_BOOT_FINISHED : INIT_STATUS_TRUSTED_UNIPRO_BOOT_FINISHED; dbgprintx32("UP Trusted: (", merge_errno_with_boot_status(boot_status), ")\n"); } else { boot_status = fallback_boot_unipro ? INIT_STATUS_FALLLBACK_UNTRUSTED_UNIPRO_BOOT_FINISHED : INIT_STATUS_UNTRUSTED_UNIPRO_BOOT_FINISHED; dbgprintx32("UP Trusted: (", merge_errno_with_boot_status(boot_status), ")\n"); /* * Disable IMS, CMS access before starting * untrusted image * NB. JTAG continues to be not enabled at this point */ efuse_rig_for_untrusted(); } /* Log that we're starting the boot-from-UniPro */ chip_advertise_boot_status(boot_status); /* TA-17 jump to Workram code (BOOTRET_o = 0 && SPIM_BOOT_N = 1) */ jump_to_image(); } if (greybus_ops.finish(false, is_secure_image) != 0) { halt_and_catch_fire(boot_status); } } /* If we reach here, we didn't find an image to boot - stop while we're * ahead... */ halt_and_catch_fire(boot_status); }
void main() { uint8 seed[16]; //seed for DRNG uint8 rndnum[30]; //233-bit random numbers uint32 i, r; ec_key_pair keypair; uint8 Uid[26] = {0x00,0x0d,0x6f,0x00,0x00,0x06,0x7a,0x1f,0x54,0x45,0x53,0x54,0x53,0x45,0x43,0x41,0x01,0x09,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00}; //The following are for ECMQV ec_key_pair keyA1, keyA2, keyB1, keyB2; uint8 skey[30]; //The following are for ECDSA uint32 s[8], t[8]; for(i = 0; i < 16; i++) seed[i] = 0x0; srand((unsigned) time (NULL)); for(i = 0; i < 8; i++) { r = rand(); seed[2*i] = (uint8)r; seed[2*i + 1] = (uint8)(r >> 8); } printf("Seed = ");for(i = 0; i < 16; i++){printf("%02x ",seed[i]);}printf("\n"); //Initialize the DRNG ctr_init(seed); for(i = 0; i < 30; i++) rndnum[i] = 0x0; //ECMQV testing with curve sect233k1 if(ctr_generate(232, rndnum) == 1) key_generation(&keyA1, rndnum, sect233k1); if(ctr_generate(232, rndnum) == 1) key_generation(&keyA2, rndnum, sect233k1); if(ctr_generate(232, rndnum) == 1) key_generation(&keyB1, rndnum, sect233k1); if(ctr_generate(232, rndnum) == 1) key_generation(&keyB2, rndnum, sect233k1); printf("\nTwo key pairs for the user A...\n"); printf("The first private key:\n"); printf(" dA1 = ");for(i = 0; i < 8; i++){printf("%08x ",keyA1.d[7 - i]);}printf("\n"); printf("The first public key:\n"); printf(" QA1x = ");for(i = 0; i < 8; i++){printf("%08x ",keyA1.Qx[7 - i]);}printf("\n"); printf("The second private key:\n"); printf(" dA2 = ");for(i = 0; i < 8; i++){printf("%08x ",keyA2.d[7 - i]);}printf("\n"); printf("The second public key:\n"); printf(" QA2x = ");for(i = 0; i < 8; i++){printf("%08x ",keyA2.Qx[7 - i]);}printf("\n"); printf("\nTwo key pairs for the user B...\n"); printf("The first private key:\n"); printf(" dB1 = ");for(i = 0; i < 8; i++){printf("%08x ",keyB1.d[7 - i]);}printf("\n"); printf("The first public key:\n"); printf(" QB1x = ");for(i = 0; i < 8; i++){printf("%08x ",keyB1.Qx[7 - i]);}printf("\n"); printf("The second private key:\n"); printf(" dB2 = ");for(i = 0; i < 8; i++){printf("%08x ",keyB2.d[7 - i]);}printf("\n"); printf("The second public key:\n"); printf(" QB2x = ");for(i = 0; i < 8; i++){printf("%08x ",keyB2.Qx[7 - i]);}printf("\n"); printf("\nECMQV Key Agreement..."); if(ECMQV(&keyA1, &keyA2, keyB1.Qx, keyB2.Qx, 30, skey, sect233k1) == 1) { printf("The shared key computed by A:\n"); printf(" skA = ");for(i = 0; i < 30; i++){printf("%02x",skey[i]);}printf("\n"); } else { printf("ERROR!\n"); goto L; } if(ECMQV(&keyB1, &keyB2, keyA1.Qx, keyA2.Qx, 30, skey, sect233k1) == 1) { printf("The shared key computed by B:\n"); printf(" skB = ");for(i = 0; i < 30; i++){printf("%02x",skey[i]);}printf("\n"); } else printf("ERROR!\n"); //ECDSA testing with curve sect233k1 printf("\nECDSA Signature Generation...\n"); if(ctr_generate(232, rndnum) == 1) key_generation(&keypair,rndnum, sect233k1); printf("Signer's Private key:\n"); printf(" k = ");for(i = 0; i < 8; i++){printf("%08x ",keypair.d[7 - i]);}printf("\n"); printf("Signer's Public key:\n"); printf(" x = ");for(i = 0; i < 8; i++){printf("%08x ",keypair.Qx[7 - i]);}printf("\n"); printf("Message:\n"); printf("msg = ");for(i = 0; i < 26; i++){printf("%02x",Uid[i]);}printf("\n"); ctr_generate(232, rndnum); if(ECDSA_sign(keypair.d, rndnum, Uid, 26, s, t, sect233k1) == 1) { printf("The signature are:\n"); printf(" r = ");for(i = 0; i < 8; i++){printf("%08x ",s[7 - i]);}printf("\n"); printf(" s = ");for(i = 0; i < 8; i++){printf("%08x ",t[7 - i]);}printf("\n"); } else { printf("ERROR!\n"); goto L; } if(ECDSA_verify(keypair.Qx, Uid, 26, s, t, sect233k1) == 1) printf("The signature is valid!\n"); else printf("The signature is invalid!\n"); L:; }