diff options
author | Jack Lloyd <[email protected]> | 2017-03-02 23:06:45 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-03-02 23:06:45 -0500 |
commit | 23cea08ffe2a3ff176a9a6e2f19e3720844ae958 (patch) | |
tree | 75a91937c1ca073ffc1473e722a948e03a1ef3ca | |
parent | 6b668aa1db95ebca5980788ec1a6906af716ffbc (diff) | |
parent | 5845d5265680368984bbb43fd2c5c68fd7e92bc5 (diff) |
Merge GH #902 Extend EC_PublicKey check, add EC_Group check, ECC invalid key tests
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.cpp | 41 | ||||
-rw-r--r-- | src/lib/pubkey/ec_group/ec_group.h | 9 | ||||
-rw-r--r-- | src/lib/pubkey/ecc_key/ecc_key.cpp | 32 | ||||
-rw-r--r-- | src/tests/data/pubkey/dh_invalid.vec | 3 | ||||
-rw-r--r-- | src/tests/data/pubkey/ecc_invalid.vec | 18 | ||||
-rw-r--r-- | src/tests/data/pubkey/ecdsa_invalid.vec | 368 | ||||
-rw-r--r-- | src/tests/test_ecdsa.cpp | 40 | ||||
-rw-r--r-- | src/tests/unit_ecc.cpp | 27 |
8 files changed, 534 insertions, 4 deletions
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp index cbc628195..e8a9672ab 100644 --- a/src/lib/pubkey/ec_group/ec_group.cpp +++ b/src/lib/pubkey/ec_group/ec_group.cpp @@ -12,6 +12,7 @@ #include <botan/der_enc.h> #include <botan/oids.h> #include <botan/pem.h> +#include <botan/reducer.h> namespace Botan { @@ -130,4 +131,44 @@ std::string EC_Group::PEM_encode() const return PEM_Code::encode(der, "EC PARAMETERS"); } +bool EC_Group::verify_group(RandomNumberGenerator& rng, + bool) const + { + //compute the discriminant + Modular_Reducer p(m_curve.get_p()); + BigInt discriminant = p.multiply(4, m_curve.get_a()); + discriminant += p.multiply(27, m_curve.get_b()); + discriminant = p.reduce(discriminant); + //check the discriminant + if(discriminant == 0) + { + return false; + } + //check for valid cofactor + if(m_cofactor < 1) + { + return false; + } + //check if the base point is on the curve + if(!m_base_point.on_the_curve()) + { + return false; + } + if((m_base_point * m_cofactor).is_zero()) + { + return false; + } + //check if order is prime + if(!is_prime(m_order, rng, 128)) + { + return false; + } + //check if order of the base point is correct + if(!(m_base_point * m_order).is_zero()) + { + return false; + } + return true; + } + } diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h index 15c09a54d..a2cd4d719 100644 --- a/src/lib/pubkey/ec_group/ec_group.h +++ b/src/lib/pubkey/ec_group/ec_group.h @@ -113,7 +113,14 @@ class BOTAN_DLL EC_Group * @result the OID */ std::string get_oid() const { return m_oid; } - + + /** + * Verify EC_Group domain + * @returns true if group is valid. false otherwise + */ + bool verify_group(RandomNumberGenerator& rng, + bool strong = false) const; + bool operator==(const EC_Group& other) const { return ((get_curve() == other.get_curve()) && diff --git a/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/lib/pubkey/ecc_key/ecc_key.cpp index cb0af42eb..0c59c75fd 100644 --- a/src/lib/pubkey/ecc_key/ecc_key.cpp +++ b/src/lib/pubkey/ecc_key/ecc_key.cpp @@ -44,12 +44,40 @@ EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, m_domain_encoding{EC_DOMPAR_ENC_EXPLICIT} {} -bool EC_PublicKey::check_key(RandomNumberGenerator&, +bool EC_PublicKey::check_key(RandomNumberGenerator& rng, bool) const { - return public_point().on_the_curve(); + //verify domain parameters + if(!m_domain_params.verify_group(rng)) + { + return false; + } + //check that public point is not at infinity + if(public_point().is_zero()) + { + return false; + } + //check that public point is on the curve + if(!public_point().on_the_curve()) + { + return false; + } + if(m_domain_params.get_cofactor() > 1) + { + if((public_point() * m_domain_params.get_cofactor()).is_zero()) + { + return false; + } + //check that public point has order q + if(!(public_point() * m_domain_params.get_order()).is_zero()) + { + return false; + } + } + return true; } + AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const { return AlgorithmIdentifier(get_oid(), DER_domain()); diff --git a/src/tests/data/pubkey/dh_invalid.vec b/src/tests/data/pubkey/dh_invalid.vec index 8911cdff3..2a5de3dd7 100644 --- a/src/tests/data/pubkey/dh_invalid.vec +++ b/src/tests/data/pubkey/dh_invalid.vec @@ -1,4 +1,5 @@ -# public keys failing checks from NIST CAVS file 20.1 (Generated on Mon Jun 20 09:02:25 2016) + +# Public keys failing checks from NIST CAVS file 20.1 (Generated on Mon Jun 20 09:02:25 2016) # http://csrc.nist.gov/groups/STM/cavp/documents/keymgmt/KASTestVectorsFFC2016.zip G = 0x1e2b67448a1869df1ce57517dc5e797b62c5d2c832e23f954bef8bcca74489db6caed2ea496b52a52cb664a168374cb176ddc4bc0068c6eef3a746e561f8dc65195fdaf12b363e90cfffdac18ab3ffefa4b2ad1904b45dd9f6b76b477ef8816802c7bd7cb0c0ab25d378098f5625e7ff737341af63f67cbd00509efbc6470ec38c17b7878a463cebda80053f36558a308923e6b41f465385a4f24fdb303c37fb998fc1e49e3c09ce345ff7cea18e9cd1457eb93daa87dba8a31508fa5695c32ce485962eb1834144413b41ef936db71b79d6fe985c018ac396e3af25054dbbc95e56ab5d4d4b7b61a70670e789c336b46b9f7be43cf6eb0e68b40e33a55d55cc diff --git a/src/tests/data/pubkey/ecc_invalid.vec b/src/tests/data/pubkey/ecc_invalid.vec new file mode 100644 index 000000000..887658f26 --- /dev/null +++ b/src/tests/data/pubkey/ecc_invalid.vec @@ -0,0 +1,18 @@ + +# Public keys failing checks from Google's Wycheproof +# https://github.com/google/wycheproof/blob/master/java/com/google/security/wycheproof/testcases/EcKeyTest.java + +# order = -115792089210356248762697446949407573529996955224135760342422259061068512044369 +SubjectPublicKey = 308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f50221ff00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf02010103420004cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8 + +# order = 0 +SubjectPublicKey = 308201123081cb06072a8648ce3d02013081bf020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5020002010103420004cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8 + +# cofactor = -1 +SubjectPublicKey = 308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc6325510201ff03420004cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8 + +# cofactor = 0 +SubjectPublicKey = 308201323081eb06072a8648ce3d02013081df020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020003420004cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8 + +# cofactor = 115792089210356248762697446949407573529996955224135760342422259061068512044369 +SubjectPublicKey = 308201553082010d06072a8648ce3d020130820100020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff30440420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255103420004cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8 diff --git a/src/tests/data/pubkey/ecdsa_invalid.vec b/src/tests/data/pubkey/ecdsa_invalid.vec new file mode 100644 index 000000000..db87a38f7 --- /dev/null +++ b/src/tests/data/pubkey/ecdsa_invalid.vec @@ -0,0 +1,368 @@ + +# Public keys failing checks from NIST CAVS file 11.0 (Generated on Tue Mar 01 23:36:01 2011) +# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-2ecdsatestvectors.zip + +# [P-192] + +Group = secp192r1 + +# Point not on curve +InvalidKeyX = 0x491c0c4761b0a4a147b5e4ce03a531546644f5d1e3d05e57 +InvalidKeyY = 0x6fa5addd47c5d6be3933fbff88f57a6c8ca0232c471965de + +# Point not on curve +InvalidKeyX = 0x4c6b9ea0dec92ecfff7799470be6a2277b9169daf45d54bb +InvalidKeyY = 0xf0eab42826704f51b26ae98036e83230becb639dd1964627 + +# Point not on curve +InvalidKeyX = 0x82c949295156192df0b52480e38c810751ac570daec460a3 +InvalidKeyY = 0x200057ada615c80b8ff256ce8d47f2562b74a438f1921ac3 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1b574acd4fb0f60dde3e3b5f3f0e94211f95112e43cba6fd2 +InvalidKeyY = 0xbcc1b8a770f01a22e84d7f14e44932ffe094d8e3b1e6ac26 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x16ba109f1f1bb44e0d05b80181c03412ea764a59601d17e9f +InvalidKeyY = 0x0569a843dbb4e287db420d6b9fe30cd7b5d578b052315f56 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1333308a7c833ede5189d25ea3525919c9bd16370d904938d +InvalidKeyY = 0xb10fd01d67df75ff9b726c700c1b50596c9f0766ea56f80e + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x158e8b6f0b14216bc52fe8897b4305d870ede70436a96741d +InvalidKeyY = 0xfb3f970b19a313571a1a23be310923f85acc1cab0a157cbd + +# Point not on curve +InvalidKeyX = 0xace95b650c08f73dbb4fa7b4bbdebd6b809a25b28ed135ef +InvalidKeyY = 0xe9b8679404166d1329dd539ad52aad9a1b6681f5f26bb9aa + +# [P-224] + +Group = secp224r1 + +# Point not on curve +InvalidKeyX = 0x3913b7c347f0d56bdda1244a973378ae1a23b6c05f6ea276491e75d8 +InvalidKeyY = 0xc5c9086cb4704540d566a9f2cc461488fb80b7dd7384cefea4616c15 + +# Point not on curve +InvalidKeyX = 0x2b27eeb74e93b92f423e8d1bdb6869811746af14c2887a54338f3982 +InvalidKeyY = 0xca92f56341ce049bf0300a1cc5f57be96cdc1703512c28b1e07ab6c4 + +# Point not on curve +InvalidKeyX = 0xc32bc4bee87df6478f76cc74552c337fbc00026d74f22068e6a98e2a +InvalidKeyY = 0x9c618bec3f89628a61638d69d61824d36070379fa0d2c6d7a63a62e7 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0xc0d570b903d8f1743b3235af72c0772abd5209e96b7d6d43f305d3f8 +InvalidKeyY = 0x11fe6013787c8a8dcc19ca6be51aec3dddc5b92d9540a047af860e76c + +# Point not on curve +InvalidKeyX = 0x7ed8ceb65fc7d06dc6f4976b33f2611ef0da9913900c1073cabd3836 +InvalidKeyY = 0xe2594a63469d0b84fdd3e29cec8a08427e71c585d9653ab1322dfad1 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x56579986c148519adb29e8d2d374e7ceddafc85448612a297f0f0f46 +InvalidKeyY = 0x1d6ac5f9a38354875f1ed2973aa44d7b8ca5e5ad7249ee3bc648b20b3 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1e2412382d3c1b0683bdd152a64a0e1ee06359146872a6fc26584b666 +InvalidKeyY = 0x125591c446520d0dcae5c9287c2ce4fb69a1f82827d41f9fe4f29744 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x847ac5c23e0f100fcd9451ab948eaf78eb38aab98060d1539cb485d0 +InvalidKeyY = 0x170ca182475dd56eda14e3eaf3f2fbd17926d41175ea272e475e8732d + +# [P-256] + +Group = secp256r1 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0xd2b419e62dc101b395401208b9868a3b3fd007ad92adb18921c068d416aa22e7 +InvalidKeyY = 0x17952007e021b46a2ab12f14115aafb70608a37f0c3366e7e3921414b904d395a + +# Point not on curve +InvalidKeyX = 0x6f969d90fd494b04913eda9e0cf23f66eea5a70dfd5fb3e48f393397421c2b02 +InvalidKeyY = 0xc19ad66d7d6993b792b608879e1d861026805cf6fde1f5d8bb4f790ad1cee456 + +# Point not on curve +InvalidKeyX = 0x8332d9d42b5f48f08b3dd969dbbb28d2be9de30adf560727068e670444f5976f +InvalidKeyY = 0x58880380a26a9b3881d189da6b48a11a531c31cefebe696efbd5eaec5917382d + +# Point not on curve +InvalidKeyX = 0xd45779fb33629e21abe0d4a5f8b99f12c71952e53aa4ca065cc393e6300d0f2e +InvalidKeyY = 0x6d1a3d5666c7ee9c84c03f02ca2834f5eaf924d6c15536a7b4877481be3fcd2c + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x18c60b77ce23fb3210073ba7dad451ca25bf16c3c1d2d67b2e6eca51f1c77e56 +InvalidKeyY = 0x19b47a0fea8c46dc3bd9f65506b281a9dc872d16ed90fd20e94f2fbc94c68d0ba + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x5772caf0d1641479a79aa443fefb222a385b3c481ff51e9fce76ccb513a9bfad +InvalidKeyY = 0x110906da47200cb4a536f2c4f601c4ecf82d8dc18405a1cd4746b25a572b46b2c + +# Point not on curve +InvalidKeyX = 0x9ba790614fa1c43816b77729ce03f2cc9666e25f27488886a270b22a36636f11 +InvalidKeyY = 0x0a0d36ae87c44c2671a2684793fe8ef2bf6c17411f3fb972b695e30b101b1184 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0xdde744307e7b64098581aa52db5de8c22cdbd46959922e15a714192b7597ecf4 +InvalidKeyY = 0x111c5393185604be8cbd53b28d2c3fcb4e853291a5bd82660564e4eeda10924c8 + +# [P-384] + +Group = secp384r1 + +# Point not on curve +InvalidKeyX = 0x58fd70ca9e315b2c99152fd3f1071889fcfbe1387c02e6169850e2cba3bb3d21c9f295def8b7680fbca9c43956cfc190 +InvalidKeyY = 0xbf7a80d161e429445fb613aeffb71840e1cd7fa9139be4c535c33ae32790f48f6ce4de4b275a55d0b433e86af00766a9 + +# Point not on curve +InvalidKeyX = 0x06a05a2f6a05c7e8684b6df74392faea822f89eecad01e791b0559f6ac650abd85084ceeddfbee85391d5809adb73fef +InvalidKeyY = 0x3191a5af6ef4bbad57fe2748ebfe98a4f71dd7b580349d853b9052f326d7a8a42a45ee6e6fd67a49ddbd23b53b92b6d6 + +# Point not on curve +InvalidKeyX = 0x432989eeadbb65d0b11ce46e6049b9c871941a7f4349b30ac0a4e5494bd43cc21608a1e61211f3071c8af12a90475792 +InvalidKeyY = 0xbc68ef58e930b4e5a4668d682582c2a1ea1de54589eebe1b754588ba6f14dbcd49b2265a584b7bcb8f7013c6cf7e7880 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1a9e6542ec66d46262c75bd60d9767e114eab403bb3e7576261e5b9a243091b9784c863bbba63cfd3a325d51bdf19eb0d +InvalidKeyY = 0x227e025dc40c7025e0961e7841d765d2b59a77fba8dab2150ec9f3153e4fdd2194f775c1b98abb2af9369e4a459cf205 + +# Point not on curve +InvalidKeyX = 0x494c8ecf87e9b7964a1a5736a999828da7904c4345d2c9a521a3d0ae07067bab548a0bca0f90828b678fc182572ea067 +InvalidKeyY = 0x15742dd1305079f2b2a8c7f75d191bbca147a7bf111b8d619fb00ae53cf9988084e7c2a90c516c93b06e4ef525e42fde + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x19c0a1c05c945ecadfd00377c81eb4902f40bc3a411c81ab94a444fde37507ee0b341be268da10b6259ac2b5a0965a08e +InvalidKeyY = 0xdb9e823dfffde66128955fbd322bac382ce2c2ceb8e11f32f98f09dec41631c22df7ea8838b160adb21685847591959b + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0xc4059321bfc49437084eb6b5c746b52c03aceb7959d72f620b9d668ef2b314ea63fec712262d516ae7d839592f8ed118 +InvalidKeyY = 0x165aa703ba328334c9938e61d660b328a6dc672e17b62b550634b862c26f63ee4856bdcc822237c6d598a55175937affd + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x14f96eb9c3623e8ca98edc297f82501d5c6c7c01c11bda6e5e5e166b8525c22c773a5e55fb5a7d04cae08f6a190ad3ac8 +InvalidKeyY = 0x47f665e4fb9e9f9e592ac8441e41aeb1c0ed240a05bbd93d6ec260a0644a4d9202aa5a5f28cefde4362878d5aae68222 + +# [P-521] + +Group = secp521r1 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x07573e6115674bbffb65097f3dcb05597a35193bf0ed1a4b90a86006eabe5ed638d1e11adb769cd6ed7fba181dea42ffc38a611a6f162fe10b925b80ce9c419ac80 +InvalidKeyY = 0x2dbe133e4ff21af1aa50742fc1f7c74cbe8342fe5037c33b961f65b218f947a4acada6d53b1e0bf9ada5be979652275bce77194c8fae2066c5531196aa9997dd2bc + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x014bc514f2b5664a35d1728cc096cc7de2b0391089c014f5f3e4d1048ec5d8497fbe6cfe008b634d708d12bac6aa616c78af1576c0a8676a17a16773ee5a827e3b5 +InvalidKeyY = 0x2c027dade98d1a7b433368075e19e8269d8465bbc91c4c3aebfdb2418115d331ea946663713d67f9226f4920c85b0d78c312e87826672f107bcd6c19ea17fff4331 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x259d237214e071f725c77674b38b8b6cc590bed12b7cfdb3d177162afb2a40ab0540f77386ab98ac049711287a5b80891ece13ea34c545c19593e87a15237e2a108 +InvalidKeyY = 0x1f33c8963f0981350d77615f0e04e24515a76efc690140272efddaa8cb85b140acad7fc42cf6da7ff5f3ce47183f46e7272b06eca4c74200536223fef2d74e095b1 + +# Point not on curve +InvalidKeyX = 0x089eb672b023d7098bb864bd7789b9f6f4ee268aa9dca6ba3268023b2119be34ee035699d7f1f776ff6028a91824fbfefa22671ed2ce7ffb46ddcece33d1087985d +InvalidKeyY = 0x07b7ea0588de385a35a5c0e7dba9cd86fd13d91f71a97a9769e483c2fb823cc3ae9fb9800a05814a25af676f780de1d805a174b70703b51e46455d0eae78b5d7e1d + +# Point not on curve +InvalidKeyX = 0x1859642073e648dd5580346ad5ba9daec8b60d5b574938b2f16ef2a48128ffcadaa46be1fa10ded234d72ec3c38d7cb898281d25264c00d83c2a14bab175ddb9d2b +InvalidKeyY = 0x11ad23cb933fa28e00d7d9b0faf78297e4f2b026e6fff74e456b8f2df938e52ceaf98760070c8d22c7f742728434eb6ae6afe7193ee81bc730f5549eebacf7f9952 + +# Point not on curve +InvalidKeyX = 0x176b36128e5a294876c57fac275f388155eb5715c8ace3d90ee4c31b755c8f867327b7e037e7be8f6b521b2674e1786d67294c1f5b098be16102ddd361d92505fd0 +InvalidKeyY = 0x0d01b3f053aecde9e0c534d6a518fe24c68ef246b4cff071a3ebbc742152c9d4e872b1acd5a76a42847fe98e9360e7c33ba8575cf75218e89564839ac9f13e6ef14 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x01f26ff28f769521f232fb83e697c9cde606d11383115deef0af16fc05e4631850b57975ae91299b87133fc53bdb424fd8f21b28c7636055eca88f3417d80a3bde1 +InvalidKeyY = 0x2748bee6ea7c3b9790fb927c0e691436b946d35b7d52b98398cbcf433683138f48ebe93a007e611f00a73dcfadfd2b0bedbc48bf2de204969df04cebfc1018072f1 + +# Point not on curve +InvalidKeyX = 0x0fcacf322f6be9da5342dae87cbc8cdcb22bc489ca6e97b186b97d2ac02610518b5ee72be37f22825278fb205895f2f823540b91b313abb54a6b41506152e0deec3 +InvalidKeyY = 0x187333ce6fe5e6dea5d08d8f5950b5207cb8eb34fa0de2cae5acad8bc8436ff617b45bd8f2975f2762982219b3136bffec3f6c58f8f2cd0d6eb2ebd46467219126f + +# TODO check FIPS 186-4 + +# Public keys failing checks from NIST CAVS file 11.0 (Generated on Wed Mar 16 16:16:42 2011) +# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip + +# [P-192] + +Group = secp192r1 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x472a620598e6715eff9cc022805d8cc8e8219f0e32042538 +InvalidKeyY = 0x1971ca86edb3471b2a16b9aae9de90f366f371b26385027e6 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x192a2b854bf4e70d5a8fecc98f43b4a744b26808f8cf4c60d +InvalidKeyY = 0x2c0b29190588eabf08dfe160ac8d3ab6f5d5cc73678ebae8 + +# Point not on curve +InvalidKeyX = 0xc07ce28e4c846d7327f0554119ddb7e865fa1dd448ba2b40 +InvalidKeyY = 0x33aefa3177b99901d9ab6c12eb0749197420296ccb9d4e4a + +# Point not on curve +InvalidKeyX = 0xf77c2e5946d99932b2a01c1c73a296ecde568978103d8e2b +InvalidKeyY = 0xde46b2d5c94dc11b53578eafaa23f96de9747b086979416c + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1016451af3e7a7fa2ce3cf2acbe07fa7fa19a5f14455bf2ec +InvalidKeyY = 0xc074630aea063e00bb41e6fbf752dd4f8e5bc742bf3363eb + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x18eea61787fbcd90f73f947346cdf13f05b4170e3e7456165 +InvalidKeyY = 0x5514c7b6e0eecc4e9c1ad99710f009a550bf3f952bb16593 + +# Point not on curve +InvalidKeyX = 0x39ed11c88869f6c4705125d9d5fc7c6b1e3d22b2fa7a6b57 +InvalidKeyY = 0xd0cf50208f6b1a61ba346a3f3f8f58128c8199e5405a6f11 + +# Point not on curve +InvalidKeyX = 0x87d67f9b7cced918d827ffc086cfd6a181fc61b2f56e000b +InvalidKeyY = 0xc6c8d686c61a816d25c085db665f018e31ad6f71ee24d895 + +[P-224] + +Group = secp224r1 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x7a9369e2173bbf29589bf47e3ae0ccf47df6d2268c2292f906cc9261 +InvalidKeyY = 0x11afc53c7c1b085029f53b41fcd5a336bafb35b89d302f2bd04df44e6 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1803faeef9b40957f59ab97d543f86690afd7471dfb8b04b84ea31085 +InvalidKeyY = 0x738cc29474ca048930b7f1a29db3773d11839ed83a6993e3f23692d7 + +# Point not on curve +InvalidKeyX = 0xc01795a001b6b8a5b3db9acbdb55c2f97f4a50aa0a0cfed1d50a4c28 +InvalidKeyY = 0xb79dbe52a47a4640100cc939b435377f0bcb8db4ec52ecaadac5d919 + +# Point not on curve +InvalidKeyX = 0xfbe3bff58dc58ca1ef9dc942fd43cdadbd060d70e0b1e6b9583a2228 +InvalidKeyY = 0xca844b43c237d497c34b986c681bf3cc54f968c0db74b2e1d9fe9d94 + +# Point not on curve +InvalidKeyX = 0xcbe83c33848dd5a89ea8c45d23b99f23254e2077bd9ab26f6b5bed9f +InvalidKeyY = 0xc0d09533d78a96e39028162534d74b097364095e2dc60776938af83b + +# Point not on curve +InvalidKeyX = 0x491e8d6c73708104c9530878f866e585cba008ef70baa46a809a2c03 +InvalidKeyY = 0x924a28ace8db9a88f7f874a1f24ac7f0bf56484f2130d5be5a8a1721 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1a89dc6a91002c9d25a3c4621fb5606b52531fd8e48a44119f442f749 +InvalidKeyX = 0x62f556641faa83059425026ca18ecbd219fe6d5df3b7713ce8b168cd + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x182a4cee32c06292556f4e29950f5b2db9ad627a56e92680358d6cac4 +InvalidKeyY = 0xfa2a87aa3757ae9fa00d11db57089632c4f9e33fb214b9324cf75bd9 + +[P-256] + +Group = secp256r1 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0xd17c446237d9df87266ba3a91ff27f45abfdcb77bfd83536e92903efb861a9a9 +InvalidKeyY = 0x1eabb6a349ce2cd447d777b6739c5fc066add2002d2029052c408d0701066231c + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x17875397ae87369365656d490e8ce956911bd97607f2aff41b56f6f3a61989826 +InvalidKeyY = 0x980a3c4f61b9692633fbba5ef04c9cb546dd05cdec9fa8428b8849670e2fba92 + +# Point not on curve +InvalidKeyX = 0xf2d1c0dc0852c3d8a2a2500a23a44813ccce1ac4e58444175b440469ffc12273 +InvalidKeyY = 0x32bfe992831b305d8c37b9672df5d29fcb5c29b4a40534683e3ace23d24647dd + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x10b0ca230fff7c04768f4b3d5c75fa9f6c539bea644dffbec5dc796a213061b58 +InvalidKeyY = 0x5edf37c11052b75f771b7f9fa050e353e464221fec916684ed45b6fead38205 + +# Point not on curve +InvalidKeyX = 0xa40d077a87dae157d93dcccf3fe3aca9c6479a75aa2669509d2ef05c7de6782f +InvalidKeyY = 0x503d86b87d743ba20804fd7e7884aa017414a7b5b5963e0d46e3a9611419ddf3 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x14bf57f76c260b51ec6bbc72dbd49f02a56eaed070b774dc4bad75a54653c3d56 +InvalidKeyY = 0x7a231a23bf8b3aa31d9600d888a0678677a30e573decd3dc56b33f365cc11236 + +# Point not on curve +InvalidKeyX = 0xf8c6dd3181a76aa0e36c2790bba47041acbe7b1e473ff71eee39a824dc595ff0 +InvalidKeyY = 0x9c965f227f281b3072b95b8daf29e88b35284f3574462e268e529bbdc50e9e52 + +# Point not on curve +InvalidKeyX = 0x7a81a7e0b015252928d8b36e4ca37e92fdc328eb25c774b4f872693028c4be38 +InvalidKeyX = 0x08862f7335147261e7b1c3d055f9a316e4cab7daf99cc09d1c647f5dd6e7d5bb + +[P-384] + +Group = secp384r1 + +# Point not on curve +InvalidKeyX = 0xe87cc868cdf196471d3fc78c324be2c4a0de8dbde182afea88baa51666f3cc9993eae5f1d60d4aec58894f0357273c48 +InvalidKeyY = 0x187219b0adc398c835791798053cc6a0bcc6e43228ac23101ee93dfce0e508be988a55fa495eb93b832064dc035e7720 + +# Point not on curve +InvalidKeyX = 0x25e5509a54f5fa62f94551dff3dfe210db1bb2bbc8fd4e672fbd5a211f9fd2f7eadc2b83fcd4198b7f857d9a2dc39c11 +InvalidKeyY = 0x98a4a13bc2f2d04bebd6d4e04412a9d306e57b90364583a6ec25bf6f0175bb5b397b8cfea83fd5d1e0ad052852b4aba7 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x11a14be72dd023667047c260dd1960dd16555289d9570001d53ea3e494c1c107800dc5b24dd4de8490a071658702a0962 +InvalidKeyY = 0x78d65f6975d10df838b96a16cba873b59c28f2c7d05654b8c8b78bd193694ae45d6c6e046a20b984c3467c72d49395fe + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1bf2238026a2489fb6ac1a8d6b82fdb33b05e8d01f1e2671eb22e61734031cc63efbf7e14d23e81fd432fc9935c627cdd +InvalidKeyY = 0x6b377c8b187d568b782a28b38a7861b69e3d016f9f9ebb7eff2e7732a5132785b5a32e069dcef12875a995908a8b72f1 + +# Point not on curve +InvalidKeyX = 0xa999b80932ea62b4689769225b3ff34b0709c4e32342a824799ca63dcce1f3ed8819e080fc7fa130c1881c8131f4bcb5 +InvalidKeyY = 0xb8c77d0868c2c159e1be6bcd60ec488ab31531c21e1cb8fe2493ed26ac848fde7d27823a9a4912650511a3d460e25ef2 + +# Point not on curve +InvalidKeyX = 0x5cbaa8088b0804fe14c2a6fa54b1adee1690fd17a682ea9ec5202ba7575e217c37e98565b7e95e7c882bb6eef76a3df1 +InvalidKeyY = 0x79d8c7e96ae7a7668496317c596b24ebe56e6ea5bc64b74c38867eb2c419d8277d20b9c27a2d5c75d1c7a47885d38d0e + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0xcfb4dbdcb1a8c6e8c6b4a9dd091eed015476ebd20837de1f6261a27999a08cff345f0d4627eb7778fc3495916a6d017b +InvalidKeyY = 0x1c08f7a421bc0731321374f9b31ecf5ca820c006180da4c496f29f0d0e4947f368808fd3052ee4f1afb8c2005fd0c0ee8 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x1adaff25f37c8dfd33ecf216691a2107e522c21c99e29a76d8c1757ef84cc37c73ec5c2aa3be2fb0d5f1d372e08fbf9e +InvalidKeyY = 0x1f39c8f86a20c130c34f767e085217232599541516e2d79d8e526fa03082bed2a5dc5fde6fd410c30245212e7816dd014 + +# [P-521] + +Group = secp521r1 + +# Point not on curve +InvalidKeyX = 0x165252970b786685babd0463f7314275c44ac1b558ab5a8e4bde60a441623b204982dcba2d3c0e7d379d5b637fd3edc0b0d2e0b7a33f7b36c03bb8bf3c6c5469ebe +InvalidKeyY = 0x1300db0f0bc9b21ecff15eff4ed3bbe3dc1ac403dc96c89344d0030304da7ce57f1dc757af6816279464c61a0ab33645c3cd6583842cff0928081660b30775f594f + +# Point not on curve +InvalidKeyX = 0x1a39c4c5d5f6af8285931694b030f6b8bbc0a012ab73c3947c72a6210643cc63673947f5847f2503bb81ae1c8b6a0d7cb0ee5675f9027ca75445aee2b6d7beb78ea +InvalidKeyY = 0x148beebbe6e298779e59d8fc88cfc28f4aa784d927e5127813894b6d593760608539d2eb9db9cc8b39813a5e5e03a7d39be67c9c8a566fa8d65ff25b5bee83b0a9b + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x0bec1326722dd943f750fda964cb485f31469095e5b4b5c4fa02041e2f443693ac36c09f371aea7d501881fc4e369f68e071bb14c5003b31dce504bd14338eb8104 +InvalidKeyY = 0x36cd502b0a4e91e1080a5b94886a819a823687693ce878408b59183730c69e5ab2d6e05ea5f3d32855cf8c7c20da59a28913025a1fa6835a3751ec6da69502f0547 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x3e064e446ce29891240b02948288bedc37a4e4163a78702f942728e2d530cfecdc0362cf2209a706a9d4db24c1dd6aba7ad81d6ddecdf6e12073a1c31e2dacd185d +InvalidKeyY = 0x12d0363dbdc4d157afd517beaecf2e6c93896a288c7cec5f9ba9394524fb6d4f647a9937fe440fda73f2e31410517ed5a814eed038356699085f9983f2ea5faccd0 + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x164ce2e2fa873f5648c22ed37f26c13d3da3180a0f6c3aa4b68d0a13293784a5f1356fc2495217065de4f3b504ee2248747ef96180e102879363fa5393fe6fc5fbe +InvalidKeyY = 0x23126d6903cbd7735291d77599cfe7f5e45056250c37deba2642dc0b7163ce0cf763d0d353bb9974cf15195c4bc4421bdae274492cfca739a8b8341235cc2268bc0 + +# Point not on curve +InvalidKeyX = 0x0dc2c4a23433293a771300ec79a3cd0f2e627110a97da85a82f4f85e7be9c280213048a3ad01b3e72bf54555a1b5da9945adcfed94ed8f6ed405c77506b5e00f45a +InvalidKeyY = 0x18f746aacd6ed4eaaf9b038789927a30125691bc525b29592abb13cf98f64c03cb36a477dc53971563ee74f3a7614677ab6817f6e5f22ceb02c90826a33fe7c94cd + +# Point not on curve +InvalidKeyX = 0x16e0383adc2986d01c18d7bde3b89eb5f732b56a6424c9394ec556a4660c3b88ddbc8654345ba6cff94bb002d16bc92e5907035f933785f633698e711738160d842 +InvalidKeyY = 0x1cf24be44e919e1576ecf51abdea113f8bb7121d670b86d8ee93ce1e6f79b17a6394987d74e6787facef5ca655196603468afd76e5cdf54ebb1331ce183cfe28c9e + +# InvalidKeyX or InvalidKeyY out of range +InvalidKeyX = 0x3d68ed9ce2bcb68f12ac37385ccdb6ee445f7b0a8f257593735abdf8bc0b98bc5ab5c5750e2e111fec2ecde6be321522ddc90d2b54634d30d28f43024f76e4653a7 +InvalidKeyY = 0x03f6f5f224d6aee43d781e3ad723062a61729a6ed959cd18c75d4982961ba8033767ed1168674a545b0a693d3587fbeaebc9b116143dbe1155ead48de89d980d617 diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp index 90899e183..148abaacc 100644 --- a/src/tests/test_ecdsa.cpp +++ b/src/tests/test_ecdsa.cpp @@ -1,5 +1,6 @@ /* * (C) 2014,2015 Jack Lloyd +* (C) 2017 René Korthaus, Rohde & Schwarz Cybersecurity * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -68,8 +69,47 @@ class ECDSA_Keygen_Tests : public PK_Key_Generation_Test std::string algo_name() const override { return "ECDSA"; } }; +class ECDSA_Invalid_Key_Tests : public Text_Based_Test + { + public: + ECDSA_Invalid_Key_Tests() : + Text_Based_Test("pubkey/ecdsa_invalid.vec", "Group,InvalidKeyX,InvalidKeyY") {} + + bool clear_between_callbacks() const override { return false; } + + Test::Result run_one_test(const std::string&, const VarMap& vars) override + { + Test::Result result("ECDSA invalid keys"); + + const std::string group_id = get_req_str(vars, "Group"); + Botan::EC_Group group(Botan::OIDS::lookup(group_id)); + const Botan::BigInt x = get_req_bn(vars, "InvalidKeyX"); + const Botan::BigInt y = get_req_bn(vars, "InvalidKeyY"); + + std::unique_ptr<Botan::PointGFp> public_point; + + try + { + public_point.reset(new Botan::PointGFp(group.get_curve(), x, y)); + } + catch(Botan::Invalid_Argument&) + { + // PointGFp() performs a range check on x, y in [0, p−1], + // which is also part of the EC public key checks, e.g., + // in NIST SP800-56A rev2, sec. 5.6.2.3.2 + result.test_success("public key fails check"); + return result; + } + + std::unique_ptr<Botan::Public_Key> key(new Botan::ECDSA_PublicKey(group, *public_point)); + result.test_eq("public key fails check", key->check_key(Test::rng(), false), false); + return result; + } + }; + BOTAN_REGISTER_TEST("ecdsa_sign", ECDSA_Signature_KAT_Tests); BOTAN_REGISTER_TEST("ecdsa_keygen", ECDSA_Keygen_Tests); +BOTAN_REGISTER_TEST("ecdsa_invalid", ECDSA_Invalid_Key_Tests); #endif diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp index 3ab22e57e..1672c289d 100644 --- a/src/tests/unit_ecc.cpp +++ b/src/tests/unit_ecc.cpp @@ -18,6 +18,8 @@ #include <botan/reducer.h> #include <botan/oids.h> #include <botan/hex.h> + #include <botan/data_src.h> + #include <botan/x509_key.h> #endif namespace Botan_Tests { @@ -833,6 +835,31 @@ class ECC_Unit_Tests : public Test BOTAN_REGISTER_TEST("ecc_unit", ECC_Unit_Tests); +class ECC_Invalid_Key_Tests : public Text_Based_Test + { + public: + ECC_Invalid_Key_Tests() : + Text_Based_Test("pubkey/ecc_invalid.vec", "SubjectPublicKey") {} + + bool clear_between_callbacks() const override { return false; } + + Test::Result run_one_test(const std::string&, const VarMap& vars) override + { + Test::Result result("ECC invalid keys"); + + const std::string encoded = get_req_str(vars, "SubjectPublicKey"); + Botan::DataSource_Memory key_data(Botan::hex_decode(encoded)); + + std::unique_ptr<Botan::Public_Key> key(Botan::X509::load_key(key_data)); + result.test_eq("public key fails check", key->check_key(Test::rng(), false), false); + + + return result; + } + }; + +BOTAN_REGISTER_TEST("ecc_invalid", ECC_Invalid_Key_Tests); + #endif } |