Update bundled openssl, sha and base64 libs

This commit is contained in:
MoNTE48 2020-06-05 22:53:40 +02:00
parent da5ce7d07a
commit 7059d450f2
7 changed files with 169 additions and 338 deletions

View File

@ -39,12 +39,13 @@ static inline bool is_base64(unsigned char c) {
bool base64_is_valid(std::string const& s) bool base64_is_valid(std::string const& s)
{ {
for(size_t i=0; i<s.size(); i++) for (char i : s)
if(!is_base64(s[i])) return false; if (!is_base64(i))
return false;
return true; return true;
} }
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { std::string base64_encode(unsigned char const *bytes_to_encode, unsigned int in_len) {
std::string ret; std::string ret;
int i = 0; int i = 0;
unsigned char char_array_3[3]; unsigned char char_array_3[3];
@ -58,16 +59,15 @@ std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f; char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++) for (i = 0; (i < 4) ; i++)
ret += base64_chars[char_array_4[i]]; ret += base64_chars[char_array_4[i]];
i = 0; i = 0;
} }
} }
if (i) if (i) {
{
int j; int j;
for(j = i; j < 3; j++) for (j = i; j < 3; j++)
char_array_3[j] = '\0'; char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
@ -80,24 +80,22 @@ std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_
// Don't pad it with = // Don't pad it with =
/*while((i++ < 3)) /*while((i++ < 3))
ret += '=';*/ ret += '=';*/
} }
return ret; return ret;
} }
std::string base64_decode(std::string const& encoded_string) { std::string base64_decode(std::string const &encoded_string) {
size_t in_len = encoded_string.size(); size_t in_len = encoded_string.size();
int i = 0; int i = 0;
int in_ = 0; int in_ = 0;
unsigned char char_array_4[4], char_array_3[3]; unsigned char char_array_4[4], char_array_3[3];
std::string ret; std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++; char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) { if (i ==4) {
for (i = 0; i <4; i++) for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]) & 0xff; char_array_4[i] = base64_chars.find(char_array_4[i]) & 0xff;
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);

View File

@ -1,10 +1,34 @@
#ifndef BASE64_HEADER /*
#define BASE64_HEADER base64.cpp and base64.h
Copyright (C) 2004-2017 René Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
#pragma once
#include <string> #include <string>
bool base64_is_valid(std::string const& s); bool base64_is_valid(std::string const &s);
std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_encode(unsigned char const *, unsigned int len);
std::string base64_decode(std::string const& s); std::string base64_decode(std::string const &s);
#endif // BASE64_HEADER

View File

