Ejemplo n.º 1
1
int main()
{

    uint8_t a_pub[ECC_BYTES+1];
    uint8_t a_pri[ECC_BYTES];

    uint8_t b_pub[ECC_BYTES+1];
    uint8_t b_pri[ECC_BYTES];

    uint8_t a_secret[ECC_BYTES];
    uint8_t b_secret[ECC_BYTES];

    uint8_t p_signature[ECC_BYTES*2];

    uint8_t a_hash[SHA256_BLOCK_SIZE];
    uint8_t b_hash[SHA256_BLOCK_SIZE];

    SHA256_CTX ctx;

    int errid = 0;
    int i=0;

    /* print ECC_CURVE parameter */
    print_parameter(ECC_CURVE);

    /* make key */
    errid = ecc_make_key(a_pub,a_pri);
    if(errid != 1){
        printf("[ecc_make _key] error!!!");
        return -1;
    }
    printf("A key pair generation completed...\n");


    errid = ecc_make_key(b_pub,b_pri);
    if(errid != 1){
        printf("[ecc_make _key] error!!!");
        return -1;
    }
    printf("B key pair generation completed...\n");

    /* compute shared secret */
    errid = ecdh_shared_secret(b_pub,a_pri,a_secret);
    if(errid != 1){
        printf("[ecdh_sharedS_secret]error!!!");
        return -1;
    }
    printf("A shared_secret generation completed...\n");

    errid = ecdh_shared_secret(a_pub,b_pri,b_secret);
    if(errid != 1){
        printf("[ecdh_sharedS_secret]error!!!");
        return -1;
    }
    printf("B shared_secret generation completed...\n");

    hash_sha256(a_secret,a_hash);
    if(errid != 1){
        printf("[hash_sha256]error!!!");
        return -1;
    }
    printf("A shared_secret hash completed...\n");

    hash_sha256(b_secret,b_hash);
    if(errid != 1){
        printf("[hash_sha256]error!!!");
        return -1;
    }
    printf("B shared_secret hash completed...\n");


    /* sign */
    errid = ecdsa_sign(a_pri,a_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_sign]error!!!");
        return -1;
    }

    /* verify */
    errid = ecdsa_verify(a_pub,a_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_verify]error!!!");
        return -1;
    }else{
        printf("success \n");
    }

    errid = ecdsa_sign(b_pri,b_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_sign]error!!!");
        return -1;
    }

    /* verify */
    errid = ecdsa_verify(b_pub,b_hash,p_signature);
    if(errid != 1){
        printf("[ecdsa_verify]error!!!");
        return -1;
    }else{
        printf("success \n");
    }

    return 0;
}
Ejemplo n.º 2
0
END_TEST

START_TEST(test_sign_speed)
{
	uint8_t sig[64], priv_key[32], msg[256];
	size_t i;
	int res;

	for (i = 0; i < sizeof(msg); i++) {
		msg[i] = i * 1103515245;
	}

	clock_t t = clock();

	memcpy(priv_key, fromhex("c55ece858b0ddd5263f96810fe14437cd3b5e1fbd7c6a2ec1e031f05e86d8bd5"), 32);
	for (i = 0 ; i < 250; i++) {
		res = ecdsa_sign(priv_key, msg, sizeof(msg), sig);
		ck_assert_int_eq(res, 0);
	}

	memcpy(priv_key, fromhex("509a0382ff5da48e402967a671bdcde70046d07f0df52cff12e8e3883b426a0a"), 32);
	for (i = 0 ; i < 250; i++) {
		res = ecdsa_sign(priv_key, msg, sizeof(msg), sig);
		ck_assert_int_eq(res, 0);
	}

	printf("Signing speed: %0.2f sig/s\n", 500.0f / ((float)(clock() - t) / CLOCKS_PER_SEC));
}
Ejemplo n.º 3
0
/*
 *		Certificate info:
 *				- id: requester identification
 *				- cname: common name
 *				- time: date on which the certificate has been generated
 *				- valid: date up to the certificate is valid
 *				- auth_key: key used in mutual authentication (SMQV)
 *				- token_key: key used to sign access token (MSS)
 *				- signature: signature under issuer's key
 *
 */
