CSL_error CSL_VerifyEccSig( CSLOSDigest digest, 
                            u32 digestSize,
                            CSLOSEccPublicKey publicKey, 
                            CSLOSEccSig sign){
    CSL_error reterr = CSL_OK;
    field_boolean res;
    CSL_VerifyEccSig_big_locals *big_locals;
#ifdef __KERNEL__
    big_locals = kmalloc(sizeof(*big_locals), GFP_KERNEL);
    if (!big_locals)
        return CSL_NO_MEMORY;
#else
    CSL_VerifyEccSig_big_locals _big_locals;
    big_locals = &_big_locals;
#endif
    
    alg_init_233_bit_ECDSA(&big_locals->base, NUM_BITS);
    OS2ECP(publicKey, OCTET_STRING_LEN*2, &big_locals->public_key);
    OS2ECP(sign, OCTET_STRING_LEN*2, (point *)&big_locals->signature);
    
    alg_poly_ECDSA_verify((char *)digest, digestSize, &big_locals->base, &big_locals->public_key, &big_locals->signature, &res);
    reterr = res == CSL_TRUE ? CSL_OK : CSL_VERIFY_ERROR;

#ifdef __KERNEL__
    kfree(big_locals);
#endif
    return reterr;
}
示例#2
0
EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
                             const secure_vector<byte>& key_bits)
   {
   m_domain_params = EC_Group(alg_id.parameters);
   m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;

   OID key_parameters;
   secure_vector<byte> public_key_bits;

   BER_Decoder(key_bits)
      .start_cons(SEQUENCE)
         .decode_and_check<size_t>(1, "Unknown version code for ECC key")
         .decode_octet_string_bigint(m_private_key)
         .decode_optional(key_parameters, ASN1_Tag(0), PRIVATE)
         .decode_optional_string(public_key_bits, BIT_STRING, 1, PRIVATE)
      .end_cons();

   if(!key_parameters.empty() && key_parameters != alg_id.oid)
      throw Decoding_Error("EC_PrivateKey - inner and outer OIDs did not match");

   if(public_key_bits.empty())
      {
      m_public_key = domain().get_base_point() * m_private_key;

      BOTAN_ASSERT(m_public_key.on_the_curve(),
                   "Public point derived from loaded key was on the curve");
      }
   else
      {
      m_public_key = OS2ECP(public_key_bits, domain().get_curve());
      // OS2ECP verifies that the point is on the curve
      }
   }
CSL_error
CSL_GenerateEccSharedKey(CSLOSEccPrivateKey privateKey, 
                         CSLOSEccPublicKey publicKey, 
                         CSLOSEccSharedKey sharedKey, u32 numBytes){
    
    field_2n pvtkey, sharedkey;
    point publickey;
    CSLOSEccSharedKey sharedKeyCopy;
    CSL_error error = CSL_OK;
    
    if(numBytes > sizeof(CSLOSEccSharedKey)){
        return CSL_OVERFLOW;
    }
    poly_elliptic_init_233_bit();
    
    OS2FEP(privateKey, &pvtkey);
    OS2ECP(publicKey, OCTET_STRING_LEN*2, &publickey);
    error = alg_generate_shared_key(&named_point, &named_curve, &publickey, &pvtkey, &sharedkey);
    /* collect the result into output */
#ifdef KDF1
    post_process_key(&sharedkey, sharedKeyCopy);
#else
    FE2OSP(sharedKeyCopy, &sharedkey);
#endif
    /* convert to octet string of desired length */
    memcpy(sharedKey, sharedKeyCopy, numBytes);
    

    return error;
}
/*
 * This call is used for precomputing the public key in expanded form
 * before using the shared key version with precomputing
 */
CSL_error
CSL_PrecomputeFour(CSLOSEccPublicKey publicKey, CSLOSEccExpPublicKey prePublicKey){
    point publickey;
    int j;
#ifdef __KERNEL__
    point *precomputedpublickey = kmalloc(sizeof(point) * 16, GFP_KERNEL);
    if (!precomputedpublickey)
        return CSL_NO_MEMORY;
#else
    point precomputedpublickey[16];
#endif

    OS2ECP(publicKey, OCTET_STRING_LEN*2, &publickey);
    alg_do_precompute_four(&publickey, &(precomputedpublickey[0]), &named_curve);

    for(j = 0; j < 16; j++){
        EC2OSP(&(precomputedpublickey[j]), (prePublicKey + ((OCTET_STRING_LEN*2)*j)), OCTET_STRING_LEN*2);
    }

#ifdef __KERNEL__
    kfree(precomputedpublickey);
#endif
    
    return CSL_OK;
}
示例#5
0
         void key_bits(const MemoryRegion<byte>& bits)
            {
            key->mp_public_point.reset(
               new PointGFp(
                  OS2ECP(bits, key->domain_parameters().get_curve())
                  ));

            key->X509_load_hook();
            }