@ -1,52 +1,10 @@
/* md32_common.h file used by sha256 implementation */ /*
/* ==================================================================== * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
* *
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/ */
/*- /*-
@ -64,8 +22,7 @@
* HASH_CBLOCK * HASH_CBLOCK
* size of a unit chunk HASH_BLOCK operates on. * size of a unit chunk HASH_BLOCK operates on.
* HASH_LONG * HASH_LONG
* has to be at lest 32 bit wide, if it's wider, then * has to be at least 32 bit wide.
* HASH_LONG_LOG2 *has to* be defined along
* HASH_CTX * HASH_CTX
* context structure that at least contains following * context structure that at least contains following
* members: * members:
@ -91,22 +48,19 @@
* name of "block" function capable of treating *unaligned* input * name of "block" function capable of treating *unaligned* input
* message in original (data) byte order, implemented externally. * message in original (data) byte order, implemented externally.
* HASH_MAKE_STRING * HASH_MAKE_STRING
* macro convering context variables to an ASCII hash string. * macro converting context variables to an ASCII hash string.
* *
* MD5 example: * MD5 example:
* *
* #define DATA_ORDER_IS_LITTLE_ENDIAN * #define DATA_ORDER_IS_LITTLE_ENDIAN
* *
* #define HASH_LONG MD5_LONG * #define HASH_LONG MD5_LONG
* #define HASH_LONG_LOG2 MD5_LONG_LOG2
* #define HASH_CTX MD5_CTX * #define HASH_CTX MD5_CTX
* #define HASH_CBLOCK MD5_CBLOCK * #define HASH_CBLOCK MD5_CBLOCK
* #define HASH_UPDATE MD5_Update * #define HASH_UPDATE MD5_Update
* #define HASH_TRANSFORM MD5_Transform * #define HASH_TRANSFORM MD5_Transform
* #define HASH_FINAL MD5_Final * #define HASH_FINAL MD5_Final
* #define HASH_BLOCK_DATA_ORDER md5_block_data_order * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
*
* <appro@fy.chalmers.se>
*/ */
#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
@ -137,164 +91,36 @@
# error "HASH_BLOCK_DATA_ORDER must be defined!" # error "HASH_BLOCK_DATA_ORDER must be defined!"
#endif #endif
/* #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
* Engage compiler specific rotate intrinsic function if available.
*/
#undef ROTATE
#ifndef PEDANTIC
# if defined(_MSC_VER)
# define ROTATE(a,n) _lrotl(a,n)
# elif defined(__ICC)
# define ROTATE(a,n) _rotl(a,n)
# elif defined(__MWERKS__)
# if defined(__POWERPC__)
# define ROTATE(a,n) __rlwinm(a,n,0,31)
# elif defined(__MC68K__)
/* Motorola specific tweak. <appro@fy.chalmers.se> */
# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
# else
# define ROTATE(a,n) __rol(a,n)
# endif
# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
/*
* Some GNU C inline assembler templates. Note that these are
* rotates by *constant* number of bits! But that's exactly
* what we need here...
* <appro@fy.chalmers.se>
*/
# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
# define ROTATE(a,n) ({ register unsigned int ret; \
asm ( \
"roll %1,%0" \
: "=r"(ret) \
: "I"(n), "0"((unsigned int)(a)) \
: "cc"); \
ret; \
})
# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
# define ROTATE(a,n) ({ register unsigned int ret; \
asm ( \
"rlwinm %0,%1,%2,0,31" \
: "=r"(ret) \
: "r"(a), "I"(n)); \
ret; \
})
# elif defined(__s390x__)
# define ROTATE(a,n) ({ register unsigned int ret; \
asm ("rll %0,%1,%2" \
: "=r"(ret) \
: "r"(a), "I"(n)); \
ret; \
})
# endif
# endif
#endif /* PEDANTIC */
#ifndef ROTATE
# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#endif
#if defined(DATA_ORDER_IS_BIG_ENDIAN) #if defined(DATA_ORDER_IS_BIG_ENDIAN)
# ifndef PEDANTIC
# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
(defined(__x86_64) || defined(__x86_64__))
# if !defined(B_ENDIAN)
/*
* This gives ~30-40% performance improvement in SHA-256 compiled
* with gcc [on P4]. Well, first macro to be frank. We can pull
* this trick on x86* platforms only, because these CPUs can fetch
* unaligned data without raising an exception.
*/
# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \
asm ("bswapl %0":"=r"(r):"0"(r)); \
(c)+=4; (l)=r; })
# define HOST_l2c(l,c) ({ unsigned int r=(l); \
asm ("bswapl %0":"=r"(r):"0"(r)); \
*((unsigned int *)(c))=r; (c)+=4; r; })
# endif
# elif defined(__aarch64__)
# if defined(__BYTE_ORDER__)
# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
# define HOST_c2l(c,l) ({ unsigned int r; \
asm ("rev %w0,%w1" \
:"=r"(r) \
:"r"(*((const unsigned int *)(c))));\
(c)+=4; (l)=r; })
# define HOST_l2c(l,c) ({ unsigned int r; \
asm ("rev %w0,%w1" \
:"=r"(r) \
:"r"((unsigned int)(l)));\
*((unsigned int *)(c))=r; (c)+=4; r; })
# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
# endif
# endif
# endif
# endif
# if defined(__s390__) || defined(__s390x__)
# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
# endif
# endif
# ifndef HOST_c2l
# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
l|=(((unsigned long)(*((c)++)))<<16), \ l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<< 8), \ l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++))) ) ) l|=(((unsigned long)(*((c)++))) ) )
# endif
# ifndef HOST_l2c
# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff), \ *((c)++)=(unsigned char)(((l) )&0xff), \
l) l)
# endif
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
# ifndef PEDANTIC
# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
# if defined(__s390x__)
# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \
:"=d"(l) :"m"(*(const unsigned int *)(c)));\
(c)+=4; (l); })
# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \
:"=m"(*(unsigned int *)(c)) :"d"(l));\
(c)+=4; (l); })
# endif
# endif
# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
# ifndef B_ENDIAN
/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l)
# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l)
# endif
# endif
# endif
# ifndef HOST_c2l
# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
l|=(((unsigned long)(*((c)++)))<< 8), \ l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++)))<<16), \ l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<<24) ) l|=(((unsigned long)(*((c)++)))<<24) )
# endif
# ifndef HOST_l2c
# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>>24)&0xff), \ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
l) l)
# endif
#endif #endif
/* /*
* Time for some action:-) * Time for some action :-)
*/ */
int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
@ -308,10 +134,6 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
return 1; return 1;
l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL; l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
/*
* 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
* <weidai@eskimo.com> for pointing it out.
*/
if (l < c->Nl) /* overflow */ if (l < c->Nl) /* overflow */
c->Nh++; c->Nh++;
c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
@ -329,6 +151,12 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
data += n; data += n;
len -= n; len -= n;
c->num = 0; c->num = 0;
/*
* We use memset rather than OPENSSL_cleanse() here deliberately.
* Using OPENSSL_cleanse() here could be a performance issue. It
* will get properly cleansed on finalisation so this isn't a
* security problem.
*/
memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
} else { } else {
memcpy(p + n, data, len); memcpy(p + n, data, len);
@ -384,7 +212,7 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c)
p -= HASH_CBLOCK; p -= HASH_CBLOCK;
HASH_BLOCK_DATA_ORDER(c, p, 1); HASH_BLOCK_DATA_ORDER(c, p, 1);
c->num = 0; c->num = 0;
memset(p, 0, HASH_CBLOCK); OPENSSL_cleanse(p, HASH_CBLOCK);
#ifndef HASH_MAKE_STRING #ifndef HASH_MAKE_STRING
# error "HASH_MAKE_STRING must be defined!" # error "HASH_MAKE_STRING must be defined!"
@ -399,7 +227,7 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c)
# if defined(__alpha) || defined(__sparcv9) || defined(__mips) # if defined(__alpha) || defined(__sparcv9) || defined(__mips)
# define MD32_REG_T long # define MD32_REG_T long
/* /*
* This comment was originaly written for MD5, which is why it * This comment was originally written for MD5, which is why it
* discusses A-D. But it basically applies to all 32-bit digests, * discusses A-D. But it basically applies to all 32-bit digests,
* which is why it was moved to common header file. * which is why it was moved to common header file.
* *
@ -413,7 +241,6 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c)
* improvement under SPARC Solaris7/64 and 5% under AlphaLinux. * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
* Well, to be honest it should say that this *prevents* * Well, to be honest it should say that this *prevents*
* performance degradation. * performance degradation.
* <appro@fy.chalmers.se>
*/ */
# else # else
/* /*
@ -421,7 +248,6 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c)
* generate better code if MD32_REG_T is defined int. The above * generate better code if MD32_REG_T is defined int. The above
* pre-processor condition reflects the circumstances under which * pre-processor condition reflects the circumstances under which
* the conclusion was made and is subject to further extension. * the conclusion was made and is subject to further extension.
* <appro@fy.chalmers.se>
*/ */
# define MD32_REG_T int # define MD32_REG_T int
# endif # endif

