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