blob: 2ebe41a9eb5cad362b14da03dfa8a2b235040805 [file] [log] [blame]
Ericc3fa0072021-05-19 17:45:38 +02001/*
2 * (C) 2021 by sysmocom s.f.m.c. GmbH
3 *
4 * Author: Eric Wild <ewild@sysmocom.de>
5 *
6 * All Rights Reserved
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 *
24 */
25
26#include <stdint.h>
27#include <string.h>
28
29#include "../../config.h"
30#if (USE_GNUTLS)
31#include <gnutls/gnutls.h>
32#include <gnutls/crypto.h>
33#define HMAC_FUNC(k,lk,s,sl,out) gnutls_hmac_fast(GNUTLS_MAC_SHA256,k,lk,s,sl,out)
34#else
35#include <osmocom/crypt/kdf.h>
36#define HMAC_FUNC(k,lk,s,sl,out) hmac_sha256(k,lk,s,sl,out)
37#endif
38
39#include <osmocom/core/bit32gen.h>
40#include <osmocom/crypt/kdf.h>
41
42#include "kdf/common.h"
43#include "kdf/sha256.h"
44
45
46#if (USE_GNUTLS)
47/* gnutls < 3.3.0 requires global init.
48 * gnutls >= 3.3.0 does it automatic.
49 * It doesn't hurt calling it twice,
50 * as long it's not done at the same time (threads).
51 */
52__attribute__((constructor))
53static void on_dso_load_gnutls(void)
54{
55 if (!gnutls_check_version("3.3.0"))
56 gnutls_global_init();
57}
58
59__attribute__((destructor))
60static void on_dso_unload_gnutls(void)
61{
62 if (!gnutls_check_version("3.3.0"))
63 gnutls_global_deinit();
64}
65#endif
66
67/*
68 * This file uses the generic key derivation function defined in 3GPP TS 33.220 Annex B
69 *
70 * The S parameter always consists of concatenated values FC | P0 | L0 | Pi | Li | ...
71 * with Pi = Parameter number i and Li = Length of Pi (two octets)
72 *
73 * FC is either a single octet or two octets 0xff | FC
74 * FC values ranges depend on the specification parts that use the KDF,
75 * they are defined in 3GPP TS 33.220 Annex B.2.2
76 *
77 */
78
79/*! \addtogroup kdf
80 * @{
81 * key derivation functions
82 *
83 * \file kdf.c */
84
85/* 3GPP TS 33.102 B.5 */
86void osmo_kdf_kc128(const uint8_t* ck, const uint8_t* ik, uint8_t* kc128) {
87 uint8_t k[16*2];
88 uint8_t s[1];
89 uint8_t out_tmp256[32];
90 memcpy (&k[0], ck, 16);
91 memcpy (&k[16], ik, 16);
92
93 s[0] = 0x32; // yeah, really just one FC byte..
94
95 HMAC_FUNC(k, 32, s, 1, out_tmp256);
96 memcpy(kc128, out_tmp256, 16);
97}
98
99/* 3GPP TS 33.401 A.2 */
100void osmo_kdf_kasme(const uint8_t *ck, const uint8_t *ik, const uint8_t* plmn_id,
101 const uint8_t *sqn, const uint8_t *ak, uint8_t *kasme)
102{
103 uint8_t s[14];
104 uint8_t k[16*2];
105 int i;
106
107 memcpy(&k[0], ck, 16);
108 memcpy(&k[16], ik, 16);
109
110 s[0] = 0x10;
111 memcpy(&s[1], plmn_id, 3);
112 s[4] = 0x00;
113 s[5] = 0x03;
114
115 for (i = 0; i < 6; i++)
116 s[6+i] = sqn[i] ^ ak[i];
117 s[12] = 0x00;
118 s[13] = 0x06;
119
120 HMAC_FUNC(k, 32, s, 14, kasme);
121}
122
123/* 3GPP TS 33.401 A.3 */
124void osmo_kdf_enb(const uint8_t *kasme, uint32_t ul_count, uint8_t *kenb)
125{
126 uint8_t s[7];
127
128 s[0] = 0x11;
129 osmo_store32be(ul_count, &s[1]);
130 s[5] = 0x00;
131 s[6] = 0x04;
132
133 HMAC_FUNC(kasme, 32, s, 7, kenb);
134}
135
136/* 3GPP TS 33.401 A.4 */
137void osmo_kdf_nh(const uint8_t *kasme, const uint8_t *sync_input, uint8_t *nh)
138{
139 uint8_t s[35];
140
141 s[0] = 0x12;
142 memcpy(s+1, sync_input, 32);
143 s[33] = 0x00;
144 s[34] = 0x20;
145
146 HMAC_FUNC(kasme, 32, s, 35, nh);
147}
148
149/* 3GPP TS 33.401 A.7 */
150void osmo_kdf_nas(uint8_t algo_type, uint8_t algo_id, const uint8_t *kasme, uint8_t *knas)
151{
152 uint8_t s[7];
153 uint8_t out[32];
154
155 s[0] = 0x15;
156 s[1] = algo_type;
157 s[2] = 0x00;
158 s[3] = 0x01;
159 s[4] = algo_id;
160 s[5] = 0x00;
161 s[6] = 0x01;
162
163 HMAC_FUNC(kasme, 32, s, 7, out);
164 memcpy(knas, out+16, 16);
165}
166
167/*! @} */