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