aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2014-01-18 14:51:40 +0000
committerDr. Stephen Henson <steve@openssl.org>2014-03-28 14:49:04 +0000
commit2514fa79acba998c2a8d4e5a8288a5b3ae990377 (patch)
tree28f4391dc3e8fc22197e53b75360800f182d9b19
parent4563da1d7c53e969e8d092d018795179bb648a7c (diff)
downloadopenssl-2514fa79acba998c2a8d4e5a8288a5b3ae990377.tar.gz
Add functions returning security bits.
Add functions to return the "bits of security" for various public key algorithms. Based on SP800-57.
-rw-r--r--crypto/asn1/ameth_lib.c7
-rw-r--r--crypto/asn1/asn1_locl.h1
-rw-r--r--crypto/bn/bn.h1
-rw-r--r--crypto/bn/bn_lib.c25
-rw-r--r--crypto/cmac/cm_ameth.c2
-rw-r--r--crypto/dh/dh.h1
-rw-r--r--crypto/dh/dh_ameth.c7
-rw-r--r--crypto/dh/dh_lib.c12
-rw-r--r--crypto/dsa/dsa.h1
-rw-r--r--crypto/dsa/dsa_ameth.c6
-rw-r--r--crypto/dsa/dsa_lib.c5
-rw-r--r--crypto/ec/ec_ameth.c17
-rw-r--r--crypto/evp/evp.h4
-rw-r--r--crypto/evp/p_lib.c9
-rw-r--r--crypto/hmac/hm_ameth.c2
-rw-r--r--crypto/rsa/rsa.h1
-rw-r--r--crypto/rsa/rsa_ameth.c6
-rw-r--r--crypto/rsa/rsa_lib.c5
18 files changed, 110 insertions, 2 deletions
diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c
index 5fff226120..f317204d9c 100644
--- a/crypto/asn1/ameth_lib.c
+++ b/crypto/asn1/ameth_lib.c
@@ -462,3 +462,10 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
{
ameth->pkey_ctrl = pkey_ctrl;
}
+
+void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pkey_security_bits)(const EVP_PKEY *pk))
+ {
+ ameth->pkey_security_bits = pkey_security_bits;
+ }
+
diff --git a/crypto/asn1/asn1_locl.h b/crypto/asn1/asn1_locl.h
index a1035cd46e..023934bb2b 100644
--- a/crypto/asn1/asn1_locl.h
+++ b/crypto/asn1/asn1_locl.h
@@ -122,6 +122,7 @@ struct evp_pkey_asn1_method_st
int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_bits)(const EVP_PKEY *pk);
+ int (*pkey_security_bits)(const EVP_PKEY *pk);
int (*param_decode)(EVP_PKEY *pkey,
const unsigned char **pder, int derlen);
diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h
index b3518cb3ba..f4c8cc0124 100644
--- a/crypto/bn/bn.h
+++ b/crypto/bn/bn.h
@@ -420,6 +420,7 @@ int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
int BN_num_bits(const BIGNUM *a);
int BN_num_bits_word(BN_ULONG l);
+int BN_security_bits(int L, int N);
BIGNUM *BN_new(void);
void BN_init(BIGNUM *);
void BN_clear_free(BIGNUM *a);
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 72da0735fd..b1e224bb4d 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -880,3 +880,28 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
}
#undef BN_CONSTTIME_SWAP
}
+
+/* Bits of security, see SP800-57 */
+
+int BN_security_bits(int L, int N)
+ {
+ int secbits, bits;
+ if (L >= 15360)
+ secbits = 256;
+ else if (L >= 7690)
+ secbits = 192;
+ else if (L >= 3072)
+ secbits = 128;
+ else if (L >= 2048)
+ secbits = 112;
+ else if (L >= 1024)
+ secbits = 80;
+ else
+ return 0;
+ if (N == -1)
+ return secbits;
+ bits = N / 2;
+ if (bits < 80)
+ return 0;
+ return bits >= secbits ? secbits : bits;
+ }
diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c
index 0b8e5670b0..455c5602d9 100644
--- a/crypto/cmac/cm_ameth.c
+++ b/crypto/cmac/cm_ameth.c
@@ -87,7 +87,7 @@ const EVP_PKEY_ASN1_METHOD cmac_asn1_meth =
0,0,0,
cmac_size,
- 0,
+ 0, 0,
0,0,0,0,0,0,0,
cmac_key_free,
diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
index 0cbb32e336..8e8f87dfdc 100644
--- a/crypto/dh/dh.h
+++ b/crypto/dh/dh.h
@@ -202,6 +202,7 @@ DH * DH_new(void);
void DH_free(DH *dh);
int DH_up_ref(DH *dh);
int DH_size(const DH *dh);
+int DH_security_bits(const DH *dh);
int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int DH_set_ex_data(DH *d, int idx, void *arg);
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 2b0035cd0a..ce1edcb0d9 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -448,6 +448,11 @@ static int dh_bits(const EVP_PKEY *pkey)
return BN_num_bits(pkey->pkey.dh->p);
}
+static int dh_security_bits(const EVP_PKEY *pkey)
+ {
+ return DH_security_bits(pkey->pkey.dh);
+ }
+
static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
{
if ( BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
@@ -620,6 +625,7 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
int_dh_size,
dh_bits,
+ dh_security_bits,
dh_param_decode,
dh_param_encode,
@@ -653,6 +659,7 @@ const EVP_PKEY_ASN1_METHOD dhx_asn1_meth =
int_dh_size,
dh_bits,
+ dh_security_bits,
dh_param_decode,
dh_param_encode,
diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c
index 7aef080e7a..83b3dc50c1 100644
--- a/crypto/dh/dh_lib.c
+++ b/crypto/dh/dh_lib.c
@@ -245,3 +245,15 @@ int DH_size(const DH *dh)
{
return(BN_num_bytes(dh->p));
}
+
+int DH_security_bits(const DH *dh)
+ {
+ int N;
+ if (dh->q)
+ N = BN_num_bits(dh->q);
+ else if (dh->length)
+ N = dh->length;
+ else
+ N = -1;
+ return BN_security_bits(BN_num_bits(dh->p), N);
+ }
diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h
index 6010a954f0..add452b27c 100644
--- a/crypto/dsa/dsa.h
+++ b/crypto/dsa/dsa.h
@@ -234,6 +234,7 @@ void DSA_free (DSA *r);
/* "up" the DSA object's reference count */
int DSA_up_ref(DSA *r);
int DSA_size(const DSA *);
+int DSA_security_bits(const DSA *d);
/* next 4 return -1 on error */
int DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
int DSA_sign(int type,const unsigned char *dgst,int dlen,
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index 6b1d52fab2..aa3f55e218 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -368,6 +368,11 @@ static int dsa_bits(const EVP_PKEY *pkey)
return BN_num_bits(pkey->pkey.dsa->p);
}
+static int dsa_security_bits(const EVP_PKEY *pkey)
+ {
+ return DSA_security_bits(pkey->pkey.dsa);
+ }
+
static int dsa_missing_parameters(const EVP_PKEY *pkey)
{
DSA *dsa;
@@ -696,6 +701,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
int_dsa_size,
dsa_bits,
+ dsa_security_bits,
dsa_param_decode,
dsa_param_encode,
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index c9b25a0561..b78fadd467 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -272,6 +272,11 @@ void *DSA_get_ex_data(DSA *d, int idx)
return(CRYPTO_get_ex_data(&d->ex_data,idx));
}
+int DSA_security_bits(const DSA *d)
+ {
+ return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
+ }
+
#ifndef OPENSSL_NO_DH
DH *DSA_dup_DH(const DSA *r)
{
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index f024f90497..ae9d5319a3 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -395,6 +395,22 @@ static int ec_bits(const EVP_PKEY *pkey)
return ret;
}
+static int ec_security_bits(const EVP_PKEY *pkey)
+ {
+ int ecbits = ec_bits(pkey);
+ if (ecbits >= 512)
+ return 256;
+ if (ecbits >= 384)
+ return 192;
+ if (ecbits >= 256)
+ return 128;
+ if (ecbits >= 224)
+ return 112;
+ if (ecbits >= 160)
+ return 80;
+ return ecbits / 2;
+ }
+
static int ec_missing_parameters(const EVP_PKEY *pkey)
{
if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
@@ -659,6 +675,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
int_ec_size,
ec_bits,
+ ec_security_bits,
eckey_param_decode,
eckey_param_encode,
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index 94d1dc863b..ea92aa28d8 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -957,6 +957,7 @@ int EVP_PKEY_type(int type);
int EVP_PKEY_id(const EVP_PKEY *pkey);
int EVP_PKEY_base_id(const EVP_PKEY *pkey);
int EVP_PKEY_bits(EVP_PKEY *pkey);
+int EVP_PKEY_security_bits(const EVP_PKEY *pkey);
int EVP_PKEY_size(EVP_PKEY *pkey);
int EVP_PKEY_set_type(EVP_PKEY *pkey,int type);
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
@@ -1115,6 +1116,9 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
long arg1, void *arg2));
+void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pkey_security_bits)(const EVP_PKEY *pk));
+
#define EVP_PKEY_OP_UNDEFINED 0
#define EVP_PKEY_OP_PARAMGEN (1<<1)
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 109188c45b..42a8be1bb8 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -89,6 +89,15 @@ int EVP_PKEY_bits(EVP_PKEY *pkey)
return 0;
}
+int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
+ {
+ if (pkey == NULL)
+ return 0;
+ if (!pkey->ameth || !pkey->ameth->pkey_security_bits)
+ return -2;
+ return pkey->ameth->pkey_security_bits(pkey);
+ }
+
int EVP_PKEY_size(EVP_PKEY *pkey)
{
if (pkey && pkey->ameth && pkey->ameth->pkey_size)
diff --git a/crypto/hmac/hm_ameth.c b/crypto/hmac/hm_ameth.c
index e03f24aeda..a6aa793110 100644
--- a/crypto/hmac/hm_ameth.c
+++ b/crypto/hmac/hm_ameth.c
@@ -152,7 +152,7 @@ const EVP_PKEY_ASN1_METHOD hmac_asn1_meth =
0,0,0,
hmac_size,
- 0,
+ 0, 0,
0,0,0,0,0,0,0,
hmac_key_free,
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index 41a052a3ee..543deaf572 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -307,6 +307,7 @@ struct rsa_st
RSA * RSA_new(void);
RSA * RSA_new_method(ENGINE *engine);
int RSA_size(const RSA *rsa);
+int RSA_security_bits(const RSA *rsa);
/* Deprecated version */
#ifndef OPENSSL_NO_DEPRECATED
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 929193b4fa..04d9f62dd0 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -170,6 +170,11 @@ static int rsa_bits(const EVP_PKEY *pkey)
return BN_num_bits(pkey->pkey.rsa->n);
}
+static int rsa_security_bits(const EVP_PKEY *pkey)
+ {
+ return RSA_security_bits(pkey->pkey.rsa);
+ }
+
static void int_rsa_free(EVP_PKEY *pkey)
{
RSA_free(pkey->pkey.rsa);
@@ -993,6 +998,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
int_rsa_size,
rsa_bits,
+ rsa_security_bits,
0,0,0,0,0,0,
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index 9e3f7dafcd..ba277cacd8 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -320,3 +320,8 @@ int RSA_memory_lock(RSA *r)
r->bignum_data=p;
return(1);
}
+
+int RSA_security_bits(const RSA *rsa)
+ {
+ return BN_security_bits(BN_num_bits(rsa->n), -1);
+ }