1 /*-
2  * Copyright (c) 2006, 2007
3  *	Thorsten Glaser <tg@mirbsd.de>
4  *
5  * Provided that these terms and disclaimer and all copyright notices
6  * are retained or reproduced in an accompanying document, permission
7  * is granted to deal in this work without restriction, including un-
8  * limited rights to use, publicly perform, distribute, sell, modify,
9  * merge, give away, or sublicence.
10  *
11  * Advertising materials mentioning features or use of this work must
12  * display the following acknowledgement:
13  *	This product includes material provided by Thorsten Glaser.
14  *
15  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
16  * the utmost extent permitted by applicable law, neither express nor
17  * implied; without malicious intent or gross negligence. In no event
18  * may a licensor, author or contributor be held liable for indirect,
19  * direct, other damage, loss, or other issues arising in any way out
20  * of dealing in the work, even if advised of the possibility of such
21  * damage or existence of a defect, except proven that it results out
22  * of said person's immediate fault when using the work as intended.
23  */
24 
25 #include <sys/types.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <suma.h>
29 
30 __RCSID("$MirOS: src/lib/libc/hash/suma.c,v 1.3 2007/08/19 12:03:13 tg Exp $");
31 
32 void
SUMAInit(SUMA_CTX * ctx)33 SUMAInit(SUMA_CTX *ctx)
34 {
35 	if (ctx != NULL)
36 		*ctx = 0xFFFFFFFF;
37 }
38 
39 void
SUMAUpdate(SUMA_CTX * ctx,const uint8_t * data,size_t len)40 SUMAUpdate(SUMA_CTX *ctx, const uint8_t *data, size_t len)
41 {
42 	size_t cnt;
43 	uint32_t crc, eax, cf, i;
44 
45 	if ((len == 0) || (ctx == NULL) || (data == NULL))
46 		return;
47 
48 	crc = *ctx;
49 	cnt = len >> 2;
50 	while (cnt--) {
51 		eax = (*(data + 3) << 24) |
52 		    (*(data + 2) << 16) |
53 		    (*(data + 1) << 8) | *data;
54 		data += 4;
55 		for (i = 32; i; --i) {
56 			cf = crc & 0x80000000;
57 			crc <<= 1;
58 			if (eax & 0x80000000)
59 				++crc;
60 			eax <<= 1;
61 			if (cf)
62 				crc ^= 0x04563521;
63 		}
64 	}
65 	cnt = len & 3;
66 	if (cnt--) {
67 		eax = *data++;
68 		if (cnt--)
69 			eax |= (*data++) << 8;
70 		if (cnt--)
71 			eax |= (*data++) << 16;
72 		for (i = 32; i; --i) {
73 			cf = !!(crc & 0x80000000);
74 			crc <<= 1;
75 			if (eax & 0x80000000)
76 				++crc;
77 			eax <<= 1;
78 			if (cf)
79 				crc ^= 0x04563521;
80 		}
81 	}
82 	*ctx = crc;
83 }
84 
85 void
SUMAPad(SUMA_CTX * ctx)86 SUMAPad(SUMA_CTX *ctx)
87 {
88 	uint32_t crc, i, cf;
89 
90 	if (ctx == NULL)
91 		return;
92 
93 	crc = *ctx;
94 	for (i = 32; i; --i) {
95 		cf = crc & 0x80000000;
96 		crc <<= 1;
97 		if (cf)
98 			crc ^= 0x04563521;
99 	}
100 	*ctx = crc;
101 }
102 
103 void
SUMAFinal(uint8_t * dst,SUMA_CTX * ctx)104 SUMAFinal(uint8_t *dst, SUMA_CTX *ctx)
105 {
106 	uint32_t tmp;
107 
108 	if (dst) {
109 		SUMAPad(ctx);
110 		tmp = htobe32(*ctx);
111 		memcpy(dst, &tmp, 4);
112 	}
113 	*ctx = 0;
114 }
115