+/* --- @ks_derivekey@ --- *
+ *
+ * Arguments: @octet *k@ = pointer to an output buffer of at least
+ * @MAXHASHSZ@ bytes
+ * @size_t ksz@ = actual size wanted (for tracing)
+ * @const struct rawkey *rk@ = a raw key, as passed into
+ * @genkeys@
+ * @int dir@ = direction for the key (@DIR_IN@ or @DIR_OUT@)
+ * @const char *what@ = label for the key (input to derivation)
+ *
+ * Returns: ---
+ *
+ * Use: Derives a session key, for use on incoming or outgoing data.
+ * This function is part of a private protocol between @ks_gen@
+ * and the bulk crypto transform @genkeys@ operation.
+ */
+
+struct rawkey {
+ const gchash *hc;
+ const octet *k;
+ size_t x, y, z;
+};
+
+void ks_derivekey(octet *k, size_t ksz, const struct rawkey *rk,
+ int dir, const char *what)
+{
+ const gchash *hc = rk->hc;
+ ghash *h;
+
+ assert(ksz <= hc->hashsz);
+ assert(hc->hashsz <= MAXHASHSZ);
+ h = GH_INIT(hc);
+ GH_HASH(h, "tripe-", 6); GH_HASH(h, what, strlen(what) + 1);
+ switch (dir) {
+ case DIR_IN:
+ GH_HASH(h, rk->k, rk->x);
+ GH_HASH(h, rk->k + rk->x, rk->y - rk->x);
+ break;
+ case DIR_OUT:
+ GH_HASH(h, rk->k + rk->x, rk->y - rk->x);
+ GH_HASH(h, rk->k, rk->x);
+ break;
+ default:
+ abort();
+ }
+ GH_HASH(h, rk->k + rk->y, rk->z - rk->y);
+ GH_DONE(h, k);
+ GH_DESTROY(h);
+ IF_TRACING(T_KEYSET, { IF_TRACING(T_CRYPTO, {
+ char _buf[32];
+ sprintf(_buf, "crypto: %s key %s", dir ? "outgoing" : "incoming", what);
+ trace_block(T_CRYPTO, _buf, k, ksz);
+ }) })
+}
+