salsa20_setnonce(ctx, nonce ? nonce : zerononce);
}
-/* --- @salsa20_setnonce@ --- *
+/* --- @salsa20_setnonce{,_ietf}@ --- *
*
* Arguments: @salsa20_ctx *ctx@ = pointer to context
- * @const void *nonce@ = the nonce (@SALSA20_NONCESZ@ bytes)
+ * @const void *nonce@ = the nonce (@SALSA20_NONCESZ@ or
+ * @SALSA20_IETF_NONCESZ@ bytes)
*
* Returns: ---
*
salsa20_seek(ctx, 0);
}
-/* --- @salsa20_seek{,u64}@ --- *
+void salsa20_setnonce_ietf(salsa20_ctx *ctx, const void *nonce)
+{
+ const octet *n = nonce;
+
+ ctx->a[ 5] = LOAD32_L(n + 0);
+ ctx->a[14] = LOAD32_L(n + 4);
+ ctx->a[11] = LOAD32_L(n + 8);
+ salsa20_seek_ietf(ctx, 0);
+}
+
+/* --- @salsa20_seek{,u64,_ietf}@ --- *
*
* Arguments: @salsa20_ctx *ctx@ = pointer to context
- * @unsigned long i@, @kludge64 i@ = new position to set
+ * @unsigned long i@, @kludge64 i@, @uint32@ = new position
*
* Returns: ---
*
ctx->bufi = SALSA20_OUTSZ;
}
-/* --- @salsa20_tell{,u64}@ --- *
+void salsa20_seek_ietf(salsa20_ctx *ctx, uint32 i)
+ { ctx->a[8] = i; }
+
+/* --- @salsa20_tell{,u64,_ietf}@ --- *
*
* Arguments: @salsa20_ctx *ctx@ = pointer to context
*
kludge64 salsa20_tellu64(salsa20_ctx *ctx)
{ kludge64 i; SET64(i, ctx->a[5], ctx->a[8]); return (i); }
+uint32 salsa20_tell_ietf(salsa20_ctx *ctx)
+ { return (ctx->a[5]); }
+
/* --- @salsa20{,12,8}_encrypt@ --- *
*
* Arguments: @salsa20_ctx *ctx@ = pointer to context
static void gsetiv(gcipher *c, const void *iv)
{ gctx *g = (gctx *)c; salsa20_setnonce(&g->ctx, iv); }
+static void gsetiv_ietf(gcipher *c, const void *iv)
+ { gctx *g = (gctx *)c; salsa20_setnonce_ietf(&g->ctx, iv); }
+
static void gdestroy(gcipher *c)
{ gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); }
#define DEFGCIPHER(r) \
\
- static const gcipher_ops gops_##r; \
+ static const gcipher_ops gops_##r, gops_##r##_ietf; \
\
static gcipher *ginit_##r(const void *k, size_t sz) \
{ return (ginit(k, sz, &gops_##r)); } \
\
+ static gcipher *ginit_##r##_ietf(const void *k, size_t sz) \
+ { return (ginit(k, sz, &gops_##r##_ietf)); } \
+ \
static void gencrypt_##r(gcipher *c, const void *s, \
void *t, size_t sz) \
{ gctx *g = (gctx *)c; SALSA20_ENCRYPT(r, &g->ctx, s, t, sz); } \
gencrypt_##r, gencrypt_##r, gdestroy, gsetiv, 0 \
}; \
\
+ static const gcipher_ops gops_##r##_ietf = { \
+ &SALSA20_DECOR(salsa20, r, _ietf), \
+ gencrypt_##r, gencrypt_##r, gdestroy, gsetiv_ietf, 0 \
+ }; \
+ \
const gccipher SALSA20_DECOR(salsa20, r, ) = { \
SALSA20_NAME_##r, salsa20_keysz, \
SALSA20_NONCESZ, ginit_##r \
+ }; \
+ \
+ const gccipher SALSA20_DECOR(salsa20, r, _ietf) = { \
+ SALSA20_NAME_##r "-ietf", salsa20_keysz, \
+ SALSA20_IETF_NONCESZ, ginit_##r##_ietf \
};
SALSA20_VARS(DEFGCIPHER)
static void gr_seek(void *r, kludge64 pos)
{ grctx *g = r; salsa20_seeku64(&g->ctx, pos); }
+static void gr_seek_ietf(void *r, kludge64 pos)
+ { grctx *g = r; salsa20_seek_ietf(&g->ctx, LO64(pos)); }
+
static kludge64 gr_tell(void *r)
{ grctx *g = r; return (salsa20_tellu64(&g->ctx)); }
+static kludge64 gr_tell_ietf(void *r)
+{
+ grctx *g = r;
+ kludge64 pos;
+
+ SET64(pos, 0, salsa20_tell_ietf(&g->ctx));
+ return (pos);
+}
+
static void gr_setnonce(void *r, const void *n)
{ grctx *g = r; salsa20_setnonce(&g->ctx, n); }
+static void gr_setnonce_ietf(void *r, const void *n)
+ { grctx *g = r; salsa20_setnonce(&g->ctx, n); }
+
static void grdestroy(grand *r)
{ grctx *g = (grctx *)r; BURN(*g); S_DESTROY(g); }
g->r.r.ops = ops;
g->r.ops = myops;
salsa20_init(&g->ctx, k, ksz, 0);
- myops->setnonce(g, n);
+ if (n) myops->setnonce(g, n);
return (&g->r.r);
}
{ SALSA20_NONCESZ, gr_seek, gr_tell, \
gr_setnonce, gr_generate_##rr }; \
\
+ static const grops grops_##rr##_ietf = \
+ { SALSA20_IETF_NONCESZ, gr_seek_ietf, gr_tell_ietf, \
+ gr_setnonce_ietf, gr_generate_##rr }; \
+ \
static const grand_ops grops_rand_##rr = { \
SALSA20_NAME_##rr, GRAND_CRYPTO, 0, \
grmisc, grdestroy, grword, \
grbyte, grword, grand_defaultrange, grfill \
}; \
\
+ static const grand_ops grops_rand_##rr##_ietf = { \
+ SALSA20_NAME_##rr "-ietf", GRAND_CRYPTO, 0, \
+ grmisc, grdestroy, grword, \
+ grbyte, grword, grand_defaultrange, grfill \
+ }; \
+ \
grand *SALSA20_DECOR(salsa20, rr, _rand) \
(const void *k, size_t ksz, const void *n) \
- { return (grinit(k, ksz, n, &grops_rand_##rr, &grops_##rr)); }
+ { return (grinit(k, ksz, n, &grops_rand_##rr, &grops_##rr)); } \
+ \
+ grand *SALSA20_DECOR(salsa20, rr, _ietf_rand) \
+ (const void *k, size_t ksz, const void *n) \
+ { \
+ return (grinit(k, ksz, n, \
+ &grops_rand_##rr##_ietf, \
+ &grops_##rr##_ietf)); \
+ }
+
SALSA20_VARS(DEFGRAND)
#define DEFXGRAND(rr) \
kludge64 pos64; \
salsa20_init(ctx, k, ksz, 0); \
if (nsz == 8) salsa20_setnonce(ctx, n); \
+ else if (nsz == 12) salsa20_setnonce_ietf(ctx, n); \
if (psz == 8) { LOAD64_(pos64, p); salsa20_seeku64(ctx, pos64); } \
+ else if (psz == 4) salsa20_seek_ietf(ctx, LOAD32(p)); \
} while (0)
#define XSALSA20_TESTSETUP(r, ctx, k, ksz, n, nsz, p, psz) do { \