Add functions returning security bits.
authorDr. Stephen Henson <steve@openssl.org>
Sat, 18 Jan 2014 14:51:40 +0000 (14:51 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 28 Mar 2014 14:49:04 +0000 (14:49 +0000)
Add functions to return the "bits of security" for various public key
algorithms. Based on SP800-57.

18 files changed:
crypto/asn1/ameth_lib.c
crypto/asn1/asn1_locl.h
crypto/bn/bn.h
crypto/bn/bn_lib.c
crypto/cmac/cm_ameth.c
crypto/dh/dh.h
crypto/dh/dh_ameth.c
crypto/dh/dh_lib.c
crypto/dsa/dsa.h
crypto/dsa/dsa_ameth.c
crypto/dsa/dsa_lib.c
crypto/ec/ec_ameth.c
crypto/evp/evp.h
crypto/evp/p_lib.c
crypto/hmac/hm_ameth.c
crypto/rsa/rsa.h
crypto/rsa/rsa_ameth.c
crypto/rsa/rsa_lib.c

index 5fff226..f317204 100644 (file)
@@ -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;
+       }
+
index a1035cd..023934b 100644 (file)
@@ -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);
index b3518cb..f4c8cc0 100644 (file)
@@ -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);
index 72da073..b1e224b 100644 (file)
@@ -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;
+       }
index 0b8e567..455c560 100644 (file)
@@ -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,
index 0cbb32e..8e8f87d 100644 (file)
@@ -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);
index 2b0035c..ce1edcb 100644 (file)
@@ -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,
index 7aef080..83b3dc5 100644 (file)
@@ -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);
+       }
index 6010a95..add452b 100644 (file)
@@ -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,
index 6b1d52f..aa3f55e 100644 (file)
@@ -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,
index c9b25a0..b78fadd 100644 (file)
@@ -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)
        {
index f024f90..ae9d531 100644 (file)
@@ -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,
index 94d1dc8..ea92aa2 100644 (file)
@@ -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)
index 109188c..42a8be1 100644 (file)
@@ -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)
index e03f24a..a6aa793 100644 (file)
@@ -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,
index 41a052a..543deaf 100644 (file)
@@ -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
index 929193b..04d9f62 100644 (file)
@@ -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,
 
index 9e3f7da..ba277ca 100644 (file)
@@ -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);
+       }