1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/*- 11e1051a39Sopenharmony_ci * This is a generic 32 bit "collector" for message digest algorithms. 12e1051a39Sopenharmony_ci * Whenever needed it collects input character stream into chunks of 13e1051a39Sopenharmony_ci * 32 bit values and invokes a block function that performs actual hash 14e1051a39Sopenharmony_ci * calculations. 15e1051a39Sopenharmony_ci * 16e1051a39Sopenharmony_ci * Porting guide. 17e1051a39Sopenharmony_ci * 18e1051a39Sopenharmony_ci * Obligatory macros: 19e1051a39Sopenharmony_ci * 20e1051a39Sopenharmony_ci * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN 21e1051a39Sopenharmony_ci * this macro defines byte order of input stream. 22e1051a39Sopenharmony_ci * HASH_CBLOCK 23e1051a39Sopenharmony_ci * size of a unit chunk HASH_BLOCK operates on. 24e1051a39Sopenharmony_ci * HASH_LONG 25e1051a39Sopenharmony_ci * has to be at least 32 bit wide. 26e1051a39Sopenharmony_ci * HASH_CTX 27e1051a39Sopenharmony_ci * context structure that at least contains following 28e1051a39Sopenharmony_ci * members: 29e1051a39Sopenharmony_ci * typedef struct { 30e1051a39Sopenharmony_ci * ... 31e1051a39Sopenharmony_ci * HASH_LONG Nl,Nh; 32e1051a39Sopenharmony_ci * either { 33e1051a39Sopenharmony_ci * HASH_LONG data[HASH_LBLOCK]; 34e1051a39Sopenharmony_ci * unsigned char data[HASH_CBLOCK]; 35e1051a39Sopenharmony_ci * }; 36e1051a39Sopenharmony_ci * unsigned int num; 37e1051a39Sopenharmony_ci * ... 38e1051a39Sopenharmony_ci * } HASH_CTX; 39e1051a39Sopenharmony_ci * data[] vector is expected to be zeroed upon first call to 40e1051a39Sopenharmony_ci * HASH_UPDATE. 41e1051a39Sopenharmony_ci * HASH_UPDATE 42e1051a39Sopenharmony_ci * name of "Update" function, implemented here. 43e1051a39Sopenharmony_ci * HASH_TRANSFORM 44e1051a39Sopenharmony_ci * name of "Transform" function, implemented here. 45e1051a39Sopenharmony_ci * HASH_FINAL 46e1051a39Sopenharmony_ci * name of "Final" function, implemented here. 47e1051a39Sopenharmony_ci * HASH_BLOCK_DATA_ORDER 48e1051a39Sopenharmony_ci * name of "block" function capable of treating *unaligned* input 49e1051a39Sopenharmony_ci * message in original (data) byte order, implemented externally. 50e1051a39Sopenharmony_ci * HASH_MAKE_STRING 51e1051a39Sopenharmony_ci * macro converting context variables to an ASCII hash string. 52e1051a39Sopenharmony_ci * 53e1051a39Sopenharmony_ci * MD5 example: 54e1051a39Sopenharmony_ci * 55e1051a39Sopenharmony_ci * #define DATA_ORDER_IS_LITTLE_ENDIAN 56e1051a39Sopenharmony_ci * 57e1051a39Sopenharmony_ci * #define HASH_LONG MD5_LONG 58e1051a39Sopenharmony_ci * #define HASH_CTX MD5_CTX 59e1051a39Sopenharmony_ci * #define HASH_CBLOCK MD5_CBLOCK 60e1051a39Sopenharmony_ci * #define HASH_UPDATE MD5_Update 61e1051a39Sopenharmony_ci * #define HASH_TRANSFORM MD5_Transform 62e1051a39Sopenharmony_ci * #define HASH_FINAL MD5_Final 63e1051a39Sopenharmony_ci * #define HASH_BLOCK_DATA_ORDER md5_block_data_order 64e1051a39Sopenharmony_ci */ 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ci#include <openssl/crypto.h> 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) 69e1051a39Sopenharmony_ci# error "DATA_ORDER must be defined!" 70e1051a39Sopenharmony_ci#endif 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci#ifndef HASH_CBLOCK 73e1051a39Sopenharmony_ci# error "HASH_CBLOCK must be defined!" 74e1051a39Sopenharmony_ci#endif 75e1051a39Sopenharmony_ci#ifndef HASH_LONG 76e1051a39Sopenharmony_ci# error "HASH_LONG must be defined!" 77e1051a39Sopenharmony_ci#endif 78e1051a39Sopenharmony_ci#ifndef HASH_CTX 79e1051a39Sopenharmony_ci# error "HASH_CTX must be defined!" 80e1051a39Sopenharmony_ci#endif 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci#ifndef HASH_UPDATE 83e1051a39Sopenharmony_ci# error "HASH_UPDATE must be defined!" 84e1051a39Sopenharmony_ci#endif 85e1051a39Sopenharmony_ci#ifndef HASH_TRANSFORM 86e1051a39Sopenharmony_ci# error "HASH_TRANSFORM must be defined!" 87e1051a39Sopenharmony_ci#endif 88e1051a39Sopenharmony_ci#ifndef HASH_FINAL 89e1051a39Sopenharmony_ci# error "HASH_FINAL must be defined!" 90e1051a39Sopenharmony_ci#endif 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci#ifndef HASH_BLOCK_DATA_ORDER 93e1051a39Sopenharmony_ci# error "HASH_BLOCK_DATA_ORDER must be defined!" 94e1051a39Sopenharmony_ci#endif 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci#if defined(DATA_ORDER_IS_BIG_ENDIAN) 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ 101e1051a39Sopenharmony_ci l|=(((unsigned long)(*((c)++)))<<16), \ 102e1051a39Sopenharmony_ci l|=(((unsigned long)(*((c)++)))<< 8), \ 103e1051a39Sopenharmony_ci l|=(((unsigned long)(*((c)++))) ) ) 104e1051a39Sopenharmony_ci# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ 105e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>>16)&0xff), \ 106e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ 107e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l) )&0xff), \ 108e1051a39Sopenharmony_ci l) 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ci#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) 111e1051a39Sopenharmony_ci 112e1051a39Sopenharmony_ci# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ 113e1051a39Sopenharmony_ci l|=(((unsigned long)(*((c)++)))<< 8), \ 114e1051a39Sopenharmony_ci l|=(((unsigned long)(*((c)++)))<<16), \ 115e1051a39Sopenharmony_ci l|=(((unsigned long)(*((c)++)))<<24) ) 116e1051a39Sopenharmony_ci# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 117e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ 118e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>>16)&0xff), \ 119e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>>24)&0xff), \ 120e1051a39Sopenharmony_ci l) 121e1051a39Sopenharmony_ci 122e1051a39Sopenharmony_ci#endif 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ci/* 125e1051a39Sopenharmony_ci * Time for some action :-) 126e1051a39Sopenharmony_ci */ 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_ciint HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) 129e1051a39Sopenharmony_ci{ 130e1051a39Sopenharmony_ci const unsigned char *data = data_; 131e1051a39Sopenharmony_ci unsigned char *p; 132e1051a39Sopenharmony_ci HASH_LONG l; 133e1051a39Sopenharmony_ci size_t n; 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci if (len == 0) 136e1051a39Sopenharmony_ci return 1; 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL; 139e1051a39Sopenharmony_ci if (l < c->Nl) /* overflow */ 140e1051a39Sopenharmony_ci c->Nh++; 141e1051a39Sopenharmony_ci c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on 142e1051a39Sopenharmony_ci * 16-bit */ 143e1051a39Sopenharmony_ci c->Nl = l; 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci n = c->num; 146e1051a39Sopenharmony_ci if (n != 0) { 147e1051a39Sopenharmony_ci p = (unsigned char *)c->data; 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { 150e1051a39Sopenharmony_ci memcpy(p + n, data, HASH_CBLOCK - n); 151e1051a39Sopenharmony_ci HASH_BLOCK_DATA_ORDER(c, p, 1); 152e1051a39Sopenharmony_ci n = HASH_CBLOCK - n; 153e1051a39Sopenharmony_ci data += n; 154e1051a39Sopenharmony_ci len -= n; 155e1051a39Sopenharmony_ci c->num = 0; 156e1051a39Sopenharmony_ci /* 157e1051a39Sopenharmony_ci * We use memset rather than OPENSSL_cleanse() here deliberately. 158e1051a39Sopenharmony_ci * Using OPENSSL_cleanse() here could be a performance issue. It 159e1051a39Sopenharmony_ci * will get properly cleansed on finalisation so this isn't a 160e1051a39Sopenharmony_ci * security problem. 161e1051a39Sopenharmony_ci */ 162e1051a39Sopenharmony_ci memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ 163e1051a39Sopenharmony_ci } else { 164e1051a39Sopenharmony_ci memcpy(p + n, data, len); 165e1051a39Sopenharmony_ci c->num += (unsigned int)len; 166e1051a39Sopenharmony_ci return 1; 167e1051a39Sopenharmony_ci } 168e1051a39Sopenharmony_ci } 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ci n = len / HASH_CBLOCK; 171e1051a39Sopenharmony_ci if (n > 0) { 172e1051a39Sopenharmony_ci HASH_BLOCK_DATA_ORDER(c, data, n); 173e1051a39Sopenharmony_ci n *= HASH_CBLOCK; 174e1051a39Sopenharmony_ci data += n; 175e1051a39Sopenharmony_ci len -= n; 176e1051a39Sopenharmony_ci } 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_ci if (len != 0) { 179e1051a39Sopenharmony_ci p = (unsigned char *)c->data; 180e1051a39Sopenharmony_ci c->num = (unsigned int)len; 181e1051a39Sopenharmony_ci memcpy(p, data, len); 182e1051a39Sopenharmony_ci } 183e1051a39Sopenharmony_ci return 1; 184e1051a39Sopenharmony_ci} 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_civoid HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data) 187e1051a39Sopenharmony_ci{ 188e1051a39Sopenharmony_ci HASH_BLOCK_DATA_ORDER(c, data, 1); 189e1051a39Sopenharmony_ci} 190e1051a39Sopenharmony_ci 191e1051a39Sopenharmony_ciint HASH_FINAL(unsigned char *md, HASH_CTX *c) 192e1051a39Sopenharmony_ci{ 193e1051a39Sopenharmony_ci unsigned char *p = (unsigned char *)c->data; 194e1051a39Sopenharmony_ci size_t n = c->num; 195e1051a39Sopenharmony_ci 196e1051a39Sopenharmony_ci p[n] = 0x80; /* there is always room for one */ 197e1051a39Sopenharmony_ci n++; 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci if (n > (HASH_CBLOCK - 8)) { 200e1051a39Sopenharmony_ci memset(p + n, 0, HASH_CBLOCK - n); 201e1051a39Sopenharmony_ci n = 0; 202e1051a39Sopenharmony_ci HASH_BLOCK_DATA_ORDER(c, p, 1); 203e1051a39Sopenharmony_ci } 204e1051a39Sopenharmony_ci memset(p + n, 0, HASH_CBLOCK - 8 - n); 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci p += HASH_CBLOCK - 8; 207e1051a39Sopenharmony_ci#if defined(DATA_ORDER_IS_BIG_ENDIAN) 208e1051a39Sopenharmony_ci (void)HOST_l2c(c->Nh, p); 209e1051a39Sopenharmony_ci (void)HOST_l2c(c->Nl, p); 210e1051a39Sopenharmony_ci#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) 211e1051a39Sopenharmony_ci (void)HOST_l2c(c->Nl, p); 212e1051a39Sopenharmony_ci (void)HOST_l2c(c->Nh, p); 213e1051a39Sopenharmony_ci#endif 214e1051a39Sopenharmony_ci p -= HASH_CBLOCK; 215e1051a39Sopenharmony_ci HASH_BLOCK_DATA_ORDER(c, p, 1); 216e1051a39Sopenharmony_ci c->num = 0; 217e1051a39Sopenharmony_ci OPENSSL_cleanse(p, HASH_CBLOCK); 218e1051a39Sopenharmony_ci 219e1051a39Sopenharmony_ci#ifndef HASH_MAKE_STRING 220e1051a39Sopenharmony_ci# error "HASH_MAKE_STRING must be defined!" 221e1051a39Sopenharmony_ci#else 222e1051a39Sopenharmony_ci HASH_MAKE_STRING(c, md); 223e1051a39Sopenharmony_ci#endif 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci return 1; 226e1051a39Sopenharmony_ci} 227e1051a39Sopenharmony_ci 228e1051a39Sopenharmony_ci#ifndef MD32_REG_T 229e1051a39Sopenharmony_ci# if defined(__alpha) || defined(__sparcv9) || defined(__mips) 230e1051a39Sopenharmony_ci# define MD32_REG_T long 231e1051a39Sopenharmony_ci/* 232e1051a39Sopenharmony_ci * This comment was originally written for MD5, which is why it 233e1051a39Sopenharmony_ci * discusses A-D. But it basically applies to all 32-bit digests, 234e1051a39Sopenharmony_ci * which is why it was moved to common header file. 235e1051a39Sopenharmony_ci * 236e1051a39Sopenharmony_ci * In case you wonder why A-D are declared as long and not 237e1051a39Sopenharmony_ci * as MD5_LONG. Doing so results in slight performance 238e1051a39Sopenharmony_ci * boost on LP64 architectures. The catch is we don't 239e1051a39Sopenharmony_ci * really care if 32 MSBs of a 64-bit register get polluted 240e1051a39Sopenharmony_ci * with eventual overflows as we *save* only 32 LSBs in 241e1051a39Sopenharmony_ci * *either* case. Now declaring 'em long excuses the compiler 242e1051a39Sopenharmony_ci * from keeping 32 MSBs zeroed resulting in 13% performance 243e1051a39Sopenharmony_ci * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. 244e1051a39Sopenharmony_ci * Well, to be honest it should say that this *prevents* 245e1051a39Sopenharmony_ci * performance degradation. 246e1051a39Sopenharmony_ci */ 247e1051a39Sopenharmony_ci# else 248e1051a39Sopenharmony_ci/* 249e1051a39Sopenharmony_ci * Above is not absolute and there are LP64 compilers that 250e1051a39Sopenharmony_ci * generate better code if MD32_REG_T is defined int. The above 251e1051a39Sopenharmony_ci * pre-processor condition reflects the circumstances under which 252e1051a39Sopenharmony_ci * the conclusion was made and is subject to further extension. 253e1051a39Sopenharmony_ci */ 254e1051a39Sopenharmony_ci# define MD32_REG_T int 255e1051a39Sopenharmony_ci# endif 256e1051a39Sopenharmony_ci#endif 257