diff options
Diffstat (limited to 'src/libstrongswan')
-rw-r--r-- | src/libstrongswan/crypto/signers/mac_signer.c | 3 | ||||
-rw-r--r-- | src/libstrongswan/plugins/af_alg/af_alg_signer.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/ccm/ccm_aead.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/gcm/gcm_aead.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c | 5 | ||||
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_pkcs7.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs12/pkcs12_decode.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_chunk.c | 27 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_utils.c | 47 | ||||
-rw-r--r-- | src/libstrongswan/utils/chunk.h | 13 | ||||
-rw-r--r-- | src/libstrongswan/utils/utils.c | 19 | ||||
-rw-r--r-- | src/libstrongswan/utils/utils.h | 5 |
14 files changed, 121 insertions, 12 deletions
diff --git a/src/libstrongswan/crypto/signers/mac_signer.c b/src/libstrongswan/crypto/signers/mac_signer.c index 7c52aa305..1094c4473 100644 --- a/src/libstrongswan/crypto/signers/mac_signer.c +++ b/src/libstrongswan/crypto/signers/mac_signer.c @@ -85,7 +85,7 @@ METHOD(signer_t, verify_signature, bool, return FALSE; } return this->mac->get_mac(this->mac, data, mac) && - memeq(signature.ptr, mac, this->truncation); + memeq_const(signature.ptr, mac, this->truncation); } METHOD(signer_t, get_key_size, size_t, @@ -136,4 +136,3 @@ signer_t *mac_signer_create(mac_t *mac, size_t len) return &this->public; } - diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c index 9ad01103a..1403144ab 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c @@ -138,7 +138,7 @@ METHOD(signer_t, verify_signature, bool, { return FALSE; } - return memeq(signature.ptr, sig, signature.len); + return memeq_const(signature.ptr, sig, signature.len); } METHOD(signer_t, get_key_size, size_t, diff --git a/src/libstrongswan/plugins/ccm/ccm_aead.c b/src/libstrongswan/plugins/ccm/ccm_aead.c index 6d4b2e13c..676d67681 100644 --- a/src/libstrongswan/plugins/ccm/ccm_aead.c +++ b/src/libstrongswan/plugins/ccm/ccm_aead.c @@ -256,7 +256,7 @@ static bool verify_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc, char buf[this->icv_size]; return create_icv(this, plain, assoc, iv, buf) && - memeq(buf, icv, this->icv_size); + memeq_const(buf, icv, this->icv_size); } METHOD(aead_t, encrypt, bool, diff --git a/src/libstrongswan/plugins/gcm/gcm_aead.c b/src/libstrongswan/plugins/gcm/gcm_aead.c index 4ab17017f..6e1694a34 100644 --- a/src/libstrongswan/plugins/gcm/gcm_aead.c +++ b/src/libstrongswan/plugins/gcm/gcm_aead.c @@ -276,7 +276,7 @@ static bool verify_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt, char tmp[this->icv_size]; return create_icv(this, assoc, crypt, j, tmp) && - memeq(tmp, icv, this->icv_size); + memeq_const(tmp, icv, this->icv_size); } METHOD(aead_t, encrypt, bool, diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c index ad659e4d7..e738908e2 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c @@ -187,7 +187,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this, " %u bytes", em.len, data.len); goto end; } - success = memeq(em.ptr, data.ptr, data.len); + success = memeq_const(em.ptr, data.ptr, data.len); } else { /* IKEv2 and X.509 certificate signatures */ @@ -258,7 +258,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this, goto end_parser; } hasher->destroy(hasher); - success = memeq(object.ptr, hash.ptr, hash.len); + success = memeq_const(object.ptr, hash.ptr, hash.len); free(hash.ptr); break; } @@ -500,4 +500,3 @@ gmp_rsa_public_key_t *gmp_rsa_public_key_load(key_type_t type, va_list args) return &this->public; } - diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c index 9c3c4040c..891e829ae 100644 --- a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c +++ b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c @@ -305,7 +305,7 @@ static bool verify_digest(CMS_ContentInfo *cms, CMS_SignerInfo *si, int hash_oid } hasher->destroy(hasher); - if (!chunk_equals(digest, hash)) + if (!chunk_equals_const(digest, hash)) { free(hash.ptr); DBG1(DBG_LIB, "invalid messageDigest"); diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index 9748e28f2..aa54d3bbd 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -74,7 +74,7 @@ static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this, RSA_PKCS1_PADDING); if (len != -1) { - valid = chunk_equals(data, chunk_create(buf, len)); + valid = chunk_equals_const(data, chunk_create(buf, len)); } free(buf); } diff --git a/src/libstrongswan/plugins/pkcs12/pkcs12_decode.c b/src/libstrongswan/plugins/pkcs12/pkcs12_decode.c index 379f24796..4441b278f 100644 --- a/src/libstrongswan/plugins/pkcs12/pkcs12_decode.c +++ b/src/libstrongswan/plugins/pkcs12/pkcs12_decode.c @@ -356,7 +356,7 @@ static bool verify_mac(hash_algorithm_t hash, chunk_t salt, { break; } - if (chunk_equals(mac, calculated)) + if (chunk_equals_const(mac, calculated)) { success = TRUE; break; diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c index 48fb5e6a4..d224ef3aa 100644 --- a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c @@ -269,7 +269,7 @@ METHOD(enumerator_t, enumerate, bool, hasher->destroy(hasher); DBG3(DBG_LIB, "hash: %B", &hash); - valid = chunk_equals(chunk, hash); + valid = chunk_equals_const(chunk, hash); free(hash.ptr); if (!valid) { diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c index b5d23658d..312a187ac 100644 --- a/src/libstrongswan/tests/suites/test_chunk.c +++ b/src/libstrongswan/tests/suites/test_chunk.c @@ -61,6 +61,32 @@ START_TEST(test_chunk_equals) END_TEST /******************************************************************************* + * equals_const + */ + +START_TEST(test_chunk_equals_const) +{ + chunk_t chunk = chunk_from_str("chunk"); + chunk_t chunk_a, chunk_b; + + chunk_a = chunk_empty; + chunk_b = chunk_empty; + ck_assert(!chunk_equals_const(chunk_a, chunk_b)); + + chunk_a = chunk; + ck_assert(!chunk_equals_const(chunk_a, chunk_b)); + chunk_b = chunk; + ck_assert(chunk_equals_const(chunk_a, chunk_b)); + + chunk_b = chunk_from_str("asdf"); + ck_assert(!chunk_equals_const(chunk_a, chunk_b)); + + chunk_b = chunk_from_str("chunk"); + ck_assert(chunk_equals_const(chunk_a, chunk_b)); +} +END_TEST + +/******************************************************************************* * chunk_compare test */ @@ -1013,6 +1039,7 @@ Suite *chunk_suite_create() tc = tcase_create("equals"); tcase_add_test(tc, test_chunk_equals); + tcase_add_test(tc, test_chunk_equals_const); suite_add_tcase(s, tc); tc = tcase_create("chunk_compare"); diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c index 85a854456..f151fb35e 100644 --- a/src/libstrongswan/tests/suites/test_utils.c +++ b/src/libstrongswan/tests/suites/test_utils.c @@ -307,6 +307,48 @@ START_TEST(test_memxor_aligned) END_TEST /******************************************************************************* + * memeq/const + */ + +static struct { + char *a; + char *b; + size_t n; + bool res; +} memeq_data[] = { + {NULL, NULL, 0, TRUE}, + {"a", "b", 0, TRUE}, + {"", "", 1, TRUE}, + {"abcdefgh", "abcdefgh", 8, TRUE}, + {"a", "b", 1, FALSE}, + {"A", "a", 1, FALSE}, + {"\0a", "\0b", 2, FALSE}, + {"abc", "abd", 3, FALSE}, + {"abc", "dbd", 3, FALSE}, + {"abcdefgh", "abcdffgh", 8, FALSE}, + {"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", 52, TRUE}, + {"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyy", 52, FALSE}, + {"bbcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", 52, FALSE}, +}; + +START_TEST(test_memeq) +{ + ck_assert(memeq(memeq_data[_i].a, memeq_data[_i].b, + memeq_data[_i].n) == memeq_data[_i].res); +} +END_TEST + +START_TEST(test_memeq_const) +{ + ck_assert(memeq_const(memeq_data[_i].a, memeq_data[_i].b, + memeq_data[_i].n) == memeq_data[_i].res); +} +END_TEST + +/******************************************************************************* * memstr */ @@ -779,6 +821,11 @@ Suite *utils_suite_create() tcase_add_test(tc, test_memxor_aligned); suite_add_tcase(s, tc); + tc = tcase_create("memeq"); + tcase_add_loop_test(tc, test_memeq, 0, countof(memeq_data)); + tcase_add_loop_test(tc, test_memeq_const, 0, countof(memeq_data)); + suite_add_tcase(s, tc); + tc = tcase_create("memstr"); tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data)); suite_add_tcase(s, tc); diff --git a/src/libstrongswan/utils/chunk.h b/src/libstrongswan/utils/chunk.h index 48405b77e..2ec7f7543 100644 --- a/src/libstrongswan/utils/chunk.h +++ b/src/libstrongswan/utils/chunk.h @@ -310,6 +310,19 @@ static inline bool chunk_equals(chunk_t a, chunk_t b) } /** + * Compare two chunks for equality, constant time for cryptographic purposes. + * + * Note that this function is constant time only for chunks with the same + * length, i.e. it does not protect against guessing the length of one of the + * chunks. + */ +static inline bool chunk_equals_const(chunk_t a, chunk_t b) +{ + return a.ptr != NULL && b.ptr != NULL && + a.len == b.len && memeq_const(a.ptr, b.ptr, a.len); +} + +/** * Compare two chunks (given as pointers) for equality (useful as callback), * NULL chunks are never equal. */ diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c index 02a720945..3d5e3dfc9 100644 --- a/src/libstrongswan/utils/utils.c +++ b/src/libstrongswan/utils/utils.c @@ -112,6 +112,25 @@ void memwipe_noinline(void *ptr, size_t n) /** * Described in header. */ +bool memeq_const(const void *x, const void *y, size_t len) +{ + const u_char *a, *b; + u_int bad = 0; + size_t i; + + a = (const u_char*)x; + b = (const u_char*)y; + + for (i = 0; i < len; i++) + { + bad |= a[i] != b[i]; + } + return !bad; +} + +/** + * Described in header. + */ void *memstr(const void *haystack, const char *needle, size_t n) { const u_char *pos = haystack; diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index 7c48d949f..2675acae8 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -185,6 +185,11 @@ static inline bool memeq(const void *x, const void *y, size_t len) } /** + * Same as memeq(), but with a constant runtime, safe for cryptographic use. + */ +bool memeq_const(const void *x, const void *y, size_t len); + +/** * Calling memcpy() with NULL pointers, even with n == 0, results in undefined * behavior according to the C standard. This version is guaranteed to not * access the pointers if n is 0. |