summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1998-08-10 18:41:00 +0000
committerNiels Provos <provos@cvs.openbsd.org>1998-08-10 18:41:00 +0000
commit66ec51ee42f8c61b0eb31938129a41dfee3c7bf7 (patch)
tree42227efe43ff3121dc695aaf2a13e35473f18601
parent7182e8c3cebdc3e69c012c12074dcc11f941924d (diff)
add ECB and CBC encryption for octet streams
-rw-r--r--include/blf.h8
-rw-r--r--lib/libc/crypt/blowfish.328
-rw-r--r--lib/libc/crypt/blowfish.c140
3 files changed, 170 insertions, 6 deletions
diff --git a/include/blf.h b/include/blf.h
index 54883b66f4f..332bc293ac0 100644
--- a/include/blf.h
+++ b/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/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)