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