]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bcal-cfb_bit.c
f8687cafc79a022e9bf24e3f0db26b107282af86
[avr-crypto-lib.git] / bcal-cfb_bit.c
1 /* bcal-cfb_bit.c */
2 /*
3  This file is part of the AVR-Crypto-Lib.
4  Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
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.
10
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.
15
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/>.
18  */
19
20 #include <stdint.h>
21 #include <string.h>
22 #include "bcal-cfb_bit.h"
23 #include "bcal-basic.h"
24
25 static uint8_t read_bit(void *block, uint32_t index)
26 {
27     uint8_t r;
28     r = ((uint8_t*) block)[index / 8];
29     r = (r & (0x80 >> (index & 7))) ? 0xff : 0x00;
30     return r;
31 }
32
33 static void write_bit(void *block, uint32_t index, uint8_t value)
34 {
35     if (value) {
36         /* set bit */
37         ((uint8_t*) block)[index / 8] |= 0x80 >> (index & 7);
38     } else {
39         /* clear bit */
40         ((uint8_t*) block)[index / 8] &= ~(0x80 >> (index & 7));
41     }
42 }
43
44 uint8_t bcal_cfb_b_init(const bcdesc_t *desc, const void *key,
45         uint16_t keysize_b, uint16_t size_b, bcal_cfb_b_ctx_t *ctx)
46 {
47     ctx->desc = (bcdesc_t*) desc;
48     ctx->blocksize_B = (bcal_cipher_getBlocksize_b(desc) + 7) / 8;
49     ctx->in_block = malloc(ctx->blocksize_B);
50     if (ctx->in_block == NULL) {
51         return 0x11;
52     }
53     if (size_b > bcal_cipher_getBlocksize_b(desc)) {
54         return 0x12;
55     }
56     ctx->size_b = size_b;
57     return bcal_cipher_init(desc, key, keysize_b, &(ctx->cctx));
58 }
59
60 void bcal_cfb_b_free(bcal_cfb_b_ctx_t *ctx)
61 {
62     free(ctx->in_block);
63     bcal_cipher_free(&(ctx->cctx));
64 }
65
66 void bcal_cfb_b_loadIV(const void *iv, bcal_cfb_b_ctx_t *ctx)
67 {
68     if (iv) {
69         memcpy(ctx->in_block, iv, ctx->blocksize_B);
70     }
71 }
72
73 void bcal_cfb_b_encNext(void *block, uint8_t offset, bcal_cfb_b_ctx_t *ctx)
74 {
75     uint8_t tmp[ctx->blocksize_B];
76     offset &= 7;
77     memcpy(tmp, ctx->in_block, ctx->blocksize_B);
78     bcal_cipher_enc(tmp, &(ctx->cctx));
79     uint16_t i, j;
80     uint8_t a;
81     for (i = 0; i < ctx->blocksize_B * 8 - ctx->size_b; ++i) {
82         a = read_bit(ctx->in_block, i + ctx->size_b);
83         write_bit(ctx->in_block, i, a);
84     }
85     for (j = offset, i = 0; i < ctx->size_b; ++i, ++j) {
86         a = read_bit(tmp, i) ^ read_bit(block, j);
87         write_bit(ctx->in_block, ctx->blocksize_B * 8 - ctx->size_b + i, a);
88         write_bit(block, j, a);
89     }
90 }
91
92 void bcal_cfb_b_decNext(void *block, uint8_t offset, bcal_cfb_b_ctx_t *ctx)
93 {
94     uint8_t tmp[ctx->blocksize_B];
95     offset &= 7;
96     memcpy(tmp, ctx->in_block, ctx->blocksize_B);
97     bcal_cipher_enc(tmp, &(ctx->cctx));
98     uint16_t i, j;
99     uint8_t a, b;
100     for (i = 0; i < ctx->blocksize_B * 8 - ctx->size_b; ++i) {
101         a = read_bit(ctx->in_block, i + ctx->size_b);
102         write_bit(ctx->in_block, i, a);
103     }
104     for (j = offset, i = 0; i < ctx->size_b; ++i, ++j) {
105         a = read_bit(tmp, i);
106         b = read_bit(block, j);
107         a ^= b;
108         write_bit(ctx->in_block, ctx->blocksize_B * 8 - ctx->size_b + i, b);
109         write_bit(block, j, a);
110     }
111 }
112
113 void bcal_cfb_b_encMsg(const void *iv, void *msg, uint8_t offset,
114         uint32_t msg_blocks, bcal_cfb_b_ctx_t *ctx)
115 {
116     bcal_cfb_b_loadIV(iv, ctx);
117     uint32_t addr;
118     addr = ((uint16_t) msg) * 8 + offset;
119     while (msg_blocks--) {
120         msg = (void*) ((uint16_t) (addr / 8));
121         offset = addr & 7;
122         bcal_cfb_b_encNext(msg, offset, ctx);
123         addr += ctx->size_b;
124     }
125 }
126
127 void bcal_cfb_b_decMsg(const void *iv, void *msg, uint8_t offset,
128         uint32_t msg_blocks, bcal_cfb_b_ctx_t *ctx)
129 {
130     bcal_cfb_b_loadIV(iv, ctx);
131     uint32_t addr;
132     addr = ((uint16_t) msg) * 8 + offset;
133     while (msg_blocks--) {
134         msg = (void*) ((uint16_t) (addr / 8));
135         offset = addr & 7;
136         bcal_cfb_b_decNext(msg, offset, ctx);
137         addr += ctx->size_b;
138     }
139 }