1/* ==================================================================== 2 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * 3. All advertising materials mentioning features or use of this 17 * software must display the following acknowledgment: 18 * "This product includes software developed by the OpenSSL Project 19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 20 * 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For written permission, please contact 24 * licensing@OpenSSL.org. 25 * 26 * 5. Products derived from this software may not be called "OpenSSL" 27 * nor may "OpenSSL" appear in their names without prior written 28 * permission of the OpenSSL Project. 29 * 30 * 6. Redistributions of any form whatsoever must retain the following 31 * acknowledgment: 32 * "This product includes software developed by the OpenSSL Project 33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46 * OF THE POSSIBILITY OF SUCH DAMAGE. 47 * ==================================================================== */ 48 49#include <openssl/base.h> 50 51#include <assert.h> 52 53#include "../../internal.h" 54 55#if defined(__cplusplus) 56extern "C" { 57#endif 58 59 60// This is a generic 32-bit "collector" for message digest algorithms. It 61// collects input character stream into chunks of 32-bit values and invokes the 62// block function that performs the actual hash calculations. To make use of 63// this mechanism, the following macros must be defined before including 64// md32_common.h. 65// 66// One of |DATA_ORDER_IS_BIG_ENDIAN| or |DATA_ORDER_IS_LITTLE_ENDIAN| must be 67// defined to specify the byte order of the input stream. 68// 69// |HASH_CBLOCK| must be defined as the integer block size, in bytes. 70// 71// |HASH_CTX| must be defined as the name of the context structure, which must 72// have at least the following members: 73// 74// typedef struct <name>_state_st { 75// uint32_t h[<chaining length> / sizeof(uint32_t)]; 76// uint32_t Nl, Nh; 77// uint8_t data[HASH_CBLOCK]; 78// unsigned num; 79// ... 80// } <NAME>_CTX; 81// 82// <chaining length> is the output length of the hash in bytes, before 83// any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and 84// SHA-512). 85// 86// |HASH_UPDATE| must be defined as the name of the "Update" function to 87// generate. 88// 89// |HASH_TRANSFORM| must be defined as the the name of the "Transform" 90// function to generate. 91// 92// |HASH_FINAL| must be defined as the name of "Final" function to generate. 93// 94// |HASH_BLOCK_DATA_ORDER| must be defined as the name of the "Block" function. 95// That function must be implemented manually. It must be capable of operating 96// on *unaligned* input data in its original (data) byte order. It must have 97// this signature: 98// 99// void HASH_BLOCK_DATA_ORDER(uint32_t *state, const uint8_t *data, 100// size_t num); 101// 102// It must update the hash state |state| with |num| blocks of data from |data|, 103// where each block is |HASH_CBLOCK| bytes; i.e. |data| points to a array of 104// |HASH_CBLOCK * num| bytes. |state| points to the |h| member of a |HASH_CTX|, 105// and so will have |<chaining length> / sizeof(uint32_t)| elements. 106// 107// |HASH_MAKE_STRING(c, s)| must be defined as a block statement that converts 108// the hash state |c->h| into the output byte order, storing the result in |s|. 109 110#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) 111#error "DATA_ORDER must be defined!" 112#endif 113 114#ifndef HASH_CBLOCK 115#error "HASH_CBLOCK must be defined!" 116#endif 117#ifndef HASH_CTX 118#error "HASH_CTX must be defined!" 119#endif 120 121#ifndef HASH_UPDATE 122#error "HASH_UPDATE must be defined!" 123#endif 124#ifndef HASH_TRANSFORM 125#error "HASH_TRANSFORM must be defined!" 126#endif 127#ifndef HASH_FINAL 128#error "HASH_FINAL must be defined!" 129#endif 130 131#ifndef HASH_BLOCK_DATA_ORDER 132#error "HASH_BLOCK_DATA_ORDER must be defined!" 133#endif 134 135#ifndef HASH_MAKE_STRING 136#error "HASH_MAKE_STRING must be defined!" 137#endif 138 139#if defined(DATA_ORDER_IS_BIG_ENDIAN) 140 141#define HOST_c2l(c, l) \ 142 do { \ 143 (l) = (((uint32_t)(*((c)++))) << 24); \ 144 (l) |= (((uint32_t)(*((c)++))) << 16); \ 145 (l) |= (((uint32_t)(*((c)++))) << 8); \ 146 (l) |= (((uint32_t)(*((c)++)))); \ 147 } while (0) 148 149#define HOST_l2c(l, c) \ 150 do { \ 151 *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ 152 *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ 153 *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ 154 *((c)++) = (uint8_t)(((l)) & 0xff); \ 155 } while (0) 156 157#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) 158 159#define HOST_c2l(c, l) \ 160 do { \ 161 (l) = (((uint32_t)(*((c)++)))); \ 162 (l) |= (((uint32_t)(*((c)++))) << 8); \ 163 (l) |= (((uint32_t)(*((c)++))) << 16); \ 164 (l) |= (((uint32_t)(*((c)++))) << 24); \ 165 } while (0) 166 167#define HOST_l2c(l, c) \ 168 do { \ 169 *((c)++) = (uint8_t)(((l)) & 0xff); \ 170 *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ 171 *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ 172 *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ 173 } while (0) 174 175#endif // DATA_ORDER 176 177int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) { 178 const uint8_t *data = data_; 179 180 if (len == 0) { 181 return 1; 182 } 183 184 uint32_t l = c->Nl + (((uint32_t)len) << 3); 185 if (l < c->Nl) { 186 // Handle carries. 187 c->Nh++; 188 } 189 c->Nh += (uint32_t)(len >> 29); 190 c->Nl = l; 191 192 size_t n = c->num; 193 if (n != 0) { 194 if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { 195 OPENSSL_memcpy(c->data + n, data, HASH_CBLOCK - n); 196 HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); 197 n = HASH_CBLOCK - n; 198 data += n; 199 len -= n; 200 c->num = 0; 201 // Keep |c->data| zeroed when unused. 202 OPENSSL_memset(c->data, 0, HASH_CBLOCK); 203 } else { 204 OPENSSL_memcpy(c->data + n, data, len); 205 c->num += (unsigned)len; 206 return 1; 207 } 208 } 209 210 n = len / HASH_CBLOCK; 211 if (n > 0) { 212 HASH_BLOCK_DATA_ORDER(c->h, data, n); 213 n *= HASH_CBLOCK; 214 data += n; 215 len -= n; 216 } 217 218 if (len != 0) { 219 c->num = (unsigned)len; 220 OPENSSL_memcpy(c->data, data, len); 221 } 222 return 1; 223} 224 225 226void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) { 227 HASH_BLOCK_DATA_ORDER(c->h, data, 1); 228} 229 230 231int HASH_FINAL(uint8_t *md, HASH_CTX *c) { 232 // |c->data| always has room for at least one byte. A full block would have 233 // been consumed. 234 size_t n = c->num; 235 assert(n < HASH_CBLOCK); 236 c->data[n] = 0x80; 237 n++; 238 239 // Fill the block with zeros if there isn't room for a 64-bit length. 240 if (n > (HASH_CBLOCK - 8)) { 241 OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - n); 242 n = 0; 243 HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); 244 } 245 OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - 8 - n); 246 247 // Append a 64-bit length to the block and process it. 248 uint8_t *p = c->data + HASH_CBLOCK - 8; 249#if defined(DATA_ORDER_IS_BIG_ENDIAN) 250 HOST_l2c(c->Nh, p); 251 HOST_l2c(c->Nl, p); 252#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) 253 HOST_l2c(c->Nl, p); 254 HOST_l2c(c->Nh, p); 255#endif 256 assert(p == c->data + HASH_CBLOCK); 257 HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); 258 c->num = 0; 259 OPENSSL_memset(c->data, 0, HASH_CBLOCK); 260 261 HASH_MAKE_STRING(c, md); 262 return 1; 263} 264 265 266#if defined(__cplusplus) 267} // extern C 268#endif 269