Hello,

I have cleaned my code and I updated my patch with a new feature for
salting the password.

- The salt is generated collecting a timestamp for every valid
keystroke supplied during password prompting: then, the least
significant byte of each timestamp is XORed providing eventually a
24bits seed for SHA256 function. The first 24bits of the generated
context are used as the salt.

- Even though I cannot claim that function is Bruce Schneier proof,
the level of complexity added should provide a certain degree of
security against rainbow tables (256bits secure hash, salt derived
from "quite random" events like keystrokes, XOR is a statistical
balanced function ...).

This patch has been tested on GTA01BV04. It is stil unclear if it
could work on FR (the twin bootloaders shall share the same ENV VARs).

Comments are always welcome,

Francesco Albanese
--- /dev/null
+++ u-boot/common/cmd_lock.c
@@ -0,0 +1,129 @@
+#include <common.h>
+#include <command.h>
+#include <password.h>
+
+#define BUFFER_MAX_LEN	PASSWORD_MAX_LEN+2
+
+#if defined(_USE_PASSWORD)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int do_lock(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	char *s = NULL;
+	char A_buffer[BUFFER_MAX_LEN] = "\0";
+	char B_buffer[BUFFER_MAX_LEN] = "\0";
+	int i;
+
+	s = getenv(PASSWORD_ENV_VAR);
+
+	if (!strcmp(argv[1], "enable") && argc == 2) {
+
+		if (!s) {
+
+			i = read_password("Enter  new password:", A_buffer,
+					  BUFFER_MAX_LEN);
+			if (i == -1)
+				return i;
+
+			if (i < PASSWORD_MIN_LEN) {
+
+				printf
+				    ("Minimum password length: %d characters\n",
+				     PASSWORD_MIN_LEN);
+				return i;
+
+			}
+
+			i = read_password("Retype new password:", B_buffer,
+					  BUFFER_MAX_LEN);
+
+			if (!strncmp(A_buffer, B_buffer, BUFFER_MAX_LEN)) {
+
+				i = set_protection(A_buffer, strlen(A_buffer));
+
+				if (i)
+					puts("Writing error\n");
+				else
+					puts("Password set\n");
+
+			} else
+				puts("Passwords mismatch\n");
+
+			memset(A_buffer, 0, BUFFER_MAX_LEN);
+			memset(B_buffer, 0, BUFFER_MAX_LEN);
+		}
+
+		else {
+			puts("Lock already enabled\n");
+
+		}
+
+	} else if (!strcmp(argv[1], "disable") && argc == 2) {
+
+		if (s) {
+
+			i = remove_protection();
+
+			if (i)
+				puts("Writing error\n");
+			else
+				puts("Password removed\n");
+		} else
+			puts("Lock already disabled\n");
+
+	} else if (!strcmp(argv[1], "change") && argc == 2) {
+
+		if (!s) {
+			puts("Lock is disabled - Run lock enable\n");
+		} else {
+
+			i = read_password("Enter  new password:", A_buffer,
+					  BUFFER_MAX_LEN);
+			if (i == -1)
+				return i;
+			i = read_password("Retype new password:", B_buffer,
+					  BUFFER_MAX_LEN);
+			if (i == -1)
+				return i;
+
+			if (!strncmp(A_buffer, B_buffer, BUFFER_MAX_LEN)) {
+
+				i = set_protection(A_buffer, strlen(A_buffer));
+				if (i)
+					puts("Writing error\n");
+				else
+					puts("Password changed\n");
+			} else
+				puts("Passwords mismatch\n");
+
+			memset(A_buffer, 0, BUFFER_MAX_LEN);
+			memset(B_buffer, 0, BUFFER_MAX_LEN);
+
+		}
+
+	} else if (!strcmp(argv[1], "status") && argc == 2) {
+		if (s) {
+			puts("Lockdown enabled\n");
+		} else
+			puts("Lockdown disabled\n");
+
+	} else {
+		printf("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	return 0;
+
+}
+
+/* -------------------------------------------------------------------- */
+
+U_BOOT_CMD(lock, 2, 1, do_lock,
+	   "lock    - lock setting commands\n",
+	   "\n '' enable  - set password protection\n"
+	   " ''  disable - unset password protection\n"
+	   " ''  status  - show lock status\n"
+	   " ''  change  - change password\n");
+
+#endif /* _USE_PASSWORD */
--- uboot.orig/drivers/usb/usbdcore_ep0.c
+++ u-boot/drivers/usb/usbdcore_ep0.c
@@ -430,6 +430,11 @@ int ep0_recv_setup (struct urb *urb)
 	if ((request->bmRequestType & 0x3f) == USB_TYPE_DFU &&
 	     (device->dfu_state != DFU_STATE_appIDLE ||
 	      le16_to_cpu(request->wIndex) == CONFIG_USBD_DFU_INTERFACE)) {
+#ifdef _USE_PASSWORD
+
+		char *out;
+		if (check_lock_status() == UNLOCKED) {
+#endif
 		int rc = dfu_ep0_handler(urb);
 		switch (rc) {
 		case DFU_EP0_NONE:
@@ -441,6 +446,29 @@ int ep0_recv_setup (struct urb *urb)
 		case DFU_EP0_STALL:
 			return -1;
 		}
+#ifdef _USE_PASSWORD
+		} else {
+			out = getenv("stdout");
+			if (out && !strcmp(out, "usbtty")) {
+				setenv("stdout", "vga");
+				setenv("stderr", "vga");
+				stdout_flag = 1;
+			}
+			puts("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+			puts("@            DEVICE LOCKED          @\n");
+			puts("@[EMAIL PROTECTED]");
+			puts("# Please unlock console, then flash #\n");
+			puts("@[EMAIL PROTECTED]");
+			puts("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+			if (stdout_flag) {
+				setenv("stdout", "usbtty");
+				setenv("stderr", "usbtty");
+				stdout_flag = 0;
+			}
+			return 0;
+
+		}
+#endif
 	}
 #endif /* CONFIG_USB_DFU */
 
--- uboot.orig/common/main.c
+++ u-boot/common/main.c
@@ -39,6 +39,7 @@
 #endif
 
 #include <post.h>
+#include <password.h>
 
 #ifdef CONFIG_SILENT_CONSOLE
 DECLARE_GLOBAL_DATA_PTR;
@@ -441,6 +442,10 @@ void main_loop (void)
 	}
 #endif
 
+#ifdef _USE_PASSWORD
+	trap_loop();
+#endif
+
 	/*
 	 * Main Loop for Monitor Command Processing
 	 */
--- uboot.orig/common/Makefile
+++ u-boot/common/Makefile
@@ -137,6 +137,9 @@ COBJS-y += crc16.o
 COBJS-y += xyzModem.o
 COBJS-y += cmd_mac.o
 COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
+COBJS-y += password.o
+COBJS-y += sha256.o
+COBJS-y += cmd_lock.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(AOBJS:.o=.S) $(COBJS:.o=.c)
--- /dev/null
+++ u-boot/include/password.h
@@ -0,0 +1,42 @@
+#ifndef _PASSWORD_H
+#define _PASSWORD_H
+
+#include <sha256.h>
+
+#define _USE_PASSWORD		1
+#define SALTED_ENV_VAR		"salt"
+#define PASSWORD_MAX_LEN	30
+#define PASSWORD_MIN_LEN	8
+#define PASSWORD_ENV_VAR	"password"
+#define	PASSWORD_HSH_LEN	32
+#define BUFFER_MAX_LEN	PASSWORD_MAX_LEN+2
+
+typedef enum {
+	UNLOCKED = 0,
+	LOCKED = 1
+} password_state_t;
+
+void trap_loop(void);
+
+int remove_protection(void);
+int verify_password(char *password, size_t length);
+int set_protection(char *password, size_t password_length);
+int read_password(const char *const prompt, char *buffer, size_t buffer_length);
+
+static char *del_char(char *buffer, char *p, int *colp, int *np, int plen);
+
+char select_mask(char c);
+void cook_stamp(void);
+void time_stamp(void);
+void uncharify_salt(char salt[8], char *uncharified);
+void charify_digest(uint8 digest[32], char *charified);
+void charify_salt(char salt[4], char *charified);
+void sha256(uint8 * input, uint32 length, uint8 digest[32]);
+void process_password(char *password, size_t password_length, char *hash,
+		      char *salt);
+
+inline password_state_t check_lock_status(void);
+inline void get_salt(char *salt);
+password_state_t setup_lock_status(void);
+password_state_t unlock(char *password, size_t length);
+#endif /* _PASSWORD_H */
--- /dev/null
+++ u-boot/common/password.c
@@ -0,0 +1,415 @@
+#include <common.h>
+#include <sha256.h>
+#include <password.h>
+
+static int pan_length;
+static char erase_seq[] = "\b \b";
+static char pan[PASSWORD_MAX_LEN * 2];
+static char pool[3];
+static password_state_t lock_state = UNLOCKED;
+
+inline password_state_t check_lock_status()
+{
+	return lock_state;
+}
+
+inline void get_salt(char *salt)
+{
+	cook_stamp();
+	uint8 *input = (uint8 *) pool;
+	uint8 digest[32];
+
+	sha256(input, 3, digest);
+
+	memcpy(salt, digest, 3);
+}
+
+/********************************************
+ *	remove_protection()
+ *
+ *	Remove password protection 
+ */
+int remove_protection()
+{
+
+	setenv(PASSWORD_ENV_VAR, NULL);
+	return (saveenv()? 1 : 0);
+
+}
+
+/********************************************
+ *	set_protection()
+ *
+ *	Set / change password protection 
+ */
+int set_protection(char *password, size_t password_length)
+{
+
+	char hash[65] = "\0";
+	char salt[3];
+	char env_var[72] = "\0";
+	char charified_salt[7] = "\0";
+
+	get_salt(salt);
+
+	process_password(password, strlen(password), hash, salt);
+	charify_salt(salt, charified_salt);
+	memcpy(env_var, hash, 64);
+
+	env_var[64] = '$';
+
+	memcpy(env_var + 65, charified_salt, 6);
+	setenv(PASSWORD_ENV_VAR, env_var);
+	return (saveenv()? 1 : 0);
+
+}
+
+/********************************************
+ *	setup_lock_status()
+ *
+ *	Control if a password is set as env
+ *	Set the lock accordingly
+ *	Return the lock status
+ */
+password_state_t setup_lock_status()
+{
+
+	char *s = NULL;
+
+	s = getenv(PASSWORD_ENV_VAR);
+
+	lock_state = s ? LOCKED : UNLOCKED;
+
+	return lock_state;
+
+}
+
+/********************************************
+ *	unlock()
+ *
+ *	If the password supplied match, unlock the lock :) 
+ */
+password_state_t unlock(char *password, size_t length)
+{
+
+	lock_state = verify_password(password, length) ? LOCKED : UNLOCKED;
+	return lock_state;
+}
+
+/********************************************
+ *	sha256()
+ *
+ *	Apply SHA256 to input  
+ */
+void sha256(uint8 * input, uint32 length, uint8 digest[32])
+{
+
+	sha256_context ctx;
+
+	sha256_starts(&ctx);
+	sha256_update(&ctx, input, length);
+	sha256_finish(&ctx, digest);
+
+	memset(&ctx, 0, sizeof(sha256_context));
+
+}
+
+/********************************************
+ *	charify_digest()
+ *
+ *	Represent raw hex as ASCII Hex  
+ */
+void charify_digest(uint8 digest[32], char *charified)
+{
+
+	int i;
+	char *c = charified;
+
+	for (i = 0; i < 32; i++) {
+		sprintf(c, "%02x", digest[i]);
+		c += 2;
+	}
+}
+
+void charify_salt(char salt[3], char *charified)
+{
+
+	int i;
+	char *c = charified;
+
+	for (i = 0; i < 3; i++) {
+		sprintf(c, "%02x", salt[i]);
+		c += 2;
+	}
+
+}
+
+/********************************************
+ *	uncharify_salt(()
+ *
+ *	Represent ASCII Hex as raw hex  
+ */
+void uncharify_salt(char salt[6], char *uncharified)
+{
+
+	int i;
+	char *c = salt;
+	char m1;
+	char m2;
+
+	for (i = 0; i < 3; i++) {
+
+		m1 = select_mask(*c) << 4;
+		c++;
+		m2 = select_mask(*c);
+		c++;
+
+		uncharified[i] = m1 | m2;
+	}
+
+}
+
+char select_mask(char c)
+{
+
+	switch (c) {
+
+	case '0':
+		return 0x00;
+	case '1':
+		return 0x01;
+	case '2':
+		return 0x02;
+	case '3':
+		return 0x03;
+	case '4':
+		return 0x04;
+	case '5':
+		return 0x05;
+	case '6':
+		return 0x06;
+	case '7':
+		return 0x07;
+	case '8':
+		return 0x08;
+	case '9':
+		return 0x09;
+	case 'a':
+		return 0x0a;
+	case 'b':
+		return 0x0b;
+	case 'c':
+		return 0x0c;
+	case 'd':
+		return 0x0d;
+	case 'e':
+		return 0x0e;
+	case 'f':
+		return 0x0f;
+
+	}
+
+}
+
+/********************************************
+ *	verify_password()
+ *
+ *	Receive a password as input
+ *	Process it
+ *	Determine if the input and the stored password match
+ */
+int verify_password(char *password, size_t length)
+{
+
+	char *original = NULL;
+	char hash[64];
+	char salt[3];
+
+	original = getenv(PASSWORD_ENV_VAR);
+	uncharify_salt(original + 65, salt);
+	process_password(password, strlen(password), hash, salt);
+
+	return strncmp(hash, original, 64);
+
+}
+
+/********************************************
+ *	process_password()
+ *
+ *	Receive a password and a salt as input
+ *	Hash the concatenation of password and salt
+ *	Represent the 32 bytes digest using a 256 bytes ASCII string
+ */
+void
+process_password(char *password, size_t password_length, char *hash, char *salt)
+{
+
+	uint8 digest[32];
+	char charified[65];
+	char salted_input[PASSWORD_MAX_LEN + 3] = "\0";
+	uint8 *input = (uint8 *) salted_input;
+	uint32 input_length = (uint32) password_length + 3;
+
+	memcpy(salted_input, password, password_length);
+	memcpy(salted_input + password_length, salt, 3);
+
+	sha256(input, input_length, digest);
+	charify_digest(digest, charified);
+	memcpy(hash, charified, 64);
+
+}
+
+static char *del_char(char *buffer, char *p, int *colp, int *np, int plen)
+{
+	if (*np == 0) {
+		return (p);
+	}
+
+	--p;
+	puts(erase_seq);
+	(*colp)--;
+
+	(*np)--;
+	return (p);
+}
+
+int read_password(const char *const prompt, char *buffer, size_t buffer_length)
+{
+
+	char *p = buffer;
+
+	char *p_buf = p;
+	int n = 0;		/* buffer index         */
+	int col;		/* output column cnt    */
+	int plen = 0;		/* prompt length        */
+	char c;
+
+	if (prompt) {
+		plen = strlen(prompt);
+		puts(prompt);
+	}
+	col = plen;
+
+	for (;;) {
+
+		c = getc();
+
+		/*
+		 * Special character handling
+		 */
+		switch (c) {
+		case '\r':	/* Enter                */
+		case '\n':
+			*p = '\0';
+			puts("\r\n");
+			return (p - p_buf);
+
+		case '\0':	/* nul                  */
+		case '\t':
+			continue;
+
+		case 0x03:	/* ^C - break           */
+			p_buf[0] = '\0';	/* discard input */
+			return (-1);
+
+		case 0x08:	/* ^H  - backspace      */
+		case 0x7F:	/* DEL - backspace      */
+			p = del_char(p_buf, p, &col, &n, plen);
+			continue;
+
+		default:
+
+			if (n < buffer_length - 2) {
+				time_stamp();
+				++col;	/* echo input           */
+				putc('*');
+
+				*p++ = c;
+				++n;
+			} else {	/* Buffer full          */
+				putc('\a');
+			}
+		}
+	}
+
+}
+
+/********************************************
+ *	trap_loop ()
+ *
+ *	Lock console execution
+ */
+void trap_loop()
+{
+
+	char buffer[BUFFER_MAX_LEN] = "\0";
+	ulong delay = 1 * CFG_HZ;
+	ulong start;
+
+	if (setup_lock_status() == LOCKED) {
+
+		while (1) {
+
+			start = get_timer(0);
+			memset(buffer, 0, BUFFER_MAX_LEN);
+			read_password("Enter password:", buffer,
+				      BUFFER_MAX_LEN);
+
+			if (!unlock(buffer, strlen(buffer)))
+				return;
+
+			while (get_timer(start) < delay)
+				udelay(100);
+
+			delay *= 2;
+
+		}
+	}
+}
+
+/********************************************
+ *	cook_stamp()
+ *
+ *	Process timestamps pool XORing the cells
+ *	Produce a 24-bits variable
+ */
+void cook_stamp()
+{
+
+	int i, j;
+	char tmp;
+
+	for (i = 0; i < 3; i++) {
+
+		j = i + 3;
+		tmp = pan[i];
+		while (j < pan_length) {
+			tmp = tmp ^ pan[j];
+			j += 3;
+		}
+
+		pool[i] = tmp;
+	}
+
+	pan_length = 0;
+	memset(pan, 0, PASSWORD_MAX_LEN * 2);
+
+}
+
+/********************************************
+ *	time_stamp()
+ *
+ *	Collect the last byte of each timestamp
+ */
+void time_stamp()
+{
+	/*
+	 * In order to generate a random salt, we collect some "noise"
+	 * (in form of the least significant 8 bits of the timer counter)
+	 * while the user enters the password.
+	 */
+	ulong u = get_timer(0);
+	if (pan_length < PASSWORD_MAX_LEN * 2) {
+		pan[pan_length++] = (char)(u & 0x000000ff);
+	}
+}
--- /dev/null
+++ u-boot/common/sha256.c
@@ -0,0 +1,259 @@
+/*
+ *  FIPS-180-2 compliant SHA-256 implementation
+ *
+ *  Copyright (C) 2001-2003  Christophe Devine
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <common.h>
+#include <sha256.h>
+#include <password.h>
+
+#if defined(_USE_PASSWORD)
+
+#define GET_UINT32(n,b,i)                       \
+{                                               \
+    (n) = ( (uint32) (b)[(i)    ] << 24 )       \
+        | ( (uint32) (b)[(i) + 1] << 16 )       \
+        | ( (uint32) (b)[(i) + 2] <<  8 )       \
+        | ( (uint32) (b)[(i) + 3]       );      \
+}
+
+#define PUT_UINT32(n,b,i)                       \
+{                                               \
+    (b)[(i)    ] = (uint8) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (uint8) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (uint8) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (uint8) ( (n)       );       \
+}
+
+void sha256_starts(sha256_context * ctx)
+{
+	ctx->total[0] = 0;
+	ctx->total[1] = 0;
+
+	ctx->state[0] = 0x6A09E667;
+	ctx->state[1] = 0xBB67AE85;
+	ctx->state[2] = 0x3C6EF372;
+	ctx->state[3] = 0xA54FF53A;
+	ctx->state[4] = 0x510E527F;
+	ctx->state[5] = 0x9B05688C;
+	ctx->state[6] = 0x1F83D9AB;
+	ctx->state[7] = 0x5BE0CD19;
+}
+
+void sha256_process(sha256_context * ctx, uint8 data[64])
+{
+	uint32 temp1, temp2, W[64];
+	uint32 A, B, C, D, E, F, G, H;
+
+	GET_UINT32(W[0], data, 0);
+	GET_UINT32(W[1], data, 4);
+	GET_UINT32(W[2], data, 8);
+	GET_UINT32(W[3], data, 12);
+	GET_UINT32(W[4], data, 16);
+	GET_UINT32(W[5], data, 20);
+	GET_UINT32(W[6], data, 24);
+	GET_UINT32(W[7], data, 28);
+	GET_UINT32(W[8], data, 32);
+	GET_UINT32(W[9], data, 36);
+	GET_UINT32(W[10], data, 40);
+	GET_UINT32(W[11], data, 44);
+	GET_UINT32(W[12], data, 48);
+	GET_UINT32(W[13], data, 52);
+	GET_UINT32(W[14], data, 56);
+	GET_UINT32(W[15], data, 60);
+
+#define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t)                                    \
+(                                               \
+    W[t] = S1(W[t -  2]) + W[t -  7] +          \
+           S0(W[t - 15]) + W[t - 16]            \
+)
+
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+{                                               \
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+    temp2 = S2(a) + F0(a,b,c);                  \
+    d += temp1; h = temp1 + temp2;              \
+}
+
+	A = ctx->state[0];
+	B = ctx->state[1];
+	C = ctx->state[2];
+	D = ctx->state[3];
+	E = ctx->state[4];
+	F = ctx->state[5];
+	G = ctx->state[6];
+	H = ctx->state[7];
+
+	P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
+	P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
+	P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
+	P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
+	P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
+	P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
+	P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
+	P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
+	P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
+	P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
+	P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
+	P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
+	P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
+	P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
+	P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
+	P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
+	P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
+	P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
+	P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
+	P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
+	P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
+	P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
+	P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
+	P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
+	P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
+	P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
+	P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
+	P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
+	P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
+	P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
+	P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
+	P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
+	P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
+	P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
+	P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
+	P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
+	P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
+	P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
+	P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
+	P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
+	P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
+	P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
+	P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
+	P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
+	P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
+	P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
+	P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
+	P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
+	P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
+	P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
+	P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
+	P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
+	P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
+	P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
+	P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
+	P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
+	P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
+	P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
+	P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
+	P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
+	P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
+	P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
+	P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
+	P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
+
+	ctx->state[0] += A;
+	ctx->state[1] += B;
+	ctx->state[2] += C;
+	ctx->state[3] += D;
+	ctx->state[4] += E;
+	ctx->state[5] += F;
+	ctx->state[6] += G;
+	ctx->state[7] += H;
+}
+
+void sha256_update(sha256_context * ctx, uint8 * input, uint32 length)
+{
+	uint32 left, fill;
+
+	if (!length)
+		return;
+
+	left = ctx->total[0] & 0x3F;
+	fill = 64 - left;
+
+	ctx->total[0] += length;
+	ctx->total[0] &= 0xFFFFFFFF;
+
+	if (ctx->total[0] < length)
+		ctx->total[1]++;
+
+	if (left && length >= fill) {
+		memcpy((void *)(ctx->buffer + left), (void *)input, fill);
+		sha256_process(ctx, ctx->buffer);
+		length -= fill;
+		input += fill;
+		left = 0;
+	}
+
+	while (length >= 64) {
+		sha256_process(ctx, input);
+		length -= 64;
+		input += 64;
+	}
+
+	if (length) {
+		memcpy((void *)(ctx->buffer + left), (void *)input, length);
+	}
+}
+
+static uint8 sha256_padding[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+void sha256_finish(sha256_context * ctx, uint8 digest[32])
+{
+	uint32 last, padn;
+	uint32 high, low;
+	uint8 msglen[8];
+
+	high = (ctx->total[0] >> 29)
+	    | (ctx->total[1] << 3);
+	low = (ctx->total[0] << 3);
+
+	PUT_UINT32(high, msglen, 0);
+	PUT_UINT32(low, msglen, 4);
+
+	last = ctx->total[0] & 0x3F;
+	padn = (last < 56) ? (56 - last) : (120 - last);
+
+	sha256_update(ctx, sha256_padding, padn);
+	sha256_update(ctx, msglen, 8);
+
+	PUT_UINT32(ctx->state[0], digest, 0);
+	PUT_UINT32(ctx->state[1], digest, 4);
+	PUT_UINT32(ctx->state[2], digest, 8);
+	PUT_UINT32(ctx->state[3], digest, 12);
+	PUT_UINT32(ctx->state[4], digest, 16);
+	PUT_UINT32(ctx->state[5], digest, 20);
+	PUT_UINT32(ctx->state[6], digest, 24);
+	PUT_UINT32(ctx->state[7], digest, 28);
+}
+#endif
--- /dev/null
+++ u-boot/include/sha256.h
@@ -0,0 +1,22 @@
+#ifndef _SHA256_H
+#define _SHA256_H
+
+#ifndef uint8
+#define uint8  unsigned char
+#endif
+
+#ifndef uint32
+#define uint32 unsigned long int
+#endif
+
+typedef struct {
+	uint32 total[2];
+	uint32 state[8];
+	uint8 buffer[64];
+} sha256_context;
+
+void sha256_starts(sha256_context * ctx);
+void sha256_update(sha256_context * ctx, uint8 * input, uint32 length);
+void sha256_finish(sha256_context * ctx, uint8 digest[32]);
+
+#endif /* _SHA256_H */

Reply via email to