Contiki-NG
Loading...
Searching...
No Matches
iq-seeder.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Hasso-Plattner-Institut.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 */
32
33/**
34 * \addtogroup csprng
35 * @{
36 *
37 * \file
38 * I/Q data-based seeder.
39 * \author
40 * Konrad Krentz <konrad.krentz@gmail.com>
41 */
42
43#include "lib/iq-seeder.h"
44#include "net/netstack.h"
45#include "lib/aes-128.h"
46#include <string.h>
47
48#define COLUMN_COUNT 50
49#define ROW_COUNT 16
50
51static const uint8_t toeplitz[COLUMN_COUNT + ROW_COUNT - 1] = {
52 93, 50, 210, 134, 79, 52, 237, 192, 40, 201,
53 3, 184, 152, 74, 27, 28, 32, 111, 79, 222,
54 174, 51, 223, 66, 152, 211, 234, 124, 92, 64,
55 206, 169, 227, 155, 106, 87, 207, 135, 238, 101,
56 254, 163, 55, 76, 50, 40, 4, 149, 27, 1,
57 127, 159, 160, 91, 251, 179, 186, 200, 225, 47,
58 235, 223, 39, 117, 19
59};
60
61/*---------------------------------------------------------------------------*/
62static uint8_t
63get_toeplitz_element(uint8_t row, uint8_t column)
64{
65 uint8_t min;
66
67 min = row < column ? row : column;
68 row -= min;
69 column -= min;
70
71 return toeplitz[row ? COLUMN_COUNT - 1 + row : column];
72}
73/*---------------------------------------------------------------------------*/
74/** Performs a multiplication within GF(256) */
75static uint8_t
76mul_gf_256(uint8_t a, uint8_t b)
77{
78 uint8_t p;
79 uint8_t i;
80
81 p = 0;
82 for(i = 0; i < 8; i++) {
83 if(b & 1) {
84 p ^= a;
85 a <<= 1;
86 if(a & 0x100) {
87 a ^= 0x11b;
88 }
89 b >>= 1;
90 }
91 }
92 return p;
93}
94/*---------------------------------------------------------------------------*/
95/**
96 * Toeplitz matrix-based extractor. For theory, see [Skorski, True Random Num-
97 * ber Generators Secure in a Changing Environment: Improved Security Bounds]
98 */
99static void
100extract(uint8_t *target, uint8_t *source)
101{
102 uint8_t row;
103 uint8_t column;
104
105 for(row = 0; row < ROW_COUNT; row++) {
106 target[row] = 0;
107 for(column = 0; column < COLUMN_COUNT; column++) {
108 target[row] ^= mul_gf_256(get_toeplitz_element(row, column), source[column]);
109 }
110 }
111}
112/*---------------------------------------------------------------------------*/
113static bool
114seed_16_bytes(uint8_t *result)
115{
116 uint8_t bit_pos;
117 uint8_t byte_pos;
118 uint16_t iq_count;
119 uint8_t accumulator[COLUMN_COUNT];
120 radio_value_t iq;
121
122 bit_pos = 0;
123 byte_pos = 0;
124 memset(accumulator, 0, COLUMN_COUNT);
125
126 if(!NETSTACK_RADIO.on()) {
127 return false;
128 }
129 for(iq_count = 0; iq_count < (COLUMN_COUNT * 8 / 2); iq_count++) {
130 if(NETSTACK_RADIO.get_value(RADIO_PARAM_IQ_LSBS, &iq) != RADIO_RESULT_OK) {
131 NETSTACK_RADIO.off();
132 return false;
133 }
134
135 /* append I/Q LSBs to accumulator */
136 accumulator[byte_pos] |= iq << bit_pos;
137 bit_pos += 2;
138 if(bit_pos == 8) {
139 bit_pos = 0;
140 byte_pos++;
141 }
142 }
143 NETSTACK_RADIO.off();
144 extract(result, accumulator);
145 return true;
146}
147/*---------------------------------------------------------------------------*/
148bool
150{
151 struct csprng_seed seed;
152
153 if(!seed_16_bytes(seed.key) || !seed_16_bytes(seed.state)) {
154 return false;
155 }
156 csprng_feed(&seed);
157 return true;
158}
159/*---------------------------------------------------------------------------*/
160
161/** @} */
AES-128.
static uint8_t mul_gf_256(uint8_t a, uint8_t b)
Performs a multiplication within GF(256)
Definition iq-seeder.c:76
void csprng_feed(struct csprng_seed *new_seed)
Mixes a new seed with the current one.
Definition csprng.c:58
static void extract(uint8_t *target, uint8_t *source)
Toeplitz matrix-based extractor.
Definition iq-seeder.c:100
bool iq_seeder_seed(void)
This function will feed the CSPRNG with a new seed.
Definition iq-seeder.c:149
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio.
Definition radio.h:88
@ RADIO_RESULT_OK
The parameter was set/read successfully.
Definition radio.h:480
@ RADIO_PARAM_IQ_LSBS
The current I/Q LSBs.
Definition radio.h:234
I/Q data-based seeder.
Include file for the Contiki low-layer network stack (NETSTACK)
This is the structure of a seed.
Definition csprng.h:72
uint8_t state[AES_128_BLOCK_SIZE]
internal state of the CSPRNG
Definition csprng.h:76
uint8_t key[AES_128_KEY_LENGTH]
AES-128 key of the CSPRNG.
Definition csprng.h:75