From 9f6d37d9c647bbf9f813b86e48f2ccd84d5c5e7c Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 3 Oct 2014 13:22:57 -0700 Subject: [PATCH] Support overlapping input and output regions in crypto_secretbox_detached() crypto_stream_salsa20() doesn't support overlapping input and output regions, except when they are aliases. --- .../crypto_secretbox/crypto_secretbox_easy.c | 8 ++++++++ test/default/secretbox_easy2.c | 16 ++++++++++++++-- test/default/secretbox_easy2.exp | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c b/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c index 5000a057..7c289a4c 100644 --- a/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c +++ b/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c @@ -29,6 +29,10 @@ crypto_secretbox_detached(unsigned char *c, unsigned char *mac, crypto_core_hsalsa20(subkey, n, k, sigma); + if (c - m < mlen || c - m > -mlen) { + memmove(c, m, mlen); + m = c; + } memset(block0, 0U, crypto_secretbox_ZEROBYTES); (void) sizeof(int[64U >= crypto_secretbox_ZEROBYTES ? 1 : -1]); mlen0 = mlen; @@ -91,6 +95,10 @@ crypto_secretbox_open_detached(unsigned char *m, const unsigned char *c, sodium_memzero(subkey, sizeof subkey); return -1; } + if (m - c < clen || m - c > -clen) { + memmove(m, c, clen); + c = m; + } mlen0 = clen; if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) { mlen0 = 64U - crypto_secretbox_ZEROBYTES; diff --git a/test/default/secretbox_easy2.c b/test/default/secretbox_easy2.c index 3ad71ce4..99e1b097 100644 --- a/test/default/secretbox_easy2.c +++ b/test/default/secretbox_easy2.c @@ -25,13 +25,25 @@ int main(void) for (i = 0; i < mlen + crypto_secretbox_MACBYTES - 1; i++) { if (crypto_secretbox_open_easy(m2, c, i, nonce, k) == 0) { - printf("short open() should have failed"); + printf("short open() should have failed\n"); return 1; } } crypto_secretbox_detached(c, mac, m, mlen, nonce, k); - crypto_secretbox_open_detached(m2, c, mac, mlen, nonce, k); + if (crypto_secretbox_open_detached(m2, c, mac, mlen, nonce, k) != 0) { + printf("crypto_secretbox_open_detached() failed\n"); + } printf("%d\n", memcmp(m, m2, mlen)); + memcpy(c, m, mlen); + crypto_secretbox_easy(c, c, mlen, nonce, k); + printf("%d\n", memcmp(m, c, mlen) == 0); + printf("%d\n", memcmp(m, c + crypto_secretbox_MACBYTES, mlen) == 0); + if (crypto_secretbox_open_easy(c, c, mlen + crypto_secretbox_MACBYTES, nonce, + k) != 0) { + printf("crypto_secretbox_open_easy() failed\n"); + } + printf("%d\n", memcmp(m, c, mlen)); + return 0; } diff --git a/test/default/secretbox_easy2.exp b/test/default/secretbox_easy2.exp index aa47d0d4..229972f2 100644 --- a/test/default/secretbox_easy2.exp +++ b/test/default/secretbox_easy2.exp @@ -1,2 +1,5 @@ 0 0 +0 +0 +0