summaryrefslogtreecommitdiffstats
path: root/sys/geom/eli/pkcs5v2.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2005-07-27 21:43:37 +0000
committerpjd <pjd@FreeBSD.org>2005-07-27 21:43:37 +0000
commit57922fa5cc21f455226d4725d6b6d303710b8534 (patch)
tree08d6bf97fadbec3f76872d8ae88345ff02534c94 /sys/geom/eli/pkcs5v2.c
parent52bcb6f38c0a472abe10e970cbfe0b6d5e4d94bc (diff)
downloadFreeBSD-src-57922fa5cc21f455226d4725d6b6d303710b8534.zip
FreeBSD-src-57922fa5cc21f455226d4725d6b6d303710b8534.tar.gz
Add GEOM_ELI class which provides GEOM providers encryption.
For features list and usage see manual page: geli(8). Sponsored by: Wheel Sp. z o.o. http://www.wheel.pl MFC after: 1 week
Diffstat (limited to 'sys/geom/eli/pkcs5v2.c')
-rw-r--r--sys/geom/eli/pkcs5v2.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/sys/geom/eli/pkcs5v2.c b/sys/geom/eli/pkcs5v2.c
new file mode 100644
index 0000000..5fcd047
--- /dev/null
+++ b/sys/geom/eli/pkcs5v2.c
@@ -0,0 +1,123 @@
+/*-
+ * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#else
+#include <sys/resource.h>
+#include <stdint.h>
+#include <strings.h>
+#endif
+
+#include <geom/eli/g_eli.h>
+#include <geom/eli/pkcs5v2.h>
+
+static __inline void
+xor(uint8_t *dst, const uint8_t *src, size_t size)
+{
+
+ for (; size > 0; size--)
+ *dst++ ^= *src++;
+}
+
+void
+pkcs5v2_genkey(uint8_t *key, unsigned keylen, const uint8_t *salt,
+ size_t saltsize, const char *passphrase, u_int iterations)
+{
+ uint8_t md[SHA512_MDLEN], saltcount[saltsize + sizeof(uint32_t)];
+ uint8_t *counter, *keyp;
+ u_int i, bsize, passlen;
+ uint32_t count;
+
+ passlen = strlen(passphrase);
+ bzero(key, keylen);
+ bcopy(salt, saltcount, saltsize);
+ counter = saltcount + saltsize;
+
+ keyp = key;
+ for (count = 1; keylen > 0; count++, keylen -= bsize, keyp += bsize) {
+ bsize = MIN(keylen, sizeof(md));
+
+ counter[0] = (count >> 24) & 0xff;
+ counter[1] = (count >> 16) & 0xff;
+ counter[2] = (count >> 8) & 0xff;
+ counter[3] = count & 0xff;
+ g_eli_crypto_hmac(passphrase, passlen, saltcount,
+ sizeof(saltcount), md, 0);
+ xor(keyp, md, bsize);
+
+ for(i = 1; i < iterations; i++) {
+ g_eli_crypto_hmac(passphrase, passlen, md, sizeof(md),
+ md, 0);
+ xor(keyp, md, bsize);
+ }
+ }
+}
+
+#ifndef _KERNEL
+/*
+ * Return the number of microseconds needed for 'interations' iterations.
+ */
+static int
+pkcs5v2_probe(int iterations)
+{
+ uint8_t key[G_ELI_USERKEYLEN], salt[G_ELI_SALTLEN];
+ uint8_t passphrase[] = "passphrase";
+ struct rusage start, end;
+ int usecs;
+
+ getrusage(RUSAGE_SELF, &start);
+ pkcs5v2_genkey(key, sizeof(key), salt, sizeof(salt), passphrase,
+ iterations);
+ getrusage(RUSAGE_SELF, &end);
+
+ usecs = end.ru_utime.tv_sec - start.ru_utime.tv_sec;
+ usecs *= 1000000;
+ usecs += end.ru_utime.tv_usec - start.ru_utime.tv_usec;
+ return (usecs);
+}
+
+/*
+ * Return the number of iterations which takes 'usecs' microseconds.
+ */
+int
+pkcs5v2_calculate(int usecs)
+{
+ int iterations, v;
+
+ for (iterations = 1; ; iterations <<= 1) {
+ v = pkcs5v2_probe(iterations);
+ if (v > 2000000)
+ break;
+ }
+ return (((intmax_t)iterations * (intmax_t)usecs) / v);
+}
+#endif /* !_KERNEL */
OpenPOWER on IntegriCloud