symm/latinpoly-def.h: Implement Bernstein's `crypto_secretbox'.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 16 Aug 2019 11:49:33 +0000 (12:49 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 8 Sep 2019 17:36:04 +0000 (18:36 +0100)
symm/.gitignore
symm/Makefile.am
symm/chacha-poly1305.c
symm/latinpoly-def.h
symm/latinpoly.c
symm/latinpoly.h
symm/salsa20-poly1305.c
symm/t/salsa20.local

index adc9d88..5c18b12 100644 (file)
@@ -46,6 +46,9 @@
 /xchacha20.h
 /xchacha12.h
 /xchacha8.h
+/chacha20-naclbox.h
+/chacha12-naclbox.h
+/chacha8-naclbox.h
 /chacha20-poly1305.h
 /chacha12-poly1305.h
 /chacha8-poly1305.h
@@ -58,6 +61,9 @@
 /xsalsa20.h
 /xsalsa2012.h
 /xsalsa208.h
+/salsa20-naclbox.h
+/salsa2012-naclbox.h
+/salsa208-naclbox.h
 /salsa20-poly1305.h
 /salsa2012-poly1305.h
 /salsa208-poly1305.h
index a4f45e9..2a43f07 100644 (file)
@@ -604,12 +604,21 @@ libsymmtest_la_SOURCES    += latinpoly-test.c latinpoly-test.h
 ALL_AEADS              += chacha20-poly1305 salsa20-poly1305
 ALL_AEADS              += chacha12-poly1305 salsa2012-poly1305
 ALL_AEADS              += chacha8-poly1305 salsa208-poly1305
+ALL_AEADS              += chacha20-naclbox salsa20-naclbox
+ALL_AEADS              += chacha12-naclbox salsa2012-naclbox
+ALL_AEADS              += chacha8-naclbox salsa208-naclbox
 STUBS_HDR              += ChaCha20-Poly1305,chacha20-poly1305,latinpoly
 STUBS_HDR              += ChaCha12-Poly1305,chacha12-poly1305,latinpoly
 STUBS_HDR              += ChaCha8-Poly1305,chacha8-poly1305,latinpoly
 STUBS_HDR              += Salsa20-Poly1305,salsa20-poly1305,latinpoly
 STUBS_HDR              += Salsa20/12-Poly1305,salsa2012-poly1305,latinpoly
 STUBS_HDR              += Salsa20/8-Poly1305,salsa208-poly1305,latinpoly
+STUBS_HDR              += ChaCha20-NaClBox,chacha20-naclbox,latinpoly
+STUBS_HDR              += ChaCha12-NaClBox,chacha12-naclbox,latinpoly
+STUBS_HDR              += ChaCha8-NaClBox,chacha8-naclbox,latinpoly
+STUBS_HDR              += Salsa20-NaClBox,salsa20-naclbox,latinpoly
+STUBS_HDR              += Salsa20/12-NaClBox,salsa2012-naclbox,latinpoly
+STUBS_HDR              += Salsa20/8-NaClBox,salsa208-naclbox,latinpoly
 TESTS                  += chacha-poly1305.t$(EXEEXT)
 TESTS                  += salsa20-poly1305.t$(EXEEXT)
 
index f307e6b..657987e 100644 (file)
@@ -50,6 +50,12 @@ static int check_chacha12_poly1305(dstr *v)
   { return latinpoly_test(&chacha12_poly1305, v); }
 static int check_chacha8_poly1305(dstr *v)
   { return latinpoly_test(&chacha8_poly1305, v); }
+static int check_chacha20_naclbox(dstr *v)
+  { return latinpoly_test(&chacha20_naclbox, v); }
+static int check_chacha12_naclbox(dstr *v)
+  { return latinpoly_test(&chacha12_naclbox, v); }
+static int check_chacha8_naclbox(dstr *v)
+  { return latinpoly_test(&chacha8_naclbox, v); }
 
 static const test_chunk tests[] = {
   { "chacha20-poly1305", check_chacha20_poly1305,
@@ -58,6 +64,12 @@ static const test_chunk tests[] = {
     { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
   { "chacha8-poly1305", check_chacha8_poly1305,
     { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
+  { "chacha20-naclbox", check_chacha20_naclbox,
+    { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
+  { "chacha12-naclbox", check_chacha12_naclbox,
+    { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
+  { "chacha8-naclbox", check_chacha8_naclbox,
+    { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
   { 0, 0, { 0 } }
 #undef TEST
 };
index 404098f..af917fa 100644 (file)
@@ -91,10 +91,12 @@ extern const octet latinpoly_noncesz[], latinpoly_tagsz[];
 /* AAD methods. */
 extern void latinpoly_aadhash_poly1305(gaead_aad */*a*/,
                                       const void */*h*/, size_t /*hsz*/);
+extern void latinpoly_aadhash_naclbox(gaead_aad */*a*/,
+                                     const void */*h*/, size_t /*hsz*/);
 extern void latinpoly_aaddestroy(gaead_aad */*a*/);
 
 /* Variants. */
-enum { LPVAR_POLY1305 };
+enum { LPVAR_NACLBOX, LPVAR_POLY1305 };
 
 /* --- @latinpoly_tag@ --- *
  *
@@ -146,6 +148,9 @@ static int reinit_##latin(x##latin##_ctx *ctx,      int var,                \
   poly1305_keyinit(&pk, b, POLY1305_KEYSZ);                            \
   poly1305_macinit(ctpoly, &pk, b + POLY1305_KEYSZ);                   \
   switch (var) {                                                       \
+    case LPVAR_NACLBOX:                                                        \
+      aadpoly->count = 0; aadpoly->nbuf = 0;                           \
+      break;                                                           \
     case LPVAR_POLY1305:                                               \
       poly1305_macinit(aadpoly, &pk, b + POLY1305_KEYSZ);              \
       latin##_encrypt(&ctx->s, 0, 0, SALSA20_OUTSZ - sizeof(b));       \
@@ -161,6 +166,8 @@ static int reinit_##latin(x##latin##_ctx *ctx,      int var,                \
 static const gaead_aadops gaops_##latin##_poly1305 =                   \
   { &latin##_poly1305, 0, latinpoly_aadhash_poly1305, latinpoly_aaddestroy }; \
                                                                        \
+static const gaead_aadops gaops_##latin##_naclbox =                    \
+  { &latin##_naclbox, 0, latinpoly_aadhash_naclbox, latinpoly_aaddestroy }; \
                                                                        \
 /* Encryption operations. */                                           \
                                                                        \
@@ -183,6 +190,15 @@ static int gereinit_##latin##_poly1305(gaead_enc *e,                       \
                         &enc->aad.poly, &enc->poly, n, nsz));          \
 }                                                                      \
                                                                        \
+static int gereinit_##latin##_naclbox(gaead_enc *e,                    \
+                                     const void *n, size_t nsz,        \
+                                     size_t hsz, size_t msz, size_t tsz) \
+{                                                                      \
+  gectx_##latin *enc = (gectx_##latin *)e;                             \
+  return (reinit_##latin(&enc->ctx, LPVAR_NACLBOX,                     \
+                        &enc->aad.poly, &enc->poly, n, nsz));          \
+}                                                                      \
+                                                                       \
 static int geenc_##latin(gaead_enc *e,                                 \
                         const void *m, size_t msz, buf *b)             \
 {                                                                      \
@@ -218,6 +234,17 @@ static int gedone_##latin##_poly1305(gaead_enc *e, const gaead_aad *a,     \
   return (0);                                                          \
 }                                                                      \
                                                                        \
+static int gedone_##latin##_naclbox(gaead_enc *e, const gaead_aad *a,  \
+                                   buf *b, void *t, size_t tsz)        \
+{                                                                      \
+  gectx_##latin *enc = (gectx_##latin *)e;                             \
+  const latinpoly_aad *aad = (const latinpoly_aad *)a;                 \
+                                                                       \
+  if (gedone_##latin##_common(enc, aad, b, tsz)) return (-1);          \
+  poly1305_done(&enc->poly, t);                                                \
+  return (0);                                                          \
+}                                                                      \
+                                                                       \
 static void gedestroy_##latin(gaead_enc *e)                            \
   { gectx_##latin *enc = (gectx_##latin *)e; BURN(*enc); S_DESTROY(enc); } \
                                                                        \
@@ -225,6 +252,10 @@ static gaead_encops geops_##latin##_poly1305 =                             \
   { &latin##_poly1305, geaad_##latin, gereinit_##latin##_poly1305,     \
     geenc_##latin, gedone_##latin##_poly1305, gedestroy_##latin };     \
                                                                        \
+static gaead_encops geops_##latin##_naclbox =                          \
+  { &latin##_naclbox, geaad_##latin, gereinit_##latin##_naclbox,       \
+    geenc_##latin, gedone_##latin##_naclbox, gedestroy_##latin };      \
+                                                                       \
 /* Decryption operations. */                                           \
                                                                        \
 typedef struct gdctx_##latin {                                         \
@@ -246,6 +277,15 @@ static int gdreinit_##latin##_poly1305(gaead_dec *d,                       \
                         &dec->aad.poly, &dec->poly, n, nsz));          \
 }                                                                      \
                                                                        \
+static int gdreinit_##latin##_naclbox(gaead_dec *d,                    \
+                                     const void *n, size_t nsz,        \
+                                     size_t hsz, size_t msz, size_t tsz) \
+{                                                                      \
+  gdctx_##latin *dec = (gdctx_##latin *)d;                             \
+  return (reinit_##latin(&dec->ctx, LPVAR_NACLBOX,                     \
+                        &dec->aad.poly, &dec->poly, n, nsz));          \
+}                                                                      \
+                                                                       \
 static int gddec_##latin(gaead_dec *d,                                 \
                         const void *c, size_t csz, buf *b)             \
 {                                                                      \
@@ -283,6 +323,19 @@ static int gddone_##latin##_poly1305(gaead_dec *d, const gaead_aad *a,     \
   else return (0);                                                     \
 }                                                                      \
                                                                        \
+static int gddone_##latin##_naclbox(gaead_dec *d, const gaead_aad *a,  \
+                                   buf *b, const void *t, size_t tsz)  \
+{                                                                      \
+  gdctx_##latin *dec = (gdctx_##latin *)d;                             \
+  const latinpoly_aad *aad = (const latinpoly_aad *)a;                 \
+  octet u[POLY1305_TAGSZ];                                             \
+                                                                       \
+  if (gddone_##latin##_common(dec, aad, b, tsz)) return (-1);          \
+  poly1305_done(&dec->poly, u);                                                \
+  if (ct_memeq(t, u, POLY1305_TAGSZ)) return (+1);                     \
+  else return (0);                                                     \
+}                                                                      \
+                                                                       \
 static void gddestroy_##latin(gaead_dec *d)                            \
   { gdctx_##latin *dec = (gdctx_##latin *)d; BURN(*dec); S_DESTROY(dec); } \
                                                                        \
@@ -290,6 +343,10 @@ static gaead_decops gdops_##latin##_poly1305 =                             \
   { &latin##_poly1305, gdaad_##latin, gdreinit_##latin##_poly1305,     \
     gddec_##latin, gddone_##latin##_poly1305, gddestroy_##latin };     \
                                                                        \
+static gaead_decops gdops_##latin##_naclbox =                          \
+  { &latin##_poly1305, gdaad_##latin, gdreinit_##latin##_naclbox,      \
+    gddec_##latin, gddone_##latin##_naclbox, gddestroy_##latin };      \
+                                                                       \
 /* Key operations. */                                                  \
                                                                        \
 static gaead_enc *gkenc_##latin##_poly1305(const gaead_key *k,         \
@@ -309,6 +366,23 @@ static gaead_enc *gkenc_##latin##_poly1305(const gaead_key *k,             \
   return (&enc->e);                                                    \
 }                                                                      \
                                                                        \
+static gaead_enc *gkenc_##latin##_naclbox(const gaead_key *k,          \
+                                         const void *n, size_t nsz,    \
+                                         size_t hsz, size_t msz,       \
+                                         size_t tsz)                   \
+{                                                                      \
+  latinpoly_key *key = (latinpoly_key *)k;                             \
+  gectx_##latin *enc = S_CREATE(gectx_##latin);                                \
+                                                                       \
+  enc->e.ops = &geops_##latin##_naclbox;                               \
+  enc->aad.a.ops = &gaops_##latin##_naclbox;                           \
+  x##latin##_init(&enc->ctx, key->key, key->ksz, 0);                   \
+  if (reinit_##latin(&enc->ctx, LPVAR_NACLBOX,                         \
+                    &enc->aad.poly, &enc->poly, n, nsz))               \
+    { gedestroy_##latin(&enc->e); return (0); }                                \
+  return (&enc->e);                                                    \
+}                                                                      \
+                                                                       \
 static gaead_dec *gkdec_##latin##_poly1305(const gaead_key *k,         \
                                           const void *n, size_t nsz,   \
                                           size_t hsz, size_t msz,      \
@@ -326,6 +400,23 @@ static gaead_dec *gkdec_##latin##_poly1305(const gaead_key *k,             \
   return (&dec->d);                                                    \
 }                                                                      \
                                                                        \
+static gaead_dec *gkdec_##latin##_naclbox(const gaead_key *k,          \
+                                         const void *n, size_t nsz,    \
+                                         size_t hsz, size_t msz,       \
+                                         size_t tsz)                   \
+{                                                                      \
+  latinpoly_key *key = (latinpoly_key *)k;                             \
+  gdctx_##latin *dec = S_CREATE(gdctx_##latin);                                \
+                                                                       \
+  dec->d.ops = &gdops_##latin##_naclbox;                               \
+  dec->aad.a.ops = &gaops_##latin##_naclbox;                           \
+  x##latin##_init(&dec->ctx, key->key, key->ksz, 0);                   \
+  if (reinit_##latin(&dec->ctx, LPVAR_NACLBOX,                         \
+                    &dec->aad.poly, &dec->poly, n, nsz))               \
+    { gddestroy_##latin(&dec->d); return (0); }                                \
+  return (&dec->d);                                                    \
+}                                                                      \
+                                                                       \
 static void gkdestroy_##latin(gaead_key *k)                            \
   { latinpoly_key *key = (latinpoly_key *)k; BURN(*key); S_DESTROY(key); } \
                                                                        \
@@ -334,6 +425,11 @@ static const gaead_keyops gkops_##latin##_poly1305 =                       \
     gkenc_##latin##_poly1305, gkdec_##latin##_poly1305,                        \
     gkdestroy_##latin };                                               \
                                                                        \
+static const gaead_keyops gkops_##latin##_naclbox =                    \
+  { &latin##_naclbox, 0,                                               \
+    gkenc_##latin##_naclbox, gkdec_##latin##_naclbox,                  \
+    gkdestroy_##latin };                                               \
+                                                                       \
 /* Class definition. */                                                        \
                                                                        \
 static gaead_key *gkey_##latin##_common(const gaead_keyops *ops,       \
@@ -349,10 +445,19 @@ static gaead_key *gkey_##latin##_common(const gaead_keyops *ops,  \
 static gaead_key *gkey_##latin##_poly1305(const void *k, size_t ksz)   \
   { return (gkey_##latin##_common(&gkops_##latin##_poly1305, k, ksz)); } \
                                                                        \
+static gaead_key *gkey_##latin##_naclbox(const void *k, size_t ksz)    \
+  { return (gkey_##latin##_common(&gkops_##latin##_naclbox, k, ksz)); }        \
+                                                                       \
 const gcaead latin##_poly1305 = {                                      \
   name "-poly1305", latin##_keysz, latinpoly_noncesz, latinpoly_tagsz, \
   64, 0, 0, AEADF_AADNDEP,                                             \
   gkey_##latin##_poly1305                                              \
+};                                                                     \
+                                                                       \
+const gcaead latin##_naclbox = {                                       \
+  name "-naclbox", latin##_keysz, latinpoly_noncesz, latinpoly_tagsz,  \
+  64, 0, 0, AEADF_AADNDEP | AEADF_NOAAD,                               \
+  gkey_##latin##_naclbox                                               \
 };
 
 /*----- That's all, folks -------------------------------------------------*/
index a4aad36..29ba71a 100644 (file)
@@ -54,6 +54,9 @@ void latinpoly_aadhash_poly1305(gaead_aad *a, const void *h, size_t hsz)
   poly1305_hash(&aad->poly, h, hsz);
 }
 
+void latinpoly_aadhash_naclbox(gaead_aad *a, const void *h, size_t hsz)
+  { assert(!hsz); }
+
 void latinpoly_aaddestroy(gaead_aad *a) { ; }
 
 /* --- @latinpoly_tag@ --- *
index 2efcd00..a9bb25e 100644 (file)
  * except that an application should not mix nonce sizes with the same key.
  * (It is possible to do this safely, but it requires detailed understanding
  * of how everything fits together and isn't worth the effort.)
+ *
+ * The @salsa20_naclbox@ with a 192-bit nonce is exactly the scheme
+ * implemented in Bernstein's `NaCl' library as @crypto_secretbox@, except
+ * that it's flexible regarding tag placement rather than insisting on
+ * prefixing it to the ciphertext.  Unlike NaCl, we provide a restartable
+ * interface, and allow the use of other ciphers and nonce lengths.
  */
 
 #ifndef CATACOMB_LATINPOLY_H
@@ -63,7 +69,9 @@
 
 extern const gcaead
   chacha20_poly1305, chacha12_poly1305, chacha8_poly1305,
-  salsa20_poly1305, salsa2012_poly1305, salsa208_poly1305;
+  chacha20_naclbox, chacha12_naclbox, chacha8_naclbox,
+  salsa20_poly1305, salsa2012_poly1305, salsa208_poly1305,
+  salsa20_naclbox, salsa2012_naclbox, salsa208_naclbox;
 
 /*----- That's all, folks -------------------------------------------------*/
 
index 55ba69a..201a083 100644 (file)
@@ -50,6 +50,12 @@ static int check_salsa2012_poly1305(dstr *v)
   { return latinpoly_test(&salsa2012_poly1305, v); }
 static int check_salsa208_poly1305(dstr *v)
   { return latinpoly_test(&salsa208_poly1305, v); }
+static int check_salsa20_naclbox(dstr *v)
+  { return latinpoly_test(&salsa20_naclbox, v); }
+static int check_salsa2012_naclbox(dstr *v)
+  { return latinpoly_test(&salsa2012_naclbox, v); }
+static int check_salsa208_naclbox(dstr *v)
+  { return latinpoly_test(&salsa208_naclbox, v); }
 
 static const test_chunk tests[] = {
   { "salsa20-poly1305", check_salsa20_poly1305,
@@ -58,6 +64,12 @@ static const test_chunk tests[] = {
     { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
   { "salsa20/8-poly1305", check_salsa208_poly1305,
     { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
+  { "salsa20-naclbox", check_salsa20_naclbox,
+    { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
+  { "salsa20/12-naclbox", check_salsa2012_naclbox,
+    { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
+  { "salsa20/8-nacblox", check_salsa208_naclbox,
+    { &type_hex, &type_hex, &type_hex, &type_hex, &type_hex, &type_hex } },
   { 0, 0, { 0 } }
 #undef TEST
 };
index 9188749..b03d2c3 100644 (file)
@@ -87,3 +87,15 @@ xsalsa20 {
   be075fc53c81f2d5cf141316ebeb0c7b5228c52a4c62cbd44b66849b64244ffce5ecbaaf33bd751a1ac728d45e6c61296cdc3c01233561f41db66cce314adb310e3be8250c46f06dceea3a7fa1348057e2f6556ad6b1318a024a838f21af1fde048977eb48f59ffd4924ca1c60902e52f0a089bc76897040e082f937763848645e0705
   8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186ac0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74e355a5;
 }
+
+salsa20-naclbox {
+  ## Taken from Daniel J. Bernstein, `Cryptography in NaCl',
+  ## https://cr.yp.to/highspeed/naclcrypto-20090310.pdf
+
+  1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389
+  69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37
+  ""
+  be075fc53c81f2d5cf141316ebeb0c7b5228c52a4c62cbd44b66849b64244ffce5ecbaaf33bd751a1ac728d45e6c61296cdc3c01233561f41db66cce314adb310e3be8250c46f06dceea3a7fa1348057e2f6556ad6b1318a024a838f21af1fde048977eb48f59ffd4924ca1c60902e52f0a089bc76897040e082f937763848645e0705
+  8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186ac0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74e355a5
+  f3ffc7703f9400e52a7dfb4b3d3305d9;
+}