From d87d7d469f91136744b8ebd517d55cd4230c4957 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Fri, 14 Nov 2014 11:37:01 -0600 Subject: [PATCH] crypto: Add passphrase generation utility --- Makefile.am | 1 + src/crypto.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/crypto.h | 27 ++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 src/crypto.c create mode 100644 src/crypto.h diff --git a/Makefile.am b/Makefile.am index 9df3ccec..c2c053f5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h linux/kdbus.h \ src/ie.h src/ie.c \ src/dbus.h src/dbus.c \ src/manager.h src/manager.c \ + src/crypto.h src/crypto.c \ iwd.h src_iwd_LDADD = ell/libell-internal.la diff --git a/src/crypto.c b/src/crypto.c new file mode 100644 index 00000000..b1b25c9d --- /dev/null +++ b/src/crypto.c @@ -0,0 +1,87 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "sha1.h" +#include "crypto.h" + +int crypto_psk_from_passphrase(const char *passphrase, + const unsigned char *ssid, size_t ssid_len, + unsigned char *out_psk) +{ + size_t passphrase_len; + size_t i; + bool result; + unsigned char psk[32]; + + if (!passphrase) + return -EINVAL; + + if (!ssid) + return -EINVAL; + + /* + * IEEE 802.11, Annex M, Section M.4.1: + * "A pass-phrase is a sequence of between 8 and 63 ASCII-encoded + * characters. The limit of 63 comes from the desire to distinguish + * between a pass-phrase and a PSK displayed as 64 hexadecimal + * characters." + */ + passphrase_len = strlen(passphrase); + if (passphrase_len < 8 || passphrase_len > 63) + return -ERANGE; + + if (ssid_len == 0 || ssid_len > 32) + return -ERANGE; + + /* IEEE 802.11, Annex M, Section M.4.1: + * "Each character in the pass-phrase must have an encoding in the + * range of 32 to 126 (decimal), inclusive." + * + * This corresponds to printable characters only + */ + for (i = 0; i < passphrase_len; i++) { + if (l_ascii_isprint(passphrase[i])) + continue; + + return -EINVAL; + } + + result = pbkdf2_sha1(passphrase, passphrase_len, ssid, ssid_len, + 4096, psk, sizeof(psk)); + if (!result) + return -ENOKEY; + + if (out_psk) + memcpy(out_psk, psk, sizeof(psk)); + + return 0; +} diff --git a/src/crypto.h b/src/crypto.h new file mode 100644 index 00000000..99897c11 --- /dev/null +++ b/src/crypto.h @@ -0,0 +1,27 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +int crypto_psk_from_passphrase(const char *passphrase, + const unsigned char *ssid, size_t ssid_len, + unsigned char *out_psk);