View File

@ -24,10 +24,10 @@ SOFTWARE.
*/ */
#include <stdio.h> #include <cstdio>
#include <string.h> #include <cstring>
#include <stdlib.h> #include <cstdlib>
#include <assert.h> #include <cassert>
#include "sha1.h" #include "sha1.h"
@ -66,15 +66,6 @@ SHA1::SHA1()
{ {
// make sure that the data type is the right size // make sure that the data type is the right size
assert( sizeof( Uint32 ) * 5 == 20 ); assert( sizeof( Uint32 ) * 5 == 20 );
// initialize
H0 = 0x67452301;
H1 = 0xefcdab89;
H2 = 0x98badcfe;
H3 = 0x10325476;
H4 = 0xc3d2e1f0;
unprocessedBytes = 0;
size = 0;
} }
// Destructor ******************************************************** // Destructor ********************************************************

View File

@ -24,17 +24,22 @@ SOFTWARE.
*/ */
#ifndef SHA1_HEADER #pragma once
typedef unsigned int Uint32; typedef unsigned int Uint32;
class SHA1 class SHA1
{ {
private: private:
// fields // fields
Uint32 H0, H1, H2, H3, H4; Uint32 H0 = 0x67452301;
Uint32 H1 = 0xefcdab89;
Uint32 H2 = 0x98badcfe;
Uint32 H3 = 0x10325476;
Uint32 H4 = 0xc3d2e1f0;
unsigned char bytes[64]; unsigned char bytes[64];
int unprocessedBytes; int unprocessedBytes = 0;
Uint32 size; Uint32 size = 0;
void process(); void process();
public: public:
@ -47,6 +52,3 @@ public:
static void storeBigEndianUint32(unsigned char *byte, Uint32 num); static void storeBigEndianUint32(unsigned char *byte, Uint32 num);
static void hexPrinter(unsigned char *c, int l); static void hexPrinter(unsigned char *c, int l);
}; };
#define SHA1_HEADER
#endif