示例#6
0
EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id,
                           const std::vector<uint8_t>& key_bits) :
   m_domain_params{EC_Group(alg_id.parameters)},
   m_public_key{OS2ECP(key_bits, domain().get_curve())}
   {
   if (!domain().get_oid().empty())
      m_domain_encoding = EC_DOMPAR_ENC_OID;
   else
      m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
   }
示例#7
0
PKCS11_EC_PublicKey::PKCS11_EC_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
   : Object(session, props)
   {
   m_domain_params = EC_Group(props.ec_params());

   secure_vector<uint8_t> ec_point;
   BER_Decoder(props.ec_point()).decode(ec_point, OCTET_STRING);
   m_public_key = OS2ECP(ec_point, m_domain_params.get_curve());
   m_domain_encoding = EC_DOMPAR_ENC_EXPLICIT;
   }
示例#8
0
文件: sm2s.cpp 项目: wqx081/alpha
int  sm2_dec
(
	sm2_prvkey *prvkey,
	unsigned char *ciphertext, 
	unsigned int clen,
	unsigned char*plaintext, 
	unsigned int *plen 
)
{
	point_affn_t ksG;
#ifndef MUL_BITS
	unsigned char tmp[FIELD_SIZE_IN_BYTES*2];
#else
	unsigned char tmp[32*2];
#endif
	unsigned char *hash = tmp;
	int c1len, xylen;
	unsigned int i;
	int ret;

	point_affn_init(ksG);

	c1len = OS2ECP(ksG, ciphertext, clen);

	if(c1len < 0 || (clen - c1len <= SM3_HASH_LEN) )
	{
		point_affn_clear(ksG);
		return 1;
	}
	mpz_BarrettSetBuf(&pXbufFieldPrime);
	point_affn_mul(ksG, ksG, prvkey->s);

	xylen = sizeof(tmp);
	EC2OSP_XY(tmp, &xylen, ksG);
	point_affn_clear(ksG);

	*plen = clen-c1len-SM3_HASH_LEN;
	sm2_KDF1_ex(plaintext, *plen, tmp, xylen, ALG_HASH_SM3, 1);
	for(i=0; i<*plen; i++)
		plaintext[i] = ciphertext[c1len+SM3_HASH_LEN+i]^plaintext[i];

	sm2_hash(tmp, xylen/2, plaintext, *plen, tmp+xylen/2, xylen/2, hash);
	if( !memcmp(hash, ciphertext+c1len, SM3_HASH_LEN) )
		ret = 0;
	else
	{
		memset(plaintext, 0, *plen);
		ret = 1;
	}

	return ret;
}
示例#9
0
PointGFp OS2ECP(const uint8_t data[], size_t data_len,
                const CurveGFp& curve)
   {
   // Should we really be doing this?
   if(data_len <= 1)
      return PointGFp(curve); // return zero

   std::pair<BigInt, BigInt> xy = OS2ECP(data, data_len, curve.get_p(), curve.get_a(), curve.get_b());

   PointGFp point(curve, xy.first, xy.second);

   if(!point.on_the_curve())
      throw Illegal_Point("OS2ECP: Decoded point was not on the curve");

   return point;
   }
示例#10
0
EC_Group::EC_Group(const std::vector<uint8_t>& ber_data)
   {
   BER_Decoder ber(ber_data);
   BER_Object obj = ber.get_next_object();

   if(obj.type_tag == NULL_TAG)
      throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters");
   else if(obj.type_tag == OBJECT_ID)
      {
      OID dom_par_oid;
      BER_Decoder(ber_data).decode(dom_par_oid);
      *this = EC_Group(dom_par_oid);
      }
   else if(obj.type_tag == SEQUENCE)
      {
      BigInt p, a, b;
      std::vector<uint8_t> sv_base_point;

      BER_Decoder(ber_data)
         .start_cons(SEQUENCE)
           .decode_and_check<size_t>(1, "Unknown ECC param version code")
           .start_cons(SEQUENCE)
            .decode_and_check(OID("1.2.840.10045.1.1"),
                              "Only prime ECC fields supported")
             .decode(p)
           .end_cons()
           .start_cons(SEQUENCE)
             .decode_octet_string_bigint(a)
             .decode_octet_string_bigint(b)
           .end_cons()
           .decode(sv_base_point, OCTET_STRING)
           .decode(m_order)
           .decode(m_cofactor)
         .end_cons()
         .verify_end();

      m_curve = CurveGFp(p, a, b);
      m_base_point = OS2ECP(sv_base_point, m_curve);
      }
   else
      throw Decoding_Error("Unexpected tag while decoding ECC domain params");
   }
示例#11
0
CSL_error
CSL_GenerateEccSharedKeyPre(CSLOSEccPrivateKey privateKey, 
                            CSLOSEccExpPublicKey publicKey, 
                            CSLOSEccSharedKey sharedKey, 
                            u32 numBytes){
    field_2n pvtkey, sharedkey;
    CSLOSEccSharedKey sharedKeyCopy;
    CSL_error error = CSL_OK;
    int j;
#ifdef __KERNEL__
    point *precomputedpublickey = kmalloc(sizeof(point) * 16, GFP_KERNEL);
    if (!precomputedpublickey)
        return CSL_NO_MEMORY;
#else
    point precomputedpublickey[16];
#endif
    
    poly_elliptic_init_233_bit();
    OS2FEP(privateKey, &pvtkey);    
    /* convert public key to point variable */
    for(j=0; j< 16; j++){
        OS2ECP((publicKey + (2*OCTET_STRING_LEN*j)), (2*OCTET_STRING_LEN),  &(precomputedpublickey[j]));
    }
    error = alg_generate_shared_key_pre(&named_point, &named_curve, &precomputedpublickey[0], &pvtkey, &sharedkey);
    /* collect the result into output */
#ifdef KDF1
    post_process_key(&sharedkey, sharedKeyCopy);
#else
    FE2OSP(sharedKeyCopy, &sharedkey);
#endif
    /* convert to octet string of desired length */
    memcpy(sharedKey, sharedKeyCopy, numBytes);

#ifdef __KERNEL__
    kfree(precomputedpublickey);
#endif

    return error;
}    
示例#12
0
文件: sm2s.cpp 项目: wqx081/alpha
int sm2_load_pubkey
(
	sm2_pubkey *pubkey,
	unsigned char *data,
	unsigned int n
)
{
	
	if( n != 48 && n != 64 && n != 49 && n != 65 )
		return 1;

	point_affn_init(pubkey->sG);
	pubkey->sG->infinity = 0;
	if(n%2 == 1)
		OS2ECP(pubkey->sG, data, n);
	else
		OS2ECP_XY(pubkey->sG, data, n);
    
	pubkey->ecp = ECPUCMP;
//	dump_point(pubkey->sG, "sG");
	return 0;
}
示例#13
0
文件: sm2s.cpp 项目: wqx081/alpha
int sm2_load_prvkey
(
	sm2_prvkey *prvkey ,
	unsigned char *data,
	unsigned int n
)
{

	if( n != 24 && n != 32 )
		return 1;
	mpz_init(prvkey->s);
	OS2IP(prvkey->s, data, FIELD_SIZE_IN_BYTES);

	point_affn_init(prvkey->sG);
	prvkey->sG->infinity = 0;
	OS2ECP(prvkey->sG, data+FIELD_SIZE_IN_BYTES, n-FIELD_SIZE_IN_BYTES);

	point_affn_init(prvkey->sG);
	point_affn_mul(prvkey->sG, GENERATOR, prvkey->s);
//	dump_point(prvkey->sG, "sG");

	return 0;
}
示例#14
0
EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id,
                           const secure_vector<byte>& key_bits) : m_domain_params{EC_Group(alg_id.parameters)}, m_public_key{OS2ECP(key_bits, domain().get_curve())}, m_domain_encoding{EC_DOMPAR_ENC_EXPLICIT}
   {}
示例#15
0
/*
* Create a new Client Key Exchange message
*/
Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
                                         Handshake_State& state,
                                         const Policy& policy,
                                         Credentials_Manager& creds,
                                         const Public_Key* server_public_key,
                                         const std::string& hostname,
                                         RandomNumberGenerator& rng)
   {
   const std::string kex_algo = state.ciphersuite().kex_algo();

   if(kex_algo == "PSK")
      {
      std::string identity_hint = "";

      if(state.server_kex())
         {
         TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());
         identity_hint = reader.get_string(2, 0, 65535);
         }

      const std::string psk_identity = creds.psk_identity("tls-client",
                                                          hostname,
                                                          identity_hint);

      append_tls_length_value(m_key_material, psk_identity, 2);

      SymmetricKey psk = creds.psk("tls-client", hostname, psk_identity);

      std::vector<byte> zeros(psk.length());

      append_tls_length_value(m_pre_master, zeros, 2);
      append_tls_length_value(m_pre_master, psk.bits_of(), 2);
      }
   else if(state.server_kex())
      {
      TLS_Data_Reader reader("ClientKeyExchange", state.server_kex()->params());

      SymmetricKey psk;

      if(kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
         {
         std::string identity_hint = reader.get_string(2, 0, 65535);

         const std::string psk_identity = creds.psk_identity("tls-client",
                                                             hostname,
                                                             identity_hint);

         append_tls_length_value(m_key_material, psk_identity, 2);

         psk = creds.psk("tls-client", hostname, psk_identity);
         }

      if(kex_algo == "DH" || kex_algo == "DHE_PSK")
         {
         BigInt p = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         BigInt Y = BigInt::decode(reader.get_range<byte>(2, 1, 65535));

         if(reader.remaining_bytes())
            throw Decoding_Error("Bad params size for DH key exchange");

         if(p.bits() < policy.minimum_dh_group_size())
            throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                                "Server sent DH group of " +
                                std::to_string(p.bits()) +
                                " bits, policy requires at least " +
                                std::to_string(policy.minimum_dh_group_size()));

         /*
         * A basic check for key validity. As we do not know q here we
         * cannot check that Y is in the right subgroup. However since
         * our key is ephemeral there does not seem to be any
         * advantage to bogus keys anyway.
         */
         if(Y <= 1 || Y >= p - 1)
            throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                                "Server sent bad DH key for DHE exchange");

         DL_Group group(p, g);

         if(!group.verify_group(rng, false))
            throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                                "DH group validation failed");

         DH_PublicKey counterparty_key(group, Y);

         DH_PrivateKey priv_key(rng, group);

         PK_Key_Agreement ka(priv_key, "Raw");

         secure_vector<byte> dh_secret = CT::strip_leading_zeros(
            ka.derive_key(0, counterparty_key.public_value()).bits_of());

         if(kex_algo == "DH")
            m_pre_master = dh_secret;
         else
            {
            append_tls_length_value(m_pre_master, dh_secret, 2);
            append_tls_length_value(m_pre_master, psk.bits_of(), 2);
            }

         append_tls_length_value(m_key_material, priv_key.public_value(), 2);
         }
      else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
         {
         const byte curve_type = reader.get_byte();

         if(curve_type != 3)
            throw Decoding_Error("Server sent non-named ECC curve");

         const u16bit curve_id = reader.get_u16bit();

         const std::string name = Supported_Elliptic_Curves::curve_id_to_name(curve_id);

         if(name == "")
            throw Decoding_Error("Server sent unknown named curve " + std::to_string(curve_id));

         EC_Group group(name);

         std::vector<byte> ecdh_key = reader.get_range<byte>(1, 1, 255);

         ECDH_PublicKey counterparty_key(group, OS2ECP(ecdh_key, group.get_curve()));

         ECDH_PrivateKey priv_key(rng, group);

         PK_Key_Agreement ka(priv_key, "Raw");

         secure_vector<byte> ecdh_secret =
            ka.derive_key(0, counterparty_key.public_value()).bits_of();

         if(kex_algo == "ECDH")
            m_pre_master = ecdh_secret;
         else
            {
            append_tls_length_value(m_pre_master, ecdh_secret, 2);
            append_tls_length_value(m_pre_master, psk.bits_of(), 2);
            }

         append_tls_length_value(m_key_material, priv_key.public_value(), 1);
         }
#if defined(BOTAN_HAS_SRP6)
      else if(kex_algo == "SRP_SHA")
         {
         const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
         std::vector<byte> salt = reader.get_range<byte>(1, 1, 255);
         const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));

         const std::string srp_group = srp6_group_identifier(N, g);

         const std::string srp_identifier =
            creds.srp_identifier("tls-client", hostname);

         const std::string srp_password =
            creds.srp_password("tls-client", hostname, srp_identifier);

         std::pair<BigInt, SymmetricKey> srp_vals =
            srp6_client_agree(srp_identifier,
                              srp_password,
                              srp_group,
                              "SHA-1",
                              salt,
                              B,
                              rng);

         append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2);
         m_pre_master = srp_vals.second.bits_of();
         }
#endif
      else
         {
         throw Internal_Error("Client_Key_Exchange: Unknown kex " +
                              kex_algo);
         }

      reader.assert_done();
      }
   else
      {
      // No server key exchange msg better mean RSA kex + RSA key in cert

      if(kex_algo != "RSA")
         throw Unexpected_Message("No server kex but negotiated kex " + kex_algo);

      if(!server_public_key)
         throw Internal_Error("No server public key for RSA exchange");

      if(auto rsa_pub = dynamic_cast<const RSA_PublicKey*>(server_public_key))
         {
         const Protocol_Version offered_version = state.client_hello()->version();

         m_pre_master = rng.random_vec(48);
         m_pre_master[0] = offered_version.major_version();
         m_pre_master[1] = offered_version.minor_version();

         PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15");

         const std::vector<byte> encrypted_key = encryptor.encrypt(m_pre_master, rng);

         append_tls_length_value(m_key_material, encrypted_key, 2);
         }
      else
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
                             "Expected a RSA key in server cert but got " +
                             server_public_key->algo_name());
      }

   state.hash().update(io.send(*this));
   }