From 9124668bb424d51ee9f0603f60ec670e40cc207e Mon Sep 17 00:00:00 2001 From: provos <> Date: Mon, 10 Aug 1998 18:40:59 +0000 Subject: [PATCH] add ECB and CBC encryption for octet streams --- src/include/blf.h | 8 +- src/lib/libc/crypt/blowfish.3 | 28 ++++++- src/lib/libc/crypt/blowfish.c | 140 +++++++++++++++++++++++++++++++++- 3 files changed, 170 insertions(+), 6 deletions(-) diff --git a/src/include/blf.h b/src/include/blf.h index 54883b66..332bc293 100644 --- a/src/include/blf.h +++ b/src/include/blf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: blf.h,v 1.3 1997/02/16 20:54:26 provos Exp $ */ +/* $OpenBSD: blf.h,v 1.4 1998/08/10 18:40:53 provos Exp $ */ /* * Blowfish - a fast block cipher designed by Bruce Schneier * @@ -69,6 +69,12 @@ void blf_key __P((blf_ctx *, const u_int8_t *, u_int16_t)); void blf_enc __P((blf_ctx *, u_int32_t *, u_int16_t)); void blf_dec __P((blf_ctx *, u_int32_t *, u_int16_t)); +void blf_ecb_encrypt __P((blf_ctx *, u_int8_t *, u_int32_t)); +void blf_ecb_decrypt __P((blf_ctx *, u_int8_t *, u_int32_t)); + +void blf_cbc_encrypt __P((blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t)); +void blf_cbc_decrypt __P((blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t)); + /* Converts u_int8_t to u_int32_t */ u_int32_t Blowfish_stream2word __P((const u_int8_t *, u_int16_t , u_int16_t *)); diff --git a/src/lib/libc/crypt/blowfish.3 b/src/lib/libc/crypt/blowfish.3 index 0b457906..02a1ef87 100644 --- a/src/lib/libc/crypt/blowfish.3 +++ b/src/lib/libc/crypt/blowfish.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: blowfish.3,v 1.1 1997/02/16 20:58:16 provos Exp $ +.\" $OpenBSD: blowfish.3,v 1.2 1998/08/10 18:40:58 provos Exp $ .\" Copyright 1997 Niels Provos .\" All rights reserved. .\" @@ -45,6 +45,14 @@ .Fn blf_enc "blf_ctx *state" "u_int32_t *data" "u_int16_t datalen" .Ft void .Fn blf_dec "blf_ctx *state" "u_int32_t *data" "u_int16_t datalen" +.Ft void +.Fn blf_ecb_encrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen" +.Ft void +.Fn blf_ecb_decrypt "blf_ctx *state" "u_int8_t *data" "u_int32_t datalen" +.Ft void +.Fn blf_cbc_encrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen" +.Ft void +.Fn blf_cbc_decrypt "blf_ctx *state" "u_int8_t *iv" "u_int8_t *data" "u_int32_t datalen" .Sh DESCRIPTION .Pa Blowfish is a fast unpatented block cipher designed by Bruce Schneier. @@ -59,12 +67,25 @@ The first argument to .Fn blf_enc is the initalized state derived from .Fn blf_key . -The stream of data is encrypted in Electronic Cookbook Mode (ECB) and +The stream of 32-bit words is encrypted in Electronic Codebook +Mode (ECB) and .Pa datalen must be even. .Fn blf_dec is used for decrypting Blowfish encrypted blocks. .Pp +The functions +.Fn blf_ecb_encrypt +and +.Fn blf_ecb_decrypt +are used for encrypting and decrypting octet streams in ECB mode. +The functions +.Fn blf_cbc_encrypt +and +.Fn blf_cbc_decrypt +are used for encrypting and decrypting octet streams in +Cipherblock Chaining Mode (CBC). +.Pp The functions .Fn Blowfish_initstate , .Fn Blowfish_expand0state , @@ -74,8 +95,7 @@ and .Fn Blowfish_decipher are used for customization of the .Pa Blowfish -cipher, i.e. for the blowfish password hashing function or for -implementation of Cipher Block Chaining Mode (CBC). +cipher, e.g. for the blowfish password hashing function. .Sh SEE ALSO .Xr crypt 3 , .Xr passwd 1 , diff --git a/src/lib/libc/crypt/blowfish.c b/src/lib/libc/crypt/blowfish.c index 5ffc634e..d9466556 100644 --- a/src/lib/libc/crypt/blowfish.c +++ b/src/lib/libc/crypt/blowfish.c @@ -1,4 +1,4 @@ -/* $OpenBSD: blowfish.c,v 1.8 1998/03/04 00:34:17 deraadt Exp $ */ +/* $OpenBSD: blowfish.c,v 1.9 1998/08/10 18:40:59 provos Exp $ */ /* * Blowfish block cipher for OpenBSD * Copyright 1997 Niels Provos @@ -584,6 +584,144 @@ blf_dec(c, data, blocks) d += 2; } } + +/* Repeating operations for little endian machines */ + +#define BLF_BLK_ENC l = ntohl (*(u_int32_t *)data); \ + r = ntohl (*(u_int32_t *)(data+4)); \ + Blowfish_encipher(c, &l, &r); \ + *(u_int32_t *)data = htonl (l); \ + *(u_int32_t *)(data + 4) = htonl (r); + +#define BLF_BLK_DEC l = ntohl (*(u_int32_t *)data); \ + r = ntohl (*(u_int32_t *)(data+4)); \ + Blowfish_decipher(c, &l, &r); \ + *(u_int32_t *)data = htonl (l); \ + *(u_int32_t *)(data + 4) = htonl (r); + + +#if __STDC__ +void +blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) +#else +void +blf_ecb_encrypt(c, data, len) + blf_ctx *c; + u_int8_t *data; + u_int32_t len; +#endif +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_int32_t l, r; +#endif + u_int32_t i; + + for (i = 0; i < len; i += 8) { +#if BYTE_ORDER == LITTLE_ENDIAN + BLF_BLK_ENC; +#else + Blowfish_encipher(c, data, data + 4); +#endif + data += 8; + } +} + +#if __STDC__ +void +blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len) +#else +void +blf_ecb_decrypt(c, data, len) + blf_ctx *c; + u_int8_t *data; + u_int32_t len; +#endif +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_int32_t l, r; +#endif + u_int32_t i; + + for (i = 0; i < len; i += 8) { +#if BYTE_ORDER == LITTLE_ENDIAN + BLF_BLK_DEC; +#else + Blowfish_decipher(c, data, data + 4); +#endif + data += 8; + } +} + +#if __STDC__ +void +blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len) +#else +void +blf_cbc_encrypt(c, iv, data, len) + blf_ctx *c; + u_int8_t *iv; + u_int8_t *data; + u_int32_t len; +#endif +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_int32_t l, r; +#endif + u_int32_t i; + + for (i = 0; i < len; i += 8) { + *(u_int32_t *)data ^= *(u_int32_t *)iv; + *(u_int32_t *)(data + 4) ^= *(u_int32_t *)(iv + 4); +#if BYTE_ORDER == LITTLE_ENDIAN + BLF_BLK_ENC; +#else + Blowfish_encipher(c, data, data + 4); +#endif + iv = data; + data += 8; + } +} + +#if __STDC__ +void +blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len) +#else +void +blf_cbc_decrypt(c, iva, data, len) + blf_ctx *c; + u_int8_t *iva; + u_int8_t *data; + u_int32_t len; +#endif +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u_int32_t l, r; +#endif + u_int8_t *iv; + u_int32_t i; + + iv = data + len - 16; + data = data + len - 8; + for (i = len - 8; i >= 8; i -= 8) { +#if BYTE_ORDER == LITTLE_ENDIAN + BLF_BLK_DEC; +#else + Blowfish_decipher(c, data, data + 4); +#endif + *(u_int32_t *)data ^= *(u_int32_t *)iv; + *(u_int32_t *)(data + 4) ^= *(u_int32_t *)(iv + 4); + iv = data; + data -= 8; + } +#if BYTE_ORDER == LITTLE_ENDIAN + BLF_BLK_DEC; +#else + Blowfish_decipher(c, data, data + 4); +#endif + *(u_int32_t *)data ^= *(u_int32_t *)iva; + *(u_int32_t *)(data + 4) ^= *(u_int32_t *)(iva + 4); +} + #if 0 void report(u_int32_t data[], u_int16_t len)