3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * email: daniel.otte@rub.de
24 * License: GPLv3 or later
25 * Description: Implementation of the A5/1 stream cipher algorithm, as used in GSM.
26 * ! Warning, this is weak crypto !
33 #include <avr/pgmspace.h>
35 uint8_t a5_1_clock_core(a5_1_ctx_t *c, uint8_t clockoverride);
38 * length is length of key in bits!
41 void a5_1_init(a5_1_ctx_t *c, void *key, uint8_t keylength_b, void *iv,
48 for (i = 0; i < keylength_b; ++i) {
49 t = ((uint8_t*) key)[i / 8];
54 a5_1_clock_core(c, 0x7);
56 for (i = 0; i < ivlength_b; ++i) {
57 t = ((uint8_t*) iv)[i / 8];
62 a5_1_clock_core(c, 0x7);
64 for (i = 0; i < 100; ++i)
65 a5_1_clock_core(c, 0);
69 void shiftreg(uint8_t *d)
75 d[1] = (d[1] << 1) | c;
76 d[2] = (d[2] << 1) | c2;
79 const uint8_t parity3_lut[] PROGMEM = { 0, 1, 1, 0,
81 const uint8_t clock_lut[] PROGMEM = { 0x7, 0x6, 0x5, 0x3,
84 uint8_t a5_1_clock_core(a5_1_ctx_t *c, uint8_t clockoverride)
87 ret = (0x04 & c->r1[2]) | (0x20 & c->r2[2]) | (0x40 & c->r3[2]);
88 ret = ret ^ (ret >> 6);
90 ret = pgm_read_byte(parity3_lut + ret);
91 clk = (0x08 & c->r1[1]) | (0x10 & c->r2[1]) | (0x20 & c->r3[1]);
93 clk = pgm_read_byte(clock_lut + clk);
97 fb = c->r1[2] ^ (1 & ((c->r1[1]) >> 5));
99 fb = pgm_read_byte(parity3_lut + fb);
108 fb = pgm_read_byte(parity3_lut + fb);
116 fb = (c->r3[2] >> 4) ^ (1 & ((c->r3[0]) >> 7));
118 fb = pgm_read_byte(parity3_lut + fb);
126 uint8_t a5_1_clock(a5_1_ctx_t *c)
128 return a5_1_clock_core(c, 0);
131 uint8_t a5_1_gen(a5_1_ctx_t *c)