Skip to content

Commit 04b2db3

Browse files
authored
Blowfish OFB Block Cipher Mode Support (#2892)
### Description of changes: * Users of PyCA cryptography are not able to use Blowfish for their legacy use cases, as we forgot to remove the `OPENSSL_NO_BF` define when we re-added support for these decrepit algorithms. * Blowfish was missing the OFB block cipher mode implementation that was present in OpenSSL. I have brought this implementation over and updated the types and function signatures. Which is also a mode support by PyCA cryptography. ### Testing: There doesn't really appear to be much extensive OFB KATs available, so I've extended the current test data using the OpenSSL 1.1.1 APIs: ``` $ echo -n "plaintextHexStr" | xxd -p -r > plaintext.txt $ openssl enc -bf-ofb -in plaintext.txt -out ciphertext -K <keyHex> -iv <ivHex> $ xxd -i < ciphertext ``` By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.
1 parent f5e4585 commit 04b2db3

File tree

46 files changed

+642
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+642
-2
lines changed

crypto/decrepit/blowfish/blowfish.c

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
LL ^= \
7272
(((S[((int)(R >> 24) & 0xff)] + S[0x0100 + ((int)(R >> 16) & 0xff)]) ^ \
7373
S[0x0200 + ((int)(R >> 8) & 0xff)]) + \
74-
S[0x0300 + ((int)(R)&0xff)]) & \
74+
S[0x0300 + ((int)(R) & 0xff)]) & \
7575
0xffffffffL)
7676

7777
void BF_encrypt(uint32_t *data, const BF_KEY *key) {
@@ -510,7 +510,7 @@ void BF_cfb64_encrypt(const uint8_t *in, uint8_t *out, size_t length,
510510
const BF_KEY *schedule, uint8_t *ivec, int *num,
511511
int encrypt) {
512512
uint32_t v0, v1, t;
513-
int n = *num;
513+
int n = *num & 0x07;
514514
size_t l = length;
515515
uint32_t ti[2];
516516
uint8_t c, cc;
@@ -562,6 +562,53 @@ void BF_cfb64_encrypt(const uint8_t *in, uint8_t *out, size_t length,
562562
*num = n;
563563
}
564564

565+
void BF_ofb64_encrypt(const uint8_t *in, uint8_t *out, size_t length,
566+
const BF_KEY *schedule, uint8_t *ivec, int *num) {
567+
uint32_t v0 = 0, v1 = 0, t = 0;
568+
int n = *num & 0x07;
569+
size_t l = length;
570+
uint8_t d[8] = {0};
571+
uint8_t *dp = NULL;
572+
uint32_t ti[2] = {0};
573+
uint8_t *iv = NULL;
574+
int save = 0;
575+
576+
iv = ivec;
577+
n2l(iv, v0);
578+
n2l(iv, v1);
579+
ti[0] = v0;
580+
ti[1] = v1;
581+
dp = d;
582+
l2n(v0, dp);
583+
l2n(v1, dp);
584+
while (l--) {
585+
if (n == 0) {
586+
BF_encrypt(ti, schedule);
587+
dp = d;
588+
t = ti[0];
589+
l2n(t, dp);
590+
t = ti[1];
591+
l2n(t, dp);
592+
save++;
593+
}
594+
*(out++) = *(in++) ^ d[n];
595+
n = (n + 1) & 0x07;
596+
}
597+
if (save) {
598+
v0 = ti[0];
599+
v1 = ti[1];
600+
iv = ivec;
601+
l2n(v0, iv);
602+
l2n(v1, iv);
603+
}
604+
OPENSSL_cleanse(&t, sizeof(t));
605+
OPENSSL_cleanse(&v0, sizeof(v0));
606+
OPENSSL_cleanse(&v1, sizeof(v1));
607+
OPENSSL_cleanse(ti, sizeof(ti));
608+
OPENSSL_cleanse(d, sizeof(d));
609+
*num = n;
610+
}
611+
565612
static int bf_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
566613
const uint8_t *iv, int enc) {
567614
BF_KEY *bf_key = ctx->cipher_data;
@@ -600,6 +647,15 @@ static int bf_cfb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
600647
return 1;
601648
}
602649

650+
static int bf_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
651+
size_t len) {
652+
BF_KEY *bf_key = ctx->cipher_data;
653+
int num = ctx->num;
654+
BF_ofb64_encrypt(in, out, len, bf_key, ctx->iv, &num);
655+
ctx->num = num;
656+
return 1;
657+
}
658+
603659
OPENSSL_END_ALLOW_DEPRECATED
604660

605661
static const EVP_CIPHER bf_ecb = {
@@ -635,10 +691,23 @@ static const EVP_CIPHER bf_cfb = {
635691
.cipher = bf_cfb_cipher,
636692
};
637693

694+
static const EVP_CIPHER bf_ofb = {
695+
.nid = NID_bf_ofb64,
696+
.block_size = 1,
697+
.key_len = 16,
698+
.iv_len = BF_BLOCK,
699+
.ctx_size = sizeof(BF_KEY),
700+
.flags = EVP_CIPH_OFB_MODE | EVP_CIPH_VARIABLE_LENGTH,
701+
.init = bf_init_key,
702+
.cipher = bf_ofb_cipher,
703+
};
704+
638705
const EVP_CIPHER *EVP_bf_ecb(void) { return &bf_ecb; }
639706

640707
const EVP_CIPHER *EVP_bf_cbc(void) { return &bf_cbc; }
641708

642709
const EVP_CIPHER *EVP_bf_cfb(void) { return &bf_cfb; }
643710

644711
const EVP_CIPHER *EVP_bf_cfb64(void) { return &bf_cfb; }
712+
713+
const EVP_CIPHER *EVP_bf_ofb(void) { return &bf_ofb; }

0 commit comments

Comments
 (0)