1 /*
2 * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 *
9 * $FreeBSD$
10 */
11
12 /*
13 * Derived from include/crypto/md32_common.h
14 *
15 * HASH_UPDATE and HASH_FINAL have been updated to work with the
16 * auth_hash interface.
17 */
18
19 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
20
21 # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
22 l|=(((unsigned long)(*((c)++)))<<16), \
23 l|=(((unsigned long)(*((c)++)))<< 8), \
24 l|=(((unsigned long)(*((c)++))) ) )
25 # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
26 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
27 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
28 *((c)++)=(unsigned char)(((l) )&0xff), \
29 l)
30
31 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
32
33 # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
34 l|=(((unsigned long)(*((c)++)))<< 8), \
35 l|=(((unsigned long)(*((c)++)))<<16), \
36 l|=(((unsigned long)(*((c)++)))<<24) )
37 # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
38 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
39 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
40 *((c)++)=(unsigned char)(((l)>>24)&0xff), \
41 l)
42
43 #endif
44
45 /*
46 * Time for some action :-)
47 */
48
49 static int
50 HASH_UPDATE(void *c_, const void *data_, unsigned int len)
51 {
52 HASH_CTX *c = c_;
53 const unsigned char *data = data_;
54 unsigned char *p;
55 HASH_LONG l;
56 size_t n;
57
58 if (len == 0)
59 return 0;
60
61 l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
62 if (l < c->Nl) /* overflow */
63 c->Nh++;
64 c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
65 * 16-bit */
66 c->Nl = l;
67
68 n = c->num;
69 if (n != 0) {
70 p = (unsigned char *)c->data;
71
72 if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
73 memcpy(p + n, data, HASH_CBLOCK - n);
74 HASH_BLOCK_DATA_ORDER(c, p, 1);
75 n = HASH_CBLOCK - n;
76 data += n;
77 len -= n;
78 c->num = 0;
79 /*
80 * We use memset rather than OPENSSL_cleanse() here deliberately.
81 * Using OPENSSL_cleanse() here could be a performance issue. It
82 * will get properly cleansed on finalisation so this isn't a
83 * security problem.
84 */
85 memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
86 } else {
87 memcpy(p + n, data, len);
88 c->num += (unsigned int)len;
89 return 0;
90 }
91 }
92
93 n = len / HASH_CBLOCK;
94 if (n > 0) {
95 HASH_BLOCK_DATA_ORDER(c, data, n);
96 n *= HASH_CBLOCK;
97 data += n;
98 len -= n;
99 }
100
101 if (len != 0) {
102 p = (unsigned char *)c->data;
103 c->num = (unsigned int)len;
104 memcpy(p, data, len);
105 }
106 return 0;
107 }
108
109 static void
110 HASH_FINAL(uint8_t *md, void *c_)
111 {
112 HASH_CTX *c = c_;
113 unsigned char *p = (unsigned char *)c->data;
114 size_t n = c->num;
115
116 p[n] = 0x80; /* there is always room for one */
117 n++;
118
119 if (n > (HASH_CBLOCK - 8)) {
120 memset(p + n, 0, HASH_CBLOCK - n);
121 n = 0;
122 HASH_BLOCK_DATA_ORDER(c, p, 1);
123 }
124 memset(p + n, 0, HASH_CBLOCK - 8 - n);
125
126 p += HASH_CBLOCK - 8;
127 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
128 (void)HOST_l2c(c->Nh, p);
129 (void)HOST_l2c(c->Nl, p);
130 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
131 (void)HOST_l2c(c->Nl, p);
132 (void)HOST_l2c(c->Nh, p);
133 #endif
134 p -= HASH_CBLOCK;
135 HASH_BLOCK_DATA_ORDER(c, p, 1);
136 c->num = 0;
137 OPENSSL_cleanse(p, HASH_CBLOCK);
138
139 #ifndef HASH_MAKE_STRING
140 # error "HASH_MAKE_STRING must be defined!"
141 #else
142 HASH_MAKE_STRING(c, md);
143 #endif
144
145 return;
146 }
Cache object: 93150cf5e021d55a6cd9c58fae6ef910
|