Merge pull request #2616 from jmichelp/fix14b
[RRG-proxmark3.git] / armsrc / optimized_cipherutils.c
blob4260ea12dde0f1e197d7617e5901ac3052c836a6
1 //-----------------------------------------------------------------------------
2 // Borrowed initially from https://github.com/holiman/loclass
3 // Copyright (C) 2014 Martin Holst Swende
4 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
5 //
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 // See LICENSE.txt for the text of the license.
17 //-----------------------------------------------------------------------------
18 // WARNING
20 // THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY.
22 // USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL
23 // PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL,
24 // AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES.
26 // THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS.
27 //-----------------------------------------------------------------------------
28 // It is a reconstruction of the cipher engine used in iClass, and RFID techology.
30 // The implementation is based on the work performed by
31 // Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and
32 // Milosch Meriac in the paper "Dismantling IClass".
33 //-----------------------------------------------------------------------------
34 #include "optimized_cipherutils.h"
35 #include <stdint.h>
37 /**
39 * @brief Return and remove the first bit (x0) in the stream : <x0 x1 x2 x3 ... xn >
40 * @param stream
41 * @return
43 bool headBit(BitstreamIn_t *stream) {
44 int bytepos = stream->position >> 3; // divide by 8
45 int bitpos = (stream->position++) & 7; // mask out 00000111
46 return (*(stream->buffer + bytepos) >> (7 - bitpos)) & 1;
48 /**
49 * @brief Return and remove the last bit (xn) in the stream: <x0 x1 x2 ... xn>
50 * @param stream
51 * @return
53 bool tailBit(BitstreamIn_t *stream) {
54 int bitpos = stream->numbits - 1 - (stream->position++);
56 int bytepos = bitpos >> 3;
57 bitpos &= 7;
58 return (*(stream->buffer + bytepos) >> (7 - bitpos)) & 1;
60 /**
61 * @brief Pushes bit onto the stream
62 * @param stream
63 * @param bit
65 void pushBit(BitstreamOut_t *stream, bool bit) {
66 int bytepos = stream->position >> 3; // divide by 8
67 int bitpos = stream->position & 7;
68 *(stream->buffer + bytepos) |= (bit) << (7 - bitpos);
69 stream->position++;
70 stream->numbits++;
73 /**
74 * @brief Pushes the lower six bits onto the stream
75 * as b0 b1 b2 b3 b4 b5 b6
76 * @param stream
77 * @param bits
79 void push6bits(BitstreamOut_t *stream, uint8_t bits) {
80 pushBit(stream, bits & 0x20);
81 pushBit(stream, bits & 0x10);
82 pushBit(stream, bits & 0x08);
83 pushBit(stream, bits & 0x04);
84 pushBit(stream, bits & 0x02);
85 pushBit(stream, bits & 0x01);
88 /**
89 * @brief bitsLeft
90 * @param stream
91 * @return number of bits left in stream
93 int bitsLeft(BitstreamIn_t *stream) {
94 return stream->numbits - stream->position;
96 /**
97 * @brief numBits
98 * @param stream
99 * @return Number of bits stored in stream
101 void x_num_to_bytes(uint64_t n, size_t len, uint8_t *dest) {
102 while (len--) {
103 dest[len] = (uint8_t) n;
104 n >>= 8;
108 uint64_t x_bytes_to_num(uint8_t *src, size_t len) {
109 uint64_t num = 0;
110 while (len--) {
111 num = (num << 8) | (*src);
112 src++;
114 return num;