Imported Upstream version 2.4
[platform/upstream/nettle.git] / md4.c
1 /* md4.h
2  *
3  * The MD4 hash function, described in RFC 1320.
4  */
5
6 /* nettle, low-level cryptographics library
7  *
8  * Copyright (C) 2003 Niels Möller, Marcus Comstedt
9  *  
10  * The nettle library is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or (at your
13  * option) any later version.
14  * 
15  * The nettle library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18  * License for more details.
19  * 
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with the nettle library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23  * MA 02111-1307, USA.
24  */
25
26 /* Based on the public domain md5 code, and modified by Marcus
27    Comstedt */
28
29 #if HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <assert.h>
34 #include <string.h>
35
36 #include "md4.h"
37
38 #include "macros.h"
39 #include "nettle-write.h"
40
41 /* A block, treated as a sequence of 32-bit words. */
42 #define MD4_DATA_LENGTH 16
43
44 static void
45 md4_transform(uint32_t *digest, const uint32_t *data);
46
47 static void
48 md4_compress(struct md4_ctx *ctx, const uint8_t *block);
49
50 /* FIXME: Could be an alias for md5_init */
51 void
52 md4_init(struct md4_ctx *ctx)
53 {
54   /* Same constants as for md5. */
55   const uint32_t iv[_MD4_DIGEST_LENGTH] =
56     {
57       0x67452301,
58       0xefcdab89,
59       0x98badcfe,
60       0x10325476,
61     };
62   memcpy(ctx->state, iv, sizeof(ctx->state));
63   
64   ctx->count_low = ctx->count_high = 0;
65   ctx->index = 0;
66 }
67
68 void
69 md4_update(struct md4_ctx *ctx,
70            unsigned length,
71            const uint8_t *data)
72 {
73   MD_UPDATE(ctx, length, data, md4_compress, MD_INCR(ctx));
74 }
75
76 void
77 md4_digest(struct md4_ctx *ctx,
78            unsigned length,
79            uint8_t *digest)
80 {
81   uint32_t data[MD4_DATA_LENGTH];
82   unsigned i;
83
84   assert(length <= MD4_DIGEST_SIZE);
85
86   MD_PAD(ctx, 8, md4_compress);
87   for (i = 0; i < MD4_DATA_LENGTH - 2; i++)
88     data[i] = LE_READ_UINT32(ctx->block + 4*i);
89
90   /* There are 512 = 2^9 bits in one block 
91    * Little-endian order => Least significant word first */
92
93   data[MD4_DATA_LENGTH-1] = (ctx->count_high << 9) | (ctx->count_low >> 23);
94   data[MD4_DATA_LENGTH-2] = (ctx->count_low << 9) | (ctx->index << 3);
95   md4_transform(ctx->state, data);
96
97   _nettle_write_le32(length, digest, ctx->state);
98   md4_init(ctx);
99 }
100
101 /* MD4 functions */
102 #define F(x, y, z) (((y) & (x)) | ((z) & ~(x)))
103 #define G(x, y, z) (((y) & (x)) | ((z) & (x)) | ((y) & (z)))
104 #define H(x, y, z) ((x) ^ (y) ^ (z))
105
106 #define ROUND(f, w, x, y, z, data, s) \
107 ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
108
109 /* Perform the MD4 transformation on one full block of 16 32-bit words. */
110    
111 static void
112 md4_transform(uint32_t *digest, const uint32_t *data)
113 {
114   uint32_t a, b, c, d;
115   a = digest[0];
116   b = digest[1];
117   c = digest[2];
118   d = digest[3];
119
120   ROUND(F, a, b, c, d, data[ 0], 3);
121   ROUND(F, d, a, b, c, data[ 1], 7);
122   ROUND(F, c, d, a, b, data[ 2], 11);
123   ROUND(F, b, c, d, a, data[ 3], 19);
124   ROUND(F, a, b, c, d, data[ 4], 3);
125   ROUND(F, d, a, b, c, data[ 5], 7);
126   ROUND(F, c, d, a, b, data[ 6], 11);
127   ROUND(F, b, c, d, a, data[ 7], 19);
128   ROUND(F, a, b, c, d, data[ 8], 3);
129   ROUND(F, d, a, b, c, data[ 9], 7);
130   ROUND(F, c, d, a, b, data[10], 11);
131   ROUND(F, b, c, d, a, data[11], 19);
132   ROUND(F, a, b, c, d, data[12], 3);
133   ROUND(F, d, a, b, c, data[13], 7);
134   ROUND(F, c, d, a, b, data[14], 11);
135   ROUND(F, b, c, d, a, data[15], 19);
136
137   ROUND(G, a, b, c, d, data[ 0] + 0x5a827999, 3);
138   ROUND(G, d, a, b, c, data[ 4] + 0x5a827999, 5);
139   ROUND(G, c, d, a, b, data[ 8] + 0x5a827999, 9);
140   ROUND(G, b, c, d, a, data[12] + 0x5a827999, 13);
141   ROUND(G, a, b, c, d, data[ 1] + 0x5a827999, 3);
142   ROUND(G, d, a, b, c, data[ 5] + 0x5a827999, 5);
143   ROUND(G, c, d, a, b, data[ 9] + 0x5a827999, 9);
144   ROUND(G, b, c, d, a, data[13] + 0x5a827999, 13);
145   ROUND(G, a, b, c, d, data[ 2] + 0x5a827999, 3);
146   ROUND(G, d, a, b, c, data[ 6] + 0x5a827999, 5);
147   ROUND(G, c, d, a, b, data[10] + 0x5a827999, 9);
148   ROUND(G, b, c, d, a, data[14] + 0x5a827999, 13);
149   ROUND(G, a, b, c, d, data[ 3] + 0x5a827999, 3);
150   ROUND(G, d, a, b, c, data[ 7] + 0x5a827999, 5);
151   ROUND(G, c, d, a, b, data[11] + 0x5a827999, 9);
152   ROUND(G, b, c, d, a, data[15] + 0x5a827999, 13);
153
154   ROUND(H, a, b, c, d, data[ 0] + 0x6ed9eba1, 3);
155   ROUND(H, d, a, b, c, data[ 8] + 0x6ed9eba1, 9);
156   ROUND(H, c, d, a, b, data[ 4] + 0x6ed9eba1, 11);
157   ROUND(H, b, c, d, a, data[12] + 0x6ed9eba1, 15);
158   ROUND(H, a, b, c, d, data[ 2] + 0x6ed9eba1, 3);
159   ROUND(H, d, a, b, c, data[10] + 0x6ed9eba1, 9);
160   ROUND(H, c, d, a, b, data[ 6] + 0x6ed9eba1, 11);
161   ROUND(H, b, c, d, a, data[14] + 0x6ed9eba1, 15);
162   ROUND(H, a, b, c, d, data[ 1] + 0x6ed9eba1, 3);
163   ROUND(H, d, a, b, c, data[ 9] + 0x6ed9eba1, 9);
164   ROUND(H, c, d, a, b, data[ 5] + 0x6ed9eba1, 11);
165   ROUND(H, b, c, d, a, data[13] + 0x6ed9eba1, 15);
166   ROUND(H, a, b, c, d, data[ 3] + 0x6ed9eba1, 3);
167   ROUND(H, d, a, b, c, data[11] + 0x6ed9eba1, 9);
168   ROUND(H, c, d, a, b, data[ 7] + 0x6ed9eba1, 11);
169   ROUND(H, b, c, d, a, data[15] + 0x6ed9eba1, 15);
170
171   digest[0] += a;
172   digest[1] += b;
173   digest[2] += c;
174   digest[3] += d;
175 }
176
177 static void
178 md4_compress(struct md4_ctx *ctx, const uint8_t *block)
179 {
180   uint32_t data[MD4_DATA_LENGTH];
181   unsigned i;
182   
183   /* Endian independent conversion */
184   for (i = 0; i<16; i++, block += 4)
185     data[i] = LE_READ_UINT32(block);
186
187   md4_transform(ctx->state, data);
188 }