void generate_certificate(const unsigned char csr[CSR_MAX_SIZE], const char valid[TIME_BUFFER_SIZE], const unsigned char ca_skey[ECDSA_SKEY_SIZE], unsigned char certificate[CERTIFICATE_MAX_SIZE]) {
	unsigned int id;
	char cname[CNAME_MAX_SIZE], time[TIME_BUFFER_SIZE];
	unsigned char auth_key[SMQV_PKEY_SIZE], token_key[MSS_PKEY_SIZE], cert_signature[ECDSA_SIGNATURE_SIZE], csr_signature[MSS_SIGNATURE_SIZE];
	unsigned char buffer[CERTIFICATE_MAX_SIZE];
	memset(buffer, 0, CERTIFICATE_MAX_SIZE);

	now(&time);

	if(compare_dates(valid, time) == -1 && read_csr(&id, cname, time, auth_key, token_key, csr_signature, csr)) {
		unsigned int index = 0;

		index += cert_append_info(buffer, id, cname, time, valid, auth_key, token_key);

		unsigned char cert_digest[2 * MSS_SEC_LVL];
        	sponge_hash(buffer, index, cert_digest, 2 * MSS_SEC_LVL);
		ecdsa_sign(ca_skey, cert_digest, cert_signature);
		memcpy(buffer + index, cert_signature, ECDSA_SIGNATURE_SIZE);
		index += ECDSA_SIGNATURE_SIZE;

		base64encode(buffer, index, certificate, CSR_MAX_SIZE);
	}
	else{
    certificate[0] = '\0';
		if( compare_dates(valid, time) != -1)
			printf("Authentication ERROR: !(valid > t_now)\n");
		else
			printf("Authentication ERROR: !mss_verify\n");
  }
}
Ejemplo n.º 4
0
//TODO: The fwrite/fread error checking was broken.
//Maybe the MS runtime is returning the number of bytes written instead of the element count?
BOOL __stdcall np_sign_file(s8 *fname)
{
	u8 padding_data[0x10] = 
	{
		0xbc, 0x3f, 0x7a, 0x48, 0xaf, 0x45, 0xef, 0x28, 0x3a, 0x05, 0x98, 0x10, 0xbc, 0x3f, 0x7a, 0x48
	};

	keyset_t *ks;
	FILE *fp = NULL;
	u8 *buffer = NULL;
	u32 length;
	u32 padding;
	u8 hash[0x14], R[0x15], S[0x15];

	//Try to find keyset.
	if((ks = keyset_find_by_name(CONFIG_NP_SIG_KNAME)) == NULL)
		return FALSE;

	if((fp = fopen(fname, "r+b")) == NULL)
		return FALSE;

	fseek(fp, 0, SEEK_END);
	length = ftell(fp);

	padding = length % 0x10;
	if(padding > 0)
	{
		fwrite(padding_data, sizeof(u8), padding, fp);
		length += padding;
	}

	fseek(fp, 0, SEEK_SET);
	if((buffer = (u8 *)calloc(length, sizeof(char))) == NULL)
	{
		fclose(fp);
		return FALSE;
	}
	fread(buffer, sizeof(u8), length, fp);

	//Generate header hash.
	sha1(buffer, length, hash);

	//Generate signature.
	/* TODO: Set the right curve and private key */
	ecdsa_set_curve(ks->ctype | USE_VSH_CURVE);
	ecdsa_set_pub(ks->pub);
	ecdsa_set_priv(ks->priv);
	ecdsa_sign(hash, R, S);
	fseek(fp, 0, SEEK_END);
	fwrite(R + 1, 0x14, 1, fp);
	fwrite(S + 1, 0x14, 1, fp);
	/* Let's be as stupid as sony here... */
	fwrite(hash + 0xC, 8, 1, fp);

	free(buffer);
	fclose(fp);

	return TRUE;
}
Ejemplo n.º 5
0
int add_npdrm_footer_sig(const char *filename) {
  FILE *fp; 

  uint8_t s[21]; 
  uint8_t r[21]; 
  uint8_t hash[20]; 

  static char padding[] = {
	0x8b, 0x3f, 0x7a,0x48,
	0xaf, 0x45, 0xef, 0x28,
	0x3a, 0x05, 0x98, 0x10,
	0xbc, 0x3f, 0x7a, 0x48
  };
  
  keyset_t *keyset = find_keyset_by_name("NP_sig");
  
  if ( !keyset)
	return 0;
	
  fp = fopen(filename, "r+b");
  if (!fp)
    return 0;
	
  fseek(fp, 0, SEEK_END);
  size_t size = ftell (fp);
  // Error ? SCETool takes left_not_aligned as (size & 0xF)
  size_t left_not_aligned = (0x10 - (size & 0xF)) & 0x0F;
  if (left_not_aligned) {
    fwrite(padding, 1, left_not_aligned, fp);
    size += left_not_aligned;
  }
  fseek(fp, 0, SEEK_SET);
  uint8_t *buffer = malloc(size);
  if (!buffer)  {
    fclose(fp);
    return 0;
  }

  if(fread(buffer, 1, size, fp) != size)
    return 0;
    
  
  sha1(buffer, size, hash);
  
  ecdsa_set_curve(keyset->ctype | 0x40);
  ecdsa_set_pub(keyset->pub_key);
  ecdsa_set_priv(keyset->priv_key);
  ecdsa_sign(r, s, hash);
  
  fseek(fp, 0, SEEK_END); 
  fwrite(&r[1], 20, 1, fp);
  fwrite(&s[1], 20, 1, fp);
  fwrite(&hash[12], 8, 1, fp);
  
  free(buffer);
  fclose(fp);  
  return 1;
}
Ejemplo n.º 6
0
int edata_sign_free(u8 *edata_buf, u8 *pgd_key)
{
	MAC_KEY mkey;
	AES_ctx aes;
	u8 sha1_hash[20], license_key[16];
	int flag, i;

	printf("re-sign EDATA ...\n");

	flag = *(u8*)(edata_buf+15);

	// get license_key
	if(flag&1){
		sceDrmBBMacInit(&mkey, 3);
		sceDrmBBMacUpdate(&mkey, edata_buf, 0x80);
		bbmac_getkey(&mkey, edata_buf+0x80, license_key);
		if(verbose) hex_dump("license key", license_key, 16);
	}

	// change to use free license
	*(u32*)(edata_buf+8) = 0x01000000;

	// build ecdsa
	ecdsa_set_curve(&ecdsa_app);
	ecdsa_set_priv(priv_key_edata);
	SHA1(edata_buf, 0x58, sha1_hash);
	ecdsa_sign(sha1_hash, edata_buf+0x58, edata_buf+0x6c, NULL);

	// build BBMAC
	if(flag&1){
		sceDrmBBMacInit(&mkey, 3);
		sceDrmBBMacUpdate(&mkey, edata_buf, 0x80);
		sceDrmBBMacFinal(&mkey, edata_buf+0x80, license_key);
		bbmac_build_final2(3, edata_buf+0x80);
	}

	// build PGD key
	sceNpDrmGetFixedKey(pgd_key, (char*)(edata_buf+16), 0x01000000);
	if(verbose) hex_dump("get_fixed_key", pgd_key, 16);

	if(flag&1){
		for(i=0; i<16; i++){
			pgd_key[i] ^= license_key[i];
		}
	}

	AES_set_key(&aes, edat_aeskey, 128);
	AES_decrypt(&aes, pgd_key, pgd_key);
	if(verbose) hex_dump("new PGD key", pgd_key, 16);

	return 0;
}
Ejemplo n.º 7
0
static void
bench_ecdsa_sign (void *p)
{
  struct ecdsa_ctx *ctx = p;
  struct dsa_signature s;

  dsa_signature_init (&s);
  ecdsa_sign (&ctx->key,
	      &ctx->rctx, (nettle_random_func *) knuth_lfib_random,
	      ctx->digest_size, ctx->digest,
	      &s);
  dsa_signature_clear (&s);
}
Ejemplo n.º 8
0
static void sign_hdr(void)
{
	u8 *r, *s;
	u8 hash[20];
	u64 sig_len;

	sig_len = be64(self + meta_offset + 0x60);
	r = self + sig_len;
	s = r + 21;

	sha1(self, sig_len, hash);

	ecdsa_sign(hash, r, s);
}
Ejemplo n.º 9
0
static void sign_hdr(void)
{
	u8 *r, *s;
	u8 hash[20];
	u64 sig_len;

	sig_len = be64(pkg + 0x60);
	r = pkg + sig_len;
	s = r + 21;

	sha1(pkg, sig_len, hash);

	ecdsa_sign(hash, r, s);
}
Ejemplo n.º 10
0
int main(){
  unsigned char key[48];
  unsigned char pkey[96];
  unsigned char digest[48];
  unsigned char signature[96];
  for(int i=0; i<1000; i++){
    randombytes(key, 48);
    randombytes(digest, 48);
    key[47]=0;
    p384_32_scalarmult_base(pkey, key);
    ecdsa_sign(signature, digest, key);
    if(!ecdsa_verify(signature, digest, pkey)){
      printf("Ecdsa failure to verify valid signature\n");
    }
    digest[0]=digest[0]+1;
    if(ecdsa_verify(signature,digest,pkey)){
      printf("Ecdsa failure to reject invalid signature\n");
    }
  }
}
Ejemplo n.º 11
0
// Send a SIGnature record, containing an ECDSA signature over both KEX records.
static bool send_sig(sptps_t *s) {
	size_t keylen = ECDH_SIZE;
	size_t siglen = ecdsa_size(s->mykey);

	// Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label
	char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
	char sig[siglen];

	msg[0] = s->initiator;
	memcpy(msg + 1, s->mykex, 1 + 32 + keylen);
	memcpy(msg + 1 + 33 + keylen, s->hiskex, 1 + 32 + keylen);
	memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen);

	// Sign the result.
	if(!ecdsa_sign(s->mykey, msg, sizeof msg, sig))
		return error(s, EINVAL, "Failed to sign SIG record");

	// Send the SIG exchange record.
	return send_record_priv(s, SPTPS_HANDSHAKE, sig, sizeof sig);
}
Ejemplo n.º 12
0
int main() {
	unsigned char skey[ECDSA_SKEY_SIZE], pkey[ECDSA_PKEY_SIZE], digest[ECDSA_DIGEST_SIZE], signature[ECDSA_SIGNATURE_SIZE];
	printf("ECDSA key generation... ");
	ecdsa_keygen(skey, pkey);
	printf("done!\n");
	Display("ECDSA skey:", skey, ECDSA_SKEY_SIZE);
	Display("ECDSA pkey:", pkey, ECDSA_PKEY_SIZE);
	printf("---------------\n");
	Display("digest:", digest, ECDSA_DIGEST_SIZE);
	printf("ECDSA signature... ");
	ecdsa_sign(skey, digest, signature);
	printf("done!\n");
	Display("signature:", signature, ECDSA_SIGNATURE_SIZE);
	printf("ECDSA verification... \n");
	if(ecdsa_verify(pkey, digest, signature))
		printf("ECDSA - OK\n");
	else
		printf("ECDSA - FAIL\n");
	return 0;
}
Ejemplo n.º 13
0
static void bacast_signed_message()
{
        msg_header_t* header;
        uint8_t* data;
        packetbuf_clear();
        header = ( msg_header_t* ) ( packetbuf_dataptr() );
        data = ( uint8_t* ) ( header + 1 );

        random_data ( data, MSG_LEN );

        hton_uint16 ( &header->data_len, MSG_LEN );

	static struct etimer nrg;
	energest_flush();
        ENERGEST_ON ( ENERGEST_TYPE_LPM );
        ENERGEST_ON ( ENERGEST_TYPE_TRANSMIT );
        ENERGEST_ON ( ENERGEST_TYPE_LISTEN );
        ENERGEST_ON ( ENERGEST_TYPE_CPU );
        last.cpu = energest_type_time ( ENERGEST_TYPE_CPU )/RTIMER_SECOND;
        ENERGEST_OFF ( ENERGEST_TYPE_CPU );
        last.lpm = energest_type_time ( ENERGEST_TYPE_LPM );
        last.transmit = energest_type_time ( ENERGEST_TYPE_TRANSMIT );
        last.listen = energest_type_time ( ENERGEST_TYPE_LISTEN );
        ENERGEST_ON ( ENERGEST_TYPE_CPU );

        ecdsa_sign ( data, MSG_LEN, header->r, header->s, prKey_alice );

        diff.cpu = energest_type_time ( ENERGEST_TYPE_CPU ) - last.cpu;
        diff.lpm = energest_type_time ( ENERGEST_TYPE_LPM ) - last.lpm;
        diff.transmit = energest_type_time ( ENERGEST_TYPE_TRANSMIT ) - last.transmit;
        diff.listen = energest_type_time ( ENERGEST_TYPE_LISTEN ) - last.listen;

        ENERGEST_OFF ( ENERGEST_TYPE_CPU );
        ENERGEST_OFF ( ENERGEST_TYPE_LPM );
        ENERGEST_OFF ( ENERGEST_TYPE_TRANSMIT );
        ENERGEST_OFF ( ENERGEST_TYPE_LISTEN );

        packetbuf_set_datalen ( sizeof ( msg_header_t ) + MSG_LEN );
        abc_send ( &abc );
	printf ( "Clock ticks recorded by\nCPU = %ld \nLPM = %ld \nTRANSMITTER = %ld\nRECEIVER = %ld\n",diff.cpu, diff.lpm, diff.transmit, diff.listen );
}
Ejemplo n.º 14
0
int main(int argc, char * argv[])
{
	uint8_t hash[SHA256_DIGEST_LENGTH] = {0};
	NN_DIGIT signature_r[NUMWORDS], signature_s[NUMWORDS];
	NN_DIGIT privKey[NUMWORDS];
	point_t pubKey;
	uint8_t data [52] = {
		1, 2, 3, 4, 5
	};
	SHA256_CTX ctx;

	memset(privKey, 0, NUMBYTES);
	memset(&pubKey, 0, sizeof(pubKey));
	memset(signature_r, 0, NUMBYTES);
	memset(signature_s, 0, NUMBYTES);


	SHA256_Init(&ctx);
	SHA256_Update(&ctx, data, 52);
	SHA256_Final(hash, &ctx);

	ecc_init();

	ecc_gen_private_key(privKey);
	ecc_gen_pub_key(privKey, &pubKey);

	ecdsa_init(&pubKey);

	ecdsa_sign(hash, signature_r, signature_s, privKey);

	assert(ecdsa_verify(hash, signature_r, signature_s, &pubKey) == 1);

	signature_r[0] ^= 0xff;

	assert(ecdsa_verify(hash, signature_r, signature_s, &pubKey) != 1);

	return 0;
}
Ejemplo n.º 15
0
// func. to ECDSA sign the SPP sections
int sign_spp(u8* pInSpp)
{
	u8 *r, *s = NULL;
	u8 hash[20] = {0};
	u64 sig_len = 0;
	mpi r1;
	mpi s1;
	int retval = -1;

	// validate input params
	if (pInSpp == NULL)
		goto exit;

	// init the mpi
	mpi_init(&r1);
	mpi_init(&s1);

	// setup the 'signature len'
	sig_len = be64(pInSpp + 0x60);
	r = pInSpp + sig_len;
	s = r + 21;

	// sha1 the hash
	sha1(pInSpp, (size_t)sig_len, hash);

	// ecdsa sign the hash
	if ( ecdsa_sign(&ecdsa_ctx.grp, (mpi*)&r1, (mpi*)&s1, &ecdsa_ctx.d, hash, ECDSA_KEYSIZE_PRIV, get_random_char, NULL) == STATUS_SUCCESS ) {		
		mpi_write_binary(&r1, (unsigned char*)r, ECDSA_KEYSIZE_PRIV);
		mpi_write_binary(&s1, (unsigned char*)s, ECDSA_KEYSIZE_PRIV);

		// status success
		retval = STATUS_SUCCESS;
	}

exit:
	return retval;	
}
Ejemplo n.º 16
0
static void *
bench_ecdsa_init (unsigned size)
{
  struct ecdsa_ctx *ctx;
  const struct ecc_curve *ecc;

  const char *xs;
  const char *ys;
  const char *zs;
  mpz_t x, y, z;
  
  ctx = xalloc (sizeof(*ctx));

  dsa_signature_init (&ctx->s);  
  knuth_lfib_init (&ctx->rctx, 17);

  switch (size)
    {
    case 192:
      ecc = &_nettle_secp_192r1;
      xs = "8e8e07360350fb6b7ad8370cfd32fa8c6bba785e6e200599";
      ys = "7f82ddb58a43d59ff8dc66053002b918b99bd01bd68d6736";
      zs = "f2e620e086d658b4b507996988480917640e4dc107808bdd";
      ctx->digest = hash_string (&nettle_sha1, "abc");
      ctx->digest_size = 20;
      break;
    case 224:
      ecc = &_nettle_secp_224r1;
      xs = "993bf363f4f2bc0f255f22563980449164e9c894d9efd088d7b77334";
      ys = "b75fff9849997d02d135140e4d0030944589586e22df1fc4b629082a";
      zs = "cdfd01838247f5de3cc70b688418046f10a2bfaca6de9ec836d48c27";
      ctx->digest = hash_string (&nettle_sha224, "abc");
      ctx->digest_size = 28;
      break;

      /* From RFC 4754 */
    case 256:
      ecc = &_nettle_secp_256r1;
      xs = "2442A5CC 0ECD015F A3CA31DC 8E2BBC70 BF42D60C BCA20085 E0822CB0 4235E970";
      ys = "6FC98BD7 E50211A4 A27102FA 3549DF79 EBCB4BF2 46B80945 CDDFE7D5 09BBFD7D";
      zs = "DC51D386 6A15BACD E33D96F9 92FCA99D A7E6EF09 34E70975 59C27F16 14C88A7F";
      ctx->digest = hash_string (&nettle_sha256, "abc");
      ctx->digest_size = 32;
      break;
    case 384:
      ecc = &_nettle_secp_384r1;
      xs = "96281BF8 DD5E0525 CA049C04 8D345D30 82968D10 FEDF5C5A CA0C64E6 465A97EA"
	"5CE10C9D FEC21797 41571072 1F437922";
      ys = "447688BA 94708EB6 E2E4D59F 6AB6D7ED FF9301D2 49FE49C3 3096655F 5D502FAD"
	"3D383B91 C5E7EDAA 2B714CC9 9D5743CA";
      zs = "0BEB6466 34BA8773 5D77AE48 09A0EBEA 865535DE 4C1E1DCB 692E8470 8E81A5AF"
	"62E528C3 8B2A81B3 5309668D 73524D9F";
      ctx->digest = hash_string (&nettle_sha384, "abc");
      ctx->digest_size = 48;
      break;
    case 521:
      ecc = &_nettle_secp_521r1;
      xs = "0151518F 1AF0F563 517EDD54 85190DF9 5A4BF57B 5CBA4CF2 A9A3F647 4725A35F"
	"7AFE0A6D DEB8BEDB CD6A197E 592D4018 8901CECD 650699C9 B5E456AE A5ADD190"
	"52A8";
      ys = "006F3B14 2EA1BFFF 7E2837AD 44C9E4FF 6D2D34C7 3184BBAD 90026DD5 E6E85317"
	"D9DF45CA D7803C6C 20035B2F 3FF63AFF 4E1BA64D 1C077577 DA3F4286 C58F0AEA"
	"E643";
      zs = "0065FDA3 409451DC AB0A0EAD 45495112 A3D813C1 7BFD34BD F8C1209D 7DF58491"
	"20597779 060A7FF9 D704ADF7 8B570FFA D6F062E9 5C7E0C5D 5481C5B1 53B48B37"
	"5FA1";

      ctx->digest = hash_string (&nettle_sha512, "abc");
      ctx->digest_size = 64;
      break;
    default:
      die ("Internal error.\n");
    }
  ecc_point_init (&ctx->pub, ecc);
  ecc_scalar_init (&ctx->key, ecc);

  mpz_init_set_str (x, xs, 16);
  mpz_init_set_str (y, ys, 16);
  mpz_init_set_str (z, zs, 16);

  ecc_point_set (&ctx->pub, x, y);
  ecc_scalar_set (&ctx->key, z);

  mpz_clear (x);
  mpz_clear (y);
  mpz_clear (z);

  ecdsa_sign (&ctx->key,
	      &ctx->rctx, (nettle_random_func *) knuth_lfib_random,
	      ctx->digest_size, ctx->digest,
	      &ctx->s);

  return ctx;
}
Ejemplo n.º 17
0
static void promptRegister(bool request, const U2F_REGISTER_REQ *req)
{
#if 0
	// Users find it confusing when a Ledger and a KeepKey are plugged in
	// at the same time. To avoid that, we elect not to show a message in
	// this case.
	if (0 == memcmp(req->appId, BOGUS_APPID, U2F_APPID_SIZE)) {
		layoutU2FDialog(request, "U2f Register",
		                "Another U2F device was used to register in this application.");
	} else {
#else
	{
#endif
		const char *appname = "";
		bool readable = getReadableAppId(req->appId, &appname);
		layoutU2FDialog(request, "U2F Register",
		                readable
		                    ? "Do you want to register with %s?"
		                    : "Do you want to register with this U2F application?\n\n%s",
		                appname);
	}
}

void u2f_register(const APDU *a)
{
	static U2F_REGISTER_REQ last_req;
	const U2F_REGISTER_REQ *req = (U2F_REGISTER_REQ *)a->data;

	if (!storage_isInitialized()) {
		layout_warning_static("Cannot register u2f: not initialized");
		send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
		delay_ms(3000);
		return;
	}

	// Validate basic request parameters
	debugLog(0, "", "u2f register");
	if (APDU_LEN(*a) != sizeof(U2F_REGISTER_REQ)) {
		debugLog(0, "", "u2f register - badlen");
		send_u2f_error(U2F_SW_WRONG_LENGTH);
		return;
	}

	// If this request is different from last request, reset state machine
	if (memcmp(&last_req, req, sizeof(last_req)) != 0) {
		memcpy(&last_req, req, sizeof(last_req));
		last_req_state = INIT;
	}

	// First Time request, return not present and display request dialog
	if (last_req_state == INIT) {
		// error: testof-user-presence is required
		//buttonUpdate();
		promptRegister(true, req);
		last_req_state = REG;
	}

	// Still awaiting Keypress
	if (last_req_state == REG) {
		// error: testof-user-presence is required
		send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
		dialog_timeout = U2F_TIMEOUT;
		return;
	}

	// Buttons said yes
	if (last_req_state == REG_PASS) {
		uint8_t data[sizeof(U2F_REGISTER_RESP) + 2];
		U2F_REGISTER_RESP *resp = (U2F_REGISTER_RESP *)&data;
		memzero(data, sizeof(data));

		resp->registerId = U2F_REGISTER_ID;
		resp->keyHandleLen = KEY_HANDLE_LEN;
		// Generate keypair for this appId
		const HDNode *node =
			generateKeyHandle(req->appId, (uint8_t*)&resp->keyHandleCertSig);

		if (!node) {
			debugLog(0, "", "getDerivedNode Fail");
			send_u2f_error(U2F_SW_WRONG_DATA); // error:bad key handle
			return;
		}

		ecdsa_get_public_key65(node->curve->params, node->private_key,
				       (uint8_t *)&resp->pubKey);

		memcpy(resp->keyHandleCertSig + resp->keyHandleLen,
		       U2F_ATT_CERT, sizeof(U2F_ATT_CERT));

		uint8_t sig[64];
		U2F_REGISTER_SIG_STR sig_base;
		sig_base.reserved = 0;
		memcpy(sig_base.appId, req->appId, U2F_APPID_SIZE);
		memcpy(sig_base.chal, req->chal, U2F_CHAL_SIZE);
		memcpy(sig_base.keyHandle, &resp->keyHandleCertSig, KEY_HANDLE_LEN);
		memcpy(sig_base.pubKey, &resp->pubKey, U2F_PUBKEY_LEN);
		if (ecdsa_sign(&nist256p1, HASHER_SHA2, U2F_ATT_PRIV_KEY, (uint8_t *)&sig_base, sizeof(sig_base), sig, NULL, NULL) != 0) {
			send_u2f_error(U2F_SW_WRONG_DATA);
			return;
		}

		// Where to write the signature in the response
		uint8_t *resp_sig = resp->keyHandleCertSig +
				    resp->keyHandleLen + sizeof(U2F_ATT_CERT);
		// Convert to der for the response
		const uint8_t sig_len = ecdsa_sig_to_der(sig, resp_sig);

		// Append success bytes
		memcpy(resp->keyHandleCertSig + resp->keyHandleLen +
			   sizeof(U2F_ATT_CERT) + sig_len,
		       "\x90\x00", 2);

		int l = 1 /* registerId */ + U2F_PUBKEY_LEN +
			1 /* keyhandleLen */ + resp->keyHandleLen +
			sizeof(U2F_ATT_CERT) + sig_len + 2;

		last_req_state = INIT;
		dialog_timeout = 0;
		send_u2f_msg(data, l);

		promptRegister(false, req);
		return;
	}

	// Didnt expect to get here
	dialog_timeout = 0;
}

static void promptAuthenticate(bool request, const U2F_AUTHENTICATE_REQ *req)
{
	const char *appname = "";
	bool readable = getReadableAppId(req->appId, &appname);
	layoutU2FDialog(request,
	                "U2F Authenticate",
	                readable
	                    ? "Log in to %s?"
	                    : "Do you want to log in?\n\n%s",
	                appname);
}


void u2f_authenticate(const APDU *a)
{
	const U2F_AUTHENTICATE_REQ *req = (U2F_AUTHENTICATE_REQ *)a->data;
	static U2F_AUTHENTICATE_REQ last_req;

	if (!storage_isInitialized()) {
		layout_warning_static("Cannot authenticate u2f: not initialized");
		send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
		delay_ms(3000);
		return;
	}

	if (APDU_LEN(*a) < 64) { /// FIXME: decent value
		debugLog(0, "", "u2f authenticate - badlen");
		send_u2f_error(U2F_SW_WRONG_LENGTH);
		return;
	}

	if (req->keyHandleLen != KEY_HANDLE_LEN) {
		debugLog(0, "", "u2f auth - bad keyhandle len");
		send_u2f_error(U2F_SW_WRONG_DATA); // error:bad key handle
		return;
	}

	const HDNode *node =
	    validateKeyHandle(req->appId, req->keyHandle);

	if (!node) {
		debugLog(0, "", "u2f auth - bad keyhandle len");
		send_u2f_error(U2F_SW_WRONG_DATA); // error:bad key handle
		return;
	}

	if (a->p1 == U2F_AUTH_CHECK_ONLY) {
		debugLog(0, "", "u2f authenticate check");
		// This is a success for a good keyhandle
		// A failed check would have happened earlier
		// error: testof-user-presence is required
		send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
		return;
	}

	if (a->p1 != U2F_AUTH_ENFORCE) {
		debugLog(0, "", "u2f authenticate unknown");
		// error:bad key handle
		send_u2f_error(U2F_SW_WRONG_DATA);
		return;
	}

	debugLog(0, "", "u2f authenticate enforce");

	if (memcmp(&last_req, req, sizeof(last_req)) != 0) {
		memcpy(&last_req, req, sizeof(last_req));
		last_req_state = INIT;
	}

	if (last_req_state == INIT) {
		// error: testof-user-presence is required
		//buttonUpdate(); // Clear button state
		promptAuthenticate(true, req);
		last_req_state = AUTH;
	}

	// Awaiting Keypress
	if (last_req_state == AUTH) {
		// error: testof-user-presence is required
		send_u2f_error(U2F_SW_CONDITIONS_NOT_SATISFIED);
		dialog_timeout = U2F_TIMEOUT;
		return;
	}

	// Buttons said yes
	if (last_req_state == AUTH_PASS) {
		uint8_t buf[sizeof(U2F_AUTHENTICATE_RESP) + 2];
		U2F_AUTHENTICATE_RESP *resp =
			(U2F_AUTHENTICATE_RESP *)&buf;

		const uint32_t ctr = storage_nextU2FCounter();
		resp->flags = U2F_AUTH_FLAG_TUP;
		resp->ctr[0] = ctr >> 24 & 0xff;
		resp->ctr[1] = ctr >> 16 & 0xff;
		resp->ctr[2] = ctr >> 8 & 0xff;
		resp->ctr[3] = ctr & 0xff;

		// Build and sign response
		U2F_AUTHENTICATE_SIG_STR sig_base;
		uint8_t sig[64];
		memcpy(sig_base.appId, req->appId, U2F_APPID_SIZE);
		sig_base.flags = resp->flags;
		memcpy(sig_base.ctr, resp->ctr, 4);
		memcpy(sig_base.chal, req->chal, U2F_CHAL_SIZE);
		if (ecdsa_sign(&nist256p1, HASHER_SHA2, node->private_key, (uint8_t *)&sig_base, sizeof(sig_base), sig, NULL, NULL) != 0) {
			send_u2f_error(U2F_SW_WRONG_DATA);
			return;
		}

		// Copy DER encoded signature into response
		const uint8_t sig_len = ecdsa_sig_to_der(sig, resp->sig);

		// Append OK
		memcpy(buf + sizeof(U2F_AUTHENTICATE_RESP) -
			   U2F_MAX_EC_SIG_SIZE + sig_len,
			   "\x90\x00", 2);
		last_req_state = INIT;
		dialog_timeout = 0;
		send_u2f_msg(buf, sizeof(U2F_AUTHENTICATE_RESP) -
					  U2F_MAX_EC_SIG_SIZE + sig_len +
					  2);

		promptAuthenticate(false, req);
	}
}
Ejemplo n.º 18
0
bool KeyPair::Sign(Signature& out, const Digest& hash) {
	return ecdsa_sign(privateKey, hash.Byte, out.Byte);
}
Ejemplo n.º 19
0
/* in case of DSA puts into data, r,s
 */
static int
_wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
		     gnutls_datum_t * signature,
		     const gnutls_datum_t * vdata,
		     const gnutls_pk_params_st * pk_params)
{
	int ret;
	unsigned int hash_len;
	const mac_entry_st *me;

	switch (algo) {
	case GNUTLS_PK_EC:	/* we do ECDSA */
		{
			struct ecc_scalar priv;
			struct dsa_signature sig;
			int curve_id = pk_params->flags;
			const struct ecc_curve *curve;

			curve = get_supported_curve(curve_id);
			if (curve == NULL)
				return
				    gnutls_assert_val
				    (GNUTLS_E_ECC_UNSUPPORTED_CURVE);

			ret =
			    _ecc_params_to_privkey(pk_params, &priv,
						   curve);
			if (ret < 0)
				return gnutls_assert_val(ret);

			dsa_signature_init(&sig);

			me = _gnutls_dsa_q_to_hash(algo, pk_params,
						   &hash_len);

			if (hash_len > vdata->size) {
				gnutls_assert();
				_gnutls_debug_log
				    ("Security level of algorithm requires hash %s(%d) or better\n",
				     _gnutls_mac_get_name(me), hash_len);
				hash_len = vdata->size;
			}

			ecdsa_sign(&priv, NULL, rnd_func, hash_len,
				   vdata->data, &sig);

			ret =
			    _gnutls_encode_ber_rs(signature, &sig.r,
						  &sig.s);

			dsa_signature_clear(&sig);
			ecc_scalar_clear(&priv);

			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}
			break;
		}
	case GNUTLS_PK_DSA:
		{
			struct dsa_public_key pub;
			struct dsa_private_key priv;
			struct dsa_signature sig;

			memset(&priv, 0, sizeof(priv));
			memset(&pub, 0, sizeof(pub));
			_dsa_params_to_pubkey(pk_params, &pub);
			_dsa_params_to_privkey(pk_params, &priv);

			dsa_signature_init(&sig);

			me = _gnutls_dsa_q_to_hash(algo, pk_params,
						   &hash_len);

			if (hash_len > vdata->size) {
				gnutls_assert();
				_gnutls_debug_log
				    ("Security level of algorithm requires hash %s(%d) or better\n",
				     _gnutls_mac_get_name(me), hash_len);
				hash_len = vdata->size;
			}

			ret =
			    _dsa_sign(&pub, &priv, NULL, rnd_func,
				      hash_len, vdata->data, &sig);
			if (ret == 0) {
				gnutls_assert();
				ret = GNUTLS_E_PK_SIGN_FAILED;
				goto dsa_fail;
			}

			ret =
			    _gnutls_encode_ber_rs(signature, &sig.r,
						  &sig.s);

		      dsa_fail:
			dsa_signature_clear(&sig);

			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}
			break;
		}
	case GNUTLS_PK_RSA:
		{
			struct rsa_private_key priv;
			struct rsa_public_key pub;
			mpz_t s;

			_rsa_params_to_privkey(pk_params, &priv);
			_rsa_params_to_pubkey(pk_params, &pub);

			mpz_init(s);

			ret =
			    rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_func,
					      vdata->size, vdata->data, s);
			if (ret == 0) {
				gnutls_assert();
				ret = GNUTLS_E_PK_SIGN_FAILED;
				goto rsa_fail;
			}

			ret =
			    _gnutls_mpi_dprint_size(s, signature,
						    pub.size);

		      rsa_fail:
			mpz_clear(s);

			if (ret < 0) {
				gnutls_assert();
				goto cleanup;
			}

			break;
		}
	default:
		gnutls_assert();
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto cleanup;
	}

	ret = 0;

      cleanup:

	return ret;
}
Ejemplo n.º 20
0
int main(int argc, char *argv[]) {
	ecdsa_t *key1, *key2;
	ecdh_t *ecdh1, *ecdh2;
	sptps_t sptps1, sptps2;
	char buf1[4096], buf2[4096], buf3[4096];
	double duration = argc > 1 ? atof(argv[1]) : 10;

	crypto_init();

	randomize(buf1, sizeof buf1);
	randomize(buf2, sizeof buf2);
	randomize(buf3, sizeof buf3);

	// Key generation

	fprintf(stderr, "Generating keys for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);)
		ecdsa_free(ecdsa_generate());
	fprintf(stderr, "%17.2lf op/s\n", rate);

	key1 = ecdsa_generate();
	key2 = ecdsa_generate();

	// Ed25519 signatures

	fprintf(stderr, "Ed25519 sign for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);)
		if(!ecdsa_sign(key1, buf1, 256, buf2))
			return 1;
	fprintf(stderr, "%20.2lf op/s\n", rate);

	fprintf(stderr, "Ed25519 verify for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);)
		if(!ecdsa_verify(key1, buf1, 256, buf2)) {
			fprintf(stderr, "Signature verification failed\n");
			return 1;
		}
	fprintf(stderr, "%18.2lf op/s\n", rate);

	ecdh1 = ecdh_generate_public(buf1);
	fprintf(stderr, "ECDH for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);) {
		ecdh2 = ecdh_generate_public(buf2);
		if(!ecdh2)
			return 1;
		if(!ecdh_compute_shared(ecdh2, buf1, buf3))
			return 1;
	}
	fprintf(stderr, "%28.2lf op/s\n", rate);
	ecdh_free(ecdh1);

	// SPTPS authentication phase

	int fd[2];
	if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
		fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno));
		return 1;
	}

	struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}};

	fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);) {
		sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record);
		sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record);
		while(poll(pfd, 2, 0)) {
			if(pfd[0].revents)
				receive_data(&sptps1);
			if(pfd[1].revents)
				receive_data(&sptps2);
		}
		sptps_stop(&sptps1);
		sptps_stop(&sptps2);
	}
	fprintf(stderr, "%10.2lf op/s\n", rate * 2);

	// SPTPS data

	sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record);
	sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record);
	while(poll(pfd, 2, 0)) {
		if(pfd[0].revents)
			receive_data(&sptps1);
		if(pfd[1].revents)
			receive_data(&sptps2);
	}
	fprintf(stderr, "SPTPS/TCP transmit for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);) {
		if(!sptps_send_record(&sptps1, 0, buf1, 1451))
			abort();
		receive_data(&sptps2);
	}
	rate *= 2 * 1451 * 8;
	if(rate > 1e9)
		fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9);
	else if(rate > 1e6)
		fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6);
	else if(rate > 1e3)
		fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3);
	sptps_stop(&sptps1);
	sptps_stop(&sptps2);

	// SPTPS datagram authentication phase

	close(fd[0]);
	close(fd[1]);

	if(socketpair(AF_UNIX, SOCK_DGRAM, 0, fd)) {
		fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno));
		return 1;
	}

	fprintf(stderr, "SPTPS/UDP authenticate for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);) {
		sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record);
		sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record);
		while(poll(pfd, 2, 0)) {
			if(pfd[0].revents)
				receive_data(&sptps1);
			if(pfd[1].revents)
				receive_data(&sptps2);
		}
		sptps_stop(&sptps1);
		sptps_stop(&sptps2);
	}
	fprintf(stderr, "%10.2lf op/s\n", rate * 2);

	// SPTPS datagram data

	sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record);
	sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record);
	while(poll(pfd, 2, 0)) {
		if(pfd[0].revents)
			receive_data(&sptps1);
		if(pfd[1].revents)
			receive_data(&sptps2);
	}
	fprintf(stderr, "SPTPS/UDP transmit for %lg seconds: ", duration);
	for(clock_start(); clock_countto(duration);) {
		if(!sptps_send_record(&sptps1, 0, buf1, 1451))
			abort();
		receive_data(&sptps2);
	}
	rate *= 2 * 1451 * 8;
	if(rate > 1e9)
		fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9);
	else if(rate > 1e6)
		fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6);
	else if(rate > 1e3)
		fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3);
	sptps_stop(&sptps1);
	sptps_stop(&sptps2);

	// Clean up

	close(fd[0]);
	close(fd[1]);
	ecdsa_free(key1);
	ecdsa_free(key2);
	crypto_exit();

	return 0;
}
Ejemplo n.º 21
0
void
test_main (void)
{
  unsigned i;
  struct knuth_lfib_ctx rctx;
  struct dsa_signature signature;

  struct tstring *digest;

  knuth_lfib_init (&rctx, 4711);
  dsa_signature_init (&signature);

  digest = SHEX (/* sha256("abc") */
		 "BA7816BF 8F01CFEA 414140DE 5DAE2223"
		 "B00361A3 96177A9C B410FF61 F20015AD");

  for (i = 0; ecc_curves[i]; i++)
    {
      const struct ecc_curve *ecc = ecc_curves[i];
      struct ecc_point pub;
      struct ecc_scalar key;

      if (verbose)
	fprintf (stderr, "Curve %d\n", ecc->bit_size);

      ecc_point_init (&pub, ecc);
      ecc_scalar_init (&key, ecc);

      ecdsa_generate_keypair (&pub, &key,
			      &rctx,
			      (nettle_random_func *) knuth_lfib_random);

      if (verbose)
	{
	  gmp_fprintf (stderr,
		       "Public key:\nx = %Nx\ny = %Nx\n",
		       pub.p, ecc->size, pub.p + ecc->size, ecc->size);
	  gmp_fprintf (stderr,
		       "Private key: %Nx\n", key.p, ecc->size);
	}
      if (!ecc_valid_p (&pub))
	die ("ecdsa_generate_keypair produced an invalid point.\n");

      ecdsa_sign (&key,
		  &rctx, (nettle_random_func *) knuth_lfib_random,
		  digest->length, digest->data,
		  &signature);

      if (!ecdsa_verify (&pub, digest->length, digest->data,
			  &signature))
	die ("ecdsa_verify failed.\n");

      digest->data[3] ^= 17;
      if (ecdsa_verify (&pub, digest->length, digest->data,
			 &signature))
	die ("ecdsa_verify  returned success with invalid digest.\n");
      digest->data[3] ^= 17;

      mpz_combit (signature.r, 117);
      if (ecdsa_verify (&pub, digest->length, digest->data,
			 &signature))
	die ("ecdsa_verify  returned success with invalid signature.r.\n");

      mpz_combit (signature.r, 117);
      mpz_combit (signature.s, 93);
      if (ecdsa_verify (&pub, digest->length, digest->data,
			 &signature))
	die ("ecdsa_verify  returned success with invalid signature.s.\n");

      ecc_point_clear (&pub);
      ecc_scalar_clear (&key);
    }
  dsa_signature_clear (&signature);
}