Allow the authentication tag to be stored separately from the message.

Encrypting in-place and storing the tag separately is a very common need.
Instead of forcing people to do their own cuisine, let's provide simple
variants of the _easy interfaces to do that.
This commit is contained in:
Frank Denis
2014-06-26 15:18:39 -07:00
parent 83e91d7955
commit 44f7a9f3cb
6 changed files with 110 additions and 45 deletions
@@ -16,9 +16,10 @@ static const unsigned char sigma[16] = {
};
int
crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k)
crypto_secretbox_easy_detached(unsigned char *c, unsigned char *mac,
const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k)
{
crypto_onetimeauth_poly1305_state state;
unsigned char block0[64U];
@@ -45,65 +46,78 @@ crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
n + 16, subkey);
crypto_onetimeauth_poly1305_init(&state, block0);
memcpy(c + crypto_secretbox_MACBYTES,
block0 + crypto_secretbox_ZEROBYTES, mlen0);
memcpy(c, block0 + crypto_secretbox_ZEROBYTES, mlen0);
sodium_memzero(block0, sizeof block0);
if (mlen > mlen0) {
crypto_stream_salsa20_xor_ic(c + crypto_secretbox_MACBYTES + mlen0,
m + mlen0, mlen - mlen0,
crypto_stream_salsa20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0,
n + 16, 1U, subkey);
}
sodium_memzero(subkey, sizeof subkey);
crypto_onetimeauth_poly1305_update
(&state, c + crypto_secretbox_MACBYTES, mlen);
crypto_onetimeauth_poly1305_final(&state, c);
crypto_onetimeauth_poly1305_update(&state, c, mlen);
crypto_onetimeauth_poly1305_final(&state, mac);
sodium_memzero(&state, sizeof state);
return 0;
}
int
crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k)
{
return crypto_secretbox_easy_detached(c + crypto_secretbox_MACBYTES,
c, m, mlen, n, k);
}
int
crypto_secretbox_open_easy_detached(unsigned char *m, const unsigned char *c,
const unsigned char *mac,
unsigned long long clen,
const unsigned char *n,
const unsigned char *k)
{
unsigned char block0[64U];
unsigned char subkey[crypto_stream_salsa20_KEYBYTES];
unsigned long long i;
unsigned long long mlen0;
crypto_core_hsalsa20(subkey, n, k, sigma);
crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES,
n + 16, subkey);
if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) {
sodium_memzero(subkey, sizeof subkey);
return -1;
}
mlen0 = clen;
if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
mlen0 = 64U - crypto_secretbox_ZEROBYTES;
}
memcpy(block0 + crypto_secretbox_ZEROBYTES, c, mlen0);
crypto_stream_salsa20_xor(block0, block0,
crypto_secretbox_ZEROBYTES + mlen0,
n + 16, subkey);
for (i = 0U; i < mlen0; i++) {
m[i] = block0[i + crypto_secretbox_ZEROBYTES];
}
if (clen > mlen0) {
crypto_stream_salsa20_xor_ic(m + mlen0, c + mlen0, clen - mlen0,
n + 16, 1U, subkey);
}
sodium_memzero(subkey, sizeof subkey);
return 0;
}
int
crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *k)
{
unsigned char block0[64U];
unsigned char subkey[crypto_stream_salsa20_KEYBYTES];
unsigned long long i;
unsigned long long mlen0;
if (clen < crypto_secretbox_MACBYTES) {
return -1;
}
crypto_core_hsalsa20(subkey, n, k, sigma);
crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES,
n + 16, subkey);
if (crypto_onetimeauth_poly1305_verify(c, c + crypto_secretbox_MACBYTES,
clen - crypto_secretbox_MACBYTES,
block0) != 0) {
sodium_memzero(subkey, sizeof subkey);
return -1;
}
mlen0 = clen - crypto_secretbox_MACBYTES;
if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) {
mlen0 = 64U - crypto_secretbox_ZEROBYTES;
}
memcpy(block0 + crypto_secretbox_ZEROBYTES,
c + crypto_secretbox_MACBYTES, mlen0);
crypto_stream_salsa20_xor(block0, block0,
crypto_secretbox_ZEROBYTES + mlen0,
n + 16, subkey);
for (i = 0U; i < mlen0; i++) {
m[i] = block0[i + crypto_secretbox_ZEROBYTES];
}
if (clen - crypto_secretbox_MACBYTES > mlen0) {
crypto_stream_salsa20_xor_ic(m + mlen0,
c + crypto_secretbox_MACBYTES + mlen0,
clen - crypto_secretbox_MACBYTES - mlen0,
n + 16, 1U, subkey);
}
sodium_memzero(subkey, sizeof subkey);
return 0;
return crypto_secretbox_open_easy_detached
(m, c + crypto_secretbox_MACBYTES, c,
clen - crypto_secretbox_MACBYTES, n, k);
}
@@ -57,6 +57,20 @@ int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_secretbox_easy_detached(unsigned char *c, unsigned char *mac,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_secretbox_open_easy_detached(unsigned char *m,
const unsigned char *c,
const unsigned char *mac,
unsigned long long clen,
const unsigned char *n,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
+12
View File
@@ -37,15 +37,27 @@ unsigned char m[131] = {
} ;
unsigned char c[147 + crypto_secretbox_MACBYTES];
unsigned char mac[crypto_secretbox_MACBYTES];
int main(void)
{
int i;
crypto_secretbox_easy(c, m, 131, nonce, firstkey);
for (i = 0;i < 131 + crypto_secretbox_MACBYTES; ++i) {
printf(",0x%02x",(unsigned int) c[i]);
if (i % 8 == 7) printf("\n");
}
printf("\n");
crypto_secretbox_easy_detached(c, mac, m, 131, nonce, firstkey);
for (i = 0;i < crypto_secretbox_MACBYTES; ++i) {
printf(",0x%02x",(unsigned int) mac[i]);
if (i % 8 == 7) printf("\n");
}
for (i = 0;i < 131; ++i) {
printf(",0x%02x",(unsigned int) c[i]);
if (i % 8 == 7) printf("\n");
}
return 0;
}
+19
View File
@@ -17,3 +17,22 @@
,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
,0xe3,0x55,0xa5
,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5
,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9
,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73
,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce
,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4
,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a
,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b
,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72
,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2
,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38
,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a
,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae
,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea
,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda
,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde
,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3
,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6
,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74
,0xe3,0x55,0xa5
+5
View File
@@ -9,6 +9,7 @@ unsigned char m2[10000];
unsigned char c[crypto_secretbox_MACBYTES + 10000];
unsigned char nonce[crypto_secretbox_NONCEBYTES];
unsigned char k[crypto_secretbox_KEYBYTES];
unsigned char mac[crypto_secretbox_MACBYTES];
int main(void)
{
@@ -23,5 +24,9 @@ int main(void)
nonce, k);
printf("%d\n", memcmp(m, m2, mlen));
crypto_secretbox_easy_detached(c, mac, m, mlen, nonce, k);
crypto_secretbox_open_easy_detached(m2, c, mac, mlen, nonce, k);
printf("%d\n", memcmp(m, m2, mlen));
return 0;
}
+1
View File
@@ -1 +1,2 @@
0
0