3
* Implements both normal and PGP-specific CFB mode.
5
* Copyright (c) 2005 Marko Kreen
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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
38
typedef int (*mix_data_t) (PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst);
47
uint8 fr[PGP_MAX_BLOCK];
48
uint8 fre[PGP_MAX_BLOCK];
49
uint8 encbuf[PGP_MAX_BLOCK];
53
pgp_cfb_create(PGP_CFB ** ctx_p, int algo, const uint8 *key, int key_len,
54
int resync, uint8 *iv)
60
res = pgp_load_cipher(algo, &ciph);
64
res = px_cipher_init(ciph, key, key_len, NULL);
71
ctx = px_alloc(sizeof(*ctx));
72
memset(ctx, 0, sizeof(*ctx));
74
ctx->block_size = px_cipher_block_size(ciph);
78
memcpy(ctx->fr, iv, ctx->block_size);
85
pgp_cfb_free(PGP_CFB * ctx)
87
px_cipher_free(ctx->ciph);
88
memset(ctx, 0, sizeof(*ctx));
93
* Data processing for normal CFB. (PGP_PKT_SYMENCRYPTED_DATA_MDC)
96
mix_encrypt_normal(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
100
for (i = ctx->pos; i < ctx->pos + len; i++)
101
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
107
mix_decrypt_normal(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
111
for (i = ctx->pos; i < ctx->pos + len; i++)
113
ctx->encbuf[i] = *data++;
114
*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
121
* Data processing for old PGP CFB mode. (PGP_PKT_SYMENCRYPTED_DATA)
123
* The goal is to hide the horror from the rest of the code,
124
* thus its all concentrated here.
127
mix_encrypt_resync(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
132
/* block #2 is 2 bytes long */
133
if (ctx->block_no == 2)
138
for (i = ctx->pos; i < ctx->pos + n; i++)
139
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
146
memcpy(ctx->fr, ctx->encbuf + 2, ctx->block_size - 2);
147
memcpy(ctx->fr + ctx->block_size - 2, ctx->encbuf, 2);
152
for (i = ctx->pos; i < ctx->pos + len; i++)
153
*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
159
mix_decrypt_resync(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
164
/* block #2 is 2 bytes long */
165
if (ctx->block_no == 2)
170
for (i = ctx->pos; i < ctx->pos + n; i++)
172
ctx->encbuf[i] = *data++;
173
*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
180
memcpy(ctx->fr, ctx->encbuf + 2, ctx->block_size - 2);
181
memcpy(ctx->fr + ctx->block_size - 2, ctx->encbuf, 2);
186
for (i = ctx->pos; i < ctx->pos + len; i++)
188
ctx->encbuf[i] = *data++;
189
*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
196
* common code for both encrypt and decrypt.
199
cfb_process(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst,
205
while (len > 0 && ctx->pos > 0)
207
n = ctx->block_size - ctx->pos;
211
n = mix_data(ctx, data, n, dst);
216
if (ctx->pos == ctx->block_size)
218
memcpy(ctx->fr, ctx->encbuf, ctx->block_size);
225
px_cipher_encrypt(ctx->ciph, ctx->fr, ctx->block_size, ctx->fre);
226
if (ctx->block_no < 5)
233
res = mix_data(ctx, data, n, dst);
238
if (ctx->pos == ctx->block_size)
240
memcpy(ctx->fr, ctx->encbuf, ctx->block_size);
252
pgp_cfb_encrypt(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
254
mix_data_t mix = ctx->resync ? mix_encrypt_resync : mix_encrypt_normal;
256
return cfb_process(ctx, data, len, dst, mix);
260
pgp_cfb_decrypt(PGP_CFB * ctx, const uint8 *data, int len, uint8 *dst)
262
mix_data_t mix = ctx->resync ? mix_decrypt_resync : mix_decrypt_normal;
264
return cfb_process(ctx, data, len, dst, mix);