| 
				
			 | 
			
			
				
				@@ -1,233 +1,295 @@ 
			 | 
		
		
	
		
			
			| 
				1
			 | 
			
				
			 | 
			
			
				
				-/*  
			 | 
		
		
	
		
			
			| 
				2
			 | 
			
				
			 | 
			
			
				
				- * Cryptographic API. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				1
			 | 
			
			
				
				+/* 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2
			 | 
			
			
				
				+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. 
			 | 
		
		
	
		
			
			| 
				3
			 | 
			
				3
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				4
			 | 
			
				
			 | 
			
			
				
				- * MD5 Message Digest Algorithm (RFC1321). 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				4
			 | 
			
			
				
				+ * This program is free software; you can redistribute it and/or 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				5
			 | 
			
			
				
				+ * modify it under the terms of the GNU General Public License as 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				6
			 | 
			
			
				
				+ * published by the Free Software Foundation; either version 2 of the 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				7
			 | 
			
			
				
				+ * License, or any later version. 
			 | 
		
		
	
		
			
			| 
				5
			 | 
			
				8
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				6
			 | 
			
				
			 | 
			
			
				
				- * Derived from cryptoapi implementation, originally based on the 
			 | 
		
		
	
		
			
			| 
				7
			 | 
			
				
			 | 
			
			
				
				- * public domain implementation written by Colin Plumb in 1993. 
			 | 
		
		
	
		
			
			| 
				8
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				9
			 | 
			
				
			 | 
			
			
				
				- * Reduced object size by around 50% compared to the original Linux 
			 | 
		
		
	
		
			
			| 
				10
			 | 
			
				
			 | 
			
			
				
				- * version for use in Etherboot by Michael Brown. 
			 | 
		
		
	
		
			
			| 
				11
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				12
			 | 
			
				
			 | 
			
			
				
				- * Copyright (c) Cryptoapi developers. 
			 | 
		
		
	
		
			
			| 
				13
			 | 
			
				
			 | 
			
			
				
				- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 
			 | 
		
		
	
		
			
			| 
				14
			 | 
			
				
			 | 
			
			
				
				- * Copyright (c) 2006 Michael Brown <mbrown@fensystems.co.uk> 
			 | 
		
		
	
		
			
			| 
				15
			 | 
			
				
			 | 
			
			
				
				- *  
			 | 
		
		
	
		
			
			| 
				16
			 | 
			
				
			 | 
			
			
				
				- * This program is free software; you can redistribute it and/or modify it 
			 | 
		
		
	
		
			
			| 
				17
			 | 
			
				
			 | 
			
			
				
				- * under the terms of the GNU General Public License as published by the Free 
			 | 
		
		
	
		
			
			| 
				18
			 | 
			
				
			 | 
			
			
				
				- * Software Foundation; either version 2 of the License, or (at your option)  
			 | 
		
		
	
		
			
			| 
				19
			 | 
			
				
			 | 
			
			
				
				- * any later version. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				9
			 | 
			
			
				
				+ * This program is distributed in the hope that it will be useful, but 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				10
			 | 
			
			
				
				+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				11
			 | 
			
			
				
				+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				12
			 | 
			
			
				
				+ * General Public License for more details. 
			 | 
		
		
	
		
			
			| 
				20
			 | 
			
				13
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				14
			 | 
			
			
				
				+ * You should have received a copy of the GNU General Public License 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				
				+ * along with this program; if not, write to the Free Software 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				16
			 | 
			
			
				
				+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
			 | 
		
		
	
		
			
			| 
				21
			 | 
			
				17
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				22
			 | 
			
				18
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				23
			 | 
			
				19
			 | 
			
			
				
				 FILE_LICENCE ( GPL2_OR_LATER ); 
			 | 
		
		
	
		
			
			| 
				24
			 | 
			
				20
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				
				+/** @file 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				23
			 | 
			
			
				
				+ * MD5 algorithm 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				25
			 | 
			
				27
			 | 
			
			
				
				 #include <stdint.h> 
			 | 
		
		
	
		
			
			| 
				26
			 | 
			
				28
			 | 
			
			
				
				 #include <string.h> 
			 | 
		
		
	
		
			
			| 
				27
			 | 
			
				29
			 | 
			
			
				
				 #include <byteswap.h> 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				30
			 | 
			
			
				
				+#include <assert.h> 
			 | 
		
		
	
		
			
			| 
				28
			 | 
			
				31
			 | 
			
			
				
				 #include <ipxe/crypto.h> 
			 | 
		
		
	
		
			
			| 
				29
			 | 
			
				32
			 | 
			
			
				
				 #include <ipxe/md5.h> 
			 | 
		
		
	
		
			
			| 
				30
			 | 
			
				33
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				31
			 | 
			
				
			 | 
			
			
				
				-struct md5_step { 
			 | 
		
		
	
		
			
			| 
				32
			 | 
			
				
			 | 
			
			
				
				-	u32 ( * f ) ( u32 b, u32 c, u32 d ); 
			 | 
		
		
	
		
			
			| 
				33
			 | 
			
				
			 | 
			
			
				
				-	u8 coefficient; 
			 | 
		
		
	
		
			
			| 
				34
			 | 
			
				
			 | 
			
			
				
				-	u8 constant; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				
				+ * Rotate dword left 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				
				+ * @v dword		Dword 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				
				+ * @v rotate		Amount of rotation 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				39
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				40
			 | 
			
			
				
				+static inline __attribute__ (( always_inline )) uint32_t 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				41
			 | 
			
			
				
				+rol32 ( uint32_t dword, unsigned int rotate ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				42
			 | 
			
			
				
				+	return ( ( dword << rotate ) | ( dword >> ( 32 - rotate ) ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				43
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				
				+/** MD5 variables */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				
				+struct md5_variables { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				
				+	/* This layout matches that of struct md5_digest_data, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				
				+	 * allowing for efficient endianness-conversion, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				
				+	uint32_t a; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				
				+	uint32_t b; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				
				+	uint32_t c; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				
				+	uint32_t d; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				
				+	uint32_t w[16]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				
				+} __attribute__ (( packed )); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				
				+/** MD5 constants */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				
				+static const uint32_t k[64] = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				
				+	0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				
				+	0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				
				+	0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				
				+	0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				
				+	0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				
				+	0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				
				+	0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				
				+	0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				
				+	0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				
				+	0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				
				+	0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				
				+/** MD5 shift amounts */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				
				+static const uint8_t r[64] = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				
				+	7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				
				+	5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				
				+	4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				
				+	6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 
			 | 
		
		
	
		
			
			| 
				35
			 | 
			
				78
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				36
			 | 
			
				79
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				37
			 | 
			
				
			 | 
			
			
				
				-static u32 f1(u32 b, u32 c, u32 d) 
			 | 
		
		
	
		
			
			| 
				38
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				39
			 | 
			
				
			 | 
			
			
				
				-	return ( d ^ ( b & ( c ^ d ) ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				
				+ * f(b,c,d) for steps 0 to 15 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				
				+ * @v v		MD5 variables 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				
				+ * @ret f	f(b,c,d) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				
				+static uint32_t md5_f_0_15 ( struct md5_variables *v ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				87
			 | 
			
			
				
				+	return ( v->d ^ ( v->b & ( v->c ^ v->d ) ) ); 
			 | 
		
		
	
		
			
			| 
				40
			 | 
			
				88
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				41
			 | 
			
				89
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				42
			 | 
			
				
			 | 
			
			
				
				-static u32 f2(u32 b, u32 c, u32 d) 
			 | 
		
		
	
		
			
			| 
				43
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				44
			 | 
			
				
			 | 
			
			
				
				-	return ( c ^ ( d & ( b ^ c ) ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				
				+ * f(b,c,d) for steps 16 to 31 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				
				+ * @v v		MD5 variables 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				
				+ * @ret f	f(b,c,d) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				96
			 | 
			
			
				
				+static uint32_t md5_f_16_31 ( struct md5_variables *v ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				
				+	return ( v->c ^ ( v->d & ( v->b ^ v->c ) ) ); 
			 | 
		
		
	
		
			
			| 
				45
			 | 
			
				98
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				46
			 | 
			
				99
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				47
			 | 
			
				
			 | 
			
			
				
				-static u32 f3(u32 b, u32 c, u32 d) 
			 | 
		
		
	
		
			
			| 
				48
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				49
			 | 
			
				
			 | 
			
			
				
				-	return ( b ^ c ^ d ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				
				+ * f(b,c,d) for steps 32 to 47 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				
				+ * @v v		MD5 variables 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+ * @ret f	f(b,c,d) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+static uint32_t md5_f_32_47 ( struct md5_variables *v ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+	return ( v->b ^ v->c ^ v->d ); 
			 | 
		
		
	
		
			
			| 
				50
			 | 
			
				108
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				51
			 | 
			
				109
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				52
			 | 
			
				
			 | 
			
			
				
				-static u32 f4(u32 b, u32 c, u32 d) 
			 | 
		
		
	
		
			
			| 
				53
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				54
			 | 
			
				
			 | 
			
			
				
				-	return ( c ^ ( b | ~d ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				110
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				111
			 | 
			
			
				
				+ * f(b,c,d) for steps 48 to 63 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				112
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				113
			 | 
			
			
				
				+ * @v v		MD5 variables 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				114
			 | 
			
			
				
				+ * @ret f	f(b,c,d) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				115
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				116
			 | 
			
			
				
				+static uint32_t md5_f_48_63 ( struct md5_variables *v ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				
				+	return ( v->c ^ ( v->b | (~v->d) ) ); 
			 | 
		
		
	
		
			
			| 
				55
			 | 
			
				118
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				56
			 | 
			
				119
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				57
			 | 
			
				
			 | 
			
			
				
				-static struct md5_step md5_steps[4] = { 
			 | 
		
		
	
		
			
			| 
				58
			 | 
			
				
			 | 
			
			
				
				-	{ 
			 | 
		
		
	
		
			
			| 
				59
			 | 
			
				
			 | 
			
			
				
				-		.f = f1, 
			 | 
		
		
	
		
			
			| 
				60
			 | 
			
				
			 | 
			
			
				
				-		.coefficient = 1, 
			 | 
		
		
	
		
			
			| 
				61
			 | 
			
				
			 | 
			
			
				
				-		.constant = 0, 
			 | 
		
		
	
		
			
			| 
				62
			 | 
			
				
			 | 
			
			
				
				-	}, 
			 | 
		
		
	
		
			
			| 
				63
			 | 
			
				
			 | 
			
			
				
				-	{ 
			 | 
		
		
	
		
			
			| 
				64
			 | 
			
				
			 | 
			
			
				
				-		.f = f2, 
			 | 
		
		
	
		
			
			| 
				65
			 | 
			
				
			 | 
			
			
				
				-		.coefficient = 5, 
			 | 
		
		
	
		
			
			| 
				66
			 | 
			
				
			 | 
			
			
				
				-		.constant = 1, 
			 | 
		
		
	
		
			
			| 
				67
			 | 
			
				
			 | 
			
			
				
				-	}, 
			 | 
		
		
	
		
			
			| 
				68
			 | 
			
				
			 | 
			
			
				
				-	{ 
			 | 
		
		
	
		
			
			| 
				69
			 | 
			
				
			 | 
			
			
				
				-		.f = f3, 
			 | 
		
		
	
		
			
			| 
				70
			 | 
			
				
			 | 
			
			
				
				-		.coefficient = 3, 
			 | 
		
		
	
		
			
			| 
				71
			 | 
			
				
			 | 
			
			
				
				-		.constant = 5, 
			 | 
		
		
	
		
			
			| 
				72
			 | 
			
				
			 | 
			
			
				
				-	}, 
			 | 
		
		
	
		
			
			| 
				73
			 | 
			
				
			 | 
			
			
				
				-	{ 
			 | 
		
		
	
		
			
			| 
				74
			 | 
			
				
			 | 
			
			
				
				-		.f = f4, 
			 | 
		
		
	
		
			
			| 
				75
			 | 
			
				
			 | 
			
			
				
				-		.coefficient = 7, 
			 | 
		
		
	
		
			
			| 
				76
			 | 
			
				
			 | 
			
			
				
				-		.constant = 0, 
			 | 
		
		
	
		
			
			| 
				77
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				120
			 | 
			
			
				
				+/** An MD5 step function */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				121
			 | 
			
			
				
				+struct md5_step { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				122
			 | 
			
			
				
				+	/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				123
			 | 
			
			
				
				+	 * Calculate f(b,c,d) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				124
			 | 
			
			
				
				+	 * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				125
			 | 
			
			
				
				+	 * @v v		MD5 variables 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				126
			 | 
			
			
				
				+	 * @ret f	f(b,c,d) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				127
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				128
			 | 
			
			
				
				+	uint32_t ( * f ) ( struct md5_variables *v ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				129
			 | 
			
			
				
				+	/** Coefficient of i in g=ni+m */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				130
			 | 
			
			
				
				+	uint8_t coefficient; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				131
			 | 
			
			
				
				+	/** Constant term in g=ni+m */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				132
			 | 
			
			
				
				+	uint8_t constant; 
			 | 
		
		
	
		
			
			| 
				78
			 | 
			
				133
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				79
			 | 
			
				134
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				80
			 | 
			
				
			 | 
			
			
				
				-static const u8 r[64] = { 
			 | 
		
		
	
		
			
			| 
				81
			 | 
			
				
			 | 
			
			
				
				-	7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, 
			 | 
		
		
	
		
			
			| 
				82
			 | 
			
				
			 | 
			
			
				
				-	5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, 
			 | 
		
		
	
		
			
			| 
				83
			 | 
			
				
			 | 
			
			
				
				-	4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, 
			 | 
		
		
	
		
			
			| 
				84
			 | 
			
				
			 | 
			
			
				
				-	6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				135
			 | 
			
			
				
				+/** MD5 steps */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				136
			 | 
			
			
				
				+static struct md5_step md5_steps[4] = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				137
			 | 
			
			
				
				+	/** 0 to 15 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				138
			 | 
			
			
				
				+	{ .f = md5_f_0_15,	.coefficient = 1,	.constant = 0 }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				139
			 | 
			
			
				
				+	/** 16 to 31 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				140
			 | 
			
			
				
				+	{ .f = md5_f_16_31,	.coefficient = 5,	.constant = 1 }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				141
			 | 
			
			
				
				+	/** 32 to 47 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				142
			 | 
			
			
				
				+	{ .f = md5_f_32_47,	.coefficient = 3,	.constant = 5 }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				143
			 | 
			
			
				
				+	/** 48 to 63 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				144
			 | 
			
			
				
				+	{ .f = md5_f_48_63,	.coefficient = 7,	.constant = 0 }, 
			 | 
		
		
	
		
			
			| 
				85
			 | 
			
				145
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				86
			 | 
			
				146
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				87
			 | 
			
				
			 | 
			
			
				
				-static const u32 k[64] = { 
			 | 
		
		
	
		
			
			| 
				88
			 | 
			
				
			 | 
			
			
				
				-	0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 
			 | 
		
		
	
		
			
			| 
				89
			 | 
			
				
			 | 
			
			
				
				-	0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, 
			 | 
		
		
	
		
			
			| 
				90
			 | 
			
				
			 | 
			
			
				
				-	0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 
			 | 
		
		
	
		
			
			| 
				91
			 | 
			
				
			 | 
			
			
				
				-	0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL, 
			 | 
		
		
	
		
			
			| 
				92
			 | 
			
				
			 | 
			
			
				
				-	0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 
			 | 
		
		
	
		
			
			| 
				93
			 | 
			
				
			 | 
			
			
				
				-	0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, 
			 | 
		
		
	
		
			
			| 
				94
			 | 
			
				
			 | 
			
			
				
				-	0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 
			 | 
		
		
	
		
			
			| 
				95
			 | 
			
				
			 | 
			
			
				
				-	0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL, 
			 | 
		
		
	
		
			
			| 
				96
			 | 
			
				
			 | 
			
			
				
				-	0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 
			 | 
		
		
	
		
			
			| 
				97
			 | 
			
				
			 | 
			
			
				
				-	0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL, 
			 | 
		
		
	
		
			
			| 
				98
			 | 
			
				
			 | 
			
			
				
				-	0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 
			 | 
		
		
	
		
			
			| 
				99
			 | 
			
				
			 | 
			
			
				
				-	0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, 
			 | 
		
		
	
		
			
			| 
				100
			 | 
			
				
			 | 
			
			
				
				-	0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 
			 | 
		
		
	
		
			
			| 
				101
			 | 
			
				
			 | 
			
			
				
				-	0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL, 
			 | 
		
		
	
		
			
			| 
				102
			 | 
			
				
			 | 
			
			
				
				-	0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 
			 | 
		
		
	
		
			
			| 
				103
			 | 
			
				
			 | 
			
			
				
				-	0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL, 
			 | 
		
		
	
		
			
			| 
				104
			 | 
			
				
			 | 
			
			
				
				-}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				147
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				148
			 | 
			
			
				
				+ * Initialise MD5 algorithm 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				149
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				150
			 | 
			
			
				
				+ * @v ctx		MD5 context 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				151
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				152
			 | 
			
			
				
				+static void md5_init ( void *ctx ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				153
			 | 
			
			
				
				+	struct md5_context *context = ctx; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				154
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				155
			 | 
			
			
				
				+	context->ddd.dd.digest.h[0] = cpu_to_le32 ( 0x67452301 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				156
			 | 
			
			
				
				+	context->ddd.dd.digest.h[1] = cpu_to_le32 ( 0xefcdab89 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				157
			 | 
			
			
				
				+	context->ddd.dd.digest.h[2] = cpu_to_le32 ( 0x98badcfe ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				158
			 | 
			
			
				
				+	context->ddd.dd.digest.h[3] = cpu_to_le32 ( 0x10325476 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				159
			 | 
			
			
				
				+	context->len = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				160
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				105
			 | 
			
				161
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				106
			 | 
			
				
			 | 
			
			
				
				-static void md5_transform(u32 *hash, const u32 *in) 
			 | 
		
		
	
		
			
			| 
				107
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				108
			 | 
			
				
			 | 
			
			
				
				-	u32 a, b, c, d, f, g, temp; 
			 | 
		
		
	
		
			
			| 
				109
			 | 
			
				
			 | 
			
			
				
				-	int i; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				162
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				163
			 | 
			
			
				
				+ * Calculate MD5 digest of accumulated data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				164
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				165
			 | 
			
			
				
				+ * @v context		MD5 context 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				166
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				167
			 | 
			
			
				
				+static void md5_digest ( struct md5_context *context ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				168
			 | 
			
			
				
				+        union { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				169
			 | 
			
			
				
				+		union md5_digest_data_dwords ddd; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				170
			 | 
			
			
				
				+		struct md5_variables v; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				171
			 | 
			
			
				
				+	} u; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				172
			 | 
			
			
				
				+	uint32_t *a = &u.v.a; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				173
			 | 
			
			
				
				+	uint32_t *b = &u.v.b; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				174
			 | 
			
			
				
				+	uint32_t *c = &u.v.c; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				175
			 | 
			
			
				
				+	uint32_t *d = &u.v.d; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				176
			 | 
			
			
				
				+	uint32_t *w = u.v.w; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				177
			 | 
			
			
				
				+	uint32_t f; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				178
			 | 
			
			
				
				+	uint32_t g; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				179
			 | 
			
			
				
				+	uint32_t temp; 
			 | 
		
		
	
		
			
			| 
				110
			 | 
			
				180
			 | 
			
			
				
				 	struct md5_step *step; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				181
			 | 
			
			
				
				+	unsigned int i; 
			 | 
		
		
	
		
			
			| 
				111
			 | 
			
				182
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				112
			 | 
			
				
			 | 
			
			
				
				-	a = hash[0]; 
			 | 
		
		
	
		
			
			| 
				113
			 | 
			
				
			 | 
			
			
				
				-	b = hash[1]; 
			 | 
		
		
	
		
			
			| 
				114
			 | 
			
				
			 | 
			
			
				
				-	c = hash[2]; 
			 | 
		
		
	
		
			
			| 
				115
			 | 
			
				
			 | 
			
			
				
				-	d = hash[3]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				183
			 | 
			
			
				
				+	/* Sanity checks */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				184
			 | 
			
			
				
				+	assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				185
			 | 
			
			
				
				+	linker_assert ( &u.ddd.dd.digest.h[0] == a, md5_bad_layout ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				186
			 | 
			
			
				
				+	linker_assert ( &u.ddd.dd.digest.h[1] == b, md5_bad_layout ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				187
			 | 
			
			
				
				+	linker_assert ( &u.ddd.dd.digest.h[2] == c, md5_bad_layout ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				188
			 | 
			
			
				
				+	linker_assert ( &u.ddd.dd.digest.h[3] == d, md5_bad_layout ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				189
			 | 
			
			
				
				+	linker_assert ( &u.ddd.dd.data.dword[0] == w, md5_bad_layout ); 
			 | 
		
		
	
		
			
			| 
				116
			 | 
			
				190
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				117
			 | 
			
				
			 | 
			
			
				
				-	for ( i = 0 ; i < 64 ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				
			 | 
			
			
				
				-		step = &md5_steps[i >> 4]; 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				
			 | 
			
			
				
				-		f = step->f ( b, c, d ); 
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				
			 | 
			
			
				
				-		g = ( ( i * step->coefficient + step->constant ) & 0xf ); 
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				
			 | 
			
			
				
				-		temp = d; 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				
			 | 
			
			
				
				-		d = c; 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				
			 | 
			
			
				
				-		c = b; 
			 | 
		
		
	
		
			
			| 
				124
			 | 
			
				
			 | 
			
			
				
				-		a += ( f + k[i] + in[g] ); 
			 | 
		
		
	
		
			
			| 
				125
			 | 
			
				
			 | 
			
			
				
				-		a = ( ( a << r[i] ) | ( a >> ( 32-r[i] ) ) ); 
			 | 
		
		
	
		
			
			| 
				126
			 | 
			
				
			 | 
			
			
				
				-		b += a; 
			 | 
		
		
	
		
			
			| 
				127
			 | 
			
				
			 | 
			
			
				
				-		a = temp; 
			 | 
		
		
	
		
			
			| 
				128
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				129
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				130
			 | 
			
				
			 | 
			
			
				
				-	hash[0] += a; 
			 | 
		
		
	
		
			
			| 
				131
			 | 
			
				
			 | 
			
			
				
				-	hash[1] += b; 
			 | 
		
		
	
		
			
			| 
				132
			 | 
			
				
			 | 
			
			
				
				-	hash[2] += c; 
			 | 
		
		
	
		
			
			| 
				133
			 | 
			
				
			 | 
			
			
				
				-	hash[3] += d; 
			 | 
		
		
	
		
			
			| 
				134
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				191
			 | 
			
			
				
				+	DBGC ( context, "MD5 digesting:\n" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				192
			 | 
			
			
				
				+	DBGC_HDA ( context, 0, &context->ddd.dd.digest, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				193
			 | 
			
			
				
				+		   sizeof ( context->ddd.dd.digest ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				194
			 | 
			
			
				
				+	DBGC_HDA ( context, context->len, &context->ddd.dd.data, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				195
			 | 
			
			
				
				+		   sizeof ( context->ddd.dd.data ) ); 
			 | 
		
		
	
		
			
			| 
				135
			 | 
			
				196
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				136
			 | 
			
				
			 | 
			
			
				
				-/* XXX: this stuff can be optimized */ 
			 | 
		
		
	
		
			
			| 
				137
			 | 
			
				
			 | 
			
			
				
				-static inline void le32_to_cpu_array(u32 *buf, unsigned int words) 
			 | 
		
		
	
		
			
			| 
				138
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				139
			 | 
			
				
			 | 
			
			
				
				-	while (words--) { 
			 | 
		
		
	
		
			
			| 
				140
			 | 
			
				
			 | 
			
			
				
				-		le32_to_cpus(buf); 
			 | 
		
		
	
		
			
			| 
				141
			 | 
			
				
			 | 
			
			
				
				-		buf++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				197
			 | 
			
			
				
				+	/* Convert h[0..3] to host-endian, and initialise a, b, c, d, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				198
			 | 
			
			
				
				+	 * and w[0..15] 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				199
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				200
			 | 
			
			
				
				+	for ( i = 0 ; i < ( sizeof ( u.ddd.dword ) / 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				201
			 | 
			
			
				
				+			    sizeof ( u.ddd.dword[0] ) ) ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				202
			 | 
			
			
				
				+		le32_to_cpus ( &context->ddd.dword[i] ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				203
			 | 
			
			
				
				+		u.ddd.dword[i] = context->ddd.dword[i]; 
			 | 
		
		
	
		
			
			| 
				142
			 | 
			
				204
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				143
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				144
			 | 
			
				205
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				145
			 | 
			
				
			 | 
			
			
				
				-static inline void cpu_to_le32_array(u32 *buf, unsigned int words) 
			 | 
		
		
	
		
			
			| 
				146
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				147
			 | 
			
				
			 | 
			
			
				
				-	while (words--) { 
			 | 
		
		
	
		
			
			| 
				148
			 | 
			
				
			 | 
			
			
				
				-		cpu_to_le32s(buf); 
			 | 
		
		
	
		
			
			| 
				149
			 | 
			
				
			 | 
			
			
				
				-		buf++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				206
			 | 
			
			
				
				+	/* Main loop */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				207
			 | 
			
			
				
				+	for ( i = 0 ; i < 64 ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				208
			 | 
			
			
				
				+		step = &md5_steps[ i / 16 ]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				209
			 | 
			
			
				
				+		f = step->f ( &u.v ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				210
			 | 
			
			
				
				+		g = ( ( ( step->coefficient * i ) + step->constant ) % 16 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				211
			 | 
			
			
				
				+		temp = *d; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				212
			 | 
			
			
				
				+		*d = *c; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				213
			 | 
			
			
				
				+		*c = *b; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				214
			 | 
			
			
				
				+		*b = ( *b + rol32 ( ( *a + f + k[i] + w[g] ), r[i] ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				215
			 | 
			
			
				
				+		*a = temp; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				216
			 | 
			
			
				
				+		DBGC2 ( context, "%2d : %08x %08x %08x %08x\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				217
			 | 
			
			
				
				+			i, *a, *b, *c, *d ); 
			 | 
		
		
	
		
			
			| 
				150
			 | 
			
				218
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				151
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				152
			 | 
			
				219
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				153
			 | 
			
				
			 | 
			
			
				
				-static inline void md5_transform_helper(struct md5_ctx *ctx) 
			 | 
		
		
	
		
			
			| 
				154
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				155
			 | 
			
				
			 | 
			
			
				
				-	le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32)); 
			 | 
		
		
	
		
			
			| 
				156
			 | 
			
				
			 | 
			
			
				
				-	md5_transform(ctx->hash, ctx->block); 
			 | 
		
		
	
		
			
			| 
				157
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				158
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				159
			 | 
			
				
			 | 
			
			
				
				-static void md5_init(void *context) 
			 | 
		
		
	
		
			
			| 
				160
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				161
			 | 
			
				
			 | 
			
			
				
				-	struct md5_ctx *mctx = context; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				220
			 | 
			
			
				
				+	/* Add chunk to hash and convert back to big-endian */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				221
			 | 
			
			
				
				+	for ( i = 0 ; i < 4 ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				222
			 | 
			
			
				
				+		context->ddd.dd.digest.h[i] = 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				223
			 | 
			
			
				
				+			cpu_to_le32 ( context->ddd.dd.digest.h[i] + 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				224
			 | 
			
			
				
				+				      u.ddd.dd.digest.h[i] ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				225
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				162
			 | 
			
				226
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				163
			 | 
			
				
			 | 
			
			
				
				-	mctx->hash[0] = 0x67452301; 
			 | 
		
		
	
		
			
			| 
				164
			 | 
			
				
			 | 
			
			
				
				-	mctx->hash[1] = 0xefcdab89; 
			 | 
		
		
	
		
			
			| 
				165
			 | 
			
				
			 | 
			
			
				
				-	mctx->hash[2] = 0x98badcfe; 
			 | 
		
		
	
		
			
			| 
				166
			 | 
			
				
			 | 
			
			
				
				-	mctx->hash[3] = 0x10325476; 
			 | 
		
		
	
		
			
			| 
				167
			 | 
			
				
			 | 
			
			
				
				-	mctx->byte_count = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				227
			 | 
			
			
				
				+	DBGC ( context, "MD5 digested:\n" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				228
			 | 
			
			
				
				+	DBGC_HDA ( context, 0, &context->ddd.dd.digest, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				229
			 | 
			
			
				
				+		   sizeof ( context->ddd.dd.digest ) ); 
			 | 
		
		
	
		
			
			| 
				168
			 | 
			
				230
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				169
			 | 
			
				231
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				170
			 | 
			
				
			 | 
			
			
				
				-static void md5_update(void *context, const void *data, size_t len) 
			 | 
		
		
	
		
			
			| 
				171
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				172
			 | 
			
				
			 | 
			
			
				
				-	struct md5_ctx *mctx = context; 
			 | 
		
		
	
		
			
			| 
				173
			 | 
			
				
			 | 
			
			
				
				-	const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); 
			 | 
		
		
	
		
			
			| 
				174
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				175
			 | 
			
				
			 | 
			
			
				
				-	mctx->byte_count += len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				232
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				233
			 | 
			
			
				
				+ * Accumulate data with MD5 algorithm 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				234
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				235
			 | 
			
			
				
				+ * @v ctx		MD5 context 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				236
			 | 
			
			
				
				+ * @v data		Data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				237
			 | 
			
			
				
				+ * @v len		Length of data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				238
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				239
			 | 
			
			
				
				+static void md5_update ( void *ctx, const void *data, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				240
			 | 
			
			
				
				+	struct md5_context *context = ctx; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				241
			 | 
			
			
				
				+	const uint8_t *byte = data; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				242
			 | 
			
			
				
				+	size_t offset; 
			 | 
		
		
	
		
			
			| 
				176
			 | 
			
				243
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				177
			 | 
			
				
			 | 
			
			
				
				-	if (avail > len) { 
			 | 
		
		
	
		
			
			| 
				178
			 | 
			
				
			 | 
			
			
				
				-		memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 
			 | 
		
		
	
		
			
			| 
				179
			 | 
			
				
			 | 
			
			
				
				-		       data, len); 
			 | 
		
		
	
		
			
			| 
				180
			 | 
			
				
			 | 
			
			
				
				-		return; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				244
			 | 
			
			
				
				+	/* Accumulate data a byte at a time, performing the digest 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				245
			 | 
			
			
				
				+	 * whenever we fill the data buffer 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				246
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				247
			 | 
			
			
				
				+	while ( len-- ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				248
			 | 
			
			
				
				+		offset = ( context->len % sizeof ( context->ddd.dd.data ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				249
			 | 
			
			
				
				+		context->ddd.dd.data.byte[offset] = *(byte++); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				250
			 | 
			
			
				
				+		context->len++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				251
			 | 
			
			
				
				+		if ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				252
			 | 
			
			
				
				+			md5_digest ( context ); 
			 | 
		
		
	
		
			
			| 
				181
			 | 
			
				253
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				254
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				182
			 | 
			
				255
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				183
			 | 
			
				
			 | 
			
			
				
				-	memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), 
			 | 
		
		
	
		
			
			| 
				184
			 | 
			
				
			 | 
			
			
				
				-	       data, avail); 
			 | 
		
		
	
		
			
			| 
				185
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				186
			 | 
			
				
			 | 
			
			
				
				-	md5_transform_helper(mctx); 
			 | 
		
		
	
		
			
			| 
				187
			 | 
			
				
			 | 
			
			
				
				-	data += avail; 
			 | 
		
		
	
		
			
			| 
				188
			 | 
			
				
			 | 
			
			
				
				-	len -= avail; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				256
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				257
			 | 
			
			
				
				+ * Generate MD5 digest 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				258
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				259
			 | 
			
			
				
				+ * @v ctx		MD5 context 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				260
			 | 
			
			
				
				+ * @v out		Output buffer 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				261
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				262
			 | 
			
			
				
				+static void md5_final ( void *ctx, void *out ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				263
			 | 
			
			
				
				+	struct md5_context *context = ctx; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				264
			 | 
			
			
				
				+	uint64_t len_bits; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				265
			 | 
			
			
				
				+	uint8_t pad; 
			 | 
		
		
	
		
			
			| 
				189
			 | 
			
				266
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				190
			 | 
			
				
			 | 
			
			
				
				-	while (len >= sizeof(mctx->block)) { 
			 | 
		
		
	
		
			
			| 
				191
			 | 
			
				
			 | 
			
			
				
				-		memcpy(mctx->block, data, sizeof(mctx->block)); 
			 | 
		
		
	
		
			
			| 
				192
			 | 
			
				
			 | 
			
			
				
				-		md5_transform_helper(mctx); 
			 | 
		
		
	
		
			
			| 
				193
			 | 
			
				
			 | 
			
			
				
				-		data += sizeof(mctx->block); 
			 | 
		
		
	
		
			
			| 
				194
			 | 
			
				
			 | 
			
			
				
				-		len -= sizeof(mctx->block); 
			 | 
		
		
	
		
			
			| 
				195
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				267
			 | 
			
			
				
				+	/* Record length before pre-processing */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				268
			 | 
			
			
				
				+	len_bits = cpu_to_le64 ( ( ( uint64_t ) context->len ) * 8 ); 
			 | 
		
		
	
		
			
			| 
				196
			 | 
			
				269
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				197
			 | 
			
				
			 | 
			
			
				
				-	memcpy(mctx->block, data, len); 
			 | 
		
		
	
		
			
			| 
				198
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				270
			 | 
			
			
				
				+	/* Pad with a single "1" bit followed by as many "0" bits as required */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				271
			 | 
			
			
				
				+	pad = 0x80; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				272
			 | 
			
			
				
				+	do { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				273
			 | 
			
			
				
				+		md5_update ( ctx, &pad, sizeof ( pad ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				274
			 | 
			
			
				
				+		pad = 0x00; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				275
			 | 
			
			
				
				+	} while ( ( context->len % sizeof ( context->ddd.dd.data ) ) != 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				276
			 | 
			
			
				
				+		  offsetof ( typeof ( context->ddd.dd.data ), final.len ) ); 
			 | 
		
		
	
		
			
			| 
				199
			 | 
			
				277
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				200
			 | 
			
				
			 | 
			
			
				
				-static void md5_final(void *context, void *out) 
			 | 
		
		
	
		
			
			| 
				201
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				202
			 | 
			
				
			 | 
			
			
				
				-	struct md5_ctx *mctx = context; 
			 | 
		
		
	
		
			
			| 
				203
			 | 
			
				
			 | 
			
			
				
				-	const unsigned int offset = mctx->byte_count & 0x3f; 
			 | 
		
		
	
		
			
			| 
				204
			 | 
			
				
			 | 
			
			
				
				-	char *p = (char *)mctx->block + offset; 
			 | 
		
		
	
		
			
			| 
				205
			 | 
			
				
			 | 
			
			
				
				-	int padding = 56 - (offset + 1); 
			 | 
		
		
	
		
			
			| 
				206
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				207
			 | 
			
				
			 | 
			
			
				
				-	*p++ = 0x80; 
			 | 
		
		
	
		
			
			| 
				208
			 | 
			
				
			 | 
			
			
				
				-	if (padding < 0) { 
			 | 
		
		
	
		
			
			| 
				209
			 | 
			
				
			 | 
			
			
				
				-		memset(p, 0x00, padding + sizeof (u64)); 
			 | 
		
		
	
		
			
			| 
				210
			 | 
			
				
			 | 
			
			
				
				-		md5_transform_helper(mctx); 
			 | 
		
		
	
		
			
			| 
				211
			 | 
			
				
			 | 
			
			
				
				-		p = (char *)mctx->block; 
			 | 
		
		
	
		
			
			| 
				212
			 | 
			
				
			 | 
			
			
				
				-		padding = 56; 
			 | 
		
		
	
		
			
			| 
				213
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				278
			 | 
			
			
				
				+	/* Append length (in bits) */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				279
			 | 
			
			
				
				+	md5_update ( ctx, &len_bits, sizeof ( len_bits ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				280
			 | 
			
			
				
				+	assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 ); 
			 | 
		
		
	
		
			
			| 
				214
			 | 
			
				281
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				215
			 | 
			
				
			 | 
			
			
				
				-	memset(p, 0, padding); 
			 | 
		
		
	
		
			
			| 
				216
			 | 
			
				
			 | 
			
			
				
				-	mctx->block[14] = mctx->byte_count << 3; 
			 | 
		
		
	
		
			
			| 
				217
			 | 
			
				
			 | 
			
			
				
				-	mctx->block[15] = mctx->byte_count >> 29; 
			 | 
		
		
	
		
			
			| 
				218
			 | 
			
				
			 | 
			
			
				
				-	le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - 
			 | 
		
		
	
		
			
			| 
				219
			 | 
			
				
			 | 
			
			
				
				-	                  sizeof(u64)) / sizeof(u32)); 
			 | 
		
		
	
		
			
			| 
				220
			 | 
			
				
			 | 
			
			
				
				-	md5_transform(mctx->hash, mctx->block); 
			 | 
		
		
	
		
			
			| 
				221
			 | 
			
				
			 | 
			
			
				
				-	cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); 
			 | 
		
		
	
		
			
			| 
				222
			 | 
			
				
			 | 
			
			
				
				-	memcpy(out, mctx->hash, sizeof(mctx->hash)); 
			 | 
		
		
	
		
			
			| 
				223
			 | 
			
				
			 | 
			
			
				
				-	memset(mctx, 0, sizeof(*mctx)); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				282
			 | 
			
			
				
				+	/* Copy out final digest */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				283
			 | 
			
			
				
				+	memcpy ( out, &context->ddd.dd.digest, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				284
			 | 
			
			
				
				+		 sizeof ( context->ddd.dd.digest ) ); 
			 | 
		
		
	
		
			
			| 
				224
			 | 
			
				285
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				225
			 | 
			
				286
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				287
			 | 
			
			
				
				+/** MD5 algorithm */ 
			 | 
		
		
	
		
			
			| 
				226
			 | 
			
				288
			 | 
			
			
				
				 struct digest_algorithm md5_algorithm = { 
			 | 
		
		
	
		
			
			| 
				227
			 | 
			
				289
			 | 
			
			
				
				 	.name		= "md5", 
			 | 
		
		
	
		
			
			| 
				228
			 | 
			
				
			 | 
			
			
				
				-	.ctxsize	= MD5_CTX_SIZE, 
			 | 
		
		
	
		
			
			| 
				229
			 | 
			
				
			 | 
			
			
				
				-	.blocksize	= ( MD5_BLOCK_WORDS * 4 ), 
			 | 
		
		
	
		
			
			| 
				230
			 | 
			
				
			 | 
			
			
				
				-	.digestsize	= MD5_DIGEST_SIZE, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				290
			 | 
			
			
				
				+	.ctxsize	= sizeof ( struct md5_context ), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				291
			 | 
			
			
				
				+	.blocksize	= sizeof ( union md5_block ), 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				292
			 | 
			
			
				
				+	.digestsize	= sizeof ( struct md5_digest ), 
			 | 
		
		
	
		
			
			| 
				231
			 | 
			
				293
			 | 
			
			
				
				 	.init		= md5_init, 
			 | 
		
		
	
		
			
			| 
				232
			 | 
			
				294
			 | 
			
			
				
				 	.update		= md5_update, 
			 | 
		
		
	
		
			
			| 
				233
			 | 
			
				295
			 | 
			
			
				
				 	.final		= md5_final, 
			 |