summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c
new file mode 100644
index 00000000..fce6a22f
--- /dev/null
+++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/pbkdf2.c
@@ -0,0 +1,84 @@
+/*
+ * cifra - embedded cryptography library
+ * Written in 2014 by Joseph Birr-Pixton <jpixton@gmail.com>
+ *
+ * To the extent possible under law, the author(s) have dedicated all
+ * copyright and related and neighboring rights to this software to the
+ * public domain worldwide. This software is distributed without any
+ * warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication
+ * along with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "pbkdf2.h"
+#include "hmac.h"
+#include "bitops.h"
+#include "handy.h"
+#include "tassert.h"
+
+#include <string.h>
+
+static void F(const cf_hmac_ctx *startctx,
+ uint32_t counter,
+ const uint8_t *salt, size_t nsalt,
+ uint32_t iterations,
+ uint8_t *out)
+{
+ uint8_t U[CF_MAXHASH];
+ size_t hashsz = startctx->hash->hashsz;
+
+ uint8_t countbuf[4];
+ write32_be(counter, countbuf);
+
+ /* First iteration:
+ * U_1 = PRF(P, S || INT_32_BE(i))
+ */
+ cf_hmac_ctx ctx = *startctx;
+ cf_hmac_update(&ctx, salt, nsalt);
+ cf_hmac_update(&ctx, countbuf, sizeof countbuf);
+ cf_hmac_finish(&ctx, U);
+ memcpy(out, U, hashsz);
+
+ /* Subsequent iterations:
+ * U_c = PRF(P, U_{c-1})
+ */
+ for (uint32_t i = 1; i < iterations; i++)
+ {
+ ctx = *startctx;
+ cf_hmac_update(&ctx, U, hashsz);
+ cf_hmac_finish(&ctx, U);
+ xor_bb(out, out, U, hashsz);
+ }
+}
+
+void cf_pbkdf2_hmac(const uint8_t *pw, size_t npw,
+ const uint8_t *salt, size_t nsalt,
+ uint32_t iterations,
+ uint8_t *out, size_t nout,
+ const cf_chash *hash)
+{
+ uint32_t counter = 1;
+ uint8_t block[CF_MAXHASH];
+
+ assert(iterations);
+ assert(out && nout);
+ assert(hash);
+
+ /* Starting point for inner loop. */
+ cf_hmac_ctx ctx;
+ cf_hmac_init(&ctx, hash, pw, npw);
+
+ while (nout)
+ {
+ F(&ctx, counter, salt, nsalt, iterations, block);
+
+ size_t taken = MIN(nout, hash->hashsz);
+ memcpy(out, block, taken);
+ out += taken;
+ nout -= taken;
+ counter++;
+ }
+}
+