ref: 7ed22aaeec7a09f2215d08003e2e5c824f903d5d
parent: b749f36baa4800e116bea6fcd0abc23c28e7078f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Sep 2 07:30:17 EDT 2015
libsec: add rfc5869 hmac-based key derivation function hkdf_x()
--- a/sys/include/libsec.h
+++ b/sys/include/libsec.h
@@ -464,3 +464,8 @@
/* password-based key derivation function 2 (rfc2898) */
void pbkdf2_x(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d, ulong dlen,
DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen);
+
+/* hmac-based key derivation function (rfc5869) */
+void hkdf_x(uchar *salt, ulong nsalt, uchar *info, ulong ninfo, uchar *key, ulong nkey, uchar *d, ulong dlen,
+ DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*), int xlen);
+
--- /dev/null
+++ b/sys/src/libsec/port/hkdf.c
@@ -1,0 +1,39 @@
+#include "os.h"
+#include <mp.h>
+#include <libsec.h>
+
+/* rfc5869 */
+void
+hkdf_x(salt, nsalt, info, ninfo, key, nkey, d, dlen, x, xlen)
+ uchar *salt, *info, *key, *d;
+ ulong nsalt, ninfo, nkey, dlen;
+ DigestState* (*x)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
+ int xlen;
+{
+ uchar prk[256], tmp[256], cnt;
+ DigestState *ds;
+
+ assert(xlen <= sizeof(tmp));
+
+ memset(tmp, 0, xlen);
+ if(nsalt == 0){
+ salt = tmp;
+ nsalt = xlen;
+ }
+ /* note that salt and key are swapped in this case */
+ (*x)(key, nkey, salt, nsalt, prk, nil);
+ ds = nil;
+ for(cnt=1;; cnt++) {
+ if(ninfo > 0)
+ ds = (*x)(info, ninfo, prk, xlen, nil, ds);
+ (*x)(&cnt, 1, prk, xlen, tmp, ds);
+ if(dlen <= xlen){
+ memmove(d, tmp, dlen);
+ break;
+ }
+ memmove(d, tmp, xlen);
+ dlen -= xlen;
+ d += xlen;
+ ds = (*x)(tmp, xlen, prk, xlen, nil, nil);
+ }
+}
--- a/sys/src/libsec/port/mkfile
+++ b/sys/src/libsec/port/mkfile
@@ -21,9 +21,10 @@
ecc.c\
ripemd.c\
dh.c\
- pbkdf2.c\
curve25519.c\
curve25519_dh.c\
+ pbkdf2.c\
+ hkdf.c\
ALLOFILES=${CFILES:%.c=%.$O}