From 94760400a6dfca7dd85f102481ff48ffb27a9014 Mon Sep 17 00:00:00 2001 From: Emil Bay Date: Fri, 12 May 2017 14:30:26 +0200 Subject: [PATCH 1/2] Add crypto_pwhash_MISMATCH errno (#541) * Add crypto_pwhash_MISMATCH errno * Use EINVAL for invalid password * Only set errno on mismatch --- .../crypto_pwhash/argon2/pwhash_argon2i.c | 6 ++- src/libsodium/include/sodium/crypto_pwhash.h | 1 - test/default/cmptest.h | 1 + test/default/pwhash.c | 39 ++++++++++++------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c index f29cc2d4..51b1841b 100644 --- a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c @@ -196,9 +196,11 @@ crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], return -1; } /* LCOV_EXCL_STOP */ - if (argon2i_verify(str, passwd, (size_t) passwdlen) != ARGON2_OK) { - return -1; + if (argon2i_verify(str, passwd, (size_t) passwdlen) == ARGON2_VERIFY_MISMATCH) { + errno = EINVAL; + return -1; } + return 0; } diff --git a/src/libsodium/include/sodium/crypto_pwhash.h b/src/libsodium/include/sodium/crypto_pwhash.h index 56eca068..9e45d7ea 100644 --- a/src/libsodium/include/sodium/crypto_pwhash.h +++ b/src/libsodium/include/sodium/crypto_pwhash.h @@ -118,4 +118,3 @@ const char *crypto_pwhash_primitive(void) #endif #endif - diff --git a/test/default/cmptest.h b/test/default/cmptest.h index 24f5ff2a..96a0ad76 100644 --- a/test/default/cmptest.h +++ b/test/default/cmptest.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "sodium.h" #include "quirks.h" diff --git a/test/default/pwhash.c b/test/default/pwhash.c index 7c0efbde..c3e6b99d 100644 --- a/test/default/pwhash.c +++ b/test/default/pwhash.c @@ -254,11 +254,13 @@ main(void) crypto_pwhash_STRBYTES - strlen(str_out2)) != 1) { printf("pwhash_str() doesn't properly pad with zeros\n"); } - if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != 0) { + if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != 0 + && errno == EINVAL) { printf("pwhash_str_verify(1) failure\n"); } str_out[14]++; - if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != -1) { + if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(2) failure\n"); } str_out[14]--; @@ -276,61 +278,72 @@ main(void) } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", 0x100000000ULL) != -1) { + "password", 0x100000000ULL) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(0)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(1)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" "9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(2)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" "$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(3)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1c29tZXNhbHQ" "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(4)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" "wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(5)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" "$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(6)) failure\n"); } if (crypto_pwhash_str_verify( "$argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "password", strlen("password")) != 0) { + "password", strlen("password")) != 0 + && errno == EINVAL) { printf("pwhash_str_verify(valid(7)) failure\n"); } if (crypto_pwhash_str_verify( "$argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "passwore", strlen("passwore")) != -1) { + "passwore", strlen("passwore")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(7)) failure\n"); } if (crypto_pwhash_str_verify( "$Argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(8)) failure\n"); } if (crypto_pwhash_str_verify( "$argon2i$v=1$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "password", strlen("password")) != -1) { + "password", strlen("password")) != -1 + && errno != EINVAL) { printf("pwhash_str_verify(invalid(9)) failure\n"); } assert(crypto_pwhash_bytes_min() > 0U); From 3e85167657ce824edb09c62dc445bc8651591a94 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 12 May 2017 15:01:48 +0200 Subject: [PATCH 2/2] Fix `crypto_pwhash_argon2i_str_verify()` and its tests after `errno` changes --- .../crypto_pwhash/argon2/pwhash_argon2i.c | 15 ++++-- test/default/pwhash.c | 49 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c index 51b1841b..abf4ef90 100644 --- a/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c +++ b/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c @@ -186,6 +186,8 @@ crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], const char *const passwd, unsigned long long passwdlen) { + int verify_ret; + if (passwdlen > ARGON2_MAX_PWD_LENGTH) { errno = EFBIG; return -1; @@ -196,12 +198,15 @@ crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], return -1; } /* LCOV_EXCL_STOP */ - if (argon2i_verify(str, passwd, (size_t) passwdlen) == ARGON2_VERIFY_MISMATCH) { - errno = EINVAL; - return -1; - } - return 0; + verify_ret = argon2i_verify(str, passwd, (size_t) passwdlen); + if (verify_ret == ARGON2_OK) { + return 0; + } + if (verify_ret == ARGON2_VERIFY_MISMATCH) { + errno = EINVAL; + } + return -1; } int diff --git a/test/default/pwhash.c b/test/default/pwhash.c index c3e6b99d..ffef570b 100644 --- a/test/default/pwhash.c +++ b/test/default/pwhash.c @@ -254,13 +254,12 @@ main(void) crypto_pwhash_STRBYTES - strlen(str_out2)) != 1) { printf("pwhash_str() doesn't properly pad with zeros\n"); } - if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != 0 - && errno == EINVAL) { + if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != 0) { printf("pwhash_str_verify(1) failure\n"); } str_out[14]++; - if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != -1 - && errno != EINVAL) { + if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != -1 || + errno != EFBIG) { printf("pwhash_str_verify(2) failure\n"); } str_out[14]--; @@ -278,72 +277,68 @@ main(void) } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", 0x100000000ULL) != -1 - && errno != EINVAL) { + "password", 0x100000000ULL) != -1 || + errno != EFBIG) { printf("pwhash_str_verify(invalid(0)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password")) != -1 - && errno != EINVAL) { - printf("pwhash_str_verify(invalid(1)) failure\n"); + "password", strlen("password")) != -1 || + errno != EFBIG) { + printf("pwhash_str_verify(invalid(1)) failure %d\n", errno); } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" "9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password")) != -1 - && errno != EINVAL) { + "password", strlen("password")) != -1 || + errno != EFBIG) { printf("pwhash_str_verify(invalid(2)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" "$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo", - "password", strlen("password")) != -1 - && errno != EINVAL) { + "password", strlen("password")) != -1 || + errno != EFBIG) { printf("pwhash_str_verify(invalid(3)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1c29tZXNhbHQ" "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", - "password", strlen("password")) != -1 - && errno != EINVAL) { + "password", strlen("password")) != -1 || + errno != EFBIG) { printf("pwhash_str_verify(invalid(4)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" "wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", - "password", strlen("password")) != -1 - && errno != EINVAL) { + "password", strlen("password")) != -1 || + errno != EFBIG) { printf("pwhash_str_verify(invalid(5)) failure\n"); } if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" "$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM", - "password", strlen("password")) != -1 - && errno != EINVAL) { + "password", strlen("password")) != -1 || + errno != EFBIG) { printf("pwhash_str_verify(invalid(6)) failure\n"); } if (crypto_pwhash_str_verify( "$argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "password", strlen("password")) != 0 - && errno == EINVAL) { + "password", strlen("password")) != 0) { printf("pwhash_str_verify(valid(7)) failure\n"); } if (crypto_pwhash_str_verify( "$argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "passwore", strlen("passwore")) != -1 - && errno != EINVAL) { + "passwore", strlen("passwore")) != -1 || errno != EINVAL) { printf("pwhash_str_verify(invalid(7)) failure\n"); } if (crypto_pwhash_str_verify( "$Argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "password", strlen("password")) != -1 - && errno != EINVAL) { + "password", strlen("password")) != -1 || errno != EINVAL) { printf("pwhash_str_verify(invalid(8)) failure\n"); } if (crypto_pwhash_str_verify( "$argon2i$v=1$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", - "password", strlen("password")) != -1 - && errno != EINVAL) { + "password", strlen("password")) != -1 || errno != EINVAL) { printf("pwhash_str_verify(invalid(9)) failure\n"); } assert(crypto_pwhash_bytes_min() > 0U);