Commit 564d93ff by Fabio Alessandrelli

CryptoCore class to access to base crypto utils.

Godot core needs MD5/SHA256/AES/Base64 which used to be provided by separate libraries. Since we bundle mbedtls in most cases, and we can easily only include the needed sources if we so desire, let's use it. To simplify library changes in the future, and better isolate header dependencies all functions have been wrapped around inside a class in `core/math/crypto_base.h`. If the mbedtls module is disabled, we only bundle the needed source files independently of the `builtin_mbedtls` option. If the module is enabled, the `builtin_mbedtls` option works as usual. Also remove some unused headers from StreamPeerMbedTLS which were causing build issues.
parent 0268a486
......@@ -250,20 +250,6 @@ Copyright: 1998-2010, Gilles Vollant
2009-2010, Mathias Svensson
License: Zlib
Files: ./thirdparty/misc/aes256.cpp
./thirdparty/misc/aes256.h
./thirdparty/misc/sha256.c
./thirdparty/misc/sha256.h
Comment: AES-256 and SHA-256 implementation
Copyright: 2007-2011, Ilya O. Levin
License: ISC
Files: ./thirdparty/misc/base64.c
./thirdparty/misc/base64.h
Comment: BASE64 conversion methods
Copyright: Ari Edelkind
License: public-domain
Files: ./thirdparty/misc/clipper.cpp
./thirdparty/misc/clipper.hpp
Comment: Clipper
......@@ -299,12 +285,6 @@ Comment: libjingle
Copyright: 2012-2013, Google Inc.
License: BSD-3-clause
Files: ./thirdparty/misc/md5.cpp
./thirdparty/misc/md5.h
Comment: MD5 Message Digest Algorithm
Copyright: 1990, RSA Data Security, Inc.
License: RSA-MD
Files: ./thirdparty/misc/mikktspace.c
./thirdparty/misc/mikktspace.h
Comment: Tangent Space Normal Maps implementation
......@@ -1072,19 +1052,6 @@ License: FTL
Robert Wilhelm <robert.wilhelm@freetype.org>
Werner Lemberg <werner.lemberg@freetype.org>
License: ISC
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
License: LGPL-2.1+SLE (libwebsockets)
Libwebsockets and included programs are provided under the terms of the GNU
Library General Public License (LGPL) 2.1, with the following exceptions:
......@@ -2101,24 +2068,6 @@ License: OFL-1.1
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE.
License: RSA-MD
License to copy and use this software is granted provided that it is
identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
in all material mentioning or referencing this software or this function.
.
License is also granted to make and use derivative works provided that such
works are identified as "derived from the RSA Data Security, Inc. MD5
Message-Digest Algorithm" in all material mentioning or referencing the
derived work.
.
RSA Data Security, Inc. makes no representations concerning either the
merchantability of this software or the suitability of this software for
any particular purpose. It is provided "as is" without express or implied
warranty of any kind.
.
These notices must be retained in any copies of any part of this
documentation and/or software.
License: Zlib
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
......
......@@ -47,15 +47,11 @@ env_thirdparty.disable_warnings()
thirdparty_misc_dir = "#thirdparty/misc/"
thirdparty_misc_sources = [
# C sources
"base64.c",
"fastlz.c",
"sha256.c",
"smaz.c",
# C++ sources
"aes256.cpp",
"hq2x.cpp",
"md5.cpp",
"pcg.cpp",
"triangulator.cpp",
"clipper.cpp",
......
......@@ -34,13 +34,12 @@
#include "core/io/file_access_encrypted.h"
#include "core/io/json.h"
#include "core/io/marshalls.h"
#include "core/math/crypto_core.h"
#include "core/math/geometry.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "thirdparty/misc/base64.h"
/**
* Time constants borrowed from loc_time.h
*/
......@@ -2438,7 +2437,8 @@ String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects)
b64buff.resize(b64len);
PoolVector<uint8_t>::Write w64 = b64buff.write();
int strlen = base64_encode((char *)(&w64[0]), (char *)(&w[0]), len);
size_t strlen = 0;
ERR_FAIL_COND_V(CryptoCore::b64_encode(&w64[0], b64len, &strlen, &w[0], len) != OK, String());
//OS::get_singleton()->print("len is %i, vector size is %i\n", b64len, strlen);
w64[strlen] = 0;
String ret = (char *)&w64[0];
......@@ -2455,7 +2455,8 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects)
buf.resize(strlen / 4 * 3 + 1);
PoolVector<uint8_t>::Write w = buf.write();
int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen);
size_t len = 0;
ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, Variant());
Variant v;
Error err = decode_variant(v, &w[0], len, NULL, p_allow_objects);
......@@ -2474,7 +2475,8 @@ String _Marshalls::raw_to_base64(const PoolVector<uint8_t> &p_arr) {
b64buff.resize(b64len);
PoolVector<uint8_t>::Write w64 = b64buff.write();
int strlen = base64_encode((char *)(&w64[0]), (char *)(&r[0]), len);
size_t strlen = 0;
ERR_FAIL_COND_V(CryptoCore::b64_encode(&w64[0], b64len, &strlen, &r[0], len) != OK, String());
w64[strlen] = 0;
String ret = (char *)&w64[0];
......@@ -2486,17 +2488,16 @@ PoolVector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) {
int strlen = p_str.length();
CharString cstr = p_str.ascii();
int arr_len;
size_t arr_len = 0;
PoolVector<uint8_t> buf;
{
buf.resize(strlen / 4 * 3 + 1);
PoolVector<uint8_t>::Write w = buf.write();
arr_len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen);
};
ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen) != OK, PoolVector<uint8_t>());
}
buf.resize(arr_len);
// conversion from PoolVector<uint8_t> to raw array?
return buf;
};
......@@ -2510,7 +2511,8 @@ String _Marshalls::utf8_to_base64(const String &p_str) {
b64buff.resize(b64len);
PoolVector<uint8_t>::Write w64 = b64buff.write();
int strlen = base64_encode((char *)(&w64[0]), (char *)cstr.get_data(), len);
size_t strlen = 0;
ERR_FAIL_COND_V(CryptoCore::b64_encode(&w64[0], b64len, &strlen, (unsigned char *)cstr.get_data(), len) != OK, String());
w64[strlen] = 0;
String ret = (char *)&w64[0];
......@@ -2527,7 +2529,8 @@ String _Marshalls::base64_to_utf8(const String &p_str) {
buf.resize(strlen / 4 * 3 + 1 + 1);
PoolVector<uint8_t>::Write w = buf.write();
int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen);
size_t len = 0;
ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, String());
w[len] = 0;
String ret = String::utf8((char *)&w[0]);
......
......@@ -30,13 +30,11 @@
#include "file_access_encrypted.h"
#include "core/math/crypto_core.h"
#include "core/os/copymem.h"
#include "core/print_string.h"
#include "core/variant.h"
#include "thirdparty/misc/aes256.h"
#include "thirdparty/misc/md5.h"
#include <stdio.h>
#define COMP_MAGIC 0x43454447
......@@ -83,25 +81,21 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
uint32_t blen = p_base->get_buffer(data.ptrw(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
aes256_context ctx;
aes256_init(&ctx, key.ptrw());
CryptoCore::AESContext ctx;
ctx.set_decode_key(key.ptrw(), 256);
for (size_t i = 0; i < ds; i += 16) {
aes256_decrypt_ecb(&ctx, &data.write[i]);
ctx.decrypt_ecb(&data.write[i], &data.write[i]);
}
aes256_done(&ctx);
data.resize(length);
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5, (uint8_t *)data.ptr(), data.size());
MD5Final(&md5);
unsigned char hash[16];
ERR_FAIL_COND_V(CryptoCore::md5(data.ptr(), data.size(), hash) != OK, ERR_BUG);
ERR_EXPLAIN("The MD5 sum of the decrypted file does not match the expected value. It could be that the file is corrupt, or that the provided decryption key is invalid.");
ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(String::md5(hash) != String::md5(md5d), ERR_FILE_CORRUPT);
file = p_base;
}
......@@ -140,10 +134,8 @@ void FileAccessEncrypted::close() {
len += 16 - (len % 16);
}
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5, (uint8_t *)data.ptr(), data.size());
MD5Final(&md5);
unsigned char hash[16];
ERR_FAIL_COND(CryptoCore::md5(data.ptr(), data.size(), hash) != OK); // Bug?
compressed.resize(len);
zeromem(compressed.ptrw(), len);
......@@ -151,20 +143,18 @@ void FileAccessEncrypted::close() {
compressed.write[i] = data[i];
}
aes256_context ctx;
aes256_init(&ctx, key.ptrw());
CryptoCore::AESContext ctx;
ctx.set_encode_key(key.ptrw(), 256);
for (size_t i = 0; i < len; i += 16) {
aes256_encrypt_ecb(&ctx, &compressed.write[i]);
ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]);
}
aes256_done(&ctx);
file->store_32(COMP_MAGIC);
file->store_32(mode);
file->store_buffer(md5.digest, 16);
file->store_buffer(hash, 16);
file->store_64(data.size());
file->store_buffer(compressed.ptr(), compressed.size());
......
......@@ -2,4 +2,37 @@
Import('env')
env.add_source_files(env.core_sources, "*.cpp")
env_math = env.Clone() # Maybe make one specific for crypto?
is_builtin = env["builtin_mbedtls"]
has_module = env["module_mbedtls_enabled"]
if is_builtin or not has_module:
# Use our headers for builtin or if the module is not going to be compiled.
# We decided not to depend on system mbedtls just for these few files that can
# be easily extracted.
env_math.Prepend(CPPPATH=["#thirdparty/mbedtls/include"])
# MbedTLS core functions (for CryptoCore).
# If the mbedtls module is compiled we don't need to add the .c files with our
# custom config since they will be built by the module itself.
# Only if the module is not enabled, we must compile here the required sources
# to make a "light" build with only the necessary mbedtls files.
if not has_module:
env_thirdparty = env_math.Clone()
env_thirdparty.disable_warnings()
# Custom config file
env_thirdparty.Append(CPPFLAGS=['-DMBEDTLS_CONFIG_FILE="\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\""'])
thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/"
thirdparty_mbedtls_sources = [
"aes.c",
"base64.c",
"md5.c",
"sha1.c",
"sha256.c",
"godot_core_mbedtls_platform.c"
]
thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources]
env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources)
env_math.add_source_files(env.core_sources, "*.cpp")
/*************************************************************************/
/* crypto_core.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "crypto_core.h"
#include <mbedtls/aes.h>
#include <mbedtls/base64.h>
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
// MD5
CryptoCore::MD5Context::MD5Context() {
ctx = memalloc(sizeof(mbedtls_md5_context));
mbedtls_md5_init((mbedtls_md5_context *)ctx);
}
CryptoCore::MD5Context::~MD5Context() {
mbedtls_md5_free((mbedtls_md5_context *)ctx);
memfree((mbedtls_md5_context *)ctx);
}
Error CryptoCore::MD5Context::start() {
int ret = mbedtls_md5_starts_ret((mbedtls_md5_context *)ctx);
return ret ? FAILED : OK;
}
Error CryptoCore::MD5Context::update(uint8_t *p_src, size_t p_len) {
int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) {
int ret = mbedtls_md5_finish_ret((mbedtls_md5_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// SHA256
CryptoCore::SHA256Context::SHA256Context() {
ctx = memalloc(sizeof(mbedtls_sha256_context));
mbedtls_sha256_init((mbedtls_sha256_context *)ctx);
}
CryptoCore::SHA256Context::~SHA256Context() {
mbedtls_sha256_free((mbedtls_sha256_context *)ctx);
memfree((mbedtls_sha256_context *)ctx);
}
Error CryptoCore::SHA256Context::start() {
int ret = mbedtls_sha256_starts_ret((mbedtls_sha256_context *)ctx, 0);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA256Context::update(uint8_t *p_src, size_t p_len) {
int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA256Context::finish(unsigned char r_hash[16]) {
int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// AES256
CryptoCore::AESContext::AESContext() {
ctx = memalloc(sizeof(mbedtls_aes_context));
mbedtls_aes_init((mbedtls_aes_context *)ctx);
}
CryptoCore::AESContext::~AESContext() {
mbedtls_aes_free((mbedtls_aes_context *)ctx);
memfree((mbedtls_aes_context *)ctx);
}
Error CryptoCore::AESContext::set_encode_key(const uint8_t *p_key, size_t p_bits) {
int ret = mbedtls_aes_setkey_enc((mbedtls_aes_context *)ctx, p_key, p_bits);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::set_decode_key(const uint8_t *p_key, size_t p_bits) {
int ret = mbedtls_aes_setkey_dec((mbedtls_aes_context *)ctx, p_key, p_bits);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_src, r_dst);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst);
return ret ? FAILED : OK;
}
// CryptoCore
Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len);
return ret ? FAILED : OK;
}
Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len);
return ret ? FAILED : OK;
}
Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) {
int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash);
return ret ? FAILED : OK;
}
Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) {
int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash);
return ret ? FAILED : OK;
}
Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) {
int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0);
return ret ? FAILED : OK;
}
/*************************************************************************/
/* crypto_core.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef CRYPTO_CORE_H
#define CRYPTO_CORE_H
#include "core/reference.h"
class CryptoCore {
public:
class MD5Context {
private:
void *ctx; // To include, or not to include...
public:
MD5Context();
~MD5Context();
Error start();
Error update(uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[16]);
};
class SHA256Context {
private:
void *ctx; // To include, or not to include...
public:
SHA256Context();
~SHA256Context();
Error start();
Error update(uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[16]);
};
class AESContext {
private:
void *ctx; // To include, or not to include...
public:
AESContext();
~AESContext();
Error set_encode_key(const uint8_t *p_key, size_t p_bits);
Error set_decode_key(const uint8_t *p_key, size_t p_bits);
Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
};
static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]);
static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]);
static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]);
};
#endif // CRYPTO_CORE_H
......@@ -32,12 +32,10 @@
#include "core/io/file_access_pack.h"
#include "core/io/marshalls.h"
#include "core/math/crypto_core.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "thirdparty/misc/md5.h"
#include "thirdparty/misc/sha256.h"
FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { 0, 0 };
FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = NULL;
......@@ -637,8 +635,8 @@ String FileAccess::get_md5(const String &p_file) {
if (!f)
return String();
MD5_CTX md5;
MD5Init(&md5);
CryptoCore::MD5Context ctx;
ctx.start();
unsigned char step[32768];
......@@ -647,24 +645,24 @@ String FileAccess::get_md5(const String &p_file) {
int br = f->get_buffer(step, 32768);
if (br > 0) {
MD5Update(&md5, step, br);
ctx.update(step, br);
}
if (br < 4096)
break;
}
MD5Final(&md5);
String ret = String::md5(md5.digest);
unsigned char hash[16];
ctx.finish(hash);
memdelete(f);
return ret;
return String::md5(hash);
}
String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
MD5_CTX md5;
MD5Init(&md5);
CryptoCore::MD5Context ctx;
ctx.start();
for (int i = 0; i < p_file.size(); i++) {
FileAccess *f = FileAccess::open(p_file[i], READ);
......@@ -677,7 +675,7 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
int br = f->get_buffer(step, 32768);
if (br > 0) {
MD5Update(&md5, step, br);
ctx.update(step, br);
}
if (br < 4096)
break;
......@@ -685,11 +683,10 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
memdelete(f);
}
MD5Final(&md5);
unsigned char hash[16];
ctx.finish(hash);
String ret = String::md5(md5.digest);
return ret;
return String::md5(hash);
}
String FileAccess::get_sha256(const String &p_file) {
......@@ -698,8 +695,8 @@ String FileAccess::get_sha256(const String &p_file) {
if (!f)
return String();
sha256_context sha256;
sha256_init(&sha256);
CryptoCore::SHA256Context ctx;
ctx.start();
unsigned char step[32768];
......@@ -708,15 +705,14 @@ String FileAccess::get_sha256(const String &p_file) {
int br = f->get_buffer(step, 32768);
if (br > 0) {
sha256_hash(&sha256, step, br);
ctx.update(step, br);
}
if (br < 4096)
break;
}
unsigned char hash[32];
sha256_done(&sha256, hash);
ctx.finish(hash);
memdelete(f);
return String::hex_encode_buffer(hash, 32);
......
......@@ -31,6 +31,7 @@
#include "ustring.h"
#include "core/color.h"
#include "core/math/crypto_core.h"
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/print_string.h"
......@@ -38,9 +39,6 @@
#include "core/ucaps.h"
#include "core/variant.h"
#include "thirdparty/misc/md5.h"
#include "thirdparty/misc/sha256.h"
#include <wchar.h>
#ifndef NO_USE_STDLIB
......@@ -2254,54 +2252,42 @@ uint64_t String::hash64() const {
String String::md5_text() const {
CharString cs = utf8();
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char *)cs.ptr(), cs.length());
MD5Final(&ctx);
return String::md5(ctx.digest);
unsigned char hash[16];
CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash);
return String::hex_encode_buffer(hash, 16);
}
String String::sha256_text() const {
CharString cs = utf8();
unsigned char hash[32];
sha256_context ctx;
sha256_init(&ctx);
sha256_hash(&ctx, (unsigned char *)cs.ptr(), cs.length());
sha256_done(&ctx, hash);
CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash);
return String::hex_encode_buffer(hash, 32);
}
Vector<uint8_t> String::md5_buffer() const {
CharString cs = utf8();
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char *)cs.ptr(), cs.length());
MD5Final(&ctx);
unsigned char hash[16];
CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash);
Vector<uint8_t> ret;
ret.resize(16);
for (int i = 0; i < 16; i++) {
ret.write[i] = ctx.digest[i];
};
ret.write[i] = hash[i];
}
return ret;
};
Vector<uint8_t> String::sha256_buffer() const {
CharString cs = utf8();
unsigned char hash[32];
sha256_context ctx;
sha256_init(&ctx);
sha256_hash(&ctx, (unsigned char *)cs.ptr(), cs.length());
sha256_done(&ctx, hash);
CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash);
Vector<uint8_t> ret;
ret.resize(32);
for (int i = 0; i < 32; i++) {
ret.write[i] = hash[i];
}
return ret;
}
......
......@@ -33,10 +33,10 @@
#include "core/color_names.inc"
#include "core/core_string_names.h"
#include "core/io/compression.h"
#include "core/math/crypto_core.h"
#include "core/object.h"
#include "core/os/os.h"
#include "core/script_language.h"
#include "thirdparty/misc/sha256.h"
typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
......@@ -598,10 +598,7 @@ struct _VariantCall {
PoolByteArray::Read r = ba->read();
String s;
unsigned char hash[32];
sha256_context sha256;
sha256_init(&sha256);
sha256_hash(&sha256, (unsigned char *)r.ptr(), ba->size());
sha256_done(&sha256, hash);
CryptoCore::sha256((unsigned char *)r.ptr(), ba->size(), hash);
s = String::hex_encode_buffer(hash, 32);
r_ret = s;
}
......
......@@ -34,6 +34,7 @@
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/io/zip_io.h"
#include "core/math/crypto_core.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
#include "core/script_language.h"
......@@ -43,7 +44,6 @@
#include "editor_node.h"
#include "editor_settings.h"
#include "scene/resources/resource_format_text.h"
#include "thirdparty/misc/md5.h"
static int _get_pad(int p_alignment, int p_n) {
......@@ -323,13 +323,11 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
}
{
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char *)p_data.ptr(), p_data.size());
MD5Final(&ctx);
unsigned char hash[16];
CryptoCore::md5(p_data.ptr(), p_data.size(), hash);
sd.md5.resize(16);
for (int i = 0; i < 16; i++) {
sd.md5.write[i] = ctx.digest[i];
sd.md5.write[i] = hash[i];
}
}
......
......@@ -30,6 +30,7 @@
#include "editor_scene_importer_gltf.h"
#include "core/io/json.h"
#include "core/math/crypto_core.h"
#include "core/math/math_defs.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
......@@ -37,7 +38,6 @@
#include "scene/3d/mesh_instance.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/surface_tool.h"
#include "thirdparty/misc/base64.h"
uint32_t EditorSceneImporterGLTF::get_import_flags() const {
......@@ -279,7 +279,8 @@ static Vector<uint8_t> _parse_base64_uri(const String &uri) {
Vector<uint8_t> buf;
buf.resize(strlen / 4 * 3 + 1 + 1);
int len = base64_decode((char *)buf.ptr(), (char *)substr.get_data(), strlen);
size_t len = 0;
ERR_FAIL_COND_V(CryptoCore::b64_decode(buf.ptrw(), buf.size(), &len, (unsigned char *)substr.get_data(), strlen) != OK, Vector<uint8_t>());
buf.resize(len);
......
......@@ -33,8 +33,6 @@
#include "core/io/stream_peer_tcp.h"
#include "core/os/file_access.h"
#include <mbedtls/platform_util.h>
static void my_debug(void *ctx, int level,
const char *file, int line,
const char *str) {
......
......@@ -37,7 +37,6 @@
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/debug.h>
#include <mbedtls/entropy.h>
#include <mbedtls/net.h>
#include <mbedtls/ssl.h>
#include <stdio.h>
......
......@@ -32,6 +32,7 @@
#include "core/bind/core_bind.h"
#include "core/io/marshalls.h"
#include "core/io/zip_io.h"
#include "core/math/crypto_core.h"
#include "core/object.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
......@@ -42,8 +43,6 @@
#include "thirdparty/minizip/unzip.h"
#include "thirdparty/minizip/zip.h"
#include "thirdparty/misc/base64.h"
#include "thirdparty/misc/sha256.h"
#include <zlib.h>
......@@ -198,15 +197,12 @@ public:
String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) {
char hash[32];
unsigned char hash[32];
char base64[45];
sha256_context ctx;
sha256_init(&ctx);
sha256_hash(&ctx, (uint8_t *)p_block_data, p_block_len);
sha256_done(&ctx, (uint8_t *)hash);
base64_encode(base64, hash, 32);
CryptoCore::sha256(p_block_data, p_block_len, hash);
size_t len = 0;
CryptoCore::b64_encode((unsigned char *)base64, 45, &len, (unsigned char *)hash, 32);
base64[44] = '\0';
return String(base64);
......
......@@ -303,6 +303,8 @@ File extracted from upstream release tarball `mbedtls-2.16.0-apache.tgz`:
- Applied the patch in `thirdparty/mbedtls/padlock.diff`. This disables VIA
padlock support which defines a symbol `unsupported` which clashes with
a symbol in libwebsockets.
- Added 2 files `godot_core_mbedtls_platform.{c,h}` providing configuration
for light bundling with core.
## miniupnpc
......@@ -340,15 +342,7 @@ Collection of single-file libraries used in Godot components.
### core
- `aes256.{cpp,h}`
* Upstream: http://www.literatecode.com/aes256
* Version: latest, as of April 2017
* License: ISC
- `base64.{c,h}`
* Upstream: http://episec.com/people/edelkind/c.html
* Version: latest, as of April 2017
* License: Public Domain
- `clipper.{cpp,hpp}`
- `clipper.{cpp,hpp}`
* Upstream: https://sourceforge.net/projects/polyclipping
* Version: 6.4.2 + Godot changes (added optional exceptions handling)
* License: BSL-1.0
......@@ -360,10 +354,6 @@ Collection of single-file libraries used in Godot components.
* Upstream: https://github.com/brunexgeek/hqx
* Version: TBD, file structure differs
* License: Apache 2.0
- `md5.{cpp,h}`
* Upstream: http://www.efgh.com/software/md5.htm
* Version: TBD, might not be latest from above URL
* License: RSA Message-Digest License
- `open-simplex-noise.{c,h}`
* Upstream: https://github.com/smcameron/open-simplex-noise-in-c
* Version: git (0d555e7, 2015)
......@@ -372,10 +362,6 @@ Collection of single-file libraries used in Godot components.
* Upstream: http://www.pcg-random.org
* Version: minimal C implementation, http://www.pcg-random.org/download.html
* License: Apache 2.0
- `sha256.{c,h}`
* Upstream: https://github.com/ilvn/SHA256
* Version: git (35ff823, 2015)
* License: ISC
- `smaz.{c,h}`
* Upstream: https://github.com/antirez/smaz
* Version: git (150e125, 2009)
......
// For AES
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_CIPHER_MODE_CFB
#define MBEDTLS_CIPHER_MODE_CTR
#define MBEDTLS_CIPHER_MODE_OFB
#define MBEDTLS_CIPHER_MODE_XTS
#define MBEDTLS_AES_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_MD5_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_PLATFORM_ZEROIZE_ALT
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#ifdef MBEDTLS_PLATFORM_ZEROIZE_ALT
static void *(*const volatile memset_func)(void *, int, size_t) = memset;
void mbedtls_platform_zeroize(void *buf, size_t len) {
memset_func( buf, 0, len );
}
#endif
/*
* Byte-oriented AES-256 implementation.
* All lookup tables replaced with 'on the fly' calculations.
*
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
* Other contributors: Hal Finney
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef AES_256_H
#define AES_256_H
#include "core/typedefs.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint8_t key[32];
uint8_t enckey[32];
uint8_t deckey[32];
} aes256_context;
void aes256_init(aes256_context *, uint8_t * /* key */);
void aes256_done(aes256_context *);
void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */);
void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */);
#ifdef __cplusplus
}
#endif
#endif
/*
* File: base64.c
* Description: Simple BASE64 conversion methods
* Author: Ari Edelkind
* License: Public Domain
* Website: http://episec.com/people/edelkind/c.html
*/
#include <string.h>
char b64string[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
long base64_encode (to, from, len)
char *to, *from;
unsigned int len;
{
char *fromp = from;
char *top = to;
unsigned char cbyte;
unsigned char obyte;
char end[3];
for (; len >= 3; len -= 3) {
cbyte = *fromp++;
*top++ = b64string[(int)(cbyte >> 2)];
obyte = (cbyte << 4) & 0x30; /* 0011 0000 */
cbyte = *fromp++;
obyte |= (cbyte >> 4); /* 0000 1111 */
*top++ = b64string[(int)obyte];
obyte = (cbyte << 2) & 0x3C; /* 0011 1100 */
cbyte = *fromp++;
obyte |= (cbyte >> 6); /* 0000 0011 */
*top++ = b64string[(int)obyte];
*top++ = b64string[(int)(cbyte & 0x3F)];/* 0011 1111 */
}
if (len) {
end[0] = *fromp++;
if (--len) end[1] = *fromp++; else end[1] = 0;
end[2] = 0;
cbyte = end[0];
*top++ = b64string[(int)(cbyte >> 2)];
obyte = (cbyte << 4) & 0x30; /* 0011 0000 */
cbyte = end[1];
obyte |= (cbyte >> 4);
*top++ = b64string[(int)obyte];
obyte = (cbyte << 2) & 0x3C; /* 0011 1100 */
if (len) *top++ = b64string[(int)obyte];
else *top++ = '=';
*top++ = '=';
}
*top = 0;
return top - to;
}
/* badchar(): check if c is decent; puts either the */
/* location of c or null into p. */
#define badchar(c,p) (!(p = memchr(b64string, c, 64)))
long base64_decode (to, from, len)
char *to, *from;
unsigned int len;
{
char *fromp = from;
char *top = to;
char *p;
unsigned char cbyte;
unsigned char obyte;
int padding = 0;
for (; len >= 4; len -= 4) {
if ((cbyte = *fromp++) == '=') cbyte = 0;
else {
if (badchar(cbyte, p)) return -1;
cbyte = (p - b64string);
}
obyte = cbyte << 2; /* 1111 1100 */
if ((cbyte = *fromp++) == '=') cbyte = 0;
else {
if (badchar(cbyte, p)) return -1;
cbyte = p - b64string;
}
obyte |= cbyte >> 4; /* 0000 0011 */
*top++ = obyte;
obyte = cbyte << 4; /* 1111 0000 */
if ((cbyte = *fromp++) == '=') { cbyte = 0; padding++; }
else {
padding = 0;
if (badchar (cbyte, p)) return -1;
cbyte = p - b64string;
}
obyte |= cbyte >> 2; /* 0000 1111 */
*top++ = obyte;
obyte = cbyte << 6; /* 1100 0000 */
if ((cbyte = *fromp++) == '=') { cbyte = 0; padding++; }
else {
padding = 0;
if (badchar (cbyte, p)) return -1;
cbyte = p - b64string;
}
obyte |= cbyte; /* 0011 1111 */
*top++ = obyte;
}
*top = 0;
if (len) return -1;
return (top - to) - padding;
}
/*
* File: base64.h
* Description: Simple BASE64 conversion methods
* Author: Ari Edelkind
* License: Public Domain
* Website: http://episec.com/people/edelkind/c.html
*/
#ifndef BASE64_H
#define BASE64_H
extern "C" {
long base64_encode(char *to, char *from, unsigned int len);
long base64_decode(char *to, char *from, unsigned int len);
};
#endif /* BASE64_H */
#ifndef MD5_H
#define MD5_H
/*
**********************************************************************
** md5.h -- Header file for implementation of MD5 **
** RSA Data Security, Inc. MD5 Message Digest Algorithm **
** Created: 2/17/90 RLR **
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
** Revised (for MD5): RLR 4/27/91 **
** -- G modified to have y&~z instead of y&z **
** -- FF, GG, HH modified to add in last register done **
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
** -- distinct additive constant for each step **
** -- round 4 added, working mod 7 **
**********************************************************************
*/
/*
**********************************************************************
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
** **
** License to copy and use this software is granted provided that **
** it is identified as the "RSA Data Security, Inc. MD5 Message **
** Digest Algorithm" in all material mentioning or referencing this **
** software or this function. **
** **
** License is also granted to make and use derivative works **
** provided that such works are identified as "derived from the RSA **
** Data Security, Inc. MD5 Message Digest Algorithm" in all **
** material mentioning or referencing the derived work. **
** **
** RSA Data Security, Inc. makes no representations concerning **
** either the merchantability of this software or the suitability **
** of this software for any particular purpose. It is provided "as **
** is" without express or implied warranty of any kind. **
** **
** These notices must be retained in any copies of any part of this **
** documentation and/or software. **
**********************************************************************
*/
/* NOT typedef a 32 bit type */
#include "core/typedefs.h"
/* Data structure for MD5 (Message Digest) computation */
typedef struct {
uint32_t i[2]; /* number of _bits_ handled mod 2^64 */
uint32_t buf[4]; /* scratch buffer */
unsigned char in[64]; /* input buffer */
unsigned char digest[16]; /* actual digest after MD5Final call */
} MD5_CTX;
void MD5Init (MD5_CTX *mdContext);
void MD5Update (MD5_CTX *mdContext,unsigned char *inBuf,unsigned int inLen);
void MD5Final (MD5_CTX *mdContext);
#endif // MD5_H
/*
* SHA-256 implementation.
*
* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define SWAP_BYTES
// #define USE_STD_MEMCPY
// #define SELF_TEST
#ifdef USE_STD_MEMCPY
#include <string.h>
#endif
#include "sha256.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RL(x,n) (((x) << n) | ((x) >> (32 - n)))
#define RR(x,n) (((x) >> n) | ((x) << (32 - n)))
#define S0(x) (RR((x), 2) ^ RR((x),13) ^ RR((x),22))
#define S1(x) (RR((x), 6) ^ RR((x),11) ^ RR((x),25))
#define G0(x) (RR((x), 7) ^ RR((x),18) ^ ((x) >> 3))
#define G1(x) (RR((x),17) ^ RR((x),19) ^ ((x) >> 10))
#ifdef SWAP_BYTES
#define BSWP(x,y) _bswapw((uint32_t *)(x), (uint32_t)(y))
#else
#define BSWP(p,n)
#endif
#ifdef USE_STD_MEMCPY
#define MEMCP(x,y,z) memcpy((x),(y),(z))
#else
#define MEMCP(x,y,z) _memcp((x),(y),(z))
#endif
#ifndef __cdecl
#define __cdecl
#endif
static const uint32_t K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
/* -------------------------------------------------------------------------- */
static void _bswapw(uint32_t *p, uint32_t i)
{
while (i--) p[i] = (RR(p[i],24) & 0x00ff00ff) | (RR(p[i],8) & 0xff00ff00);
} /* _bswapw */
/* -------------------------------------------------------------------------- */
#ifndef USE_STD_MEMCPY
void * __cdecl _memcp (void *d, const void *s, uint32_t sz)
{
void *rv = d;
while (sz--) *(char *)d = *(char *)s, d = (char *)d + 1, s = (char *)s + 1;
return(rv);
} /* _memcp */
#endif
/* -------------------------------------------------------------------------- */
static void _rtrf(uint32_t *b, uint32_t *p, uint32_t i, uint32_t j)
{
#define B(x, y) b[(x-y) & 7]
#define P(x, y) p[(x+y) & 15]
B(7,i) += (j ? (p[i & 15] += G1(P(i,14)) + P(i,9) + G0(P(i,1))) : p[i & 15])
+ K[i+j] + S1(B(4,i))
+ (B(6,i) ^ (B(4,i) & (B(5,i) ^ B(6,i))));
B(3,i) += B(7,i);
B(7,i) += S0(B(0,i)) + ( (B(0,i) & B(1,i)) | (B(2,i) & (B(0,i) ^ B(1,i))) );
#undef P
#undef B
} /* _rtrf */
/* -------------------------------------------------------------------------- */
static void _hash(sha256_context *ctx)
{
uint32_t b[8], *p, j;
b[0] = ctx->hash[0]; b[1] = ctx->hash[1]; b[2] = ctx->hash[2];
b[3] = ctx->hash[3]; b[4] = ctx->hash[4]; b[5] = ctx->hash[5];
b[6] = ctx->hash[6]; b[7] = ctx->hash[7];
for (p = ctx->buf, j = 0; j < 64; j += 16)
_rtrf(b, p, 0, j), _rtrf(b, p, 1, j), _rtrf(b, p, 2, j),
_rtrf(b, p, 3, j), _rtrf(b, p, 4, j), _rtrf(b, p, 5, j),
_rtrf(b, p, 6, j), _rtrf(b, p, 7, j), _rtrf(b, p, 8, j),
_rtrf(b, p, 9, j), _rtrf(b, p, 10, j), _rtrf(b, p, 11, j),
_rtrf(b, p, 12, j), _rtrf(b, p, 13, j), _rtrf(b, p, 14, j),
_rtrf(b, p, 15, j);
ctx->hash[0] += b[0]; ctx->hash[1] += b[1]; ctx->hash[2] += b[2];
ctx->hash[3] += b[3]; ctx->hash[4] += b[4]; ctx->hash[5] += b[5];
ctx->hash[6] += b[6]; ctx->hash[7] += b[7];
} /* _hash */
/* -------------------------------------------------------------------------- */
void sha256_init(sha256_context ctx[1])
{
ctx->len[0] = ctx->len[1] = 0;
ctx->hash[0] = 0x6a09e667; ctx->hash[1] = 0xbb67ae85;
ctx->hash[2] = 0x3c6ef372; ctx->hash[3] = 0xa54ff53a;
ctx->hash[4] = 0x510e527f; ctx->hash[5] = 0x9b05688c;
ctx->hash[6] = 0x1f83d9ab; ctx->hash[7] = 0x5be0cd19;
} /* sha256_init */
/* -------------------------------------------------------------------------- */
void sha256_hash(sha256_context *ctx, uint8_t *dat, uint32_t sz)
{
register uint32_t i = ctx->len[0] & 63, l, j;
if ((ctx->len[0] += sz) < sz) ++(ctx->len[1]);
for (j = 0, l = 64-i; sz >= l; j += l, sz -= l, l = 64, i = 0)
{
MEMCP(&ctx->buf[i], &dat[j], l);
BSWP(ctx->buf, 16 );
_hash(ctx);
}
MEMCP(&ctx->buf[i], &dat[j], sz);
} /* _hash */
/* -------------------------------------------------------------------------- */
void sha256_done(sha256_context *ctx, uint8_t *buf)
{
uint32_t i = (uint32_t)(ctx->len[0] & 63), j = ((~i) & 3) << 3;
BSWP(ctx->buf, (i + 3) >> 2);
ctx->buf[i >> 2] &= 0xffffff80 << j; /* add padding */
ctx->buf[i >> 2] |= 0x00000080 << j;
if (i < 56) i = (i >> 2) + 1;
else ctx->buf[15] ^= (i < 60) ? ctx->buf[15] : 0, _hash(ctx), i = 0;
while (i < 14) ctx->buf[i++] = 0;
ctx->buf[14] = (ctx->len[1] << 3)|(ctx->len[0] >> 29); /* add length */
ctx->buf[15] = ctx->len[0] << 3;
_hash(ctx);
for (i = 0; i < 32; i++)
ctx->buf[i % 16] = 0, /* may remove this line in case of a DIY cleanup */
buf[i] = (uint8_t)(ctx->hash[i >> 2] >> ((~i & 3) << 3));
} /* sha256_done */
#ifdef SELF_TEST
#pragma warning (push, 0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(pop)
char *buf[] = {
"",
"e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855",
"abc",
"ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1",
"The quick brown fox jumps over the lazy dog",
"d7a8fbb3 07d78094 69ca9abc b0082e4f 8d5651e4 6d3cdb76 2d02d0bf 37c9e592",
"The quick brown fox jumps over the lazy cog", /* avalanche effect test */
"e4c4d8f3 bf76b692 de791a17 3e053211 50f7a345 b46484fe 427f6acc 7ecc81be",
"bhn5bjmoniertqea40wro2upyflkydsibsk8ylkmgbvwi420t44cq034eou1szc1k0mk46oeb7ktzmlxqkbte2sy",
"9085df2f 02e0cc45 5928d0f5 1b27b4bf 1d9cd260 a66ed1fd a11b0a3f f5756d99"
};
int main(int argc, char *argv[])
{
sha256_context ctx;
uint8_t hv[32];
uint32_t i, j;
for (j = 0; j < (sizeof(buf)/sizeof(buf[0])); j += 2)
{
sha256_init(&ctx);
sha256_hash(&ctx, (uint8_t *)buf[j], (uint32_t)strlen(buf[j]));
sha256_done(&ctx, hv);
printf("input = %s\ndigest: %s\nresult: ", buf[j], buf[j+1]);
for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
printf("\n\n");
}
for (j = 1; j < (uint32_t)argc; j++)
{
printf("argv[%d]: %s\nresult: ", (int)j, argv[j]);
sha256_init(&ctx);
sha256_hash(&ctx, (uint8_t *)argv[j], (uint32_t)strlen(argv[j]));
sha256_done(&ctx, hv);
for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":"");
printf("\n\n");
}
return 0;
} /* main */
#endif
#ifdef __cplusplus
}
#endif
/*
* SHA-256 implementation.
*
* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef _MSC_VER
#ifndef uint8_t
typedef unsigned __int8 uint8_t;
#endif
#ifndef uint32_t
typedef unsigned __int32 uint32_t;
#endif
#ifndef uint64_t
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#endif
#else
#include <stdint.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct {
uint32_t buf[16];
uint32_t hash[8];
uint32_t len[2];
} sha256_context;
void sha256_init(sha256_context *);
void sha256_hash(sha256_context *, uint8_t * /* data */, uint32_t /* len */);
void sha256_done(sha256_context *, uint8_t * /* hash */);
#ifdef __cplusplus
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment