aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-10-08 02:32:56 +0000
committerlloyd <[email protected]>2008-10-08 02:32:56 +0000
commit89fed41be3c9a77aff495a636d40bf67ac503fa9 (patch)
tree7ce90033aead61eec1f6b70eb79c47cdc2a43fe4
parentdbec5c3bbbd53f1a208707300752e59213cf53c6 (diff)
Split ecdsa module into ecc_key, ecdsa, eckaeg
Add actual implementations (from InSiTo) for ECDSA_Operation and ECKAEG_Operation.
-rw-r--r--src/build-data/botan-config.in6
-rw-r--r--src/build-data/cc/gcc4
-rw-r--r--src/core/libstate/eng_def.h12
-rw-r--r--src/core/libstate/engine.h9
-rw-r--r--src/math/gfpmath/info.txt2
-rw-r--r--src/pubkey/ecc_key/ecc_key.cpp (renamed from src/pubkey/ecdsa/ecc_key.cpp)51
-rw-r--r--src/pubkey/ecc_key/ecc_key.h (renamed from src/pubkey/ecdsa/ecc_key.h)1
-rw-r--r--src/pubkey/ecc_key/info.txt19
-rw-r--r--src/pubkey/ecdsa/ecc_op.h44
-rw-r--r--src/pubkey/ecdsa/ecdsa.cpp99
-rw-r--r--src/pubkey/ecdsa/ecdsa.h1
-rw-r--r--src/pubkey/ecdsa/ecdsa_core.cpp53
-rw-r--r--src/pubkey/ecdsa/ecdsa_core.h (renamed from src/pubkey/ecdsa/ecc_core.h)37
-rw-r--r--src/pubkey/ecdsa/ecdsa_op.cpp136
-rw-r--r--src/pubkey/ecdsa/ecdsa_op.h62
-rw-r--r--src/pubkey/ecdsa/info.txt14
-rw-r--r--src/pubkey/eckaeg/eckaeg.cpp (renamed from src/pubkey/ecdsa/eckaeg.cpp)0
-rw-r--r--src/pubkey/eckaeg/eckaeg.h (renamed from src/pubkey/ecdsa/eckaeg.h)1
-rw-r--r--src/pubkey/eckaeg/eckaeg_core.cpp (renamed from src/pubkey/ecdsa/ecc_core.cpp)41
-rw-r--r--src/pubkey/eckaeg/eckaeg_core.h42
-rw-r--r--src/pubkey/eckaeg/eckaeg_op.cpp44
-rw-r--r--src/pubkey/eckaeg/eckaeg_op.h47
-rw-r--r--src/pubkey/eckaeg/info.txt24
23 files changed, 549 insertions, 200 deletions
diff --git a/src/build-data/botan-config.in b/src/build-data/botan-config.in
index ef2b5fe4d..5f3c2e933 100644
--- a/src/build-data/botan-config.in
+++ b/src/build-data/botan-config.in
@@ -1,10 +1,10 @@
#!/bin/sh
-guess_prefix=`dirname \`dirname $0\``
+guess_prefix=`dirname $0`
install_prefix=@{var:prefix}
prefix=
-includedir=@{var:includedir}
-libdir=@{var:libdir}
+includedir=build/include
+libdir=
usage()
{
diff --git a/src/build-data/cc/gcc b/src/build-data/cc/gcc
index ac4f7bd58..7ceb8b10f 100644
--- a/src/build-data/cc/gcc
+++ b/src/build-data/cc/gcc
@@ -9,8 +9,8 @@ add_lib_dir_option "-L"
add_lib_option "-l"
lang_flags "-D_REENTRANT -ansi -Wno-long-long"
-warning_flags "-W -Wall"
-#warning_flags "-Werror -Wextra -Wall -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wno-unused-parameter"
+#warning_flags "-W -Wall"
+warning_flags "-Werror -Wextra -Wall -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wno-unused-parameter"
lib_opt_flags "-O2 -finline-functions"
check_opt_flags "-O2"
diff --git a/src/core/libstate/eng_def.h b/src/core/libstate/eng_def.h
index 66cb774d2..36ef14a69 100644
--- a/src/core/libstate/eng_def.h
+++ b/src/core/libstate/eng_def.h
@@ -40,6 +40,18 @@ class BOTAN_DLL Default_Engine : public Engine
DH_Operation* dh_op(const DL_Group&, const BigInt&) const;
#endif
+#if defined(BOTAN_HAS_ECDSA)
+ virtual ECDSA_Operation* ecdsa_op(const EC_Domain_Params&,
+ const BigInt&,
+ const PointGFp&) const;
+#endif
+
+#if defined(BOTAN_HAS_ECKAEG)
+ virtual ECKAEG_Operation* eckaeg_op(const EC_Domain_Params&,
+ const BigInt&,
+ const PointGFp&) const;
+#endif
+
Modular_Exponentiator* mod_exp(const BigInt&,
Power_Mod::Usage_Hints) const;
diff --git a/src/core/libstate/engine.h b/src/core/libstate/engine.h
index 35d43afc3..d9b70011c 100644
--- a/src/core/libstate/engine.h
+++ b/src/core/libstate/engine.h
@@ -35,7 +35,12 @@
#endif
#if defined(BOTAN_HAS_ECDSA)
- #include <botan/ecc_op.h>
+ #include <botan/ecdsa_op.h>
+ #include <botan/ec_dompar.h>
+#endif
+
+#if defined(BOTAN_HAS_ECKAEG)
+ #include <botan/eckaeg_op.h>
#include <botan/ec_dompar.h>
#endif
@@ -91,7 +96,9 @@ class BOTAN_DLL Engine
const BigInt&,
const PointGFp&) const
{ return 0; }
+#endif
+#if defined(BOTAN_HAS_ECKAEG)
virtual ECKAEG_Operation* eckaeg_op(const EC_Domain_Params&,
const BigInt&,
const PointGFp&) const
diff --git a/src/math/gfpmath/info.txt b/src/math/gfpmath/info.txt
index ab4e440df..9c62d7761 100644
--- a/src/math/gfpmath/info.txt
+++ b/src/math/gfpmath/info.txt
@@ -1,6 +1,6 @@
realname "GF(p) Math"
-load_on request
+load_on auto
define BIGINT_GFP
diff --git a/src/pubkey/ecdsa/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp
index 36226b47b..78284b6ae 100644
--- a/src/pubkey/ecdsa/ecc_key.cpp
+++ b/src/pubkey/ecc_key/ecc_key.cpp
@@ -138,4 +138,55 @@ void EC_PrivateKey::affirm_init() const // virtual
}
}
+/**
+* Return the PKCS #8 public key decoder
+*/
+PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&)
+ {
+ class EC_Key_Decoder : public PKCS8_Decoder
+ {
+ public:
+ void alg_id ( const AlgorithmIdentifier& alg_id )
+ {
+ key->mp_dom_pars.reset ( new EC_Domain_Params ( decode_ber_ec_dompar ( alg_id.parameters ) ) );
+ }
+
+ void key_bits ( const MemoryRegion<byte>& bits )
+ {
+ u32bit version;
+ SecureVector<byte> octstr_secret;
+ BER_Decoder ( bits )
+ .start_cons ( SEQUENCE )
+ .decode ( version )
+ .decode ( octstr_secret, OCTET_STRING )
+ .verify_end()
+ .end_cons();
+ key->m_private_value = BigInt::decode ( octstr_secret, octstr_secret.size() );
+ if ( version != 1 )
+ throw Decoding_Error ( "Wrong PKCS #1 key format version for EC key" );
+ key->PKCS8_load_hook();
+ }
+
+ EC_Key_Decoder ( EC_PrivateKey* k ) : key ( k )
+ {}
+ private:
+ EC_PrivateKey* key;
+ };
+
+ return new EC_Key_Decoder(this);
+ }
+
+
+void EC_PrivateKey::PKCS8_load_hook ( bool )
+ {
+ // we cannot use affirm_init() here because mp_public_point might still be null
+ if (mp_dom_pars.get() == 0 )
+ {
+ throw Invalid_State("attempt to set public point for an uninitialized key");
+ }
+ mp_public_point.reset ( new PointGFp ( m_private_value * mp_dom_pars->get_base_point() ) );
+ mp_public_point->check_invariants();
+
+ }
+
}
diff --git a/src/pubkey/ecdsa/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h
index 1beba96c5..89fd5e7f1 100644
--- a/src/pubkey/ecdsa/ecc_key.h
+++ b/src/pubkey/ecc_key/ecc_key.h
@@ -12,7 +12,6 @@
#include <botan/curve_gfp.h>
#include <botan/pk_keys.h>
#include <botan/ec_dompar.h>
-#include <botan/ecc_core.h>
#include <botan/x509_key.h>
#include <botan/pkcs8.h>
diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt
new file mode 100644
index 000000000..c5213aef4
--- /dev/null
+++ b/src/pubkey/ecc_key/info.txt
@@ -0,0 +1,19 @@
+realname "ECC Public Key"
+
+define ECC_PUBLIC_KEY_CRYPTO
+
+load_on auto
+
+<requires>
+asn1
+bigint
+ec_dompar
+numbertheory
+gfpmath
+pubkey
+</requires>
+
+<add>
+ecc_key.cpp
+ecc_key.h
+</add>
diff --git a/src/pubkey/ecdsa/ecc_op.h b/src/pubkey/ecdsa/ecc_op.h
deleted file mode 100644
index 319e02da9..000000000
--- a/src/pubkey/ecdsa/ecc_op.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*************************************************
-* ECDSA/ECKAEG Operations Header File *
-* (C) 1999-2008 Jack Lloyd *
-*************************************************/
-
-#ifndef BOTAN_ECDSA_OPERATIONS_H__
-#define BOTAN_ECDSA_OPERATIONS_H__
-
-#include <botan/bigint.h>
-#include <botan/point_gfp.h>
-
-namespace Botan {
-
-/*************************************************
-* ECDSA Operation *
-*************************************************/
-class BOTAN_DLL ECDSA_Operation
- {
- public:
- virtual bool verify(const byte sig[], u32bit sig_len,
- const byte msg[], u32bit msg_len) const = 0;
-
- virtual SecureVector<byte> sign(const byte message[],
- u32bit mess_len) const = 0;
-
- virtual ECDSA_Operation* clone() const = 0;
-
- virtual ~ECDSA_Operation() {}
- };
-
-/*************************************************
-* ECKAEG Operation *
-*************************************************/
-class BOTAN_DLL ECKAEG_Operation
- {
- public:
- virtual SecureVector<byte> agree(const PointGFp&) const = 0;
- virtual ECKAEG_Operation* clone() const = 0;
- virtual ~ECKAEG_Operation() {}
- };
-
-}
-
-#endif
diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp
index ae098cdc0..5cc226203 100644
--- a/src/pubkey/ecdsa/ecdsa.cpp
+++ b/src/pubkey/ecdsa/ecdsa.cpp
@@ -90,60 +90,6 @@ PKCS8_Encoder* EC_PrivateKey::pkcs8_encoder() const
return new EC_Key_Encoder(this);
}
-/**
-* Return the PKCS #8 public key decoder
-*/
-PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&)
- {
- class EC_Key_Decoder : public PKCS8_Decoder
- {
- public:
- void alg_id ( const AlgorithmIdentifier& alg_id )
- {
- key->mp_dom_pars.reset ( new EC_Domain_Params ( decode_ber_ec_dompar ( alg_id.parameters ) ) );
- }
-
- void key_bits ( const MemoryRegion<byte>& bits )
- {
- u32bit version;
- SecureVector<byte> octstr_secret;
- BER_Decoder ( bits )
- .start_cons ( SEQUENCE )
- .decode ( version )
- .decode ( octstr_secret, OCTET_STRING )
- .verify_end()
- .end_cons();
- key->m_private_value = BigInt::decode ( octstr_secret, octstr_secret.size() );
- if ( version != 1 )
- throw Decoding_Error ( "Wrong PKCS #1 key format version for EC key" );
- key->PKCS8_load_hook();
- }
-
- EC_Key_Decoder ( EC_PrivateKey* k ) : key ( k )
- {}
- private:
- EC_PrivateKey* key;
- };
-
- return new EC_Key_Decoder(this);
- }
-
-
-void EC_PrivateKey::PKCS8_load_hook ( bool )
- {
- // we cannot use affirm_init() here because mp_public_point might still be null
- if (mp_dom_pars.get() == 0 )
- {
- throw Invalid_State("attempt to set public point for an uninitialized key");
- }
- mp_public_point.reset ( new PointGFp ( m_private_value * mp_dom_pars->get_base_point() ) );
- mp_public_point->check_invariants();
-
- }
-
-
-
-
/*************************************************
* ECDSA_PublicKey *
*************************************************/
@@ -183,6 +129,7 @@ void ECDSA_PublicKey::set_domain_parameters(EC_Domain_Params const& dom_pars)
{
throw Invalid_State("EC_PublicKey::set_domain_parameters(): point does not lie on provided curve");
}
+
std::auto_ptr<EC_Domain_Params> p_tmp_pars(new EC_Domain_Params(dom_pars));
ECDSA_Core tmp_ecdsa_core( *p_tmp_pars, BigInt ( 0 ), tmp_pp );
mp_public_point.reset(new PointGFp(tmp_pp));
@@ -195,28 +142,31 @@ void ECDSA_PublicKey::set_all_values ( ECDSA_PublicKey const& other )
m_param_enc = other.m_param_enc;
m_ecdsa_core = other.m_ecdsa_core;
m_enc_public_point = other.m_enc_public_point;
- if ( other.mp_dom_pars.get() )
- {
+ if(other.mp_dom_pars.get())
mp_dom_pars.reset ( new EC_Domain_Params ( * ( other.mp_dom_pars ) ) );
- }
- if ( other.mp_public_point.get() )
- {
+
+ if(other.mp_public_point.get())
mp_public_point.reset ( new PointGFp ( * ( other.mp_public_point ) ) );
- }
}
-ECDSA_PublicKey::ECDSA_PublicKey ( ECDSA_PublicKey const& other )
+
+ECDSA_PublicKey::ECDSA_PublicKey(const ECDSA_PublicKey& other)
: Public_Key(),
EC_PublicKey(),
PK_Verifying_wo_MR_Key()
{
set_all_values ( other );
}
-ECDSA_PublicKey const& ECDSA_PublicKey::operator= ( ECDSA_PublicKey const& rhs )
+
+const ECDSA_PublicKey& ECDSA_PublicKey::operator=(const ECDSA_PublicKey& rhs)
{
set_all_values ( rhs );
return *this;
}
-bool ECDSA_PublicKey::verify ( const byte message[], u32bit mess_len, const byte signature [], u32bit sig_len ) const
+
+bool ECDSA_PublicKey::verify(const byte message[],
+ u32bit mess_len,
+ const byte signature[],
+ u32bit sig_len) const
{
affirm_init();
ECDSA_Signature sig;
@@ -227,19 +177,23 @@ bool ECDSA_PublicKey::verify ( const byte message[], u32bit mess_len, const byte
SecureVector<byte> sv_plain_sig = sig.get_concatenation();
return m_ecdsa_core.verify ( sv_plain_sig, sv_plain_sig.size(), message, mess_len );
}
-ECDSA_PublicKey::ECDSA_PublicKey ( EC_Domain_Params const& dom_par, PointGFp const& public_point )
+
+ECDSA_PublicKey::ECDSA_PublicKey(const EC_Domain_Params& dom_par,
+ const PointGFp& public_point)
{
- mp_dom_pars = std::auto_ptr<EC_Domain_Params> ( new EC_Domain_Params ( dom_par ) );
- mp_public_point = std::auto_ptr<PointGFp> ( new PointGFp ( public_point ) );
+ mp_dom_pars = std::auto_ptr<EC_Domain_Params>(new EC_Domain_Params(dom_par));
+ mp_public_point = std::auto_ptr<PointGFp>(new PointGFp(public_point));
m_param_enc = ENC_EXPLICIT;
- m_ecdsa_core = ECDSA_Core ( *mp_dom_pars, BigInt ( 0 ), *mp_public_point );
+ m_ecdsa_core = ECDSA_Core(*mp_dom_pars, BigInt(0), *mp_public_point);
}
+
void ECDSA_PublicKey::X509_load_hook()
{
EC_PublicKey::X509_load_hook();
EC_PublicKey::affirm_init();
m_ecdsa_core = ECDSA_Core ( *mp_dom_pars, BigInt ( 0 ), *mp_public_point );
}
+
u32bit ECDSA_PublicKey::max_input_bits() const
{
if(!mp_dom_pars.get())
@@ -249,11 +203,9 @@ u32bit ECDSA_PublicKey::max_input_bits() const
return mp_dom_pars->get_order().bits();
}
-
/*************************
* ECDSA_PrivateKey *
*************************/
-
void ECDSA_PrivateKey::affirm_init() const // virtual
{
EC_PrivateKey::affirm_init();
@@ -293,16 +245,19 @@ ECDSA_PrivateKey::ECDSA_PrivateKey(ECDSA_PrivateKey const& other)
{
set_all_values(other);
}
-ECDSA_PrivateKey const& ECDSA_PrivateKey::operator= (ECDSA_PrivateKey const& rhs)
+
+const ECDSA_PrivateKey& ECDSA_PrivateKey::operator=(const ECDSA_PrivateKey& rhs)
{
set_all_values(rhs);
return *this;
}
-SecureVector<byte> ECDSA_PrivateKey::sign ( const byte message [], u32bit mess_len, RandomNumberGenerator&) const
+SecureVector<byte> ECDSA_PrivateKey::sign(const byte message[],
+ u32bit mess_len,
+ RandomNumberGenerator& rng) const
{
affirm_init();
- SecureVector<byte> sv_sig = m_ecdsa_core.sign ( message, mess_len );
+ SecureVector<byte> sv_sig = m_ecdsa_core.sign(message, mess_len, rng);
//code which der encodes the signature returned
ECDSA_Signature sig = decode_concatenation( sv_sig );
std::auto_ptr<ECDSA_Signature_Encoder> enc(sig.x509_encoder());
diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h
index 68d69b24a..4b7e7b5b3 100644
--- a/src/pubkey/ecdsa/ecdsa.h
+++ b/src/pubkey/ecdsa/ecdsa.h
@@ -9,6 +9,7 @@
#define BOTAN_ECDSA_KEY_H__
#include <botan/ecc_key.h>
+#include <botan/ecdsa_core.h>
namespace Botan {
diff --git a/src/pubkey/ecdsa/ecdsa_core.cpp b/src/pubkey/ecdsa/ecdsa_core.cpp
new file mode 100644
index 000000000..2a5ea29cb
--- /dev/null
+++ b/src/pubkey/ecdsa/ecdsa_core.cpp
@@ -0,0 +1,53 @@
+/*************************************************
+* ECDSA Core Source File *
+* (C) 1999-2007 Jack Lloyd *
+* (C) 2007 FlexSecure GmbH *
+*************************************************/
+
+#include <botan/ecdsa_core.h>
+#include <botan/numthry.h>
+#include <botan/engine.h>
+#include <botan/parsing.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* ECDSA Operation *
+*************************************************/
+bool ECDSA_Core::verify(const byte signature[], u32bit sig_len,
+ const byte message[], u32bit mess_len) const
+ {
+ //assert(op.get());
+ return op->verify(signature, sig_len, message, mess_len);
+ }
+
+SecureVector<byte> ECDSA_Core::sign(const byte message[],
+ u32bit mess_len,
+ RandomNumberGenerator& rng) const
+ {
+ //assert(op.get());
+ return op->sign(message, mess_len, rng);
+ }
+
+ECDSA_Core& ECDSA_Core::operator=(const ECDSA_Core& core)
+ {
+ delete op;
+ if(core.op)
+ op = core.op->clone();
+ return (*this);
+ }
+
+ECDSA_Core::ECDSA_Core(const ECDSA_Core& core)
+ {
+ op = 0;
+ if(core.op)
+ op = core.op->clone();
+ }
+
+ECDSA_Core::ECDSA_Core(EC_Domain_Params const& dom_pars, const BigInt& priv_key, PointGFp const& pub_key)
+ {
+ op = Engine_Core::ecdsa_op(dom_pars, priv_key, pub_key);
+ }
+
+}
diff --git a/src/pubkey/ecdsa/ecc_core.h b/src/pubkey/ecdsa/ecdsa_core.h
index 46be43b8a..30668d858 100644
--- a/src/pubkey/ecdsa/ecc_core.h
+++ b/src/pubkey/ecdsa/ecdsa_core.h
@@ -1,13 +1,13 @@
/*************************************************
-* ECC Core Header File *
+* ECDSA Core Header File *
* (C) 1999-2007 Jack Lloyd *
* (C) 2007 FlexSecure GmbH *
*************************************************/
-#ifndef BOTAN_ECC_CORE_H__
-#define BOTAN_ECC_CORE_H__
+#ifndef BOTAN_ECDSA_CORE_H__
+#define BOTAN_ECDSA_CORE_H__
-#include <botan/ecc_op.h>
+#include <botan/ecdsa_op.h>
#include <botan/blinding.h>
#include <botan/ec_dompar.h>
@@ -16,13 +16,14 @@ namespace Botan {
/*************************************************
* ECDSA Core *
*************************************************/
-class ECDSA_Core
+class BOTAN_DLL ECDSA_Core
{
public:
bool verify(const byte signature[], u32bit sig_len,
const byte message[], u32bit mess_len) const;
- SecureVector<byte> sign(const byte message[], u32bit mess_len) const;
+ SecureVector<byte> sign(const byte message[], u32bit mess_len,
+ RandomNumberGenerator& rng) const;
ECDSA_Core& operator=(const ECDSA_Core&);
@@ -39,30 +40,6 @@ class ECDSA_Core
ECDSA_Operation* op;
};
-/*************************************************
-* ECKAEG Core *
-*************************************************/
-class ECKAEG_Core
- {
- public:
- SecureVector<byte> agree(const PointGFp&) const;
-
- ECKAEG_Core& operator=(const ECKAEG_Core&);
-
- ECKAEG_Core() { op = 0; }
-
- ECKAEG_Core(const ECKAEG_Core&);
-
- ECKAEG_Core(const EC_Domain_Params& dom_pars,
- const BigInt& priv_key,
- PointGFp const& pub_key);
-
- ~ECKAEG_Core() { delete op; }
- private:
- ECKAEG_Operation* op;
- Blinder blinder;
- };
-
}
#endif
diff --git a/src/pubkey/ecdsa/ecdsa_op.cpp b/src/pubkey/ecdsa/ecdsa_op.cpp
new file mode 100644
index 000000000..58f00cb4b
--- /dev/null
+++ b/src/pubkey/ecdsa/ecdsa_op.cpp
@@ -0,0 +1,136 @@
+/*************************************************
+* ECDSA Operation *
+* (C) 2007 FlexSecure GmbH *
+* 2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/eng_def.h>
+
+namespace Botan {
+
+bool Default_ECDSA_Op::verify(const byte signature[], u32bit sig_len,
+ const byte message[], u32bit mess_len) const
+ {
+ if(sig_len % 2 != 0)
+ throw Invalid_Argument("Erroneous length of signature");
+
+ //NOTE: it is not checked whether the public point is set
+ if(m_dom_pars.get_curve().get_p() == 0)
+ throw Internal_Error("domain parameters not set");
+
+ BigInt e(message, mess_len);
+
+ u32bit rs_len = sig_len/2;
+ SecureVector<byte> sv_r;
+ SecureVector<byte> sv_s;
+ sv_r.set(signature, rs_len);
+ sv_s.set(signature+rs_len, rs_len);
+ BigInt r = BigInt::decode ( sv_r, sv_r.size());
+ BigInt s = BigInt::decode (sv_s, sv_s.size());
+
+ if(r < 0 || r >= m_dom_pars.get_order())
+ throw Invalid_Argument("r in ECDSA signature has an illegal value");
+
+ if(s < 0 || s >= m_dom_pars.get_order())
+ throw Invalid_Argument("s in ECDSA signature has an illegal value");
+
+ BigInt w = inverse_mod(s, m_dom_pars.get_order());
+
+ PointGFp R = w*(e*m_dom_pars.get_base_point() + r*m_pub_key);
+ if(R.is_zero())
+ return false;
+
+ BigInt x = R.get_affine_x().get_value();
+ bool result = (x % m_dom_pars.get_order() == r);
+ return result;
+ }
+
+SecureVector<byte> Default_ECDSA_Op::sign(const byte message[],
+ u32bit mess_len,
+ RandomNumberGenerator& rng) const
+ {
+ if(m_priv_key == 0)
+ throw Internal_Error("Default_ECDSA_Op::sign(): no private key");
+
+ if(m_dom_pars.get_curve().get_p() == 0)
+ throw Internal_Error("Default_ECDSA_Op::sign(): domain parameters not set");
+
+ BigInt e(message, mess_len);
+
+ // generate k
+ BigInt k;
+ BigInt r(0);
+ const BigInt n(m_dom_pars.get_order());
+ while(r == 0)
+ {
+ k = BigInt::random_integer(rng, 1, n);
+
+ PointGFp k_times_P(m_dom_pars.get_base_point());
+ k_times_P.mult_this_secure(k, n, n-1);
+ k_times_P.check_invariants();
+ r = k_times_P.get_affine_x().get_value() % n;
+ }
+ BigInt k_inv = inverse_mod(k, n);
+
+ // use randomization against attacks on s:
+ // a = k_inv * (r*(d + x) + e) mod n
+ // b = k_inv * r * x mod n
+ // s = a - b mod n
+ // where x is a random integer
+
+#ifdef CMS_RAND
+ BigInt x = Botan::random_integer(0, n);
+ BigInt s = m_priv_key + x; // obscure the secret from the beginning
+ // all following operations thus are randomized
+ s *= r;
+ s += e;
+ s *= k_inv;
+ s %= n;
+
+ BigInt b = x; // again, start with the random number
+ b *= r;
+ b *= k_inv;
+ b %= n;
+ s -= b; // s = a - b
+ if(s <= 0) // s %= n
+ {
+ s += n;
+ }
+#else // CMS_RAND
+ // no countermeasure here
+ BigInt s(r);
+ s *= m_priv_key;
+ s += e;
+ s *= k_inv;
+ s %= n;
+
+#endif // CMS_RAND
+
+ SecureVector<byte> sv_r = BigInt::encode_1363 ( r, m_dom_pars.get_order().bytes() );
+ SecureVector<byte> sv_s = BigInt::encode_1363 ( s, m_dom_pars.get_order().bytes() );
+
+ SecureVector<byte> result(sv_r);
+ result.append(sv_s);
+ return result;
+ }
+
+Default_ECDSA_Op::Default_ECDSA_Op(const EC_Domain_Params& dom_pars, const BigInt& priv_key, const PointGFp& pub_key)
+ : m_dom_pars(dom_pars),
+ m_pub_key(pub_key),
+ m_priv_key(priv_key)
+ {
+
+ }
+
+/*************************************************
+* Acquire a ECDSA op *
+*************************************************/
+ECDSA_Operation* Default_Engine::ecdsa_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key) const
+ {
+ return new Default_ECDSA_Op(dom_pars, priv_key, pub_key);
+ }
+
+}
+
diff --git a/src/pubkey/ecdsa/ecdsa_op.h b/src/pubkey/ecdsa/ecdsa_op.h
new file mode 100644
index 000000000..235824b89
--- /dev/null
+++ b/src/pubkey/ecdsa/ecdsa_op.h
@@ -0,0 +1,62 @@
+/*************************************************
+* ECDSA Operations Header File *
+* (C) 1999-2008 Jack Lloyd *
+* (C) 2007 FlexSecure GmbH *
+*************************************************/
+
+#ifndef BOTAN_ECDSA_OPERATIONS_H__
+#define BOTAN_ECDSA_OPERATIONS_H__
+
+#include <botan/ec_dompar.h>
+#include <botan/rng.h>
+
+namespace Botan {
+
+/*************************************************
+* ECDSA Operation *
+*************************************************/
+class BOTAN_DLL ECDSA_Operation
+ {
+ public:
+ virtual bool verify(const byte sig[], u32bit sig_len,
+ const byte msg[], u32bit msg_len) const = 0;
+
+ virtual SecureVector<byte> sign(const byte message[],
+ u32bit mess_len,
+ RandomNumberGenerator&) const = 0;
+
+ virtual ECDSA_Operation* clone() const = 0;
+
+ virtual ~ECDSA_Operation() {}
+ };
+
+
+/*************************************************
+* Default ECDSA operation *
+*************************************************/
+class Default_ECDSA_Op : public ECDSA_Operation
+ {
+ public:
+ bool verify(const byte signature[], u32bit sig_len,
+ const byte message[], u32bit mess_len) const;
+
+ SecureVector<byte> sign(const byte message[], u32bit mess_len,
+ RandomNumberGenerator& rng) const;
+
+ ECDSA_Operation* clone() const
+ {
+ return new Default_ECDSA_Op(*this);
+ }
+
+ Default_ECDSA_Op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key);
+ private:
+ EC_Domain_Params m_dom_pars;
+ PointGFp m_pub_key;
+ BigInt m_priv_key;
+ };
+
+}
+
+#endif
diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt
index 5769abd03..6e692bd5f 100644
--- a/src/pubkey/ecdsa/info.txt
+++ b/src/pubkey/ecdsa/info.txt
@@ -1,4 +1,4 @@
-realname "ECDSA/ECKAEG"
+realname "ECDSA"
define ECDSA
@@ -8,21 +8,19 @@ load_on auto
asn1
bigint
ec_dompar
+ecc_key
numbertheory
gfpmath
pubkey
</requires>
<add>
-ecc_core.cpp
-ecc_core.h
-ecc_key.cpp
-ecc_key.h
-ecc_op.h
ecdsa.cpp
ecdsa.h
+ecdsa_core.cpp
+ecdsa_core.h
+ecdsa_op.cpp
+ecdsa_op.h
ecdsa_sig.cpp
ecdsa_sig.h
-eckaeg.cpp
-eckaeg.h
</add>
diff --git a/src/pubkey/ecdsa/eckaeg.cpp b/src/pubkey/eckaeg/eckaeg.cpp
index dcd30499a..dcd30499a 100644
--- a/src/pubkey/ecdsa/eckaeg.cpp
+++ b/src/pubkey/eckaeg/eckaeg.cpp
diff --git a/src/pubkey/ecdsa/eckaeg.h b/src/pubkey/eckaeg/eckaeg.h
index 7ab286424..024f44eda 100644
--- a/src/pubkey/ecdsa/eckaeg.h
+++ b/src/pubkey/eckaeg/eckaeg.h
@@ -9,6 +9,7 @@
#define BOTAN_ECKAEG_KEY_H__
#include <botan/ecc_key.h>
+#include <botan/eckaeg_core.h>
namespace Botan {
diff --git a/src/pubkey/ecdsa/ecc_core.cpp b/src/pubkey/eckaeg/eckaeg_core.cpp
index f644e231c..9d59af118 100644
--- a/src/pubkey/ecdsa/ecc_core.cpp
+++ b/src/pubkey/eckaeg/eckaeg_core.cpp
@@ -1,9 +1,10 @@
/*************************************************
-* ECDSA/ECKAEG Core Source File *
+* ECKAEG Core Source File *
* (C) 1999-2007 Jack Lloyd *
+* (C) 2007 FlexSecure GmbH *
*************************************************/
-#include <botan/ecc_core.h>
+#include <botan/eckaeg_core.h>
#include <botan/numthry.h>
#include <botan/engine.h>
#include <botan/parsing.h>
@@ -53,40 +54,4 @@ SecureVector<byte> ECKAEG_Core::agree(const PointGFp& otherKey) const
return op->agree(otherKey);
}
-/*************************************************
-* ECDSA Operation *
-*************************************************/
-bool ECDSA_Core::verify(const byte signature[], u32bit sig_len,
- const byte message[], u32bit mess_len) const
- {
- //assert(op.get());
- return op->verify(signature, sig_len, message, mess_len);
- }
-
-SecureVector<byte> ECDSA_Core::sign(const byte message[], u32bit mess_len) const
- {
- //assert(op.get());
- return op->sign(message, mess_len);
- }
-
-ECDSA_Core& ECDSA_Core::operator=(const ECDSA_Core& core)
- {
- delete op;
- if(core.op)
- op = core.op->clone();
- return (*this);
- }
-
-ECDSA_Core::ECDSA_Core(const ECDSA_Core& core)
- {
- op = 0;
- if(core.op)
- op = core.op->clone();
- }
-
-ECDSA_Core::ECDSA_Core(EC_Domain_Params const& dom_pars, const BigInt& priv_key, PointGFp const& pub_key)
- {
- op = Engine_Core::ecdsa_op(dom_pars, priv_key, pub_key);
- }
-
}
diff --git a/src/pubkey/eckaeg/eckaeg_core.h b/src/pubkey/eckaeg/eckaeg_core.h
new file mode 100644
index 000000000..e4494bc98
--- /dev/null
+++ b/src/pubkey/eckaeg/eckaeg_core.h
@@ -0,0 +1,42 @@
+/*************************************************
+* ECKAEG Core Header File *
+* (C) 1999-2007 Jack Lloyd *
+* (C) 2007 FlexSecure GmbH *
+*************************************************/
+
+#ifndef BOTAN_ECKAEG_CORE_H__
+#define BOTAN_ECKAEG_CORE_H__
+
+#include <botan/eckaeg_op.h>
+#include <botan/blinding.h>
+#include <botan/ec_dompar.h>
+
+namespace Botan {
+
+/*************************************************
+* ECKAEG Core *
+*************************************************/
+class ECKAEG_Core
+ {
+ public:
+ SecureVector<byte> agree(const PointGFp&) const;
+
+ ECKAEG_Core& operator=(const ECKAEG_Core&);
+
+ ECKAEG_Core() { op = 0; }
+
+ ECKAEG_Core(const ECKAEG_Core&);
+
+ ECKAEG_Core(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ PointGFp const& pub_key);
+
+ ~ECKAEG_Core() { delete op; }
+ private:
+ ECKAEG_Operation* op;
+ Blinder blinder;
+ };
+
+}
+
+#endif
diff --git a/src/pubkey/eckaeg/eckaeg_op.cpp b/src/pubkey/eckaeg/eckaeg_op.cpp
new file mode 100644
index 000000000..3e7fb45d2
--- /dev/null
+++ b/src/pubkey/eckaeg/eckaeg_op.cpp
@@ -0,0 +1,44 @@
+/*************************************************
+* ECKAEG Operation *
+* (C) 2007 FlexSecure GmbH *
+* 2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/eckaeg_op.h>
+#include <botan/eng_def.h>
+
+namespace Botan {
+
+Default_ECKAEG_Op::Default_ECKAEG_Op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key)
+ : m_dom_pars(dom_pars),
+ m_pub_key(pub_key),
+ m_priv_key(priv_key)
+ {
+ }
+
+SecureVector<byte> Default_ECKAEG_Op::agree(const PointGFp& i) const
+ {
+ BigInt cofactor(m_dom_pars.get_cofactor());
+ BigInt n = m_dom_pars.get_order();
+ BigInt l(inverse_mod(cofactor,n)); // l=h^-1 mod n
+ PointGFp Q(cofactor*i); // q = h*Pb
+ PointGFp S(Q);
+ BigInt group_order = m_dom_pars.get_cofactor() * n;
+ S.mult_this_secure((m_priv_key*l)%n, group_order, n-1);
+ S.check_invariants();
+ return FE2OSP(S.get_affine_x()); // fe2os(xs)
+ }
+
+/*************************************************
+* Acquire a ECKAEG op *
+*************************************************/
+ECKAEG_Operation* Default_Engine::eckaeg_op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key) const
+ {
+ return new Default_ECKAEG_Op(dom_pars, priv_key, pub_key);
+ }
+
+}
diff --git a/src/pubkey/eckaeg/eckaeg_op.h b/src/pubkey/eckaeg/eckaeg_op.h
new file mode 100644
index 000000000..be2ff50f8
--- /dev/null
+++ b/src/pubkey/eckaeg/eckaeg_op.h
@@ -0,0 +1,47 @@
+/*************************************************
+* ECKAEG Operations Header File *
+* (C) 1999-2008 Jack Lloyd *
+* 2007 FlexSecure GmbH *
+*************************************************/
+
+#ifndef BOTAN_ECKAEG_OPERATIONS_H__
+#define BOTAN_ECKAEG_OPERATIONS_H__
+
+#include <botan/ec_dompar.h>
+
+namespace Botan {
+
+/*************************************************
+* ECKAEG Operation *
+*************************************************/
+class BOTAN_DLL ECKAEG_Operation
+ {
+ public:
+ virtual SecureVector<byte> agree(const PointGFp&) const = 0;
+ virtual ECKAEG_Operation* clone() const = 0;
+ virtual ~ECKAEG_Operation() {}
+ };
+
+/*************************************************
+* Default ECKAEG operation *
+*************************************************/
+class Default_ECKAEG_Op : public ECKAEG_Operation
+ {
+ public:
+ SecureVector<byte> agree(const PointGFp& i) const;
+
+ ECKAEG_Operation* clone() const { return new Default_ECKAEG_Op(*this); }
+
+ Default_ECKAEG_Op(const EC_Domain_Params& dom_pars,
+ const BigInt& priv_key,
+ const PointGFp& pub_key);
+ private:
+ EC_Domain_Params m_dom_pars;
+ PointGFp m_pub_key;
+ BigInt m_priv_key;
+ };
+
+
+}
+
+#endif
diff --git a/src/pubkey/eckaeg/info.txt b/src/pubkey/eckaeg/info.txt
new file mode 100644
index 000000000..bac47f861
--- /dev/null
+++ b/src/pubkey/eckaeg/info.txt
@@ -0,0 +1,24 @@
+realname "ECKAEG"
+
+define ECKAEG
+
+load_on auto
+
+<requires>
+asn1
+bigint
+ec_dompar
+ecc_key
+numbertheory
+gfpmath
+pubkey
+</requires>
+
+<add>
+eckaeg.cpp
+eckaeg.h
+eckaeg_core.cpp
+eckaeg_core.h
+eckaeg_op.cpp
+eckaeg_op.h
+</add>