diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1998-08-10 18:41:00 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1998-08-10 18:41:00 +0000 |
commit | 66ec51ee42f8c61b0eb31938129a41dfee3c7bf7 (patch) | |
tree | 42227efe43ff3121dc695aaf2a13e35473f18601 /lib | |
parent | 7182e8c3cebdc3e69c012c12074dcc11f941924d (diff) |
add ECB and CBC encryption for octet streams
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/crypt/blowfish.3 | 28 | ||||
-rw-r--r-- | lib/libc/crypt/blowfish.c | 140 |
2 files changed, 163 insertions, 5 deletions
diff --git a/lib/libc/crypt/blowfish.3 b/lib/libc/crypt/blowfish.3 index 0b45790658d..02a1ef87384 100644 --- a/lib/libc/crypt/blowfish.3 +++ b/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 <provos@physnet.uni-hamburg.de> .\" 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/lib/libc/crypt/blowfish.c b/lib/libc/crypt/blowfish.c index 5ffc634efa5..d9466556245 100644 --- a/lib/libc/crypt/blowfish.c +++ b/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 <provos@physnet.uni-hamburg.de> @@ -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) |