<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/24291">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  dexter: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">kdf: add key derivation functions<br><br>generic sha code from git://w1.fi/hostap.git commit<br>5ea93947ca67ba83529798b806a15b247cdb2e93 which also happens<br>to be the source of our milenage code.<br><br>Related: SYS#5324<br>Change-Id: Ibf2e49edada944d91ceba62bd0d6b6ce69261fcd<br>---<br>M TODO-RELEASE<br>M include/Makefile.am<br>A include/osmocom/crypt/kdf.h<br>M src/gsm/Makefile.am<br>A src/gsm/kdf.c<br>A src/gsm/kdf/common.h<br>A src/gsm/kdf/crypto.h<br>A src/gsm/kdf/sha1-internal.c<br>A src/gsm/kdf/sha1.c<br>A src/gsm/kdf/sha1.h<br>A src/gsm/kdf/sha1_i.h<br>A src/gsm/kdf/sha256-internal.c<br>A src/gsm/kdf/sha256.c<br>A src/gsm/kdf/sha256.h<br>A src/gsm/kdf/sha256_i.h<br>M src/gsm/libosmogsm.map<br>16 files changed, 1,752 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/TODO-RELEASE b/TODO-RELEASE</span><br><span>index 0f70081..260e1d4 100644</span><br><span>--- a/TODO-RELEASE</span><br><span>+++ b/TODO-RELEASE</span><br><span>@@ -14,3 +14,4 @@</span><br><span> libosmovty      vty_read_config_filep   New API</span><br><span> libosmosim    osim_card_{reset,close} New API</span><br><span> libosmocore     struct rate_ctr_group, osmo_stat_item_group_desc ABI breakage due to new struct members</span><br><span style="color: hsl(120, 100%, 40%);">+libosmgsm      kdf functions   New API</span><br><span>diff --git a/include/Makefile.am b/include/Makefile.am</span><br><span>index f0742d5..e25ed48 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -62,6 +62,7 @@</span><br><span>                        osmocom/core/use_count.h \</span><br><span>                        osmocom/crypt/auth.h \</span><br><span>                        osmocom/crypt/gprs_cipher.h \</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmocom/crypt/kdf.h \</span><br><span>                 osmocom/ctrl/control_cmd.h \</span><br><span>                 osmocom/ctrl/control_if.h \</span><br><span>                  osmocom/ctrl/ports.h \</span><br><span>diff --git a/include/osmocom/crypt/kdf.h b/include/osmocom/crypt/kdf.h</span><br><span>new file mode 100644</span><br><span>index 0000000..4a3b3b2</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/crypt/kdf.h</span><br><span>@@ -0,0 +1,21 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \defgroup kdf key derivation functions</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file kdf.h */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_kc128(const uint8_t* ck, const uint8_t* ik, uint8_t* kc128);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_kasme(const uint8_t *ck, const uint8_t *ik, const uint8_t* plmn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const uint8_t *sqn,  const uint8_t *ak, uint8_t *kasme);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_enb(const uint8_t *kasme, uint32_t ul_count, uint8_t *kenb);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_nh(const uint8_t *kasme, const uint8_t *sync_input, uint8_t *nh);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_nas(uint8_t algo_type, uint8_t algo_id, const uint8_t *kasme, uint8_t *knas);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* @} */</span><br><span>diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am</span><br><span>index f1e2a5a..b336239 100644</span><br><span>--- a/src/gsm/Makefile.am</span><br><span>+++ b/src/gsm/Makefile.am</span><br><span>@@ -33,7 +33,8 @@</span><br><span>                        gsup.c gsup_sms.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \</span><br><span>                  gsm23003.c gsm23236.c mncc.c bts_features.c oap_client.c \</span><br><span>                   gsm29118.c gsm48_rest_octets.c cbsp.c gsm48049.c i460_mux.c \</span><br><span style="color: hsl(0, 100%, 40%);">-                   gad.c bsslap.c bssmap_le.c</span><br><span style="color: hsl(120, 100%, 40%);">+                    gad.c bsslap.c bssmap_le.c kdf.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> libgsmint_la_LDFLAGS = -no-undefined</span><br><span> libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la</span><br><span> </span><br><span>@@ -44,6 +45,10 @@</span><br><span> if ENABLE_GNUTLS</span><br><span> AM_CPPFLAGS += $(LIBGNUTLS_CFLAGS)</span><br><span> libosmogsm_la_LIBADD += $(LIBGNUTLS_LIBS)</span><br><span style="color: hsl(120, 100%, 40%);">+else</span><br><span style="color: hsl(120, 100%, 40%);">+noinst_HEADERS += kdf/sha1.h kdf/sha256.h kdf/common.h kdf/sha1_i.h kdf/sha256_i.h</span><br><span style="color: hsl(120, 100%, 40%);">+libgsmint_la_SOURCES +=  kdf/sha256.c kdf/sha256-internal.c \</span><br><span style="color: hsl(120, 100%, 40%);">+                        kdf/sha1.c kdf/sha1-internal.c</span><br><span> endif</span><br><span> </span><br><span> EXTRA_DIST = libosmogsm.map</span><br><span>diff --git a/src/gsm/kdf.c b/src/gsm/kdf.c</span><br><span>new file mode 100644</span><br><span>index 0000000..2ebe41a</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf.c</span><br><span>@@ -0,0 +1,167 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Eric Wild <ewild@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "../../config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#if (USE_GNUTLS)</span><br><span style="color: hsl(120, 100%, 40%);">+#include <gnutls/gnutls.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <gnutls/crypto.h></span><br><span style="color: hsl(120, 100%, 40%);">+#define HMAC_FUNC(k,lk,s,sl,out) gnutls_hmac_fast(GNUTLS_MAC_SHA256,k,lk,s,sl,out)</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/crypt/kdf.h></span><br><span style="color: hsl(120, 100%, 40%);">+#define HMAC_FUNC(k,lk,s,sl,out) hmac_sha256(k,lk,s,sl,out)</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/bit32gen.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/crypt/kdf.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "kdf/common.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "kdf/sha256.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if (USE_GNUTLS)</span><br><span style="color: hsl(120, 100%, 40%);">+/* gnutls < 3.3.0 requires global init.</span><br><span style="color: hsl(120, 100%, 40%);">+ * gnutls >= 3.3.0 does it automatic.</span><br><span style="color: hsl(120, 100%, 40%);">+ * It doesn't hurt calling it twice,</span><br><span style="color: hsl(120, 100%, 40%);">+ * as long it's not done at the same time (threads).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((constructor))</span><br><span style="color: hsl(120, 100%, 40%);">+static void on_dso_load_gnutls(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!gnutls_check_version("3.3.0"))</span><br><span style="color: hsl(120, 100%, 40%);">+         gnutls_global_init();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+__attribute__((destructor))</span><br><span style="color: hsl(120, 100%, 40%);">+static void on_dso_unload_gnutls(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!gnutls_check_version("3.3.0"))</span><br><span style="color: hsl(120, 100%, 40%);">+         gnutls_global_deinit();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file uses the generic key derivation function defined in 3GPP TS 33.220 Annex B</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The S parameter always consists of concatenated values FC | P0 | L0 | Pi | Li | ...</span><br><span style="color: hsl(120, 100%, 40%);">+ * with Pi = Parameter number i and Li = Length of Pi (two octets)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * FC is either a single octet or two octets 0xff | FC</span><br><span style="color: hsl(120, 100%, 40%);">+ * FC values ranges depend on the specification parts that use the KDF,</span><br><span style="color: hsl(120, 100%, 40%);">+ * they are defined in 3GPP TS 33.220 Annex B.2.2</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \addtogroup kdf</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ *  key derivation functions</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file kdf.c */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 33.102 B.5 */</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_kc128(const uint8_t* ck, const uint8_t* ik, uint8_t* kc128) {</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t k[16*2];</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t s[1];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t out_tmp256[32];</span><br><span style="color: hsl(120, 100%, 40%);">+       memcpy (&k[0], ck, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy (&k[16], ik, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        s[0] = 0x32; // yeah, really just one FC byte..</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     HMAC_FUNC(k, 32, s, 1, out_tmp256);</span><br><span style="color: hsl(120, 100%, 40%);">+   memcpy(kc128, out_tmp256, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 33.401 A.2 */</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_kasme(const uint8_t *ck, const uint8_t *ik, const uint8_t* plmn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      const uint8_t *sqn,  const uint8_t *ak, uint8_t *kasme)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t s[14];</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t k[16*2];</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(&k[0], ck, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(&k[16], ik, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ s[0] = 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+  memcpy(&s[1], plmn_id, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+        s[4] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+  s[5] = 0x03;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 6; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+            s[6+i] = sqn[i] ^ ak[i];</span><br><span style="color: hsl(120, 100%, 40%);">+      s[12] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+ s[13] = 0x06;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       HMAC_FUNC(k, 32, s, 14, kasme);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 33.401 A.3 */</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_enb(const uint8_t *kasme, uint32_t ul_count, uint8_t *kenb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t s[7];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       s[0] = 0x11;</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_store32be(ul_count, &s[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+  s[5] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+  s[6] = 0x04;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        HMAC_FUNC(kasme, 32, s, 7, kenb);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 33.401 A.4 */</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_nh(const uint8_t *kasme, const uint8_t *sync_input, uint8_t *nh)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t s[35];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      s[0] = 0x12;</span><br><span style="color: hsl(120, 100%, 40%);">+  memcpy(s+1, sync_input, 32);</span><br><span style="color: hsl(120, 100%, 40%);">+  s[33] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+ s[34] = 0x20;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       HMAC_FUNC(kasme, 32, s, 35, nh);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 33.401 A.7 */</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_kdf_nas(uint8_t algo_type, uint8_t algo_id, const uint8_t *kasme, uint8_t *knas)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t s[7];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t out[32];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    s[0] = 0x15;</span><br><span style="color: hsl(120, 100%, 40%);">+  s[1] = algo_type;</span><br><span style="color: hsl(120, 100%, 40%);">+     s[2] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+  s[3] = 0x01;</span><br><span style="color: hsl(120, 100%, 40%);">+  s[4] = algo_id;</span><br><span style="color: hsl(120, 100%, 40%);">+       s[5] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+  s[6] = 0x01;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        HMAC_FUNC(kasme, 32, s, 7, out);</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(knas, out+16, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/src/gsm/kdf/common.h b/src/gsm/kdf/common.h</span><br><span>new file mode 100644</span><br><span>index 0000000..c1ef17e</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/common.h</span><br><span>@@ -0,0 +1,101 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define CONFIG_CRYPTO_INTERNAL</span><br><span style="color: hsl(120, 100%, 40%);">+#define TEST_FAIL() 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MSG_DEBUG</span><br><span style="color: hsl(120, 100%, 40%);">+#define wpa_hexdump(x, args...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define wpa_hexdump_key(x, args...)</span><br><span style="color: hsl(120, 100%, 40%);">+#define wpa_printf(x, args...)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define os_memcpy(x, y, z)  memcpy(x, y, z)</span><br><span style="color: hsl(120, 100%, 40%);">+#define os_memcmp(x, y, z)  memcmp(x, y, z)</span><br><span style="color: hsl(120, 100%, 40%);">+#define os_memset(x, y, z)  memset(x, y, z)</span><br><span style="color: hsl(120, 100%, 40%);">+#define os_malloc(x)  malloc(x)</span><br><span style="color: hsl(120, 100%, 40%);">+#define os_free(x)  free(x)</span><br><span style="color: hsl(120, 100%, 40%);">+#define os_strlen(x)  strlen(x)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define forced_memzero(ptr, len) memset(ptr, 0, len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint64_t u64;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint32_t u32;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint16_t u16;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint8_t u8;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int64_t s64;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int32_t s32;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int16_t s16;</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int8_t s8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Macros for handling unaligned memory accesses */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_PUT_BE16(a, val)                  \</span><br><span style="color: hsl(120, 100%, 40%);">+     do {                                    \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[0] = ((u16) (val)) >> 8;      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[1] = ((u16) (val)) & 0xff;      \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_PUT_LE16(a, val)                     \</span><br><span style="color: hsl(120, 100%, 40%);">+     do {                                    \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[1] = ((u16) (val)) >> 8;      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[0] = ((u16) (val)) & 0xff;      \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                         ((u32) (a)[2]))</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_PUT_BE24(a, val)                                  \</span><br><span style="color: hsl(120, 100%, 40%);">+     do {                                                    \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);  \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[2] = (u8) (((u32) (val)) & 0xff);               \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                        (((u32) (a)[2]) << 8) | ((u32) (a)[3]))</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_PUT_BE32(a, val)                                    \</span><br><span style="color: hsl(120, 100%, 40%);">+     do {                                                    \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff);  \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[3] = (u8) (((u32) (val)) & 0xff);               \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                        (((u32) (a)[1]) << 8) | ((u32) (a)[0]))</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_PUT_LE32(a, val)                                    \</span><br><span style="color: hsl(120, 100%, 40%);">+     do {                                                    \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff);  \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[0] = (u8) (((u32) (val)) & 0xff);               \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                        (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                       (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                       (((u64) (a)[6]) << 8) | ((u64) (a)[7]))</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_PUT_BE64(a, val)                            \</span><br><span style="color: hsl(120, 100%, 40%);">+     do {                                            \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[0] = (u8) (((u64) (val)) >> 56);      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[1] = (u8) (((u64) (val)) >> 48);      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[2] = (u8) (((u64) (val)) >> 40);      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[3] = (u8) (((u64) (val)) >> 32);      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[4] = (u8) (((u64) (val)) >> 24);      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[5] = (u8) (((u64) (val)) >> 16);      \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[6] = (u8) (((u64) (val)) >> 8);       \</span><br><span style="color: hsl(120, 100%, 40%);">+             (a)[7] = (u8) (((u64) (val)) & 0xff);       \</span><br><span style="color: hsl(120, 100%, 40%);">+     } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define WPA_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                        (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                       (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \</span><br><span style="color: hsl(120, 100%, 40%);">+                       (((u64) (a)[1]) << 8) | ((u64) (a)[0]))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define __must_check</span><br><span>diff --git a/src/gsm/kdf/crypto.h b/src/gsm/kdf/crypto.h</span><br><span>new file mode 100644</span><br><span>index 0000000..6dca191</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/crypto.h</span><br><span>@@ -0,0 +1,470 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * WPA Supplicant / wrapper functions for crypto libraries</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file defines the cryptographic functions that need to be implemented</span><br><span style="color: hsl(120, 100%, 40%);">+ * for wpa_supplicant and hostapd. When TLS is not used, internal</span><br><span style="color: hsl(120, 100%, 40%);">+ * implementation of MD5, SHA1, and AES is used and no external libraries are</span><br><span style="color: hsl(120, 100%, 40%);">+ * required. When TLS is enabled (e.g., by enabling EAP-TLS or EAP-PEAP), the</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto library used by the TLS implementation is expected to be used for</span><br><span style="color: hsl(120, 100%, 40%);">+ * non-TLS needs, too, in order to save space by not implementing these</span><br><span style="color: hsl(120, 100%, 40%);">+ * functions twice.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Wrapper code for using each crypto library is in its own file (crypto*.c)</span><br><span style="color: hsl(120, 100%, 40%);">+ * and one of these files is build and linked in to provide the functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * defined here.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef CRYPTO_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define CRYPTO_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * md4_vector - MD4 hash for data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * md5_vector - MD5 hash for data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef CONFIG_FIPS</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * md5_vector_non_fips_allow - MD5 hash for data vector (non-FIPS use allowed)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int md5_vector_non_fips_allow(size_t num_elem, const u8 *addr[],</span><br><span style="color: hsl(120, 100%, 40%);">+                           const size_t *len, u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+#else /* CONFIG_FIPS */</span><br><span style="color: hsl(120, 100%, 40%);">+#define md5_vector_non_fips_allow md5_vector</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* CONFIG_FIPS */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * sha1_vector - SHA-1 hash for data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len,</span><br><span style="color: hsl(120, 100%, 40%);">+          u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * fips186_2-prf - NIST FIPS Publication 186-2 change notice 1 PRF</span><br><span style="color: hsl(120, 100%, 40%);">+ * @seed: Seed/key for the PRF</span><br><span style="color: hsl(120, 100%, 40%);">+ * @seed_len: Seed length in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @x: Buffer for PRF output</span><br><span style="color: hsl(120, 100%, 40%);">+ * @xlen: Output length in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function implements random number generation specified in NIST FIPS</span><br><span style="color: hsl(120, 100%, 40%);">+ * Publication 186-2 for EAP-SIM. This PRF uses a function that is similar to</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA-1, but has different message padding.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x,</span><br><span style="color: hsl(120, 100%, 40%);">+                         size_t xlen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * sha256_vector - SHA256 hash for data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,</span><br><span style="color: hsl(120, 100%, 40%);">+                u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * des_encrypt - Encrypt one block with DES</span><br><span style="color: hsl(120, 100%, 40%);">+ * @clear: 8 octets (in)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: 7 octets (in) (no parity bits included)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @cypher: 8 octets (out)</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * aes_encrypt_init - Initialize AES for encryption</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Encryption key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Key length in bytes (usually 16, i.e., 128 bits)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: Pointer to context data or %NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void * aes_encrypt_init(const u8 *key, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * aes_encrypt - Encrypt one AES block</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from aes_encrypt_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ * @plain: Plaintext data to be encrypted (16 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @crypt: Buffer for the encrypted data (16 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * aes_encrypt_deinit - Deinitialize AES encryption</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from aes_encrypt_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void aes_encrypt_deinit(void *ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * aes_decrypt_init - Initialize AES for decryption</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Decryption key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Key length in bytes (usually 16, i.e., 128 bits)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: Pointer to context data or %NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void * aes_decrypt_init(const u8 *key, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * aes_decrypt - Decrypt one AES block</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from aes_encrypt_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ * @crypt: Encrypted data (16 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @plain: Buffer for the decrypted data (16 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * aes_decrypt_deinit - Deinitialize AES decryption</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from aes_encrypt_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void aes_decrypt_deinit(void *ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum crypto_hash_alg {</span><br><span style="color: hsl(120, 100%, 40%);">+   CRYPTO_HASH_ALG_MD5, CRYPTO_HASH_ALG_SHA1,</span><br><span style="color: hsl(120, 100%, 40%);">+    CRYPTO_HASH_ALG_HMAC_MD5, CRYPTO_HASH_ALG_HMAC_SHA1,</span><br><span style="color: hsl(120, 100%, 40%);">+  CRYPTO_HASH_ALG_SHA256, CRYPTO_HASH_ALG_HMAC_SHA256</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_hash;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_hash_init - Initialize hash/HMAC function</span><br><span style="color: hsl(120, 100%, 40%);">+ * @alg: Hash algorithm</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key for keyed hash (e.g., HMAC) or %NULL if not needed</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of the key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: Pointer to hash context to use with other hash functions or %NULL</span><br><span style="color: hsl(120, 100%, 40%);">+ * on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      size_t key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_hash_update - Add data to hash calculation</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from crypto_hash_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data: Data buffer to add</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Length of the buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_hash_finish - Complete hash calculation</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from crypto_hash_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ * @hash: Buffer for hash value or %NULL if caller is just freeing the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * context</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Pointer to length of the buffer or %NULL if caller is just freeing the</span><br><span style="color: hsl(120, 100%, 40%);">+ * hash context; on return, this is set to the actual length of the hash value</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 if buffer is too small (len set to needed length),</span><br><span style="color: hsl(120, 100%, 40%);">+ * or -2 on other failures (including failed crypto_hash_update() operations)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function calculates the hash value and frees the context buffer that</span><br><span style="color: hsl(120, 100%, 40%);">+ * was used for hash calculation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int crypto_hash_finish(struct crypto_hash *ctx, u8 *hash, size_t *len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum crypto_cipher_alg {</span><br><span style="color: hsl(120, 100%, 40%);">+     CRYPTO_CIPHER_NULL = 0, CRYPTO_CIPHER_ALG_AES, CRYPTO_CIPHER_ALG_3DES,</span><br><span style="color: hsl(120, 100%, 40%);">+        CRYPTO_CIPHER_ALG_DES, CRYPTO_CIPHER_ALG_RC2, CRYPTO_CIPHER_ALG_RC4</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_cipher;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_cipher_init - Initialize block/stream cipher function</span><br><span style="color: hsl(120, 100%, 40%);">+ * @alg: Cipher algorithm</span><br><span style="color: hsl(120, 100%, 40%);">+ * @iv: Initialization vector for block ciphers or %NULL for stream ciphers</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Cipher key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: Pointer to cipher context to use with other cipher functions or</span><br><span style="color: hsl(120, 100%, 40%);">+ * %NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          const u8 *iv, const u8 *key,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          size_t key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_cipher_encrypt - Cipher encrypt</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from crypto_cipher_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ * @plain: Plaintext to cipher</span><br><span style="color: hsl(120, 100%, 40%);">+ * @crypt: Resulting ciphertext</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Length of the plaintext</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_cipher_encrypt(struct crypto_cipher *ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   const u8 *plain, u8 *crypt, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_cipher_decrypt - Cipher decrypt</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from crypto_cipher_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ * @crypt: Ciphertext to decrypt</span><br><span style="color: hsl(120, 100%, 40%);">+ * @plain: Resulting plaintext</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Length of the cipher text</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_cipher_decrypt(struct crypto_cipher *ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   const u8 *crypt, u8 *plain, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_cipher_decrypt - Free cipher context</span><br><span style="color: hsl(120, 100%, 40%);">+ * @ctx: Context pointer from crypto_cipher_init()</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void crypto_cipher_deinit(struct crypto_cipher *ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_public_key;</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_private_key;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_public_key_import - Import an RSA public key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key buffer (DER encoded RSA public key)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Key buffer length in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: Pointer to the public key or %NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function can just return %NULL if the crypto library supports X.509</span><br><span style="color: hsl(120, 100%, 40%);">+ * parsing. In that case, crypto_public_key_from_cert() is used to import the</span><br><span style="color: hsl(120, 100%, 40%);">+ * public key from a certificate.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_private_key_import - Import an RSA private key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key buffer (DER encoded RSA private key)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Key buffer length in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @passwd: Key encryption password or %NULL if key is not encrypted</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: Pointer to the private key or %NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_private_key * crypto_private_key_import(const u8 *key,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                 size_t len,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   const char *passwd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_public_key_from_cert - Import an RSA public key from a certificate</span><br><span style="color: hsl(120, 100%, 40%);">+ * @buf: DER encoded X.509 certificate</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Certificate buffer length in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: Pointer to public key or %NULL on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function can just return %NULL if the crypto library does not support</span><br><span style="color: hsl(120, 100%, 40%);">+ * X.509 parsing. In that case, internal code will be used to parse the</span><br><span style="color: hsl(120, 100%, 40%);">+ * certificate and public key is imported using crypto_public_key_import().</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                       size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_public_key_encrypt_pkcs1_v15 - Public key encryption (PKCS #1 v1.5)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Public key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @in: Plaintext buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * @inlen: Length of plaintext buffer in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @out: Output buffer for encrypted data</span><br><span style="color: hsl(120, 100%, 40%);">+ * @outlen: Length of output buffer in bytes; set to used length on success</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_public_key_encrypt_pkcs1_v15(</span><br><span style="color: hsl(120, 100%, 40%);">+   struct crypto_public_key *key, const u8 *in, size_t inlen,</span><br><span style="color: hsl(120, 100%, 40%);">+    u8 *out, size_t *outlen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_private_key_decrypt_pkcs1_v15 - Private key decryption (PKCS #1 v1.5)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Private key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @in: Encrypted buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * @inlen: Length of encrypted buffer in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @out: Output buffer for encrypted data</span><br><span style="color: hsl(120, 100%, 40%);">+ * @outlen: Length of output buffer in bytes; set to used length on success</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_private_key_decrypt_pkcs1_v15(</span><br><span style="color: hsl(120, 100%, 40%);">+ struct crypto_private_key *key, const u8 *in, size_t inlen,</span><br><span style="color: hsl(120, 100%, 40%);">+   u8 *out, size_t *outlen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_private_key_sign_pkcs1 - Sign with private key (PKCS #1)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Private key from crypto_private_key_import()</span><br><span style="color: hsl(120, 100%, 40%);">+ * @in: Plaintext buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * @inlen: Length of plaintext buffer in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @out: Output buffer for encrypted (signed) data</span><br><span style="color: hsl(120, 100%, 40%);">+ * @outlen: Length of output buffer in bytes; set to used length on success</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_private_key_sign_pkcs1(struct crypto_private_key *key,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           const u8 *in, size_t inlen,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           u8 *out, size_t *outlen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_public_key_free - Free public key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Public key</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void crypto_public_key_free(struct crypto_public_key *key);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_private_key_free - Free private key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Private key from crypto_private_key_import()</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void crypto_private_key_free(struct crypto_private_key *key);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_public_key_decrypt_pkcs1 - Decrypt PKCS #1 signature</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Public key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @crypt: Encrypted signature data (using the private key)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @crypt_len: Encrypted signature data length</span><br><span style="color: hsl(120, 100%, 40%);">+ * @plain: Buffer for plaintext (at least crypt_len bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @plain_len: Plaintext length (max buffer size on input, real len on output);</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_public_key_decrypt_pkcs1(</span><br><span style="color: hsl(120, 100%, 40%);">+       struct crypto_public_key *key, const u8 *crypt, size_t crypt_len,</span><br><span style="color: hsl(120, 100%, 40%);">+     u8 *plain, size_t *plain_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_global_init - Initialize crypto wrapper</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_global_init(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_global_deinit - Deinitialize crypto wrapper</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void crypto_global_deinit(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * crypto_mod_exp - Modular exponentiation of large integers</span><br><span style="color: hsl(120, 100%, 40%);">+ * @base: Base integer (big endian byte array)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @base_len: Length of base integer in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @power: Power integer (big endian byte array)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @power_len: Length of power integer in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @modulus: Modulus integer (big endian byte array)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @modulus_len: Length of modulus integer in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @result: Buffer for the result</span><br><span style="color: hsl(120, 100%, 40%);">+ * @result_len: Result length (max buffer size on input, real len on output)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function calculates result = base ^ power mod modulus. modules_len is</span><br><span style="color: hsl(120, 100%, 40%);">+ * used as the maximum size of modulus buffer. It is set to the used size on</span><br><span style="color: hsl(120, 100%, 40%);">+ * success.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is only used with internal TLSv1 implementation</span><br><span style="color: hsl(120, 100%, 40%);">+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need</span><br><span style="color: hsl(120, 100%, 40%);">+ * to implement this.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check crypto_mod_exp(const u8 *base, size_t base_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                             const u8 *power, size_t power_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                            const u8 *modulus, size_t modulus_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                                u8 *result, size_t *result_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * rc4_skip - XOR RC4 stream to given data with skip-stream-start</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: RC4 key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @keylen: RC4 key length</span><br><span style="color: hsl(120, 100%, 40%);">+ * @skip: number of bytes to skip from the beginning of the RC4 stream</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data: data to be XOR'ed with RC4 stream</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data_len: buf length</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Generate RC4 pseudo random stream for the given key, skip beginning of the</span><br><span style="color: hsl(120, 100%, 40%);">+ * stream, and XOR the end result with the data buffer to perform RC4</span><br><span style="color: hsl(120, 100%, 40%);">+ * encryption/decryption.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int rc4_skip(const u8 *key, size_t keylen, size_t skip,</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 *data, size_t data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* CRYPTO_H */</span><br><span>diff --git a/src/gsm/kdf/sha1-internal.c b/src/gsm/kdf/sha1-internal.c</span><br><span>new file mode 100644</span><br><span>index 0000000..2216b43</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha1-internal.c</span><br><span>@@ -0,0 +1,307 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA1 hash implementation and interface functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "common.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "sha1.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "sha1_i.h"</span><br><span style="color: hsl(120, 100%, 40%);">+//#include "md5.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "crypto.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+typedef struct SHA1Context SHA1_CTX;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Transform(u32 state[5], const unsigned char buffer[64]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * sha1_vector - SHA-1 hash for data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 of failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      SHA1_CTX ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   SHA1Init(&ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i = 0; i < num_elem; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+             SHA1Update(&ctx, addr[i], len[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+        SHA1Final(mac, &ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* ===== start - public domain SHA1 implementation ===== */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+SHA-1 in C</span><br><span style="color: hsl(120, 100%, 40%);">+By Steve Reid <sreid@sea-to-sky.net></span><br><span style="color: hsl(120, 100%, 40%);">+100% Public Domain</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+-----------------</span><br><span style="color: hsl(120, 100%, 40%);">+Modified 7/98 </span><br><span style="color: hsl(120, 100%, 40%);">+By James H. Brown <jbrown@burgoyne.com></span><br><span style="color: hsl(120, 100%, 40%);">+Still 100% Public Domain</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Corrected a problem which generated improper hash values on 16 bit machines</span><br><span style="color: hsl(120, 100%, 40%);">+Routine SHA1Update changed from</span><br><span style="color: hsl(120, 100%, 40%);">+ void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int</span><br><span style="color: hsl(120, 100%, 40%);">+len)</span><br><span style="color: hsl(120, 100%, 40%);">+to</span><br><span style="color: hsl(120, 100%, 40%);">+        void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned</span><br><span style="color: hsl(120, 100%, 40%);">+long len)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+The 'len' parameter was declared an int which works fine on 32 bit machines.</span><br><span style="color: hsl(120, 100%, 40%);">+However, on 16 bit machines an int is too small for the shifts being done</span><br><span style="color: hsl(120, 100%, 40%);">+against</span><br><span style="color: hsl(120, 100%, 40%);">+it.  This caused the hash function to generate incorrect values if len was</span><br><span style="color: hsl(120, 100%, 40%);">+greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Since the file IO in main() reads 16K at a time, any file 8K or larger would</span><br><span style="color: hsl(120, 100%, 40%);">+be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million</span><br><span style="color: hsl(120, 100%, 40%);">+"a"s).</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+I also changed the declaration of variables i & j in SHA1Update to </span><br><span style="color: hsl(120, 100%, 40%);">+unsigned long from unsigned int for the same reason.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+These changes should make no difference to any 32 bit implementations since</span><br><span style="color: hsl(120, 100%, 40%);">+an</span><br><span style="color: hsl(120, 100%, 40%);">+int and a long are the same size in those environments.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+--</span><br><span style="color: hsl(120, 100%, 40%);">+I also corrected a few compiler warnings generated by Borland C.</span><br><span style="color: hsl(120, 100%, 40%);">+1. Added #include <process.h> for exit() prototype</span><br><span style="color: hsl(120, 100%, 40%);">+2. Removed unused variable 'j' in SHA1Final</span><br><span style="color: hsl(120, 100%, 40%);">+3. Changed exit(0) to return(0) at end of main.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ALL changes I made can be located by searching for comments containing 'JHB'</span><br><span style="color: hsl(120, 100%, 40%);">+-----------------</span><br><span style="color: hsl(120, 100%, 40%);">+Modified 8/98</span><br><span style="color: hsl(120, 100%, 40%);">+By Steve Reid <sreid@sea-to-sky.net></span><br><span style="color: hsl(120, 100%, 40%);">+Still 100% public domain</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+1- Removed #include <process.h> and used return() instead of exit()</span><br><span style="color: hsl(120, 100%, 40%);">+2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)</span><br><span style="color: hsl(120, 100%, 40%);">+3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+-----------------</span><br><span style="color: hsl(120, 100%, 40%);">+Modified 4/01</span><br><span style="color: hsl(120, 100%, 40%);">+By Saul Kravitz <Saul.Kravitz@celera.com></span><br><span style="color: hsl(120, 100%, 40%);">+Still 100% PD</span><br><span style="color: hsl(120, 100%, 40%);">+Modified to run on Compaq Alpha hardware.  </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+-----------------</span><br><span style="color: hsl(120, 100%, 40%);">+Modified 4/01</span><br><span style="color: hsl(120, 100%, 40%);">+By Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+Minor changes to match the coding style used in Dynamics.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Modified September 24, 2004</span><br><span style="color: hsl(120, 100%, 40%);">+By Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+Fixed alignment issue in SHA1Transform when SHA1HANDSOFF is defined.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+Test Vectors (from FIPS PUB 180-1)</span><br><span style="color: hsl(120, 100%, 40%);">+"abc"</span><br><span style="color: hsl(120, 100%, 40%);">+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D</span><br><span style="color: hsl(120, 100%, 40%);">+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"</span><br><span style="color: hsl(120, 100%, 40%);">+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1</span><br><span style="color: hsl(120, 100%, 40%);">+A million repetitions of "a"</span><br><span style="color: hsl(120, 100%, 40%);">+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA1HANDSOFF</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* blk0() and blk() perform the initial expand. */</span><br><span style="color: hsl(120, 100%, 40%);">+/* I got the idea of expanding during the round function from SSLeay */</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef WORDS_BIGENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \</span><br><span style="color: hsl(120, 100%, 40%);">+   (rol(block->l[i], 8) & 0x00FF00FF))</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+#define blk0(i) block->l[i]</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \</span><br><span style="color: hsl(120, 100%, 40%);">+   block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define R0(v,w,x,y,z,i) \</span><br><span style="color: hsl(120, 100%, 40%);">+        z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \</span><br><span style="color: hsl(120, 100%, 40%);">+    w = rol(w, 30);</span><br><span style="color: hsl(120, 100%, 40%);">+#define R1(v,w,x,y,z,i) \</span><br><span style="color: hsl(120, 100%, 40%);">+    z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \</span><br><span style="color: hsl(120, 100%, 40%);">+     w = rol(w, 30);</span><br><span style="color: hsl(120, 100%, 40%);">+#define R2(v,w,x,y,z,i) \</span><br><span style="color: hsl(120, 100%, 40%);">+    z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);</span><br><span style="color: hsl(120, 100%, 40%);">+#define R3(v,w,x,y,z,i) \</span><br><span style="color: hsl(120, 100%, 40%);">+        z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \</span><br><span style="color: hsl(120, 100%, 40%);">+   w = rol(w, 30);</span><br><span style="color: hsl(120, 100%, 40%);">+#define R4(v,w,x,y,z,i) \</span><br><span style="color: hsl(120, 100%, 40%);">+    z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \</span><br><span style="color: hsl(120, 100%, 40%);">+ w=rol(w, 30);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef VERBOSE  /* SAK */</span><br><span style="color: hsl(120, 100%, 40%);">+void SHAPrintContext(SHA1_CTX *context, char *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("%s (%d,%d) %x %x %x %x %x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              msg,</span><br><span style="color: hsl(120, 100%, 40%);">+          context->count[0], context->count[1], </span><br><span style="color: hsl(120, 100%, 40%);">+          context->state[0],</span><br><span style="color: hsl(120, 100%, 40%);">+         context->state[1],</span><br><span style="color: hsl(120, 100%, 40%);">+         context->state[2],</span><br><span style="color: hsl(120, 100%, 40%);">+         context->state[3],</span><br><span style="color: hsl(120, 100%, 40%);">+         context->state[4]);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Hash a single 512-bit block. This is the core of the algorithm. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Transform(u32 state[5], const unsigned char buffer[64])</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 a, b, c, d, e;</span><br><span style="color: hsl(120, 100%, 40%);">+    typedef union {</span><br><span style="color: hsl(120, 100%, 40%);">+               unsigned char c[64];</span><br><span style="color: hsl(120, 100%, 40%);">+          u32 l[16];</span><br><span style="color: hsl(120, 100%, 40%);">+    } CHAR64LONG16;</span><br><span style="color: hsl(120, 100%, 40%);">+       CHAR64LONG16* block;</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef SHA1HANDSOFF</span><br><span style="color: hsl(120, 100%, 40%);">+     CHAR64LONG16 workspace;</span><br><span style="color: hsl(120, 100%, 40%);">+       block = &workspace;</span><br><span style="color: hsl(120, 100%, 40%);">+       os_memcpy(block, buffer, 64);</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+  block = (CHAR64LONG16 *) buffer;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Copy context->state[] to working vars */</span><br><span style="color: hsl(120, 100%, 40%);">+        a = state[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ b = state[1];</span><br><span style="color: hsl(120, 100%, 40%);">+ c = state[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ d = state[3];</span><br><span style="color: hsl(120, 100%, 40%);">+ e = state[4];</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 4 rounds of 20 operations each. Loop unrolled. */</span><br><span style="color: hsl(120, 100%, 40%);">+  R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+       R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);</span><br><span style="color: hsl(120, 100%, 40%);">+       R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);</span><br><span style="color: hsl(120, 100%, 40%);">+       R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);</span><br><span style="color: hsl(120, 100%, 40%);">+       R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);</span><br><span style="color: hsl(120, 100%, 40%);">+       R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);</span><br><span style="color: hsl(120, 100%, 40%);">+       R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);</span><br><span style="color: hsl(120, 100%, 40%);">+       R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);</span><br><span style="color: hsl(120, 100%, 40%);">+       R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);</span><br><span style="color: hsl(120, 100%, 40%);">+       R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);</span><br><span style="color: hsl(120, 100%, 40%);">+       R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);</span><br><span style="color: hsl(120, 100%, 40%);">+       R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);</span><br><span style="color: hsl(120, 100%, 40%);">+       R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);</span><br><span style="color: hsl(120, 100%, 40%);">+       R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);</span><br><span style="color: hsl(120, 100%, 40%);">+       R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);</span><br><span style="color: hsl(120, 100%, 40%);">+       R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);</span><br><span style="color: hsl(120, 100%, 40%);">+       R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);</span><br><span style="color: hsl(120, 100%, 40%);">+       R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);</span><br><span style="color: hsl(120, 100%, 40%);">+       R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);</span><br><span style="color: hsl(120, 100%, 40%);">+       R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Add the working vars back into context.state[] */</span><br><span style="color: hsl(120, 100%, 40%);">+  state[0] += a;</span><br><span style="color: hsl(120, 100%, 40%);">+        state[1] += b;</span><br><span style="color: hsl(120, 100%, 40%);">+        state[2] += c;</span><br><span style="color: hsl(120, 100%, 40%);">+        state[3] += d;</span><br><span style="color: hsl(120, 100%, 40%);">+        state[4] += e;</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Wipe variables */</span><br><span style="color: hsl(120, 100%, 40%);">+  a = b = c = d = e = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef SHA1HANDSOFF</span><br><span style="color: hsl(120, 100%, 40%);">+   os_memset(block, 0, 64);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* SHA1Init - Initialize new context */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Init(SHA1_CTX* context)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       /* SHA1 initialization constants */</span><br><span style="color: hsl(120, 100%, 40%);">+   context->state[0] = 0x67452301;</span><br><span style="color: hsl(120, 100%, 40%);">+    context->state[1] = 0xEFCDAB89;</span><br><span style="color: hsl(120, 100%, 40%);">+    context->state[2] = 0x98BADCFE;</span><br><span style="color: hsl(120, 100%, 40%);">+    context->state[3] = 0x10325476;</span><br><span style="color: hsl(120, 100%, 40%);">+    context->state[4] = 0xC3D2E1F0;</span><br><span style="color: hsl(120, 100%, 40%);">+    context->count[0] = context->count[1] = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Run your data through this. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       u32 i, j;</span><br><span style="color: hsl(120, 100%, 40%);">+     const unsigned char *data = _data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef VERBOSE</span><br><span style="color: hsl(120, 100%, 40%);">+  SHAPrintContext(context, "before");</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ j = (context->count[0] >> 3) & 63;</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((context->count[0] += len << 3) < (len << 3))</span><br><span style="color: hsl(120, 100%, 40%);">+           context->count[1]++;</span><br><span style="color: hsl(120, 100%, 40%);">+       context->count[1] += (len >> 29);</span><br><span style="color: hsl(120, 100%, 40%);">+    if ((j + len) > 63) {</span><br><span style="color: hsl(120, 100%, 40%);">+              os_memcpy(&context->buffer[j], data, (i = 64-j));</span><br><span style="color: hsl(120, 100%, 40%);">+              SHA1Transform(context->state, context->buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+         for ( ; i + 63 < len; i += 64) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   SHA1Transform(context->state, &data[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             j = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     else i = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   os_memcpy(&context->buffer[j], &data[i], len - i);</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef VERBOSE</span><br><span style="color: hsl(120, 100%, 40%);">+ SHAPrintContext(context, "after ");</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Add padding and return the message digest. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 i;</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned char finalcount[8];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          finalcount[i] = (unsigned char)</span><br><span style="color: hsl(120, 100%, 40%);">+                       ((context->count[(i >= 4 ? 0 : 1)] >></span><br><span style="color: hsl(120, 100%, 40%);">+                       ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     SHA1Update(context, (unsigned char *) "\200", 1);</span><br><span style="color: hsl(120, 100%, 40%);">+   while ((context->count[0] & 504) != 448) {</span><br><span style="color: hsl(120, 100%, 40%);">+             SHA1Update(context, (unsigned char *) "\0", 1);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform()</span><br><span style="color: hsl(120, 100%, 40%);">+                                              */</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < 20; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         digest[i] = (unsigned char)</span><br><span style="color: hsl(120, 100%, 40%);">+                   ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &</span><br><span style="color: hsl(120, 100%, 40%);">+                      255);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Wipe variables */</span><br><span style="color: hsl(120, 100%, 40%);">+  i = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        os_memset(context->buffer, 0, 64);</span><br><span style="color: hsl(120, 100%, 40%);">+ os_memset(context->state, 0, 20);</span><br><span style="color: hsl(120, 100%, 40%);">+  os_memset(context->count, 0, 8);</span><br><span style="color: hsl(120, 100%, 40%);">+   os_memset(finalcount, 0, 8);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* ===== end - public domain SHA1 implementation ===== */</span><br><span>diff --git a/src/gsm/kdf/sha1.c b/src/gsm/kdf/sha1.c</span><br><span>new file mode 100644</span><br><span>index 0000000..0d39f77</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha1.c</span><br><span>@@ -0,0 +1,162 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA1 hash implementation and interface functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "common.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "sha1.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "crypto.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * hmac_sha1_vector - HMAC-SHA1 over data vector (RFC 2104)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key for HMAC operations</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of the key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash (20 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 on failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,</span><br><span style="color: hsl(120, 100%, 40%);">+                    const u8 *addr[], const size_t *len, u8 *mac)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned char tk[20];</span><br><span style="color: hsl(120, 100%, 40%);">+ const u8 *_addr[6];</span><br><span style="color: hsl(120, 100%, 40%);">+   size_t _len[6], i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (num_elem > 5) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /*</span><br><span style="color: hsl(120, 100%, 40%);">+             * Fixed limit on the number of fragments to avoid having to</span><br><span style="color: hsl(120, 100%, 40%);">+           * allocate memory (which could fail).</span><br><span style="color: hsl(120, 100%, 40%);">+                 */</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* if key is longer than 64 bytes reset it to key = SHA1(key) */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (key_len > 64) {</span><br><span style="color: hsl(120, 100%, 40%);">+         if (sha1_vector(1, &key, &key_len, tk))</span><br><span style="color: hsl(120, 100%, 40%);">+                       return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            key = tk;</span><br><span style="color: hsl(120, 100%, 40%);">+             key_len = 20;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* the HMAC_SHA1 transform looks like:</span><br><span style="color: hsl(120, 100%, 40%);">+         *</span><br><span style="color: hsl(120, 100%, 40%);">+     * SHA1(K XOR opad, SHA1(K XOR ipad, text))</span><br><span style="color: hsl(120, 100%, 40%);">+    *</span><br><span style="color: hsl(120, 100%, 40%);">+     * where K is an n byte key</span><br><span style="color: hsl(120, 100%, 40%);">+    * ipad is the byte 0x36 repeated 64 times</span><br><span style="color: hsl(120, 100%, 40%);">+     * opad is the byte 0x5c repeated 64 times</span><br><span style="color: hsl(120, 100%, 40%);">+     * and text is the data being protected */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* start out by storing key in ipad */</span><br><span style="color: hsl(120, 100%, 40%);">+        os_memset(k_pad, 0, sizeof(k_pad));</span><br><span style="color: hsl(120, 100%, 40%);">+   os_memcpy(k_pad, key, key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* XOR key with ipad values */</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 64; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+           k_pad[i] ^= 0x36;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* perform inner SHA1 */</span><br><span style="color: hsl(120, 100%, 40%);">+      _addr[0] = k_pad;</span><br><span style="color: hsl(120, 100%, 40%);">+     _len[0] = 64;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < num_elem; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+           _addr[i + 1] = addr[i];</span><br><span style="color: hsl(120, 100%, 40%);">+               _len[i + 1] = len[i];</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (sha1_vector(1 + num_elem, _addr, _len, mac))</span><br><span style="color: hsl(120, 100%, 40%);">+              return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  os_memset(k_pad, 0, sizeof(k_pad));</span><br><span style="color: hsl(120, 100%, 40%);">+   os_memcpy(k_pad, key, key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* XOR key with opad values */</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 64; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+           k_pad[i] ^= 0x5c;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* perform outer SHA1 */</span><br><span style="color: hsl(120, 100%, 40%);">+      _addr[0] = k_pad;</span><br><span style="color: hsl(120, 100%, 40%);">+     _len[0] = 64;</span><br><span style="color: hsl(120, 100%, 40%);">+ _addr[1] = mac;</span><br><span style="color: hsl(120, 100%, 40%);">+       _len[1] = SHA1_MAC_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+       return sha1_vector(2, _addr, _len, mac);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * hmac_sha1 - HMAC-SHA1 over data buffer (RFC 2104)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key for HMAC operations</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of the key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data: Pointers to the data area</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data_len: Length of the data area</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash (20 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 of failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,</span><br><span style="color: hsl(120, 100%, 40%);">+              u8 *mac)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * sha1_prf - SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key for PRF</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of the key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @label: A unique label for each purpose of the PRF</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data: Extra data to bind into the key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data_len: Length of the data</span><br><span style="color: hsl(120, 100%, 40%);">+ * @buf: Buffer for the generated pseudo-random key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @buf_len: Number of bytes of key to generate</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 of failure</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is used to derive new, cryptographically separate keys from a</span><br><span style="color: hsl(120, 100%, 40%);">+ * given key (e.g., PMK in IEEE 802.11i).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int sha1_prf(const u8 *key, size_t key_len, const char *label,</span><br><span style="color: hsl(120, 100%, 40%);">+          const u8 *data, size_t data_len, u8 *buf, size_t buf_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     u8 counter = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t pos, plen;</span><br><span style="color: hsl(120, 100%, 40%);">+     u8 hash[SHA1_MAC_LEN];</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t label_len = os_strlen(label) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      const unsigned char *addr[3];</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t len[3];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      addr[0] = (u8 *) label;</span><br><span style="color: hsl(120, 100%, 40%);">+       len[0] = label_len;</span><br><span style="color: hsl(120, 100%, 40%);">+   addr[1] = data;</span><br><span style="color: hsl(120, 100%, 40%);">+       len[1] = data_len;</span><br><span style="color: hsl(120, 100%, 40%);">+    addr[2] = &counter;</span><br><span style="color: hsl(120, 100%, 40%);">+       len[2] = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pos = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      while (pos < buf_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+            plen = buf_len - pos;</span><br><span style="color: hsl(120, 100%, 40%);">+         if (plen >= SHA1_MAC_LEN) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (hmac_sha1_vector(key, key_len, 3, addr, len,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           &buf[pos]))</span><br><span style="color: hsl(120, 100%, 40%);">+                          return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                    pos += SHA1_MAC_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+          } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (hmac_sha1_vector(key, key_len, 3, addr, len,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           hash))</span><br><span style="color: hsl(120, 100%, 40%);">+                           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                    os_memcpy(&buf[pos], hash, plen);</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             counter++;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/gsm/kdf/sha1.h b/src/gsm/kdf/sha1.h</span><br><span>new file mode 100644</span><br><span>index 0000000..f0c1a5f</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha1.h</span><br><span>@@ -0,0 +1,33 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA1 hash implementation and interface functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef SHA1_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA1_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA1_MAC_LEN 20</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const u8 *addr[], const size_t *len, u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,</span><br><span style="color: hsl(120, 100%, 40%);">+           u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+int sha1_prf(const u8 *key, size_t key_len, const char *label,</span><br><span style="color: hsl(120, 100%, 40%);">+           const u8 *data, size_t data_len, u8 *buf, size_t buf_len);</span><br><span style="color: hsl(120, 100%, 40%);">+int sha1_t_prf(const u8 *key, size_t key_len, const char *label,</span><br><span style="color: hsl(120, 100%, 40%);">+            const u8 *seed, size_t seed_len, u8 *buf, size_t buf_len);</span><br><span style="color: hsl(120, 100%, 40%);">+int __must_check tls_prf_sha1_md5(const u8 *secret, size_t secret_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                               const char *label, const u8 *seed,</span><br><span style="color: hsl(120, 100%, 40%);">+                            size_t seed_len, u8 *out, size_t outlen);</span><br><span style="color: hsl(120, 100%, 40%);">+int pbkdf2_sha1(const char *passphrase, const char *ssid, size_t ssid_len,</span><br><span style="color: hsl(120, 100%, 40%);">+               int iterations, u8 *buf, size_t buflen);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* SHA1_H */</span><br><span>diff --git a/src/gsm/kdf/sha1_i.h b/src/gsm/kdf/sha1_i.h</span><br><span>new file mode 100644</span><br><span>index 0000000..ec2f82f</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha1_i.h</span><br><span>@@ -0,0 +1,29 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA1 internal definitions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef SHA1_I_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA1_I_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct SHA1Context {</span><br><span style="color: hsl(120, 100%, 40%);">+       u32 state[5];</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 count[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned char buffer[64];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Init(struct SHA1Context *context);</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Update(struct SHA1Context *context, const void *data, u32 len);</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Final(unsigned char digest[20], struct SHA1Context *context);</span><br><span style="color: hsl(120, 100%, 40%);">+void SHA1Transform(u32 state[5], const unsigned char buffer[64]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* SHA1_I_H */</span><br><span>diff --git a/src/gsm/kdf/sha256-internal.c b/src/gsm/kdf/sha256-internal.c</span><br><span>new file mode 100644</span><br><span>index 0000000..18cc8f8</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha256-internal.c</span><br><span>@@ -0,0 +1,231 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA-256 hash implementation and interface functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "common.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "sha256.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "sha256_i.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "crypto.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * sha256_vector - SHA256 hash for data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns: 0 on success, -1 of failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,</span><br><span style="color: hsl(120, 100%, 40%);">+            u8 *mac)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sha256_state ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   sha256_init(&ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < num_elem; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+             if (sha256_process(&ctx, addr[i], len[i]))</span><br><span style="color: hsl(120, 100%, 40%);">+                        return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (sha256_done(&ctx, mac))</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* ===== start - public domain SHA256 implementation ===== */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* This is based on SHA256 implementation in LibTomCrypt that was released into</span><br><span style="color: hsl(120, 100%, 40%);">+ * public domain by Tom St Denis. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* the K array */</span><br><span style="color: hsl(120, 100%, 40%);">+static const unsigned long K[64] = {</span><br><span style="color: hsl(120, 100%, 40%);">+   0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Various logical functions */</span><br><span style="color: hsl(120, 100%, 40%);">+#define RORc(x, y) \</span><br><span style="color: hsl(120, 100%, 40%);">+( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \</span><br><span style="color: hsl(120, 100%, 40%);">+   ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)</span><br><span style="color: hsl(120, 100%, 40%);">+#define Ch(x,y,z)       (z ^ (x & (y ^ z)))</span><br><span style="color: hsl(120, 100%, 40%);">+#define Maj(x,y,z)      (((x | y) & z) | (x & y)) </span><br><span style="color: hsl(120, 100%, 40%);">+#define S(x, n)         RORc((x), (n))</span><br><span style="color: hsl(120, 100%, 40%);">+#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(n))</span><br><span style="color: hsl(120, 100%, 40%);">+#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))</span><br><span style="color: hsl(120, 100%, 40%);">+#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))</span><br><span style="color: hsl(120, 100%, 40%);">+#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))</span><br><span style="color: hsl(120, 100%, 40%);">+#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef MIN</span><br><span style="color: hsl(120, 100%, 40%);">+#define MIN(x, y) (((x) < (y)) ? (x) : (y))</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* compress 512-bits */</span><br><span style="color: hsl(120, 100%, 40%);">+static int sha256_compress(struct sha256_state *md, unsigned char *buf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 S[8], W[64], t0, t1;</span><br><span style="color: hsl(120, 100%, 40%);">+      u32 t;</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* copy state into S */</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          S[i] = md->state[i];</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* copy the state into 512-bits into W[0..15] */</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < 16; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+           W[i] = WPA_GET_BE32(buf + (4 * i));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* fill W[16..63] */</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 16; i < 64; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +</span><br><span style="color: hsl(120, 100%, 40%);">+                      W[i - 16];</span><br><span style="color: hsl(120, 100%, 40%);">+    }        </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Compress */</span><br><span style="color: hsl(120, 100%, 40%);">+#define RND(a,b,c,d,e,f,g,h,i)                          \</span><br><span style="color: hsl(120, 100%, 40%);">+     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \</span><br><span style="color: hsl(120, 100%, 40%);">+     t1 = Sigma0(a) + Maj(a, b, c);                  \</span><br><span style="color: hsl(120, 100%, 40%);">+     d += t0;                                        \</span><br><span style="color: hsl(120, 100%, 40%);">+     h  = t0 + t1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < 64; ++i) {</span><br><span style="color: hsl(120, 100%, 40%);">+         RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);</span><br><span style="color: hsl(120, 100%, 40%);">+               t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; </span><br><span style="color: hsl(120, 100%, 40%);">+             S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* feedback */</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          md->state[i] = md->state[i] + S[i];</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Initialize the hash state */</span><br><span style="color: hsl(120, 100%, 40%);">+void sha256_init(struct sha256_state *md)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       md->curlen = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    md->length = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    md->state[0] = 0x6A09E667UL;</span><br><span style="color: hsl(120, 100%, 40%);">+       md->state[1] = 0xBB67AE85UL;</span><br><span style="color: hsl(120, 100%, 40%);">+       md->state[2] = 0x3C6EF372UL;</span><br><span style="color: hsl(120, 100%, 40%);">+       md->state[3] = 0xA54FF53AUL;</span><br><span style="color: hsl(120, 100%, 40%);">+       md->state[4] = 0x510E527FUL;</span><br><span style="color: hsl(120, 100%, 40%);">+       md->state[5] = 0x9B05688CUL;</span><br><span style="color: hsl(120, 100%, 40%);">+       md->state[6] = 0x1F83D9ABUL;</span><br><span style="color: hsl(120, 100%, 40%);">+       md->state[7] = 0x5BE0CD19UL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+   Process a block of memory though the hash</span><br><span style="color: hsl(120, 100%, 40%);">+   @param md     The hash state</span><br><span style="color: hsl(120, 100%, 40%);">+   @param in     The data to hash</span><br><span style="color: hsl(120, 100%, 40%);">+   @param inlen  The length of the data (octets)</span><br><span style="color: hsl(120, 100%, 40%);">+   @return CRYPT_OK if successful</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+int sha256_process(struct sha256_state *md, const unsigned char *in,</span><br><span style="color: hsl(120, 100%, 40%);">+               unsigned long inlen)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned long n;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (md->curlen >= sizeof(md->buf))</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  while (inlen > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (sha256_compress(md, (unsigned char *) in) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                    md->length += SHA256_BLOCK_SIZE * 8;</span><br><span style="color: hsl(120, 100%, 40%);">+                       in += SHA256_BLOCK_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+                      inlen -= SHA256_BLOCK_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen));</span><br><span style="color: hsl(120, 100%, 40%);">+                  os_memcpy(md->buf + md->curlen, in, n);</span><br><span style="color: hsl(120, 100%, 40%);">+                 md->curlen += n;</span><br><span style="color: hsl(120, 100%, 40%);">+                   in += n;</span><br><span style="color: hsl(120, 100%, 40%);">+                      inlen -= n;</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (md->curlen == SHA256_BLOCK_SIZE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (sha256_compress(md, md->buf) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                                   return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                            md->length += 8 * SHA256_BLOCK_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+                               md->curlen = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+   Terminate the hash to get the digest</span><br><span style="color: hsl(120, 100%, 40%);">+   @param md  The hash state</span><br><span style="color: hsl(120, 100%, 40%);">+   @param out [out] The destination of the hash (32 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+   @return CRYPT_OK if successful</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+int sha256_done(struct sha256_state *md, unsigned char *out)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (md->curlen >= sizeof(md->buf))</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* increase the length of the message */</span><br><span style="color: hsl(120, 100%, 40%);">+      md->length += md->curlen * 8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* append the '1' bit */</span><br><span style="color: hsl(120, 100%, 40%);">+      md->buf[md->curlen++] = (unsigned char) 0x80;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* if the length is currently above 56 bytes we append zeros</span><br><span style="color: hsl(120, 100%, 40%);">+   * then compress.  Then we can fall back to padding zeros and length</span><br><span style="color: hsl(120, 100%, 40%);">+   * encoding like normal.</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (md->curlen > 56) {</span><br><span style="color: hsl(120, 100%, 40%);">+          while (md->curlen < SHA256_BLOCK_SIZE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        md->buf[md->curlen++] = (unsigned char) 0;</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             sha256_compress(md, md->buf);</span><br><span style="color: hsl(120, 100%, 40%);">+              md->curlen = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* pad up to 56 bytes of zeroes */</span><br><span style="color: hsl(120, 100%, 40%);">+    while (md->curlen < 56) {</span><br><span style="color: hsl(120, 100%, 40%);">+               md->buf[md->curlen++] = (unsigned char) 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* store length */</span><br><span style="color: hsl(120, 100%, 40%);">+    WPA_PUT_BE64(md->buf + 56, md->length);</span><br><span style="color: hsl(120, 100%, 40%);">+ sha256_compress(md, md->buf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* copy output */</span><br><span style="color: hsl(120, 100%, 40%);">+     for (i = 0; i < 8; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+            WPA_PUT_BE32(out + (4 * i), md->state[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* ===== end - public domain SHA256 implementation ===== */</span><br><span>diff --git a/src/gsm/kdf/sha256.c b/src/gsm/kdf/sha256.c</span><br><span>new file mode 100644</span><br><span>index 0000000..4f8b6cc</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha256.c</span><br><span>@@ -0,0 +1,156 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA-256 hash implementation and interface functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "common.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "sha256.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "crypto.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key for HMAC operations</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of the key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @num_elem: Number of elements in the data vector</span><br><span style="color: hsl(120, 100%, 40%);">+ * @addr: Pointers to the data areas</span><br><span style="color: hsl(120, 100%, 40%);">+ * @len: Lengths of the data blocks</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash (32 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,</span><br><span style="color: hsl(120, 100%, 40%);">+                       const u8 *addr[], const size_t *len, u8 *mac)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned char tk[32];</span><br><span style="color: hsl(120, 100%, 40%);">+ const u8 *_addr[6];</span><br><span style="color: hsl(120, 100%, 40%);">+   size_t _len[6], i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (num_elem > 5) {</span><br><span style="color: hsl(120, 100%, 40%);">+                /*</span><br><span style="color: hsl(120, 100%, 40%);">+             * Fixed limit on the number of fragments to avoid having to</span><br><span style="color: hsl(120, 100%, 40%);">+           * allocate memory (which could fail).</span><br><span style="color: hsl(120, 100%, 40%);">+                 */</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* if key is longer than 64 bytes reset it to key = SHA256(key) */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (key_len > 64) {</span><br><span style="color: hsl(120, 100%, 40%);">+               sha256_vector(1, &key, &key_len, tk);</span><br><span style="color: hsl(120, 100%, 40%);">+         key = tk;</span><br><span style="color: hsl(120, 100%, 40%);">+             key_len = 32;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* the HMAC_SHA256 transform looks like:</span><br><span style="color: hsl(120, 100%, 40%);">+       *</span><br><span style="color: hsl(120, 100%, 40%);">+     * SHA256(K XOR opad, SHA256(K XOR ipad, text))</span><br><span style="color: hsl(120, 100%, 40%);">+        *</span><br><span style="color: hsl(120, 100%, 40%);">+     * where K is an n byte key</span><br><span style="color: hsl(120, 100%, 40%);">+    * ipad is the byte 0x36 repeated 64 times</span><br><span style="color: hsl(120, 100%, 40%);">+     * opad is the byte 0x5c repeated 64 times</span><br><span style="color: hsl(120, 100%, 40%);">+     * and text is the data being protected */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* start out by storing key in ipad */</span><br><span style="color: hsl(120, 100%, 40%);">+        os_memset(k_pad, 0, sizeof(k_pad));</span><br><span style="color: hsl(120, 100%, 40%);">+   os_memcpy(k_pad, key, key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* XOR key with ipad values */</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 64; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+           k_pad[i] ^= 0x36;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* perform inner SHA256 */</span><br><span style="color: hsl(120, 100%, 40%);">+    _addr[0] = k_pad;</span><br><span style="color: hsl(120, 100%, 40%);">+     _len[0] = 64;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < num_elem; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+           _addr[i + 1] = addr[i];</span><br><span style="color: hsl(120, 100%, 40%);">+               _len[i + 1] = len[i];</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     sha256_vector(1 + num_elem, _addr, _len, mac);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      os_memset(k_pad, 0, sizeof(k_pad));</span><br><span style="color: hsl(120, 100%, 40%);">+   os_memcpy(k_pad, key, key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+       /* XOR key with opad values */</span><br><span style="color: hsl(120, 100%, 40%);">+        for (i = 0; i < 64; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+           k_pad[i] ^= 0x5c;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* perform outer SHA256 */</span><br><span style="color: hsl(120, 100%, 40%);">+    _addr[0] = k_pad;</span><br><span style="color: hsl(120, 100%, 40%);">+     _len[0] = 64;</span><br><span style="color: hsl(120, 100%, 40%);">+ _addr[1] = mac;</span><br><span style="color: hsl(120, 100%, 40%);">+       _len[1] = SHA256_MAC_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+     sha256_vector(2, _addr, _len, mac);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key for HMAC operations</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of the key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data: Pointers to the data area</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data_len: Length of the data area</span><br><span style="color: hsl(120, 100%, 40%);">+ * @mac: Buffer for the hash (20 bytes)</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void hmac_sha256(const u8 *key, size_t key_len, const u8 *data,</span><br><span style="color: hsl(120, 100%, 40%);">+                size_t data_len, u8 *mac)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key: Key for PRF</span><br><span style="color: hsl(120, 100%, 40%);">+ * @key_len: Length of the key in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * @label: A unique label for each purpose of the PRF</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data: Extra data to bind into the key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @data_len: Length of the data</span><br><span style="color: hsl(120, 100%, 40%);">+ * @buf: Buffer for the generated pseudo-random key</span><br><span style="color: hsl(120, 100%, 40%);">+ * @buf_len: Number of bytes of key to generate</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function is used to derive new, cryptographically separate keys from a</span><br><span style="color: hsl(120, 100%, 40%);">+ * given key.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void sha256_prf(const u8 *key, size_t key_len, const char *label,</span><br><span style="color: hsl(120, 100%, 40%);">+            const u8 *data, size_t data_len, u8 *buf, size_t buf_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  u16 counter = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t pos, plen;</span><br><span style="color: hsl(120, 100%, 40%);">+     u8 hash[SHA256_MAC_LEN];</span><br><span style="color: hsl(120, 100%, 40%);">+      const u8 *addr[4];</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t len[4];</span><br><span style="color: hsl(120, 100%, 40%);">+        u8 counter_le[2], length_le[2];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     addr[0] = counter_le;</span><br><span style="color: hsl(120, 100%, 40%);">+ len[0] = 2;</span><br><span style="color: hsl(120, 100%, 40%);">+   addr[1] = (u8 *) label;</span><br><span style="color: hsl(120, 100%, 40%);">+       len[1] = os_strlen(label);</span><br><span style="color: hsl(120, 100%, 40%);">+    addr[2] = data;</span><br><span style="color: hsl(120, 100%, 40%);">+       len[2] = data_len;</span><br><span style="color: hsl(120, 100%, 40%);">+    addr[3] = length_le;</span><br><span style="color: hsl(120, 100%, 40%);">+  len[3] = sizeof(length_le);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ WPA_PUT_LE16(length_le, buf_len * 8);</span><br><span style="color: hsl(120, 100%, 40%);">+ pos = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      while (pos < buf_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+            plen = buf_len - pos;</span><br><span style="color: hsl(120, 100%, 40%);">+         WPA_PUT_LE16(counter_le, counter);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (plen >= SHA256_MAC_LEN) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      hmac_sha256_vector(key, key_len, 4, addr, len,</span><br><span style="color: hsl(120, 100%, 40%);">+                                           &buf[pos]);</span><br><span style="color: hsl(120, 100%, 40%);">+                    pos += SHA256_MAC_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+                } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      hmac_sha256_vector(key, key_len, 4, addr, len, hash);</span><br><span style="color: hsl(120, 100%, 40%);">+                 os_memcpy(&buf[pos], hash, plen);</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             counter++;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/gsm/kdf/sha256.h b/src/gsm/kdf/sha256.h</span><br><span>new file mode 100644</span><br><span>index 0000000..b1ce6af</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha256.h</span><br><span>@@ -0,0 +1,30 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA256 hash implementation and interface functions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef SHA256_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA256_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA256_MAC_LEN 32</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const u8 *addr[], const size_t *len, u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+void hmac_sha256(const u8 *key, size_t key_len, const u8 *data,</span><br><span style="color: hsl(120, 100%, 40%);">+          size_t data_len, u8 *mac);</span><br><span style="color: hsl(120, 100%, 40%);">+void sha256_prf(const u8 *key, size_t key_len, const char *label,</span><br><span style="color: hsl(120, 100%, 40%);">+              const u8 *data, size_t data_len, u8 *buf, size_t buf_len);</span><br><span style="color: hsl(120, 100%, 40%);">+void tls_prf_sha256(const u8 *secret, size_t secret_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                const char *label, const u8 *seed, size_t seed_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                   u8 *out, size_t outlen);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* SHA256_H */</span><br><span>diff --git a/src/gsm/kdf/sha256_i.h b/src/gsm/kdf/sha256_i.h</span><br><span>new file mode 100644</span><br><span>index 0000000..20ae488</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/kdf/sha256_i.h</span><br><span>@@ -0,0 +1,31 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * SHA-256 internal definitions</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License version 2 as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Alternatively, this software may be distributed under the terms of BSD</span><br><span style="color: hsl(120, 100%, 40%);">+ * license.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See README and COPYING for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef SHA256_I_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA256_I_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define SHA256_BLOCK_SIZE 64</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct sha256_state {</span><br><span style="color: hsl(120, 100%, 40%);">+ u64 length;</span><br><span style="color: hsl(120, 100%, 40%);">+   u32 state[8], curlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ u8 buf[SHA256_BLOCK_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void sha256_init(struct sha256_state *md);</span><br><span style="color: hsl(120, 100%, 40%);">+int sha256_process(struct sha256_state *md, const unsigned char *in,</span><br><span style="color: hsl(120, 100%, 40%);">+               unsigned long inlen);</span><br><span style="color: hsl(120, 100%, 40%);">+int sha256_done(struct sha256_state *md, unsigned char *out);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* SHA256_I_H */</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index 3fd01db..437599b 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -547,6 +547,12 @@</span><br><span> osmo_auth_c3;</span><br><span> osmo_sub_auth_type_names;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+osmo_kdf_kc128;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_kdf_kasme;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_kdf_enb;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_kdf_nh;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_kdf_nas;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> osmo_rsl2sitype;</span><br><span> osmo_sitype2rsl;</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/24291">change 24291</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/24291"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ibf2e49edada944d91ceba62bd0d6b6ce69261fcd </div>
<div style="display:none"> Gerrit-Change-Number: 24291 </div>
<div style="display:none"> Gerrit-PatchSet: 8 </div>
<div style="display:none"> Gerrit-Owner: Hoernchen <ewild@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>