[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: announce: linux-int-2.4.3.1-hvr3



On 13 April 2001, Jari Ruusu <jari.ruusu@pp.inet.fi> wrote:
> Enforcing minimum password length of 20 characters is a good feature. If
> someone is trying to brute force your password, 20 characters is a *major*
> obstacle. Five or six characters is not.
I perfectly agree with you, but the user should have the liberty of choice.
My passwords are somewhere between 12 to 18 characters including special
characters.

> Does anyone know of GPL licenced implementation of SHA-256, SHA-384 or
> SHA-512? SHA-256 should provide 128 bits of useable key material.

I found two:
SHA-256/384/512 (http://www.aarongifford.com/computers/sha.html)
BeeCrypt (http://www.virtualunlimited.com/products/beecrypt/)

I've verified both against the test vectors published at:
	http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
The first has a BSD license and the second a LGPL one.
I've adapted the former and included it as yet another alternative
to patch util-linux. Mapping the 32 bytes hash to the 16 bytes
encryption key is done by xoring the two halves (diff attached).

As a side note, if someone wants to store an encrypted partition on
a CD you may create a 650M file, mkfs.ext2 it, encrypt it, store 
you data and then use cdrecord to burn that file DIRECTLY as an 
image to the CD. You may then mount your CD with:
	mount -t ext2 -o loop,encryption=AES /dev/cdrom /mount_point
On some CD units you may have to previously mount/unmount a normal 
ISO9660 CD. If you don't write anything on the CD label it might fool
other people to disregard it because there will be no ISO9660 filesystem 
on it and it will look like a burned CD failure.

I encourage everyone to use non-readily available encryption techniques
including your own changes. AES looks (to me) suspiciously to quickly 
adopted so feel free to replace it.

Also keep in mind that good encryption algorithms are not everything because an
attacker will always chose the easiest way to recover your data. One way would
be to record your keystrokes. So seal your keyboard and check the seal
regularly, keep your computer without the cover so you can spot any inside
added device, don't use APM bios functions because the BIOS can be easily
flashed with trojaned versions. Also don't forget about TEMPEST and don't
display data on a CRT monitor when you see vans with parabolic antennas close
to your house.

I have an alarm with an infrared detector in the room where I have my
computers.  The remote control for the alarm (and the pair circuit inside the
base station) have been replaced with other one-time key-lock chips because you
may never know what backdoor codes this alarms have.
Some call me paranoic but I really don't care ;-)

-- 
								Regards,
								Emil
--
If nothing ever sticks to TEFLON, how do they make TEFLON stick to the pan?
diff -urN util-linux-2.11a/mount/Makefile util-linux-2.11a-new/mount/Makefile
--- util-linux-2.11a/mount/Makefile	Sun Mar  4 19:38:53 2001
+++ util-linux-2.11a-new/mount/Makefile	Mon Apr 16 00:22:24 2001
@@ -24,7 +24,7 @@
 
 MAYBE = pivot_root swapoff
 
-LO_OBJS = lomount.o $(LIB)/xstrncpy.o
+LO_OBJS = lomount.o sha256.o $(LIB)/xstrncpy.o
 NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
 GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
 
@@ -57,7 +57,7 @@
 main_losetup.o: lomount.c
 	$(COMPILE) -DMAIN lomount.c -o $@
 
-losetup: main_losetup.o $(LIB)/xstrncpy.o
+losetup: main_losetup.o sha256.o $(LIB)/xstrncpy.o
 	$(LINK) $^ -o $@
 
 mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
diff -urN util-linux-2.11a/mount/lomount.c util-linux-2.11a-new/mount/lomount.c
--- util-linux-2.11a/mount/lomount.c	Sun Mar  4 19:27:59 2001
+++ util-linux-2.11a-new/mount/lomount.c	Sun Apr 15 23:44:02 2001
@@ -27,6 +27,7 @@
 
 #include "loop.h"
 #include "lomount.h"
+#include "sha256.h"
 #include "xstrncpy.h"
 #include "nls.h"
 
@@ -34,6 +35,8 @@
 extern char *xstrdup (const char *s);	/* not: #include "sundries.h" */
 extern void error (const char *fmt, ...);	/* idem */
 
+#define LO_CRYPT_AES    16
+
 #ifdef LOOP_SET_FD
 struct crypt_type_struct {
 	int id;
@@ -42,7 +45,7 @@
 	{ LO_CRYPT_NONE, "no" },
 	{ LO_CRYPT_NONE, "none" },
 	{ LO_CRYPT_XOR, "xor" },
-	{ LO_CRYPT_DES, "DES" },
+	{ LO_CRYPT_AES, "AES" },
 	{ -1, NULL   }
 };
 
@@ -199,7 +202,7 @@
 set_loop (const char *device, const char *file, int offset,
 	  const char *encryption, int *loopro) {
 	struct loop_info loopinfo;
-	int fd, ffd, mode, i;
+	int fd, ffd, mode;
 	char *pass;
 
 	mode = (*loopro ? O_RDONLY : O_RDWR);
@@ -249,22 +252,26 @@
 		xstrncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
 		loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
 		break;
-	case LO_CRYPT_DES:
-		pass = getpass (_("Password: "));
-		strncpy (loopinfo.lo_encrypt_key, pass, 8);
-		loopinfo.lo_encrypt_key[8] = 0;
-		loopinfo.lo_encrypt_key_size = 8;
-		pass = getpass (_("Init (up to 16 hex digits): "));
-		for (i = 0; i < 16 && pass[i]; i++)
-			if (isxdigit (pass[i])) {
-				loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
-				  (islower (pass[i]) ? toupper (pass[i]) :
-				   pass[i])-'A'+10 : pass[i]-'0') << (i&7) * 4;
-			} else {
-				fprintf (stderr, _("Non-hex digit '%c'.\n"),
-					 pass[i]);
-				return 1;
-			}
+	case LO_CRYPT_AES:  /* AES */
+		pass = getpass( _( "Password: " ) );
+		{
+		  sha256Param   shap;
+		  unsigned char keybits[32], *k;
+		  int           i;
+		
+		  /* use the sha256 function to generate a 16 bytes hash */
+		  sha256Reset( &shap );
+		  sha256Update( &shap, pass, strlen( pass ) );
+		  sha256Digest( &shap, ( u_int32_t * ) keybits );
+		  /* zero unencrypted passwords in memory */
+		  memset( pass, 0, strlen( pass ) );
+		  k = ( unsigned char * ) loopinfo.lo_encrypt_key;
+		  for ( i = 0; i < 16; i++ )
+		    k[i] = keybits[i] ^ keybits[i + 16];
+		  /* zero hash in memory */
+		  memset( keybits, 0, 32 );
+		  loopinfo.lo_encrypt_key_size = 16;	/* 128 bits */
+		}
 		break;
 	default:
 		fprintf (stderr,
@@ -281,6 +288,7 @@
 		perror ("ioctl: LOOP_SET_STATUS");
 		return 1;
 	}
+	memset(loopinfo.lo_encrypt_key, 0, sizeof(loopinfo.lo_encrypt_key));
 	close (fd);
 	close (ffd);
 	if (verbose > 1)
diff -urN util-linux-2.11a/mount/losetup.8 util-linux-2.11a-new/mount/losetup.8
--- util-linux-2.11a/mount/losetup.8	Fri Aug 11 07:11:30 2000
+++ util-linux-2.11a-new/mount/losetup.8	Sun Apr 15 23:24:07 2001
@@ -1,4 +1,4 @@
-.TH LOSETUP 8 "Nov 24 1993" "Linux" "MAINTENANCE COMMANDS"
+.TH LOSETUP 8 "Apr 8 2001" "Linux" "MAINTENANCE COMMANDS"
 .SH NAME
 losetup \- set up and control loop devices
 .SH SYNOPSIS
@@ -36,11 +36,8 @@
 .PD 0
 .IP \fBXOR\fP
 use a simple XOR encryption.
-.IP \fBDES\fP
-use DES encryption. DES encryption is only available if the optional
-DES package has been added to the kernel. DES encryption uses an additional
-start value that is used to protect passwords against dictionary
-attacks.
+.IP \fBAES\fP
+use AES encryption.
 .PD
 .RE
 .IP "\fB\-o \fIoffset\fP"
@@ -69,9 +66,8 @@
 .nf
 .IP
 dd if=/dev/zero of=/file bs=1k count=100
-losetup -e des /dev/loop0 /file
+losetup -e AES /dev/loop0 /file
 Password:
-Init (up to 16 hex digits):
 mkfs -t ext2 /dev/loop0 100
 mount -t ext2 /dev/loop0 /mnt
  ...
@@ -86,7 +82,7 @@
 .LP
 .fi
 .SH RESTRICTION
-DES encryption is painfully slow. On the other hand, XOR is terribly weak.
+AES encryption is slow. On the other hand, XOR is terribly weak.
 .SH AUTHORS
 .nf
 Original version: Theodore Ts'o <tytso@athena.mit.edu>
diff -urN util-linux-2.11a/mount/sha256.c util-linux-2.11a-new/mount/sha256.c
--- util-linux-2.11a/mount/sha256.c	Wed Dec 31 19:00:00 1969
+++ util-linux-2.11a-new/mount/sha256.c	Sun Apr 15 22:56:39 2001
@@ -0,0 +1,271 @@
+/*
+ * sha256.c
+ *
+ * SHA-256 hash function, code
+ *
+ * Copyright (c) 2000, 2001 Virtual Unlimited B.V.
+ *
+ * Author: Bob Deblier <bob@virtualunlimited.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "sha256.h"
+
+static const u_int32_t k[64] = {
+  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+  0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+  0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+  0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+  0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+  0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static const u_int32_t hinit[8] = {
+  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
+  0x1f83d9ab, 0x5be0cd19
+};
+
+inline        u_int32_t
+swapu32( u_int32_t n )
+{
+  return ( ( ( n & 0xffU ) << 24 ) |
+      ( ( n & 0xff00U ) << 8 ) |
+      ( ( n & 0xff0000U ) >> 8 ) | ( ( n & 0xff000000U ) >> 24 ) );
+}
+
+int
+sha256Reset( register sha256Param * p )
+{
+  int           i;
+
+  for ( i = 0; i < 8; i++ )
+    p->h[i] = hinit[i];
+  for ( i = 0; i < 64; i++ )
+    p->data[i] = 0;
+  p->length = 0;
+  p->offset = 0;
+  return 0;
+}
+
+#ifndef ROTR32
+# define ROTR32(x, s) (((x) >> (s)) | ((x) << (32 - (s))))
+#endif
+
+#define R(x,s)  ((x) >> (s))
+#define S(x,s) ROTR32(x, s)
+
+#define CH(x,y,z) ((x&(y^z))^z)
+#define MAJ(x,y,z) (((x|y)&z)|(x&y))
+#define SIG0(x)	(S(x,2) ^ S(x,13) ^ S(x,22))
+#define SIG1(x)	(S(x,6) ^ S(x,11) ^ S(x,25))
+#define sig0(x) (S(x,7) ^ S(x,18) ^ R(x,3))
+#define sig1(x) (S(x,17) ^ S(x,19) ^ R(x,10))
+
+#define ROUND(a,b,c,d,e,f,g,h,w,k)	\
+	temp = h + SIG1(e) + CH(e,f,g) + k + w;	\
+	h = temp + SIG0(a) + MAJ(a,b,c);	\
+	d += temp
+
+void
+sha256Process( register sha256Param * p )
+{
+  register u_int32_t a, b, c, d, e, f, g, h, temp;
+  register u_int32_t *w;
+  register u_int8_t t;
+
+#if BYTE_ORDER == BIG_ENDIAN
+  w = p->data + 16;
+#else
+  w = p->data;
+  t = 16;
+  while ( t-- )
+  {
+    register u_int32_t temp = swapu32( *w );
+
+    *( w++ ) = temp;
+  }
+#endif
+
+  t = 48;
+  while ( t-- )
+  {
+    register u_int32_t temp = sig1( w[-2] ) + w[-7] + sig0( w[-15] ) + w[-16];
+
+    *( w++ ) = temp;
+  }
+
+  w = p->data;
+
+  a = p->h[0];
+  b = p->h[1];
+  c = p->h[2];
+  d = p->h[3];
+  e = p->h[4];
+  f = p->h[5];
+  g = p->h[6];
+  h = p->h[7];
+
+  ROUND( a, b, c, d, e, f, g, h, w[0], k[0] );
+  ROUND( h, a, b, c, d, e, f, g, w[1], k[1] );
+  ROUND( g, h, a, b, c, d, e, f, w[2], k[2] );
+  ROUND( f, g, h, a, b, c, d, e, w[3], k[3] );
+  ROUND( e, f, g, h, a, b, c, d, w[4], k[4] );
+  ROUND( d, e, f, g, h, a, b, c, w[5], k[5] );
+  ROUND( c, d, e, f, g, h, a, b, w[6], k[6] );
+  ROUND( b, c, d, e, f, g, h, a, w[7], k[7] );
+  ROUND( a, b, c, d, e, f, g, h, w[8], k[8] );
+  ROUND( h, a, b, c, d, e, f, g, w[9], k[9] );
+  ROUND( g, h, a, b, c, d, e, f, w[10], k[10] );
+  ROUND( f, g, h, a, b, c, d, e, w[11], k[11] );
+  ROUND( e, f, g, h, a, b, c, d, w[12], k[12] );
+  ROUND( d, e, f, g, h, a, b, c, w[13], k[13] );
+  ROUND( c, d, e, f, g, h, a, b, w[14], k[14] );
+  ROUND( b, c, d, e, f, g, h, a, w[15], k[15] );
+  ROUND( a, b, c, d, e, f, g, h, w[16], k[16] );
+  ROUND( h, a, b, c, d, e, f, g, w[17], k[17] );
+  ROUND( g, h, a, b, c, d, e, f, w[18], k[18] );
+  ROUND( f, g, h, a, b, c, d, e, w[19], k[19] );
+  ROUND( e, f, g, h, a, b, c, d, w[20], k[20] );
+  ROUND( d, e, f, g, h, a, b, c, w[21], k[21] );
+  ROUND( c, d, e, f, g, h, a, b, w[22], k[22] );
+  ROUND( b, c, d, e, f, g, h, a, w[23], k[23] );
+  ROUND( a, b, c, d, e, f, g, h, w[24], k[24] );
+  ROUND( h, a, b, c, d, e, f, g, w[25], k[25] );
+  ROUND( g, h, a, b, c, d, e, f, w[26], k[26] );
+  ROUND( f, g, h, a, b, c, d, e, w[27], k[27] );
+  ROUND( e, f, g, h, a, b, c, d, w[28], k[28] );
+  ROUND( d, e, f, g, h, a, b, c, w[29], k[29] );
+  ROUND( c, d, e, f, g, h, a, b, w[30], k[30] );
+  ROUND( b, c, d, e, f, g, h, a, w[31], k[31] );
+  ROUND( a, b, c, d, e, f, g, h, w[32], k[32] );
+  ROUND( h, a, b, c, d, e, f, g, w[33], k[33] );
+  ROUND( g, h, a, b, c, d, e, f, w[34], k[34] );
+  ROUND( f, g, h, a, b, c, d, e, w[35], k[35] );
+  ROUND( e, f, g, h, a, b, c, d, w[36], k[36] );
+  ROUND( d, e, f, g, h, a, b, c, w[37], k[37] );
+  ROUND( c, d, e, f, g, h, a, b, w[38], k[38] );
+  ROUND( b, c, d, e, f, g, h, a, w[39], k[39] );
+  ROUND( a, b, c, d, e, f, g, h, w[40], k[40] );
+  ROUND( h, a, b, c, d, e, f, g, w[41], k[41] );
+  ROUND( g, h, a, b, c, d, e, f, w[42], k[42] );
+  ROUND( f, g, h, a, b, c, d, e, w[43], k[43] );
+  ROUND( e, f, g, h, a, b, c, d, w[44], k[44] );
+  ROUND( d, e, f, g, h, a, b, c, w[45], k[45] );
+  ROUND( c, d, e, f, g, h, a, b, w[46], k[46] );
+  ROUND( b, c, d, e, f, g, h, a, w[47], k[47] );
+  ROUND( a, b, c, d, e, f, g, h, w[48], k[48] );
+  ROUND( h, a, b, c, d, e, f, g, w[49], k[49] );
+  ROUND( g, h, a, b, c, d, e, f, w[50], k[50] );
+  ROUND( f, g, h, a, b, c, d, e, w[51], k[51] );
+  ROUND( e, f, g, h, a, b, c, d, w[52], k[52] );
+  ROUND( d, e, f, g, h, a, b, c, w[53], k[53] );
+  ROUND( c, d, e, f, g, h, a, b, w[54], k[54] );
+  ROUND( b, c, d, e, f, g, h, a, w[55], k[55] );
+  ROUND( a, b, c, d, e, f, g, h, w[56], k[56] );
+  ROUND( h, a, b, c, d, e, f, g, w[57], k[57] );
+  ROUND( g, h, a, b, c, d, e, f, w[58], k[58] );
+  ROUND( f, g, h, a, b, c, d, e, w[59], k[59] );
+  ROUND( e, f, g, h, a, b, c, d, w[60], k[60] );
+  ROUND( d, e, f, g, h, a, b, c, w[61], k[61] );
+  ROUND( c, d, e, f, g, h, a, b, w[62], k[62] );
+  ROUND( b, c, d, e, f, g, h, a, w[63], k[63] );
+
+  p->h[0] += a;
+  p->h[1] += b;
+  p->h[2] += c;
+  p->h[3] += d;
+  p->h[4] += e;
+  p->h[5] += f;
+  p->h[6] += g;
+  p->h[7] += h;
+}
+
+int
+sha256Update( register sha256Param * p, const u_int8_t * data, int size )
+{
+  register int  proclength;
+
+  p->length += size;
+  while ( size > 0 )
+  {
+    proclength = ( ( p->offset + size ) > 64 ) ? ( 64 - p->offset ) : size;
+    memcpy( ( ( u_int8_t * ) p->data ) + p->offset, data, proclength );
+    size -= proclength;
+    data += proclength;
+    p->offset += proclength;
+
+    if ( p->offset == 64 )
+    {
+      sha256Process( p );
+      p->offset = 0;
+    }
+  }
+  return 0;
+}
+
+static void
+sha256Finish( register sha256Param * p )
+{
+  register u_int8_t *ptr = ( ( u_int8_t * ) p->data ) + p->offset++;
+
+  *( ptr++ ) = 0x80;
+
+  if ( p->offset > 56 )
+  {
+    while ( p->offset++ < 64 )
+      *( ptr++ ) = 0;
+
+    sha256Process( p );
+    p->offset = 0;
+  }
+
+  ptr = ( ( u_int8_t * ) p->data ) + p->offset;
+  while ( p->offset++ < 56 )
+    *( ptr++ ) = 0;
+
+#if BYTE_ORDER == BIG_ENDIAN
+  p->data[14] = ( ( u_int32_t ) ( p->length >> 29 ) );
+  p->data[15] = ( ( u_int32_t ) ( ( p->length << 3 ) & 0xffffffff ) );
+#else
+  p->data[14] = swapu32( ( u_int32_t ) ( p->length >> 29 ) );
+  p->data[15] = swapu32( ( u_int32_t ) ( ( p->length << 3 ) & 0xffffffff ) );
+#endif
+
+  sha256Process( p );
+  p->offset = 0;
+}
+
+int
+sha256Digest( register sha256Param * p, u_int32_t * data )
+{
+  int           i;
+
+  sha256Finish( p );
+  for ( i = 0; i < 8; i++ )
+#if BYTE_ORDER == BIG_ENDIAN
+    *data++ = p->h[i];
+#else
+    *data++ = swapu32( p->h[i] );
+#endif
+  sha256Reset( p );
+  return 0;
+}
diff -urN util-linux-2.11a/mount/sha256.h util-linux-2.11a-new/mount/sha256.h
--- util-linux-2.11a/mount/sha256.h	Wed Dec 31 19:00:00 1969
+++ util-linux-2.11a-new/mount/sha256.h	Sun Apr 15 22:52:41 2001
@@ -0,0 +1,50 @@
+/*
+ * sha256.h
+ *
+ * SHA-256 hash function, header
+ *
+ * Copyright (c) 2000, 2001 Virtual Unlimited B.V.
+ *
+ * Author: Bob Deblier <bob@virtualunlimited.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _SHA256_H
+#define _SHA256_H
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <sys/bitypes.h>
+#include <endian.h>
+
+typedef struct
+{
+  u_int32_t     h[8];
+  u_int32_t     data[64];
+  u_int64_t     length;
+  u_int8_t      offset;
+}
+sha256Param;
+
+void          sha256Process( sha256Param * );
+int           sha256Reset( sha256Param * );
+int           sha256Update( sha256Param *, const u_int8_t *, int );
+int           sha256Digest( sha256Param *, u_int32_t * );
+
+#endif