1 /*
2  * libtilemcore - Graphing calculator emulation library
3  *
4  * Copyright (C) 2009 Benjamin Moody
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 
25 #include <stdio.h>
26 #include "tilem.h"
27 
tilem_md5_assist_reset(TilemCalc * calc)28 void tilem_md5_assist_reset(TilemCalc* calc)
29 {
30 	int i;
31 
32 	for (i = 0; i < 6; i++)
33 		calc->md5assist.regs[i] = 0;
34 	calc->md5assist.shift = 0;
35 	calc->md5assist.mode = 0;
36 }
37 
tilem_md5_assist_get_value(TilemCalc * calc)38 dword tilem_md5_assist_get_value(TilemCalc* calc)
39 {
40 	/* Return the result of a complete MD5 operation:
41 	   b + ((a + f(b,c,d) + X + T) <<< s) */
42 	dword a, b, c, d, x, t, result;
43 	byte mode, s;
44 
45 	mode = calc->md5assist.mode;
46 	a = calc->md5assist.regs[TILEM_MD5_REG_A];
47 	b = calc->md5assist.regs[TILEM_MD5_REG_B];
48 	c = calc->md5assist.regs[TILEM_MD5_REG_C];
49 	d = calc->md5assist.regs[TILEM_MD5_REG_D];
50 	x = calc->md5assist.regs[TILEM_MD5_REG_X];
51 	t = calc->md5assist.regs[TILEM_MD5_REG_T];
52 	s = calc->md5assist.shift;
53 
54 	switch (mode) {
55 	case TILEM_MD5_FUNC_FF:
56 		/* F(X,Y,Z) = XY v not(X) Z */
57 		result = (b & c) | ((~b) & d);
58 		break;
59 
60 	case TILEM_MD5_FUNC_GG:
61 		/* G(X,Y,Z) = XZ v Y not(Z) */
62 		result = (b & d) | (c & (~d));
63 		break;
64 
65 	case TILEM_MD5_FUNC_HH:
66 		/* H(X,Y,Z) = X xor Y xor Z */
67 		result = b ^ c ^ d;
68 		break;
69 
70 	case TILEM_MD5_FUNC_II:
71 		/* I(X,Y,Z) = Y xor (X v not(Z)) */
72 		result = c ^ (b | (~d));
73 		break;
74 
75 	default:
76 		tilem_internal(calc, "Invalid MD5 mode %d", mode);
77 		return 0;
78 	}
79 
80 	result += a + x + t;
81 	result &= 0xffffffff;
82 	result = (result << s) | (result >> (32 - s));
83 	result += b;
84 
85 	return result;
86 }
87