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);
39 * length is length of key in bits!
42 void a5_1_init(a5_1_ctx_t *c, void* key, uint8_t keylength_b, void* iv, uint8_t ivlength_b){
47 for(i=0; i<keylength_b; ++i){
48 t=((uint8_t*)key)[i/8];
53 a5_1_clock_core(c, 0x7);
55 for(i=0; i<ivlength_b; ++i){
56 t=((uint8_t*)iv)[i/8];
61 a5_1_clock_core(c, 0x7);
68 void shiftreg(uint8_t* d){
74 d[2] = (d[2]<<1) | c2;
77 const uint8_t parity3_lut[] PROGMEM = {0, 1, 1, 0,
79 const uint8_t clock_lut[] PROGMEM = {0x7, 0x6, 0x5, 0x3,
82 uint8_t a5_1_clock_core(a5_1_ctx_t *c, uint8_t clockoverride){
84 ret = (0x04&c->r1[2]) | (0x20&c->r2[2]) | (0x40&c->r3[2]);
87 ret = pgm_read_byte(parity3_lut+ret);
88 clk = (0x08&c->r1[1]) | (0x10&c->r2[1]) | (0x20&c->r3[1]);
90 clk = pgm_read_byte(clock_lut+clk);
94 fb = c->r1[2] ^ (1&((c->r1[1])>>5));
96 fb = pgm_read_byte(parity3_lut+fb);
105 fb = pgm_read_byte(parity3_lut+fb);
113 fb = (c->r3[2]>>4) ^ (1&((c->r3[0])>>7));
115 fb = pgm_read_byte(parity3_lut+fb);
123 uint8_t a5_1_clock(a5_1_ctx_t *c){
124 return a5_1_clock_core(c, 0);
128 uint8_t a5_1_gen(a5_1_ctx_t *c){