예제 #1
0
파일: start.c 프로젝트: projectara/bootrom
/**
 * @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);
}
예제 #2
0
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:;
}