View File

@ -56,8 +56,7 @@
* [including the GNU Public Licence.] * [including the GNU Public Licence.]
*/ */
#ifndef HEADER_SHA_H #pragma once
#define HEADER_SHA_H
#include <stddef.h> #include <stddef.h>
@ -153,5 +152,3 @@ void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif

View File

@ -1,36 +1,28 @@
/* crypto/sha/sha256.c */ /*
/* ==================================================================== * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2004 The OpenSSL Project. All rights reserved *
* according to the OpenSSL license [found in ../../LICENSE]. * Licensed under the Apache License 2.0 (the "License"). You may not use
* ==================================================================== * this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/ */
# include <stdlib.h>
# include <string.h>
# include <util/sha2.h> #include <stdlib.h>
#include <string.h>
# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2a 19 Mar 2015" #include <util/sha2.h>
# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT;
/* mem_clr.c */ /* mem_clr.c */
unsigned static char cleanse_ctr = 0; typedef void *(*memset_t)(void *, int, size_t);
static void OPENSSL_cleanse(void *ptr, size_t len)
static volatile memset_t memset_func = memset;
void OPENSSL_cleanse(void *ptr, size_t len)
{ {
unsigned char *p = ptr; memset_func(ptr, 0, len);
size_t loop = len, ctr = cleanse_ctr;
while (loop--) {
*(p++) = (unsigned char)ctr;
ctr += (17 + ((size_t)p & 0xF));
}
p = memchr(ptr, (unsigned char)ctr, len);
if (p)
ctr += (63 + (size_t)p);
cleanse_ctr = (unsigned char)ctr;
} }
fips_md_init_ctx(SHA224, SHA256) int SHA224_Init(SHA256_CTX *c)
{ {
memset(c, 0, sizeof(*c)); memset(c, 0, sizeof(*c));
c->h[0] = 0xc1059ed8UL; c->h[0] = 0xc1059ed8UL;
@ -45,7 +37,7 @@ fips_md_init_ctx(SHA224, SHA256)
return 1; return 1;
} }
fips_md_init(SHA256) int SHA256_Init(SHA256_CTX *c)
{ {
memset(c, 0, sizeof(*c)); memset(c, 0, sizeof(*c));
c->h[0] = 0x6a09e667UL; c->h[0] = 0x6a09e667UL;
@ -71,7 +63,7 @@ unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
SHA256_Update(&c, d, n); SHA256_Update(&c, d, n);
SHA256_Final(md, &c); SHA256_Final(md, &c);
OPENSSL_cleanse(&c, sizeof(c)); OPENSSL_cleanse(&c, sizeof(c));
return (md); return md;
} }
unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
@ -85,7 +77,7 @@ unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
SHA256_Update(&c, d, n); SHA256_Update(&c, d, n);
SHA256_Final(md, &c); SHA256_Final(md, &c);
OPENSSL_cleanse(&c, sizeof(c)); OPENSSL_cleanse(&c, sizeof(c));
return (md); return md;
} }
int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
@ -98,20 +90,21 @@ int SHA224_Final(unsigned char *md, SHA256_CTX *c)
return SHA256_Final(md, c); return SHA256_Final(md, c);
} }
# define DATA_ORDER_IS_BIG_ENDIAN #define DATA_ORDER_IS_BIG_ENDIAN
#define HASH_LONG SHA_LONG
#define HASH_CTX SHA256_CTX
#define HASH_CBLOCK SHA_CBLOCK
# define HASH_LONG SHA_LONG
# define HASH_CTX SHA256_CTX
# define HASH_CBLOCK SHA_CBLOCK
/* /*
* Note that FIPS180-2 discusses "Truncation of the Hash Function Output." * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
* default: case below covers for it. It's not clear however if it's * default: case below covers for it. It's not clear however if it's
* permitted to truncate to amount of bytes not divisible by 4. I bet not, * permitted to truncate to amount of bytes not divisible by 4. I bet not,
* but if it is, then default: case shall be extended. For reference. * but if it is, then default: case shall be extended. For reference.
* Idea behind separate cases for pre-defined lenghts is to let the * Idea behind separate cases for pre-defined lengths is to let the
* compiler decide if it's appropriate to unroll small loops. * compiler decide if it's appropriate to unroll small loops.
*/ */
# define HASH_MAKE_STRING(c,s) do { \ #define HASH_MAKE_STRING(c,s) do { \
unsigned long ll; \ unsigned long ll; \
unsigned int nn; \ unsigned int nn; \
switch ((c)->md_len) \ switch ((c)->md_len) \
@ -132,18 +125,18 @@ int SHA224_Final(unsigned char *md, SHA256_CTX *c)
} \ } \
} while (0) } while (0)
# define HASH_UPDATE SHA256_Update #define HASH_UPDATE SHA256_Update
# define HASH_TRANSFORM SHA256_Transform #define HASH_TRANSFORM SHA256_Transform
# define HASH_FINAL SHA256_Final #define HASH_FINAL SHA256_Final
# define HASH_BLOCK_DATA_ORDER sha256_block_data_order #define HASH_BLOCK_DATA_ORDER sha256_block_data_order
# ifndef SHA256_ASM #ifndef SHA256_ASM
static static
# endif #endif
void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
# include "md32_common.h" #include "md32_common.h"
# ifndef SHA256_ASM #ifndef SHA256_ASM
static const SHA_LONG K256[64] = { static const SHA_LONG K256[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
@ -198,7 +191,7 @@ static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
h = ctx->h[7]; h = ctx->h[7];
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[i] = l; T1 = X[i] = l;
T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
T2 = Sigma0(a) + Maj(a, b, c); T2 = Sigma0(a) + Maj(a, b, c);
@ -322,52 +315,52 @@ static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
} else { } else {
SHA_LONG l; SHA_LONG l;
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[0] = l; T1 = X[0] = l;
ROUND_00_15(0, a, b, c, d, e, f, g, h); ROUND_00_15(0, a, b, c, d, e, f, g, h);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[1] = l; T1 = X[1] = l;
ROUND_00_15(1, h, a, b, c, d, e, f, g); ROUND_00_15(1, h, a, b, c, d, e, f, g);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[2] = l; T1 = X[2] = l;
ROUND_00_15(2, g, h, a, b, c, d, e, f); ROUND_00_15(2, g, h, a, b, c, d, e, f);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[3] = l; T1 = X[3] = l;
ROUND_00_15(3, f, g, h, a, b, c, d, e); ROUND_00_15(3, f, g, h, a, b, c, d, e);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[4] = l; T1 = X[4] = l;
ROUND_00_15(4, e, f, g, h, a, b, c, d); ROUND_00_15(4, e, f, g, h, a, b, c, d);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[5] = l; T1 = X[5] = l;
ROUND_00_15(5, d, e, f, g, h, a, b, c); ROUND_00_15(5, d, e, f, g, h, a, b, c);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[6] = l; T1 = X[6] = l;
ROUND_00_15(6, c, d, e, f, g, h, a, b); ROUND_00_15(6, c, d, e, f, g, h, a, b);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[7] = l; T1 = X[7] = l;
ROUND_00_15(7, b, c, d, e, f, g, h, a); ROUND_00_15(7, b, c, d, e, f, g, h, a);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[8] = l; T1 = X[8] = l;
ROUND_00_15(8, a, b, c, d, e, f, g, h); ROUND_00_15(8, a, b, c, d, e, f, g, h);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[9] = l; T1 = X[9] = l;
ROUND_00_15(9, h, a, b, c, d, e, f, g); ROUND_00_15(9, h, a, b, c, d, e, f, g);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[10] = l; T1 = X[10] = l;
ROUND_00_15(10, g, h, a, b, c, d, e, f); ROUND_00_15(10, g, h, a, b, c, d, e, f);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[11] = l; T1 = X[11] = l;
ROUND_00_15(11, f, g, h, a, b, c, d, e); ROUND_00_15(11, f, g, h, a, b, c, d, e);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[12] = l; T1 = X[12] = l;
ROUND_00_15(12, e, f, g, h, a, b, c, d); ROUND_00_15(12, e, f, g, h, a, b, c, d);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[13] = l; T1 = X[13] = l;
ROUND_00_15(13, d, e, f, g, h, a, b, c); ROUND_00_15(13, d, e, f, g, h, a, b, c);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[14] = l; T1 = X[14] = l;
ROUND_00_15(14, c, d, e, f, g, h, a, b); ROUND_00_15(14, c, d, e, f, g, h, a, b);
HOST_c2l(data, l); (void)HOST_c2l(data, l);
T1 = X[15] = l; T1 = X[15] = l;
ROUND_00_15(15, b, c, d, e, f, g, h, a); ROUND_00_15(15, b, c, d, e, f, g, h, a);
} }
@ -396,4 +389,4 @@ static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
} }
# endif # endif
# endif /* SHA256_ASM */ #endif /* SHA256_ASM */