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