From 3a5a7de90601038570001c75d47a142e0642a7b5 Mon Sep 17 00:00:00 2001 From: "j4ck.fr0st" Date: Fri, 19 Feb 2010 17:05:26 +0000 Subject: [PATCH] NoGUI: general cleanup, add initialization stuff added in r5064, fixed the cocoa event loop not shutting down when not booting a game on OSX. SysConf: removed the Save call in the dtor, this crashes on linux trying to read m_Filename (which might be already freed). Common: set eol-style native, again. Fixes Issue 2332 git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5082 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/Atomic.h | 64 +- Source/Core/Common/Src/Atomic_GCC.h | 236 ++-- Source/Core/Common/Src/Atomic_Win32.h | 162 +-- Source/Core/Common/Src/ConsoleListener.h | 110 +- Source/Core/Common/Src/Crypto/ec.cpp | 796 ++++++------- Source/Core/Common/Src/Crypto/md5.cpp | 1140 +++++++++--------- Source/Core/Common/Src/Crypto/md5.h | 276 ++--- Source/Core/Common/Src/Crypto/sha1.cpp | 1222 ++++++++++---------- Source/Core/Common/Src/Crypto/sha1.h | 276 ++--- Source/Core/Common/Src/Crypto/tools.h | 42 +- Source/Core/Common/Src/LinearDiskCache.cpp | 298 ++--- Source/Core/Common/Src/LinearDiskCache.h | 132 +-- Source/Core/Common/Src/OpenCL.cpp | 506 ++++---- Source/Core/Common/Src/OpenCL.h | 140 +-- Source/Core/Common/Src/SysConf.cpp | 338 +++--- Source/Core/Common/Src/SysConf.h | 258 ++--- Source/Core/DolphinWX/Src/MainNoGUI.cpp | 58 +- 17 files changed, 3025 insertions(+), 3029 deletions(-) diff --git a/Source/Core/Common/Src/Atomic.h b/Source/Core/Common/Src/Atomic.h index 494b76c4d0..5b37b79c3d 100644 --- a/Source/Core/Common/Src/Atomic.h +++ b/Source/Core/Common/Src/Atomic.h @@ -1,32 +1,32 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _ATOMIC_H_ -#define _ATOMIC_H_ - -#ifdef _WIN32 - -#include "Atomic_Win32.h" - -#else - -// GCC-compatible compiler assumed! -#include "Atomic_GCC.h" - -#endif - -#endif +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _ATOMIC_H_ +#define _ATOMIC_H_ + +#ifdef _WIN32 + +#include "Atomic_Win32.h" + +#else + +// GCC-compatible compiler assumed! +#include "Atomic_GCC.h" + +#endif + +#endif diff --git a/Source/Core/Common/Src/Atomic_GCC.h b/Source/Core/Common/Src/Atomic_GCC.h index 62a2ecfb6b..8171926fb1 100644 --- a/Source/Core/Common/Src/Atomic_GCC.h +++ b/Source/Core/Common/Src/Atomic_GCC.h @@ -1,118 +1,118 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _ATOMIC_GCC_H_ -#define _ATOMIC_GCC_H_ - -#include "Common.h" - -// Atomic operations are performed in a single step by the CPU. It is -// impossible for other threads to see the operation "half-done." -// -// Some atomic operations can be combined with different types of memory -// barriers called "Acquire semantics" and "Release semantics", defined below. -// -// Acquire semantics: Future memory accesses cannot be relocated to before the -// operation. -// -// Release semantics: Past memory accesses cannot be relocated to after the -// operation. -// -// These barriers affect not only the compiler, but also the CPU. - -namespace Common -{ - -inline void AtomicAdd(volatile u32& target, u32 value) { - __sync_add_and_fetch(&target, value); -} - -inline void AtomicAnd(volatile u32& target, u32 value) { - __sync_and_and_fetch(&target, value); -} - -inline void AtomicIncrement(volatile u32& target) { - __sync_add_and_fetch(&target, 1); -} - -inline u32 AtomicLoad(volatile u32& src) { - return src; // 32-bit reads are always atomic. -} -inline u32 AtomicLoadAcquire(volatile u32& src) { - __sync_synchronize(); // TODO: May not be necessary. - return src; -} - -inline void AtomicOr(volatile u32& target, u32 value) { - __sync_or_and_fetch(&target, value); -} - -inline void AtomicStore(volatile u32& dest, u32 value) { - dest = value; // 32-bit writes are always atomic. -} -inline void AtomicStoreRelease(volatile u32& dest, u32 value) { - __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics. -} - -} - -// Old code kept here for reference in case we need the parts with __asm__ __volatile__. -#if 0 -LONG SyncInterlockedIncrement(LONG *Dest) -{ -#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) - return __sync_add_and_fetch(Dest, 1); -#else - register int result; - __asm__ __volatile__("lock; xadd %0,%1" - : "=r" (result), "=m" (*Dest) - : "0" (1), "m" (*Dest) - : "memory"); - return result; -#endif -} - -LONG SyncInterlockedExchangeAdd(LONG *Dest, LONG Val) -{ -#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) - return __sync_add_and_fetch(Dest, Val); -#else - register int result; - __asm__ __volatile__("lock; xadd %0,%1" - : "=r" (result), "=m" (*Dest) - : "0" (Val), "m" (*Dest) - : "memory"); - return result; -#endif -} - -LONG SyncInterlockedExchange(LONG *Dest, LONG Val) -{ -#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) - return __sync_lock_test_and_set(Dest, Val); -#else - register int result; - __asm__ __volatile__("lock; xchg %0,%1" - : "=r" (result), "=m" (*Dest) - : "0" (Val), "m" (*Dest) - : "memory"); - return result; -#endif -} -#endif - -#endif +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _ATOMIC_GCC_H_ +#define _ATOMIC_GCC_H_ + +#include "Common.h" + +// Atomic operations are performed in a single step by the CPU. It is +// impossible for other threads to see the operation "half-done." +// +// Some atomic operations can be combined with different types of memory +// barriers called "Acquire semantics" and "Release semantics", defined below. +// +// Acquire semantics: Future memory accesses cannot be relocated to before the +// operation. +// +// Release semantics: Past memory accesses cannot be relocated to after the +// operation. +// +// These barriers affect not only the compiler, but also the CPU. + +namespace Common +{ + +inline void AtomicAdd(volatile u32& target, u32 value) { + __sync_add_and_fetch(&target, value); +} + +inline void AtomicAnd(volatile u32& target, u32 value) { + __sync_and_and_fetch(&target, value); +} + +inline void AtomicIncrement(volatile u32& target) { + __sync_add_and_fetch(&target, 1); +} + +inline u32 AtomicLoad(volatile u32& src) { + return src; // 32-bit reads are always atomic. +} +inline u32 AtomicLoadAcquire(volatile u32& src) { + __sync_synchronize(); // TODO: May not be necessary. + return src; +} + +inline void AtomicOr(volatile u32& target, u32 value) { + __sync_or_and_fetch(&target, value); +} + +inline void AtomicStore(volatile u32& dest, u32 value) { + dest = value; // 32-bit writes are always atomic. +} +inline void AtomicStoreRelease(volatile u32& dest, u32 value) { + __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics. +} + +} + +// Old code kept here for reference in case we need the parts with __asm__ __volatile__. +#if 0 +LONG SyncInterlockedIncrement(LONG *Dest) +{ +#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) + return __sync_add_and_fetch(Dest, 1); +#else + register int result; + __asm__ __volatile__("lock; xadd %0,%1" + : "=r" (result), "=m" (*Dest) + : "0" (1), "m" (*Dest) + : "memory"); + return result; +#endif +} + +LONG SyncInterlockedExchangeAdd(LONG *Dest, LONG Val) +{ +#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) + return __sync_add_and_fetch(Dest, Val); +#else + register int result; + __asm__ __volatile__("lock; xadd %0,%1" + : "=r" (result), "=m" (*Dest) + : "0" (Val), "m" (*Dest) + : "memory"); + return result; +#endif +} + +LONG SyncInterlockedExchange(LONG *Dest, LONG Val) +{ +#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) + return __sync_lock_test_and_set(Dest, Val); +#else + register int result; + __asm__ __volatile__("lock; xchg %0,%1" + : "=r" (result), "=m" (*Dest) + : "0" (Val), "m" (*Dest) + : "memory"); + return result; +#endif +} +#endif + +#endif diff --git a/Source/Core/Common/Src/Atomic_Win32.h b/Source/Core/Common/Src/Atomic_Win32.h index 2d5c95c46b..4c2a9ec085 100644 --- a/Source/Core/Common/Src/Atomic_Win32.h +++ b/Source/Core/Common/Src/Atomic_Win32.h @@ -1,81 +1,81 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _ATOMIC_WIN32_H_ -#define _ATOMIC_WIN32_H_ - -#include "Common.h" -#include -#include - -// Atomic operations are performed in a single step by the CPU. It is -// impossible for other threads to see the operation "half-done." -// -// Some atomic operations can be combined with different types of memory -// barriers called "Acquire semantics" and "Release semantics", defined below. -// -// Acquire semantics: Future memory accesses cannot be relocated to before the -// operation. -// -// Release semantics: Past memory accesses cannot be relocated to after the -// operation. -// -// These barriers affect not only the compiler, but also the CPU. -// -// NOTE: Acquire and Release are not differentiated right now. They perform a -// full memory barrier instead of a "one-way" memory barrier. The newest -// Windows SDK has Acquire and Release versions of some Interlocked* functions. - -namespace Common -{ - -inline void AtomicAdd(volatile u32& target, u32 value) { - InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); -} - -inline void AtomicAnd(volatile u32& target, u32 value) { - _InterlockedAnd((volatile LONG*)&target, (LONG)value); -} - -inline void AtomicIncrement(volatile u32& target) { - InterlockedIncrement((volatile LONG*)&target); -} - -inline u32 AtomicLoad(volatile u32& src) { - return src; // 32-bit reads are always atomic. -} -inline u32 AtomicLoadAcquire(volatile u32& src) { - u32 result = src; // 32-bit reads are always atomic. - _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics. - return result; -} - -inline void AtomicOr(volatile u32& target, u32 value) { - _InterlockedOr((volatile LONG*)&target, (LONG)value); -} - -inline void AtomicStore(volatile u32& dest, u32 value) { - dest = value; // 32-bit writes are always atomic. -} -inline void AtomicStoreRelease(volatile u32& dest, u32 value) { - _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics. - dest = value; // 32-bit writes are always atomic. -} - -} - -#endif +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _ATOMIC_WIN32_H_ +#define _ATOMIC_WIN32_H_ + +#include "Common.h" +#include +#include + +// Atomic operations are performed in a single step by the CPU. It is +// impossible for other threads to see the operation "half-done." +// +// Some atomic operations can be combined with different types of memory +// barriers called "Acquire semantics" and "Release semantics", defined below. +// +// Acquire semantics: Future memory accesses cannot be relocated to before the +// operation. +// +// Release semantics: Past memory accesses cannot be relocated to after the +// operation. +// +// These barriers affect not only the compiler, but also the CPU. +// +// NOTE: Acquire and Release are not differentiated right now. They perform a +// full memory barrier instead of a "one-way" memory barrier. The newest +// Windows SDK has Acquire and Release versions of some Interlocked* functions. + +namespace Common +{ + +inline void AtomicAdd(volatile u32& target, u32 value) { + InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); +} + +inline void AtomicAnd(volatile u32& target, u32 value) { + _InterlockedAnd((volatile LONG*)&target, (LONG)value); +} + +inline void AtomicIncrement(volatile u32& target) { + InterlockedIncrement((volatile LONG*)&target); +} + +inline u32 AtomicLoad(volatile u32& src) { + return src; // 32-bit reads are always atomic. +} +inline u32 AtomicLoadAcquire(volatile u32& src) { + u32 result = src; // 32-bit reads are always atomic. + _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics. + return result; +} + +inline void AtomicOr(volatile u32& target, u32 value) { + _InterlockedOr((volatile LONG*)&target, (LONG)value); +} + +inline void AtomicStore(volatile u32& dest, u32 value) { + dest = value; // 32-bit writes are always atomic. +} +inline void AtomicStoreRelease(volatile u32& dest, u32 value) { + _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics. + dest = value; // 32-bit writes are always atomic. +} + +} + +#endif diff --git a/Source/Core/Common/Src/ConsoleListener.h b/Source/Core/Common/Src/ConsoleListener.h index 2484599638..2e8bffcf4b 100644 --- a/Source/Core/Common/Src/ConsoleListener.h +++ b/Source/Core/Common/Src/ConsoleListener.h @@ -1,55 +1,55 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _CONSOLELISTENER_H -#define _CONSOLELISTENER_H - -#include "LogManager.h" - -#ifdef _WIN32 -#include -#endif - -class ConsoleListener : public LogListener -{ -public: - ConsoleListener(); - ~ConsoleListener(); - - void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); - void UpdateHandle(); - void Close(); - bool IsOpen(); - void LetterSpace(int Width, int Height); - void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); - void PixelSpace(int Left, int Top, int Width, int Height, bool); - #ifdef _WIN32 - COORD GetCoordinates(int BytesRead, int BufferWidth); - #endif - void Log(LogTypes::LOG_LEVELS, const char *Text); - void ClearScreen(bool Cursor = true); - - const char *getName() const { return "Console"; } - -private: -#ifdef _WIN32 - HWND GetHwnd(void); - HANDLE hConsole; -#endif -}; - -#endif // _CONSOLELISTENER_H +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _CONSOLELISTENER_H +#define _CONSOLELISTENER_H + +#include "LogManager.h" + +#ifdef _WIN32 +#include +#endif + +class ConsoleListener : public LogListener +{ +public: + ConsoleListener(); + ~ConsoleListener(); + + void Open(bool Hidden = false, int Width = 100, int Height = 100, const char * Name = "Console"); + void UpdateHandle(); + void Close(); + bool IsOpen(); + void LetterSpace(int Width, int Height); + void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst); + void PixelSpace(int Left, int Top, int Width, int Height, bool); + #ifdef _WIN32 + COORD GetCoordinates(int BytesRead, int BufferWidth); + #endif + void Log(LogTypes::LOG_LEVELS, const char *Text); + void ClearScreen(bool Cursor = true); + + const char *getName() const { return "Console"; } + +private: +#ifdef _WIN32 + HWND GetHwnd(void); + HANDLE hConsole; +#endif +}; + +#endif // _CONSOLELISTENER_H diff --git a/Source/Core/Common/Src/Crypto/ec.cpp b/Source/Core/Common/Src/Crypto/ec.cpp index fc99d99410..507fea128e 100644 --- a/Source/Core/Common/Src/Crypto/ec.cpp +++ b/Source/Core/Common/Src/Crypto/ec.cpp @@ -1,398 +1,398 @@ -// Copyright 2007,2008 Segher Boessenkool -// Licensed under the terms of the GNU GPL, version 2 -// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt - -#include -#include -#include -#include - -#include "../Common.h" -#include "tools.h" -// y**2 + x*y = x**3 + x + b -static u8 ec_b[30] = - {0x00,0x66,0x64,0x7e,0xde,0x6c,0x33,0x2c,0x7f,0x8c,0x09,0x23,0xbb,0x58,0x21 - ,0x3b,0x33,0x3b,0x20,0xe9,0xce,0x42,0x81,0xfe,0x11,0x5f,0x7d,0x8f,0x90,0xad}; - -// order of the addition group of points -static u8 ec_N[30] = - {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - ,0x13,0xe9,0x74,0xe7,0x2f,0x8a,0x69,0x22,0x03,0x1d,0x26,0x03,0xcf,0xe0,0xd7}; - -// base point -static u8 ec_G[60] = - {0x00,0xfa,0xc9,0xdf,0xcb,0xac,0x83,0x13,0xbb,0x21,0x39,0xf1,0xbb,0x75,0x5f - ,0xef,0x65,0xbc,0x39,0x1f,0x8b,0x36,0xf8,0xf8,0xeb,0x73,0x71,0xfd,0x55,0x8b - ,0x01,0x00,0x6a,0x08,0xa4,0x19,0x03,0x35,0x06,0x78,0xe5,0x85,0x28,0xbe,0xbf - ,0x8a,0x0b,0xef,0xf8,0x67,0xa7,0xca,0x36,0x71,0x6f,0x7e,0x01,0xf8,0x10,0x52}; - -/*static void elt_print(char *name, u8 *a) -{ - u32 i; - - printf("%s = ", name); - - for (i = 0; i < 30; i++) - printf("%02x", a[i]); - - printf("\n"); -}*/ - -static void elt_copy(u8 *d, u8 *a) -{ - memcpy(d, a, 30); -} - -static void elt_zero(u8 *d) -{ - memset(d, 0, 30); -} - -static int elt_is_zero(u8 *d) -{ - u32 i; - - for (i = 0; i < 30; i++) - if (d[i] != 0) - return 0; - - return 1; -} - -static void elt_add(u8 *d, u8 *a, u8 *b) -{ - u32 i; - - for (i = 0; i < 30; i++) - d[i] = a[i] ^ b[i]; -} - -static void elt_mul_x(u8 *d, u8 *a) -{ - u8 carry, x, y; - u32 i; - - carry = a[0] & 1; - - x = 0; - for (i = 0; i < 29; i++) { - y = a[i + 1]; - d[i] = x ^ (y >> 7); - x = y << 1; - } - d[29] = x ^ carry; - - d[20] ^= carry << 2; -} - -static void elt_mul(u8 *d, u8 *a, u8 *b) -{ - u32 i, n; - u8 mask; - - elt_zero(d); - - i = 0; - mask = 1; - for (n = 0; n < 233; n++) { - elt_mul_x(d, d); - - if ((a[i] & mask) != 0) - elt_add(d, d, b); - - mask >>= 1; - if (mask == 0) { - mask = 0x80; - i++; - } - } -} - -static const u8 square[16] = -{0x00,0x01,0x04,0x05,0x10,0x11,0x14,0x15,0x40,0x41,0x44,0x45,0x50,0x51,0x54,0x55}; - -static void elt_square_to_wide(u8 *d, u8 *a) -{ - u32 i; - - for (i = 0; i < 30; i++) { - d[2*i] = square[a[i] >> 4]; - d[2*i + 1] = square[a[i] & 15]; - } -} - -static void wide_reduce(u8 *d) -{ - u32 i; - u8 x; - - for (i = 0; i < 30; i++) { - x = d[i]; - - d[i + 19] ^= x >> 7; - d[i + 20] ^= x << 1; - - d[i + 29] ^= x >> 1; - d[i + 30] ^= x << 7; - } - - x = d[30] & ~1; - - d[49] ^= x >> 7; - d[50] ^= x << 1; - - d[59] ^= x >> 1; - - d[30] &= 1; -} - -static void elt_square(u8 *d, u8 *a) -{ - u8 wide[60]; - - elt_square_to_wide(wide, a); - wide_reduce(wide); - - elt_copy(d, wide + 30); -} - -static void itoh_tsujii(u8 *d, u8 *a, u8 *b, u32 j) -{ - u8 t[30]; - - elt_copy(t, a); - while (j--) { - elt_square(d, t); - elt_copy(t, d); - } - - elt_mul(d, t, b); -} - -static void elt_inv(u8 *d, u8 *a) -{ - u8 t[30]; - u8 s[30]; - - itoh_tsujii(t, a, a, 1); - itoh_tsujii(s, t, a, 1); - itoh_tsujii(t, s, s, 3); - itoh_tsujii(s, t, a, 1); - itoh_tsujii(t, s, s, 7); - itoh_tsujii(s, t, t, 14); - itoh_tsujii(t, s, a, 1); - itoh_tsujii(s, t, t, 29); - itoh_tsujii(t, s, s, 58); - itoh_tsujii(s, t, t, 116); - elt_square(d, s); -} - -/*static int point_is_on_curve(u8 *p) -{ - u8 s[30], t[30]; - u8 *x, *y; - - x = p; - y = p + 30; - - elt_square(t, x); - elt_mul(s, t, x); - - elt_add(s, s, t); - - elt_square(t, y); - elt_add(s, s, t); - - elt_mul(t, x, y); - elt_add(s, s, t); - - elt_add(s, s, ec_b); - - return elt_is_zero(s); -} -*/ -static int point_is_zero(u8 *p) -{ - return elt_is_zero(p) && elt_is_zero(p + 30); -} - -static void point_double(u8 *r, u8 *p) -{ - u8 s[30], t[30]; - u8 *px, *py, *rx, *ry; - - px = p; - py = p + 30; - rx = r; - ry = r + 30; - - if (elt_is_zero(px)) { - elt_zero(rx); - elt_zero(ry); - - return; - } - - elt_inv(t, px); - elt_mul(s, py, t); - elt_add(s, s, px); - - elt_square(t, px); - - elt_square(rx, s); - elt_add(rx, rx, s); - rx[29] ^= 1; - - elt_mul(ry, s, rx); - elt_add(ry, ry, rx); - elt_add(ry, ry, t); -} - -static void point_add(u8 *r, u8 *p, u8 *q) -{ - u8 s[30], t[30], u[30]; - u8 *px, *py, *qx, *qy, *rx, *ry; - - px = p; - py = p + 30; - qx = q; - qy = q + 30; - rx = r; - ry = r + 30; - - if (point_is_zero(p)) { - elt_copy(rx, qx); - elt_copy(ry, qy); - return; - } - - if (point_is_zero(q)) { - elt_copy(rx, px); - elt_copy(ry, py); - return; - } - - elt_add(u, px, qx); - - if (elt_is_zero(u)) { - elt_add(u, py, qy); - if (elt_is_zero(u)) - point_double(r, p); - else { - elt_zero(rx); - elt_zero(ry); - } - - return; - } - - elt_inv(t, u); - elt_add(u, py, qy); - elt_mul(s, t, u); - - elt_square(t, s); - elt_add(t, t, s); - elt_add(t, t, qx); - t[29] ^= 1; - - elt_mul(u, s, t); - elt_add(s, u, py); - elt_add(rx, t, px); - elt_add(ry, s, rx); -} - -static void point_mul(u8 *d, u8 *a, u8 *b) // a is bignum -{ - u32 i; - u8 mask; - - elt_zero(d); - elt_zero(d + 30); - - for (i = 0; i < 30; i++) - for (mask = 0x80; mask != 0; mask >>= 1) { - point_double(d, d); - if ((a[i] & mask) != 0) - point_add(d, d, b); - } -} - -void silly_random(u8 * rndArea, u8 count) -{ - u16 i; - srand((unsigned) (time(NULL))); - - for(i=0;i= 0) - bn_sub_modulus(R, ec_N, 30); - - // S = m**-1*(e + Rk) (mod N) - - elt_copy(kk, k); - if (bn_compare(kk, ec_N, 30) >= 0) - bn_sub_modulus(kk, ec_N, 30); - bn_mul(S, R, kk, ec_N, 30); - bn_add(kk, S, e, ec_N, 30); - bn_inv(minv, m, ec_N, 30); - bn_mul(S, minv, kk, ec_N, 30); -} - -int check_ecdsa(u8 *Q, u8 *R, u8 *S, u8 *hash) -{ - u8 Sinv[30]; - u8 e[30]; - u8 w1[30], w2[30]; - u8 r1[60], r2[60]; - - bn_inv(Sinv, S, ec_N, 30); - - elt_zero(e); - memcpy(e + 10, hash, 20); - - bn_mul(w1, e, Sinv, ec_N, 30); - bn_mul(w2, R, Sinv, ec_N, 30); - - point_mul(r1, w1, ec_G); - point_mul(r2, w2, Q); - - point_add(r1, r1, r2); - - if (bn_compare(r1, ec_N, 30) >= 0) - bn_sub_modulus(r1, ec_N, 30); - - return (bn_compare(r1, R, 30) == 0); -} - -void ec_priv_to_pub(u8 *k, u8 *Q) -{ - point_mul(Q, k, ec_G); -} +// Copyright 2007,2008 Segher Boessenkool +// Licensed under the terms of the GNU GPL, version 2 +// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + +#include +#include +#include +#include + +#include "../Common.h" +#include "tools.h" +// y**2 + x*y = x**3 + x + b +static u8 ec_b[30] = + {0x00,0x66,0x64,0x7e,0xde,0x6c,0x33,0x2c,0x7f,0x8c,0x09,0x23,0xbb,0x58,0x21 + ,0x3b,0x33,0x3b,0x20,0xe9,0xce,0x42,0x81,0xfe,0x11,0x5f,0x7d,0x8f,0x90,0xad}; + +// order of the addition group of points +static u8 ec_N[30] = + {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + ,0x13,0xe9,0x74,0xe7,0x2f,0x8a,0x69,0x22,0x03,0x1d,0x26,0x03,0xcf,0xe0,0xd7}; + +// base point +static u8 ec_G[60] = + {0x00,0xfa,0xc9,0xdf,0xcb,0xac,0x83,0x13,0xbb,0x21,0x39,0xf1,0xbb,0x75,0x5f + ,0xef,0x65,0xbc,0x39,0x1f,0x8b,0x36,0xf8,0xf8,0xeb,0x73,0x71,0xfd,0x55,0x8b + ,0x01,0x00,0x6a,0x08,0xa4,0x19,0x03,0x35,0x06,0x78,0xe5,0x85,0x28,0xbe,0xbf + ,0x8a,0x0b,0xef,0xf8,0x67,0xa7,0xca,0x36,0x71,0x6f,0x7e,0x01,0xf8,0x10,0x52}; + +/*static void elt_print(char *name, u8 *a) +{ + u32 i; + + printf("%s = ", name); + + for (i = 0; i < 30; i++) + printf("%02x", a[i]); + + printf("\n"); +}*/ + +static void elt_copy(u8 *d, u8 *a) +{ + memcpy(d, a, 30); +} + +static void elt_zero(u8 *d) +{ + memset(d, 0, 30); +} + +static int elt_is_zero(u8 *d) +{ + u32 i; + + for (i = 0; i < 30; i++) + if (d[i] != 0) + return 0; + + return 1; +} + +static void elt_add(u8 *d, u8 *a, u8 *b) +{ + u32 i; + + for (i = 0; i < 30; i++) + d[i] = a[i] ^ b[i]; +} + +static void elt_mul_x(u8 *d, u8 *a) +{ + u8 carry, x, y; + u32 i; + + carry = a[0] & 1; + + x = 0; + for (i = 0; i < 29; i++) { + y = a[i + 1]; + d[i] = x ^ (y >> 7); + x = y << 1; + } + d[29] = x ^ carry; + + d[20] ^= carry << 2; +} + +static void elt_mul(u8 *d, u8 *a, u8 *b) +{ + u32 i, n; + u8 mask; + + elt_zero(d); + + i = 0; + mask = 1; + for (n = 0; n < 233; n++) { + elt_mul_x(d, d); + + if ((a[i] & mask) != 0) + elt_add(d, d, b); + + mask >>= 1; + if (mask == 0) { + mask = 0x80; + i++; + } + } +} + +static const u8 square[16] = +{0x00,0x01,0x04,0x05,0x10,0x11,0x14,0x15,0x40,0x41,0x44,0x45,0x50,0x51,0x54,0x55}; + +static void elt_square_to_wide(u8 *d, u8 *a) +{ + u32 i; + + for (i = 0; i < 30; i++) { + d[2*i] = square[a[i] >> 4]; + d[2*i + 1] = square[a[i] & 15]; + } +} + +static void wide_reduce(u8 *d) +{ + u32 i; + u8 x; + + for (i = 0; i < 30; i++) { + x = d[i]; + + d[i + 19] ^= x >> 7; + d[i + 20] ^= x << 1; + + d[i + 29] ^= x >> 1; + d[i + 30] ^= x << 7; + } + + x = d[30] & ~1; + + d[49] ^= x >> 7; + d[50] ^= x << 1; + + d[59] ^= x >> 1; + + d[30] &= 1; +} + +static void elt_square(u8 *d, u8 *a) +{ + u8 wide[60]; + + elt_square_to_wide(wide, a); + wide_reduce(wide); + + elt_copy(d, wide + 30); +} + +static void itoh_tsujii(u8 *d, u8 *a, u8 *b, u32 j) +{ + u8 t[30]; + + elt_copy(t, a); + while (j--) { + elt_square(d, t); + elt_copy(t, d); + } + + elt_mul(d, t, b); +} + +static void elt_inv(u8 *d, u8 *a) +{ + u8 t[30]; + u8 s[30]; + + itoh_tsujii(t, a, a, 1); + itoh_tsujii(s, t, a, 1); + itoh_tsujii(t, s, s, 3); + itoh_tsujii(s, t, a, 1); + itoh_tsujii(t, s, s, 7); + itoh_tsujii(s, t, t, 14); + itoh_tsujii(t, s, a, 1); + itoh_tsujii(s, t, t, 29); + itoh_tsujii(t, s, s, 58); + itoh_tsujii(s, t, t, 116); + elt_square(d, s); +} + +/*static int point_is_on_curve(u8 *p) +{ + u8 s[30], t[30]; + u8 *x, *y; + + x = p; + y = p + 30; + + elt_square(t, x); + elt_mul(s, t, x); + + elt_add(s, s, t); + + elt_square(t, y); + elt_add(s, s, t); + + elt_mul(t, x, y); + elt_add(s, s, t); + + elt_add(s, s, ec_b); + + return elt_is_zero(s); +} +*/ +static int point_is_zero(u8 *p) +{ + return elt_is_zero(p) && elt_is_zero(p + 30); +} + +static void point_double(u8 *r, u8 *p) +{ + u8 s[30], t[30]; + u8 *px, *py, *rx, *ry; + + px = p; + py = p + 30; + rx = r; + ry = r + 30; + + if (elt_is_zero(px)) { + elt_zero(rx); + elt_zero(ry); + + return; + } + + elt_inv(t, px); + elt_mul(s, py, t); + elt_add(s, s, px); + + elt_square(t, px); + + elt_square(rx, s); + elt_add(rx, rx, s); + rx[29] ^= 1; + + elt_mul(ry, s, rx); + elt_add(ry, ry, rx); + elt_add(ry, ry, t); +} + +static void point_add(u8 *r, u8 *p, u8 *q) +{ + u8 s[30], t[30], u[30]; + u8 *px, *py, *qx, *qy, *rx, *ry; + + px = p; + py = p + 30; + qx = q; + qy = q + 30; + rx = r; + ry = r + 30; + + if (point_is_zero(p)) { + elt_copy(rx, qx); + elt_copy(ry, qy); + return; + } + + if (point_is_zero(q)) { + elt_copy(rx, px); + elt_copy(ry, py); + return; + } + + elt_add(u, px, qx); + + if (elt_is_zero(u)) { + elt_add(u, py, qy); + if (elt_is_zero(u)) + point_double(r, p); + else { + elt_zero(rx); + elt_zero(ry); + } + + return; + } + + elt_inv(t, u); + elt_add(u, py, qy); + elt_mul(s, t, u); + + elt_square(t, s); + elt_add(t, t, s); + elt_add(t, t, qx); + t[29] ^= 1; + + elt_mul(u, s, t); + elt_add(s, u, py); + elt_add(rx, t, px); + elt_add(ry, s, rx); +} + +static void point_mul(u8 *d, u8 *a, u8 *b) // a is bignum +{ + u32 i; + u8 mask; + + elt_zero(d); + elt_zero(d + 30); + + for (i = 0; i < 30; i++) + for (mask = 0x80; mask != 0; mask >>= 1) { + point_double(d, d); + if ((a[i] & mask) != 0) + point_add(d, d, b); + } +} + +void silly_random(u8 * rndArea, u8 count) +{ + u16 i; + srand((unsigned) (time(NULL))); + + for(i=0;i= 0) + bn_sub_modulus(R, ec_N, 30); + + // S = m**-1*(e + Rk) (mod N) + + elt_copy(kk, k); + if (bn_compare(kk, ec_N, 30) >= 0) + bn_sub_modulus(kk, ec_N, 30); + bn_mul(S, R, kk, ec_N, 30); + bn_add(kk, S, e, ec_N, 30); + bn_inv(minv, m, ec_N, 30); + bn_mul(S, minv, kk, ec_N, 30); +} + +int check_ecdsa(u8 *Q, u8 *R, u8 *S, u8 *hash) +{ + u8 Sinv[30]; + u8 e[30]; + u8 w1[30], w2[30]; + u8 r1[60], r2[60]; + + bn_inv(Sinv, S, ec_N, 30); + + elt_zero(e); + memcpy(e + 10, hash, 20); + + bn_mul(w1, e, Sinv, ec_N, 30); + bn_mul(w2, R, Sinv, ec_N, 30); + + point_mul(r1, w1, ec_G); + point_mul(r2, w2, Q); + + point_add(r1, r1, r2); + + if (bn_compare(r1, ec_N, 30) >= 0) + bn_sub_modulus(r1, ec_N, 30); + + return (bn_compare(r1, R, 30) == 0); +} + +void ec_priv_to_pub(u8 *k, u8 *Q) +{ + point_mul(Q, k, ec_G); +} diff --git a/Source/Core/Common/Src/Crypto/md5.cpp b/Source/Core/Common/Src/Crypto/md5.cpp index 6f0b438f71..7fff7713da 100644 --- a/Source/Core/Common/Src/Crypto/md5.cpp +++ b/Source/Core/Common/Src/Crypto/md5.cpp @@ -1,570 +1,570 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright (C) 2006-2009, Paul Bakker - * All rights reserved. - * - * Joined copyright on original XySSL code with: Christophe Devine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -//#include "polarssl/config.h" - -#if defined(POLARSSL_MD5_C) - -#include "polarssl/md5.h" -#else -#include "md5.h" - -#include -#include - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -/* - * MD5 context setup - */ -void md5_starts( md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md5_process( md5_context *ctx, unsigned char data[64] ) -{ - unsigned long X[16], A, B, C, D; - - GET_ULONG_LE( X[ 0], data, 0 ); - GET_ULONG_LE( X[ 1], data, 4 ); - GET_ULONG_LE( X[ 2], data, 8 ); - GET_ULONG_LE( X[ 3], data, 12 ); - GET_ULONG_LE( X[ 4], data, 16 ); - GET_ULONG_LE( X[ 5], data, 20 ); - GET_ULONG_LE( X[ 6], data, 24 ); - GET_ULONG_LE( X[ 7], data, 28 ); - GET_ULONG_LE( X[ 8], data, 32 ); - GET_ULONG_LE( X[ 9], data, 36 ); - GET_ULONG_LE( X[10], data, 40 ); - GET_ULONG_LE( X[11], data, 44 ); - GET_ULONG_LE( X[12], data, 48 ); - GET_ULONG_LE( X[13], data, 52 ); - GET_ULONG_LE( X[14], data, 56 ); - GET_ULONG_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) (y ^ (z & (x ^ y))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) (y ^ (x | ~z)) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD5 process buffer - */ -void md5_update( md5_context *ctx, unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - md5_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md5_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, ilen ); - } -} - -static const unsigned char md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD5 final digest - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_LE( low, msglen, 0 ); - PUT_ULONG_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md5_update( ctx, (unsigned char *) md5_padding, padn ); - md5_update( ctx, msglen, 8 ); - - PUT_ULONG_LE( ctx->state[0], output, 0 ); - PUT_ULONG_LE( ctx->state[1], output, 4 ); - PUT_ULONG_LE( ctx->state[2], output, 8 ); - PUT_ULONG_LE( ctx->state[3], output, 12 ); -} - -/* - * output = MD5( input buffer ) - */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ) -{ - md5_context ctx; - - md5_starts( &ctx ); - md5_update( &ctx, input, ilen ); - md5_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); -} - -/* - * output = MD5( file contents ) - */ -int md5_file( char *path, unsigned char output[16] ) -{ - FILE *f; - size_t n; - md5_context ctx; - unsigned char buf[1024]; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( 1 ); - - md5_starts( &ctx ); - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - md5_update( &ctx, buf, (int) n ); - - md5_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); - - if( ferror( f ) != 0 ) - { - fclose( f ); - return( 2 ); - } - - fclose( f ); - return( 0 ); -} - -/* - * MD5 HMAC context setup - */ -void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ) -{ - int i; - unsigned char sum[16]; - - if( keylen > 64 ) - { - md5( key, keylen, sum ); - keylen = 16; - key = sum; - } - - memset( ctx->ipad, 0x36, 64 ); - memset( ctx->opad, 0x5C, 64 ); - - for( i = 0; i < keylen; i++ ) - { - ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); - ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); - } - - md5_starts( ctx ); - md5_update( ctx, ctx->ipad, 64 ); - - memset( sum, 0, sizeof( sum ) ); -} - -/* - * MD5 HMAC process buffer - */ -void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ) -{ - md5_update( ctx, input, ilen ); -} - -/* - * MD5 HMAC final digest - */ -void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ) -{ - unsigned char tmpbuf[16]; - - md5_finish( ctx, tmpbuf ); - md5_starts( ctx ); - md5_update( ctx, ctx->opad, 64 ); - md5_update( ctx, tmpbuf, 16 ); - md5_finish( ctx, output ); - - memset( tmpbuf, 0, sizeof( tmpbuf ) ); -} - -/* - * output = HMAC-MD5( hmac key, input buffer ) - */ -void md5_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen, - unsigned char output[16] ) -{ - md5_context ctx; - - md5_hmac_starts( &ctx, key, keylen ); - md5_hmac_update( &ctx, input, ilen ); - md5_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( md5_context ) ); -} - -#if defined(POLARSSL_SELF_TEST) -/* - * RFC 1321 test vectors - */ -static unsigned char md5_test_buf[7][81] = -{ - { "" }, - { "a" }, - { "abc" }, - { "message digest" }, - { "abcdefghijklmnopqrstuvwxyz" }, - { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, - { "12345678901234567890123456789012345678901234567890123456789012" \ - "345678901234567890" } -}; - -static const int md5_test_buflen[7] = -{ - 0, 1, 3, 14, 26, 62, 80 -}; - -static const unsigned char md5_test_sum[7][16] = -{ - { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, - 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, - { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, - 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, - { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, - 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, - { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, - 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, - { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, - 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, - { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, - 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, - { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, - 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } -}; - -/* - * RFC 2202 test vectors - */ -static unsigned char md5_hmac_test_key[7][26] = -{ - { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" }, - { "Jefe" }, - { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }, - { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" - "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, - { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" }, - { "" }, /* 0xAA 80 times */ - { "" } -}; - -static const int md5_hmac_test_keylen[7] = -{ - 16, 4, 16, 25, 16, 80, 80 -}; - -static unsigned char md5_hmac_test_buf[7][74] = -{ - { "Hi There" }, - { "what do ya want for nothing?" }, - { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, - { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, - { "Test With Truncation" }, - { "Test Using Larger Than Block-Size Key - Hash Key First" }, - { "Test Using Larger Than Block-Size Key and Larger" - " Than One Block-Size Data" } -}; - -static const int md5_hmac_test_buflen[7] = -{ - 8, 28, 50, 50, 20, 54, 73 -}; - -static const unsigned char md5_hmac_test_sum[7][16] = -{ - { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C, - 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D }, - { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03, - 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 }, - { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88, - 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 }, - { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA, - 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 }, - { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00, - 0xF9, 0xBA, 0xB9, 0x95 }, - { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F, - 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD }, - { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE, - 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E } -}; - -/* - * Checkup routine - */ -int md5_self_test( int verbose ) -{ - int i, buflen; - unsigned char buf[1024]; - unsigned char md5sum[16]; - md5_context ctx; - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - printf( " MD5 test #%d: ", i + 1 ); - - md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); - - if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - printf( " HMAC-MD5 test #%d: ", i + 1 ); - - if( i == 5 || i == 6 ) - { - memset( buf, '\xAA', buflen = 80 ); - md5_hmac_starts( &ctx, buf, buflen ); - } - else - md5_hmac_starts( &ctx, md5_hmac_test_key[i], - md5_hmac_test_keylen[i] ); - - md5_hmac_update( &ctx, md5_hmac_test_buf[i], - md5_hmac_test_buflen[i] ); - - md5_hmac_finish( &ctx, md5sum ); - - buflen = ( i == 4 ) ? 12 : 16; - - if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - return( 0 ); -} - -#endif - -#endif +/* + * RFC 1321 compliant MD5 implementation + * + * Copyright (C) 2006-2009, Paul Bakker + * All rights reserved. + * + * Joined copyright on original XySSL code with: Christophe Devine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD5 algorithm was designed by Ron Rivest in 1991. + * + * http://www.ietf.org/rfc/rfc1321.txt + */ + +//#include "polarssl/config.h" + +#if defined(POLARSSL_MD5_C) + +#include "polarssl/md5.h" +#else +#include "md5.h" + +#include +#include + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * MD5 context setup + */ +void md5_starts( md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md5_process( md5_context *ctx, unsigned char data[64] ) +{ + unsigned long X[16], A, B, C, D; + + GET_ULONG_LE( X[ 0], data, 0 ); + GET_ULONG_LE( X[ 1], data, 4 ); + GET_ULONG_LE( X[ 2], data, 8 ); + GET_ULONG_LE( X[ 3], data, 12 ); + GET_ULONG_LE( X[ 4], data, 16 ); + GET_ULONG_LE( X[ 5], data, 20 ); + GET_ULONG_LE( X[ 6], data, 24 ); + GET_ULONG_LE( X[ 7], data, 28 ); + GET_ULONG_LE( X[ 8], data, 32 ); + GET_ULONG_LE( X[ 9], data, 36 ); + GET_ULONG_LE( X[10], data, 40 ); + GET_ULONG_LE( X[11], data, 44 ); + GET_ULONG_LE( X[12], data, 48 ); + GET_ULONG_LE( X[13], data, 52 ); + GET_ULONG_LE( X[14], data, 56 ); + GET_ULONG_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD5 process buffer + */ +void md5_update( md5_context *ctx, unsigned char *input, int ilen ) +{ + int fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + md5_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md5_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD5 final digest + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_LE( low, msglen, 0 ); + PUT_ULONG_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, (unsigned char *) md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_ULONG_LE( ctx->state[0], output, 0 ); + PUT_ULONG_LE( ctx->state[1], output, 4 ); + PUT_ULONG_LE( ctx->state[2], output, 8 ); + PUT_ULONG_LE( ctx->state[3], output, 12 ); +} + +/* + * output = MD5( input buffer ) + */ +void md5( unsigned char *input, int ilen, unsigned char output[16] ) +{ + md5_context ctx; + + md5_starts( &ctx ); + md5_update( &ctx, input, ilen ); + md5_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md5_context ) ); +} + +/* + * output = MD5( file contents ) + */ +int md5_file( char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + md5_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( 1 ); + + md5_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md5_update( &ctx, buf, (int) n ); + + md5_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md5_context ) ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( 2 ); + } + + fclose( f ); + return( 0 ); +} + +/* + * MD5 HMAC context setup + */ +void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ) +{ + int i; + unsigned char sum[16]; + + if( keylen > 64 ) + { + md5( key, keylen, sum ); + keylen = 16; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + md5_starts( ctx ); + md5_update( ctx, ctx->ipad, 64 ); + + memset( sum, 0, sizeof( sum ) ); +} + +/* + * MD5 HMAC process buffer + */ +void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ) +{ + md5_update( ctx, input, ilen ); +} + +/* + * MD5 HMAC final digest + */ +void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned char tmpbuf[16]; + + md5_finish( ctx, tmpbuf ); + md5_starts( ctx ); + md5_update( ctx, ctx->opad, 64 ); + md5_update( ctx, tmpbuf, 16 ); + md5_finish( ctx, output ); + + memset( tmpbuf, 0, sizeof( tmpbuf ) ); +} + +/* + * output = HMAC-MD5( hmac key, input buffer ) + */ +void md5_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen, + unsigned char output[16] ) +{ + md5_context ctx; + + md5_hmac_starts( &ctx, key, keylen ); + md5_hmac_update( &ctx, input, ilen ); + md5_hmac_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( md5_context ) ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * RFC 1321 test vectors + */ +static unsigned char md5_test_buf[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const int md5_test_buflen[7] = +{ + 0, 1, 3, 14, 26, 62, 80 +}; + +static const unsigned char md5_test_sum[7][16] = +{ + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char md5_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int md5_hmac_test_keylen[7] = +{ + 16, 4, 16, 25, 16, 80, 80 +}; + +static unsigned char md5_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int md5_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char md5_hmac_test_sum[7][16] = +{ + { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C, + 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D }, + { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03, + 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 }, + { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88, + 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 }, + { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA, + 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 }, + { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00, + 0xF9, 0xBA, 0xB9, 0x95 }, + { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F, + 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD }, + { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE, + 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E } +}; + +/* + * Checkup routine + */ +int md5_self_test( int verbose ) +{ + int i, buflen; + unsigned char buf[1024]; + unsigned char md5sum[16]; + md5_context ctx; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + printf( " MD5 test #%d: ", i + 1 ); + + md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); + + if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + printf( " HMAC-MD5 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + md5_hmac_starts( &ctx, buf, buflen ); + } + else + md5_hmac_starts( &ctx, md5_hmac_test_key[i], + md5_hmac_test_keylen[i] ); + + md5_hmac_update( &ctx, md5_hmac_test_buf[i], + md5_hmac_test_buflen[i] ); + + md5_hmac_finish( &ctx, md5sum ); + + buflen = ( i == 4 ) ? 12 : 16; + + if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + return( 0 ); +} + +#endif + +#endif diff --git a/Source/Core/Common/Src/Crypto/md5.h b/Source/Core/Common/Src/Crypto/md5.h index 24a02197fa..a69024d116 100644 --- a/Source/Core/Common/Src/Crypto/md5.h +++ b/Source/Core/Common/Src/Crypto/md5.h @@ -1,138 +1,138 @@ -/** - * \file md5.h - * - * Copyright (C) 2006-2009, Paul Bakker - * All rights reserved. - * - * Joined copyright on original XySSL code with: Christophe Devine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef POLARSSL_MD5_H -#define POLARSSL_MD5_H - -/** - * \brief MD5 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ - - unsigned char ipad[64]; /*!< HMAC: inner padding */ - unsigned char opad[64]; /*!< HMAC: outer padding */ -} -md5_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD5 context setup - * - * \param ctx context to be initialized - */ -void md5_starts( md5_context *ctx ); - -/** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md5_update( md5_context *ctx, unsigned char *input, int ilen ); - -/** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ); - -/** - * \brief Output = MD5( file contents ) - * - * \param path input file name - * \param output MD5 checksum result - * - * \return 0 if successful, 1 if fopen failed, - * or 2 if fread failed - */ -int md5_file( char *path, unsigned char output[16] ); - -/** - * \brief MD5 HMAC context setup - * - * \param ctx HMAC context to be initialized - * \param key HMAC secret key - * \param keylen length of the HMAC key - */ -void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ); - -/** - * \brief MD5 HMAC process buffer - * - * \param ctx HMAC context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ); - -/** - * \brief MD5 HMAC final digest - * - * \param ctx HMAC context - * \param output MD5 HMAC checksum result - */ -void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = HMAC-MD5( hmac key, input buffer ) - * - * \param key HMAC secret key - * \param keylen length of the HMAC key - * \param input buffer holding the data - * \param ilen length of the input data - * \param output HMAC-MD5 result - */ -void md5_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[16] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int md5_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* md5.h */ +/** + * \file md5.h + * + * Copyright (C) 2006-2009, Paul Bakker + * All rights reserved. + * + * Joined copyright on original XySSL code with: Christophe Devine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MD5_H +#define POLARSSL_MD5_H + +/** + * \brief MD5 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +md5_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD5 context setup + * + * \param ctx context to be initialized + */ +void md5_starts( md5_context *ctx ); + +/** + * \brief MD5 process buffer + * + * \param ctx MD5 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_update( md5_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief MD5 final digest + * + * \param ctx MD5 context + * \param output MD5 checksum result + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = MD5( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD5 checksum result + */ +void md5( unsigned char *input, int ilen, unsigned char output[16] ); + +/** + * \brief Output = MD5( file contents ) + * + * \param path input file name + * \param output MD5 checksum result + * + * \return 0 if successful, 1 if fopen failed, + * or 2 if fread failed + */ +int md5_file( char *path, unsigned char output[16] ); + +/** + * \brief MD5 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen ); + +/** + * \brief MD5 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief MD5 HMAC final digest + * + * \param ctx HMAC context + * \param output MD5 HMAC checksum result + */ +void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = HMAC-MD5( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-MD5 result + */ +void md5_hmac( unsigned char *key, int keylen, + unsigned char *input, int ilen, + unsigned char output[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int md5_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* md5.h */ diff --git a/Source/Core/Common/Src/Crypto/sha1.cpp b/Source/Core/Common/Src/Crypto/sha1.cpp index 96845dd8aa..17ad930986 100644 --- a/Source/Core/Common/Src/Crypto/sha1.cpp +++ b/Source/Core/Common/Src/Crypto/sha1.cpp @@ -1,611 +1,611 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright (C) 2006-2009, Paul Bakker - * All rights reserved. - * - * Joined copyright on original XySSL code with: Christophe Devine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ -/* -#include "polarssl/config.h" - -#if defined(POLARSSL_SHA1_C) - -#include "polarssl/sha1.h" -*/ -#include "sha1.h" -#include -#include - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * SHA-1 context setup - */ -void sha1_starts( sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -static void sha1_process( sha1_context *ctx, unsigned char data[64] ) -{ - unsigned long temp, W[16], A, B, C, D, E; - - GET_ULONG_BE( W[ 0], data, 0 ); - GET_ULONG_BE( W[ 1], data, 4 ); - GET_ULONG_BE( W[ 2], data, 8 ); - GET_ULONG_BE( W[ 3], data, 12 ); - GET_ULONG_BE( W[ 4], data, 16 ); - GET_ULONG_BE( W[ 5], data, 20 ); - GET_ULONG_BE( W[ 6], data, 24 ); - GET_ULONG_BE( W[ 7], data, 28 ); - GET_ULONG_BE( W[ 8], data, 32 ); - GET_ULONG_BE( W[ 9], data, 36 ); - GET_ULONG_BE( W[10], data, 40 ); - GET_ULONG_BE( W[11], data, 44 ); - GET_ULONG_BE( W[12], data, 48 ); - GET_ULONG_BE( W[13], data, 52 ); - GET_ULONG_BE( W[14], data, 56 ); - GET_ULONG_BE( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -/* - * SHA-1 process buffer - */ -void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - sha1_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - sha1_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, ilen ); - } -} - -static const unsigned char sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * SHA-1 final digest - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_BE( high, msglen, 0 ); - PUT_ULONG_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - sha1_update( ctx, (unsigned char *) sha1_padding, padn ); - sha1_update( ctx, msglen, 8 ); - - PUT_ULONG_BE( ctx->state[0], output, 0 ); - PUT_ULONG_BE( ctx->state[1], output, 4 ); - PUT_ULONG_BE( ctx->state[2], output, 8 ); - PUT_ULONG_BE( ctx->state[3], output, 12 ); - PUT_ULONG_BE( ctx->state[4], output, 16 ); -} - -/* - * output = SHA-1( input buffer ) - */ -void sha1( unsigned char *input, int ilen, unsigned char output[20] ) -{ - sha1_context ctx; - - sha1_starts( &ctx ); - sha1_update( &ctx, input, ilen ); - sha1_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); -} - -/* - * output = SHA-1( file contents ) - */ -int sha1_file( char *path, unsigned char output[20] ) -{ - FILE *f; - size_t n; - sha1_context ctx; - unsigned char buf[1024]; - - if( ( f = fopen( path, "rb" ) ) == NULL ) - return( 1 ); - - sha1_starts( &ctx ); - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - sha1_update( &ctx, buf, (int) n ); - - sha1_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); - - if( ferror( f ) != 0 ) - { - fclose( f ); - return( 2 ); - } - - fclose( f ); - return( 0 ); -} - -/* - * SHA-1 HMAC context setup - */ -void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ) -{ - int i; - unsigned char sum[20]; - - if( keylen > 64 ) - { - sha1( key, keylen, sum ); - keylen = 20; - key = sum; - } - - memset( ctx->ipad, 0x36, 64 ); - memset( ctx->opad, 0x5C, 64 ); - - for( i = 0; i < keylen; i++ ) - { - ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); - ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); - } - - sha1_starts( ctx ); - sha1_update( ctx, ctx->ipad, 64 ); - - memset( sum, 0, sizeof( sum ) ); -} - -/* - * SHA-1 HMAC process buffer - */ -void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ) -{ - sha1_update( ctx, input, ilen ); -} - -/* - * SHA-1 HMAC final digest - */ -void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) -{ - unsigned char tmpbuf[20]; - - sha1_finish( ctx, tmpbuf ); - sha1_starts( ctx ); - sha1_update( ctx, ctx->opad, 64 ); - sha1_update( ctx, tmpbuf, 20 ); - sha1_finish( ctx, output ); - - memset( tmpbuf, 0, sizeof( tmpbuf ) ); -} - -/* - * output = HMAC-SHA-1( hmac key, input buffer ) - */ -void sha1_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[20] ) -{ - sha1_context ctx; - - sha1_hmac_starts( &ctx, key, keylen ); - sha1_hmac_update( &ctx, input, ilen ); - sha1_hmac_finish( &ctx, output ); - - memset( &ctx, 0, sizeof( sha1_context ) ); -} - -#if defined(POLARSSL_SELF_TEST) -/* - * FIPS-180-1 test vectors - */ -static unsigned char sha1_test_buf[3][57] = -{ - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - { "" } -}; - -static const int sha1_test_buflen[3] = -{ - 3, 56, 1000 -}; - -static const unsigned char sha1_test_sum[3][20] = -{ - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, - { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, - 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } -}; - -/* - * RFC 2202 test vectors - */ -static unsigned char sha1_hmac_test_key[7][26] = -{ - { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" - "\x0B\x0B\x0B\x0B" }, - { "Jefe" }, - { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" - "\xAA\xAA\xAA\xAA" }, - { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" - "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, - { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" - "\x0C\x0C\x0C\x0C" }, - { "" }, /* 0xAA 80 times */ - { "" } -}; - -static const int sha1_hmac_test_keylen[7] = -{ - 20, 4, 20, 25, 20, 80, 80 -}; - -static unsigned char sha1_hmac_test_buf[7][74] = -{ - { "Hi There" }, - { "what do ya want for nothing?" }, - { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" - "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, - { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" - "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, - { "Test With Truncation" }, - { "Test Using Larger Than Block-Size Key - Hash Key First" }, - { "Test Using Larger Than Block-Size Key and Larger" - " Than One Block-Size Data" } -}; - -static const int sha1_hmac_test_buflen[7] = -{ - 8, 28, 50, 50, 20, 54, 73 -}; - -static const unsigned char sha1_hmac_test_sum[7][20] = -{ - { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, - 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, - { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, - 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, - { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, - 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, - { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, - 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, - { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, - 0x7B, 0xE1 }, - { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, - 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, - { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, - 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } -}; - -/* - * Checkup routine - */ -int sha1_self_test( int verbose ) -{ - int i, j, buflen; - unsigned char buf[1024]; - unsigned char sha1sum[20]; - sha1_context ctx; - - /* - * SHA-1 - */ - for( i = 0; i < 3; i++ ) - { - if( verbose != 0 ) - printf( " SHA-1 test #%d: ", i + 1 ); - - sha1_starts( &ctx ); - - if( i == 2 ) - { - memset( buf, 'a', buflen = 1000 ); - - for( j = 0; j < 1000; j++ ) - sha1_update( &ctx, buf, buflen ); - } - else - sha1_update( &ctx, sha1_test_buf[i], - sha1_test_buflen[i] ); - - sha1_finish( &ctx, sha1sum ); - - if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - for( i = 0; i < 7; i++ ) - { - if( verbose != 0 ) - printf( " HMAC-SHA-1 test #%d: ", i + 1 ); - - if( i == 5 || i == 6 ) - { - memset( buf, '\xAA', buflen = 80 ); - sha1_hmac_starts( &ctx, buf, buflen ); - } - else - sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], - sha1_hmac_test_keylen[i] ); - - sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], - sha1_hmac_test_buflen[i] ); - - sha1_hmac_finish( &ctx, sha1sum ); - - buflen = ( i == 4 ) ? 12 : 20; - - if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) - { - if( verbose != 0 ) - printf( "failed\n" ); - - return( 1 ); - } - - if( verbose != 0 ) - printf( "passed\n" ); - } - - if( verbose != 0 ) - printf( "\n" ); - - return( 0 ); -} - -#endif - -//#endif +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2009, Paul Bakker + * All rights reserved. + * + * Joined copyright on original XySSL code with: Christophe Devine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ +/* +#include "polarssl/config.h" + +#if defined(POLARSSL_SHA1_C) + +#include "polarssl/sha1.h" +*/ +#include "sha1.h" +#include +#include + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * SHA-1 context setup + */ +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +static void sha1_process( sha1_context *ctx, unsigned char data[64] ) +{ + unsigned long temp, W[16], A, B, C, D, E; + + GET_ULONG_BE( W[ 0], data, 0 ); + GET_ULONG_BE( W[ 1], data, 4 ); + GET_ULONG_BE( W[ 2], data, 8 ); + GET_ULONG_BE( W[ 3], data, 12 ); + GET_ULONG_BE( W[ 4], data, 16 ); + GET_ULONG_BE( W[ 5], data, 20 ); + GET_ULONG_BE( W[ 6], data, 24 ); + GET_ULONG_BE( W[ 7], data, 28 ); + GET_ULONG_BE( W[ 8], data, 32 ); + GET_ULONG_BE( W[ 9], data, 36 ); + GET_ULONG_BE( W[10], data, 40 ); + GET_ULONG_BE( W[11], data, 44 ); + GET_ULONG_BE( W[12], data, 48 ); + GET_ULONG_BE( W[13], data, 52 ); + GET_ULONG_BE( W[14], data, 56 ); + GET_ULONG_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ + W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + * SHA-1 process buffer + */ +void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ) +{ + int fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_BE( high, msglen, 0 ); + PUT_ULONG_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, (unsigned char *) sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_ULONG_BE( ctx->state[0], output, 0 ); + PUT_ULONG_BE( ctx->state[1], output, 4 ); + PUT_ULONG_BE( ctx->state[2], output, 8 ); + PUT_ULONG_BE( ctx->state[3], output, 12 ); + PUT_ULONG_BE( ctx->state[4], output, 16 ); +} + +/* + * output = SHA-1( input buffer ) + */ +void sha1( unsigned char *input, int ilen, unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha1_context ) ); +} + +/* + * output = SHA-1( file contents ) + */ +int sha1_file( char *path, unsigned char output[20] ) +{ + FILE *f; + size_t n; + sha1_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( 1 ); + + sha1_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha1_update( &ctx, buf, (int) n ); + + sha1_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha1_context ) ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( 2 ); + } + + fclose( f ); + return( 0 ); +} + +/* + * SHA-1 HMAC context setup + */ +void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ) +{ + int i; + unsigned char sum[20]; + + if( keylen > 64 ) + { + sha1( key, keylen, sum ); + keylen = 20; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); + + memset( sum, 0, sizeof( sum ) ); +} + +/* + * SHA-1 HMAC process buffer + */ +void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ) +{ + sha1_update( ctx, input, ilen ); +} + +/* + * SHA-1 HMAC final digest + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned char tmpbuf[20]; + + sha1_finish( ctx, tmpbuf ); + sha1_starts( ctx ); + sha1_update( ctx, ctx->opad, 64 ); + sha1_update( ctx, tmpbuf, 20 ); + sha1_finish( ctx, output ); + + memset( tmpbuf, 0, sizeof( tmpbuf ) ); +} + +/* + * output = HMAC-SHA-1( hmac key, input buffer ) + */ +void sha1_hmac( unsigned char *key, int keylen, + unsigned char *input, int ilen, + unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_hmac_starts( &ctx, key, keylen ); + sha1_hmac_update( &ctx, input, ilen ); + sha1_hmac_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha1_context ) ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * FIPS-180-1 test vectors + */ +static unsigned char sha1_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha1_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha1_test_sum[3][20] = +{ + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, + { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, + 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char sha1_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int sha1_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 80, 80 +}; + +static unsigned char sha1_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int sha1_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char sha1_hmac_test_sum[7][20] = +{ + { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, + 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, + { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, + 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, + { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, + 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, + { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, + 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, + { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, + 0x7B, 0xE1 }, + { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, + 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, + { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, + 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } +}; + +/* + * Checkup routine + */ +int sha1_self_test( int verbose ) +{ + int i, j, buflen; + unsigned char buf[1024]; + unsigned char sha1sum[20]; + sha1_context ctx; + + /* + * SHA-1 + */ + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + printf( " SHA-1 test #%d: ", i + 1 ); + + sha1_starts( &ctx ); + + if( i == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha1_update( &ctx, buf, buflen ); + } + else + sha1_update( &ctx, sha1_test_buf[i], + sha1_test_buflen[i] ); + + sha1_finish( &ctx, sha1sum ); + + if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + printf( " HMAC-SHA-1 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + sha1_hmac_starts( &ctx, buf, buflen ); + } + else + sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], + sha1_hmac_test_keylen[i] ); + + sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], + sha1_hmac_test_buflen[i] ); + + sha1_hmac_finish( &ctx, sha1sum ); + + buflen = ( i == 4 ) ? 12 : 20; + + if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + return( 0 ); +} + +#endif + +//#endif diff --git a/Source/Core/Common/Src/Crypto/sha1.h b/Source/Core/Common/Src/Crypto/sha1.h index 846a938b41..01e522d5db 100644 --- a/Source/Core/Common/Src/Crypto/sha1.h +++ b/Source/Core/Common/Src/Crypto/sha1.h @@ -1,138 +1,138 @@ -/** - * \file sha1.h - * - * Copyright (C) 2006-2009, Paul Bakker - * All rights reserved. - * - * Joined copyright on original XySSL code with: Christophe Devine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef POLARSSL_SHA1_H -#define POLARSSL_SHA1_H - -/** - * \brief SHA-1 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[5]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ - - unsigned char ipad[64]; /*!< HMAC: inner padding */ - unsigned char opad[64]; /*!< HMAC: outer padding */ -} -sha1_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief SHA-1 context setup - * - * \param ctx context to be initialized - */ -void sha1_starts( sha1_context *ctx ); - -/** - * \brief SHA-1 process buffer - * - * \param ctx SHA-1 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ); - -/** - * \brief SHA-1 final digest - * - * \param ctx SHA-1 context - * \param output SHA-1 checksum result - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ); - -/** - * \brief Output = SHA-1( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-1 checksum result - */ -void sha1( unsigned char *input, int ilen, unsigned char output[20] ); - -/** - * \brief Output = SHA-1( file contents ) - * - * \param path input file name - * \param output SHA-1 checksum result - * - * \return 0 if successful, 1 if fopen failed, - * or 2 if fread failed - */ -int sha1_file( char *path, unsigned char output[20] ); - -/** - * \brief SHA-1 HMAC context setup - * - * \param ctx HMAC context to be initialized - * \param key HMAC secret key - * \param keylen length of the HMAC key - */ -void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ); - -/** - * \brief SHA-1 HMAC process buffer - * - * \param ctx HMAC context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ); - -/** - * \brief SHA-1 HMAC final digest - * - * \param ctx HMAC context - * \param output SHA-1 HMAC checksum result - */ -void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); - -/** - * \brief Output = HMAC-SHA-1( hmac key, input buffer ) - * - * \param key HMAC secret key - * \param keylen length of the HMAC key - * \param input buffer holding the data - * \param ilen length of the input data - * \param output HMAC-SHA-1 result - */ -void sha1_hmac( unsigned char *key, int keylen, - unsigned char *input, int ilen, - unsigned char output[20] ); - -/** - * \brief Checkup routine - * - * \return 0 if successful, or 1 if the test failed - */ -int sha1_self_test( int verbose ); - -#ifdef __cplusplus -} -#endif - -#endif /* sha1.h */ +/** + * \file sha1.h + * + * Copyright (C) 2006-2009, Paul Bakker + * All rights reserved. + * + * Joined copyright on original XySSL code with: Christophe Devine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SHA1_H +#define POLARSSL_SHA1_H + +/** + * \brief SHA-1 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +sha1_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + */ +void sha1_starts( sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-1 checksum result + */ +void sha1( unsigned char *input, int ilen, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( file contents ) + * + * \param path input file name + * \param output SHA-1 checksum result + * + * \return 0 if successful, 1 if fopen failed, + * or 2 if fread failed + */ +int sha1_file( char *path, unsigned char output[20] ); + +/** + * \brief SHA-1 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen ); + +/** + * \brief SHA-1 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief SHA-1 HMAC final digest + * + * \param ctx HMAC context + * \param output SHA-1 HMAC checksum result + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief Output = HMAC-SHA-1( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-SHA-1 result + */ +void sha1_hmac( unsigned char *key, int keylen, + unsigned char *input, int ilen, + unsigned char output[20] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int sha1_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* sha1.h */ diff --git a/Source/Core/Common/Src/Crypto/tools.h b/Source/Core/Common/Src/Crypto/tools.h index 2621b86c29..a3946d66a1 100644 --- a/Source/Core/Common/Src/Crypto/tools.h +++ b/Source/Core/Common/Src/Crypto/tools.h @@ -1,21 +1,21 @@ -// Copyright 2007,2008 Segher Boessenkool -// Licensed under the terms of the GNU GPL, version 2 -// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt - -#ifndef _TOOLS_H -#define _TOOLS_H -#include "sha1.h" - -// bignum -int bn_compare(u8 *a, u8 *b, u32 n); -void bn_sub_modulus(u8 *a, u8 *N, u32 n); -void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n); -void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n); -void bn_inv(u8 *d, u8 *a, u8 *N, u32 n); // only for prime N -void bn_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en); - -void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash); - -void ec_priv_to_pub(u8 *k, u8 *Q); - -#endif +// Copyright 2007,2008 Segher Boessenkool +// Licensed under the terms of the GNU GPL, version 2 +// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt + +#ifndef _TOOLS_H +#define _TOOLS_H +#include "sha1.h" + +// bignum +int bn_compare(u8 *a, u8 *b, u32 n); +void bn_sub_modulus(u8 *a, u8 *N, u32 n); +void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n); +void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n); +void bn_inv(u8 *d, u8 *a, u8 *N, u32 n); // only for prime N +void bn_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en); + +void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash); + +void ec_priv_to_pub(u8 *k, u8 *Q); + +#endif diff --git a/Source/Core/Common/Src/LinearDiskCache.cpp b/Source/Core/Common/Src/LinearDiskCache.cpp index 2a2a9959a3..ae52433ba0 100644 --- a/Source/Core/Common/Src/LinearDiskCache.cpp +++ b/Source/Core/Common/Src/LinearDiskCache.cpp @@ -1,149 +1,149 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include "LinearDiskCache.h" - -static const char ID[4] = {'D', 'C', 'A', 'C'}; -const int version = 4888; // TODO: Get from SVN_REV - -LinearDiskCache::LinearDiskCache() - : file_(NULL), num_entries_(0) { -} - -void LinearDiskCache::WriteHeader() { - fwrite(ID, 4, 1, file_); - fwrite(&version, 4, 1, file_); -} - -bool LinearDiskCache::ValidateHeader() { - char header_id[4]; - int header_version; - fread(&header_id, 4, 1, file_); - fread(&header_version, 4, 1, file_); - if (memcmp(header_id, ID, 4) != 0) - return false; - if (header_version != version) - return false; - return true; -} - -int LinearDiskCache::OpenAndRead(const char *filename, LinearDiskCacheReader *reader) { - int items_read_count = 0; - file_ = fopen(filename, "rb"); - int file_size = 0; - if (file_) { - fseek(file_, 0, SEEK_END); - file_size = (int)ftell(file_); - } - - bool file_corrupt = false; - if (file_size == 0) { - if (file_) - fclose(file_); - // Reopen for writing. - file_ = fopen(filename, "wb"); - // Cache empty, let's initialize a header. - WriteHeader(); - num_entries_ = 0; - } else { - // file_ must be != 0 here. - // Back to the start we go. - fseek(file_, 0, SEEK_SET); - // Check that the file is valid - if (!ValidateHeader()) { - // Not valid - delete the file and start over. - fclose(file_); - unlink(filename); - - // PanicAlert("LinearDiskCache file header broken."); - - file_ = fopen(filename, "wb"); - WriteHeader(); - num_entries_ = 0; - } else { - // Valid - blow through it. - // We're past the header already thanks to ValidateHeader. - while (!feof(file_)) { - int key_size, value_size; - size_t key_size_size = fread(&key_size, 1, sizeof(key_size), file_); - size_t value_size_size = fread(&value_size, 1, sizeof(value_size), file_); - if (key_size_size == 0 && value_size_size == 0) { - // I guess feof isn't doing it's job - we're at the end. - break; - } - if (key_size <= 0 || value_size < 0 || key_size_size != 4 || value_size_size != 4) { - // PanicAlert("Disk cache file %s corrupted/truncated! ks: %i vs %i kss %i vss %i", filename, - // key_size, value_size, key_size_size, value_size_size); - file_corrupt = true; - break; - } - u8 *key = new u8[key_size]; - u8 *value = new u8[value_size]; - int actual_key_size = (int)fread(key, 1, key_size, file_); - int actual_value_size = (int)fread(value, 1, value_size, file_); - if (actual_key_size != key_size || actual_value_size != value_size) { - // PanicAlert("Disk cache file %s corrupted/truncated! ks: %i actual ks: %i vs: %i actual vs: %i", filename, - // key_size, actual_key_size, value_size, actual_value_size); - file_corrupt = true; - } else { - reader->Read(key, key_size, value, value_size); - items_read_count++; - } - delete [] key; - delete [] value; - } - fclose(file_); - // Done reading. - - // Reopen file for append. - // At this point, ftell() will be at the end of the file, - // which happens to be exactly what we want. - file_ = fopen(filename, "ab"); - fseek(file_, 0, SEEK_END); - } - } - - if (file_corrupt) { - // Restore sanity, start over. - fclose(file_); - unlink(filename); - - file_ = fopen(filename, "wb+"); - WriteHeader(); - } - - return items_read_count; -} - -void LinearDiskCache::Append( - const u8 *key, int key_size, const u8 *value, int value_size) { - // Should do a check that we don't already have "key"? - fwrite(&key_size, 1, sizeof(key_size), file_); - fwrite(&value_size, 1, sizeof(value_size), file_); - fwrite(key, 1, key_size, file_); - fwrite(value, 1, value_size, file_); -} - -void LinearDiskCache::Sync() { - fflush(file_); -} - -void LinearDiskCache::Close() { - fclose(file_); - file_ = 0; - num_entries_ = 0; -} +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "LinearDiskCache.h" + +static const char ID[4] = {'D', 'C', 'A', 'C'}; +const int version = 4888; // TODO: Get from SVN_REV + +LinearDiskCache::LinearDiskCache() + : file_(NULL), num_entries_(0) { +} + +void LinearDiskCache::WriteHeader() { + fwrite(ID, 4, 1, file_); + fwrite(&version, 4, 1, file_); +} + +bool LinearDiskCache::ValidateHeader() { + char header_id[4]; + int header_version; + fread(&header_id, 4, 1, file_); + fread(&header_version, 4, 1, file_); + if (memcmp(header_id, ID, 4) != 0) + return false; + if (header_version != version) + return false; + return true; +} + +int LinearDiskCache::OpenAndRead(const char *filename, LinearDiskCacheReader *reader) { + int items_read_count = 0; + file_ = fopen(filename, "rb"); + int file_size = 0; + if (file_) { + fseek(file_, 0, SEEK_END); + file_size = (int)ftell(file_); + } + + bool file_corrupt = false; + if (file_size == 0) { + if (file_) + fclose(file_); + // Reopen for writing. + file_ = fopen(filename, "wb"); + // Cache empty, let's initialize a header. + WriteHeader(); + num_entries_ = 0; + } else { + // file_ must be != 0 here. + // Back to the start we go. + fseek(file_, 0, SEEK_SET); + // Check that the file is valid + if (!ValidateHeader()) { + // Not valid - delete the file and start over. + fclose(file_); + unlink(filename); + + // PanicAlert("LinearDiskCache file header broken."); + + file_ = fopen(filename, "wb"); + WriteHeader(); + num_entries_ = 0; + } else { + // Valid - blow through it. + // We're past the header already thanks to ValidateHeader. + while (!feof(file_)) { + int key_size, value_size; + size_t key_size_size = fread(&key_size, 1, sizeof(key_size), file_); + size_t value_size_size = fread(&value_size, 1, sizeof(value_size), file_); + if (key_size_size == 0 && value_size_size == 0) { + // I guess feof isn't doing it's job - we're at the end. + break; + } + if (key_size <= 0 || value_size < 0 || key_size_size != 4 || value_size_size != 4) { + // PanicAlert("Disk cache file %s corrupted/truncated! ks: %i vs %i kss %i vss %i", filename, + // key_size, value_size, key_size_size, value_size_size); + file_corrupt = true; + break; + } + u8 *key = new u8[key_size]; + u8 *value = new u8[value_size]; + int actual_key_size = (int)fread(key, 1, key_size, file_); + int actual_value_size = (int)fread(value, 1, value_size, file_); + if (actual_key_size != key_size || actual_value_size != value_size) { + // PanicAlert("Disk cache file %s corrupted/truncated! ks: %i actual ks: %i vs: %i actual vs: %i", filename, + // key_size, actual_key_size, value_size, actual_value_size); + file_corrupt = true; + } else { + reader->Read(key, key_size, value, value_size); + items_read_count++; + } + delete [] key; + delete [] value; + } + fclose(file_); + // Done reading. + + // Reopen file for append. + // At this point, ftell() will be at the end of the file, + // which happens to be exactly what we want. + file_ = fopen(filename, "ab"); + fseek(file_, 0, SEEK_END); + } + } + + if (file_corrupt) { + // Restore sanity, start over. + fclose(file_); + unlink(filename); + + file_ = fopen(filename, "wb+"); + WriteHeader(); + } + + return items_read_count; +} + +void LinearDiskCache::Append( + const u8 *key, int key_size, const u8 *value, int value_size) { + // Should do a check that we don't already have "key"? + fwrite(&key_size, 1, sizeof(key_size), file_); + fwrite(&value_size, 1, sizeof(value_size), file_); + fwrite(key, 1, key_size, file_); + fwrite(value, 1, value_size, file_); +} + +void LinearDiskCache::Sync() { + fflush(file_); +} + +void LinearDiskCache::Close() { + fclose(file_); + file_ = 0; + num_entries_ = 0; +} diff --git a/Source/Core/Common/Src/LinearDiskCache.h b/Source/Core/Common/Src/LinearDiskCache.h index c2265b26a4..1163415d3a 100644 --- a/Source/Core/Common/Src/LinearDiskCache.h +++ b/Source/Core/Common/Src/LinearDiskCache.h @@ -1,67 +1,67 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _LINEAR_DISKCACHE -#define _LINEAR_DISKCACHE - -#include "Common.h" - -#include -#include - -// On disk format: -// uint32 'DCAC' -// uint32 version; // svn_rev -// uint32 key_length; -// uint32 value_length; -// .... key; -// .... value; - -class LinearDiskCacheReader { -public: - virtual void Read(const u8 *key, int key_size, const u8 *value, int value_size) = 0; -}; - -// Dead simple unsorted key-value store with append functionality. -// No random read functionality, all reading is done in OpenAndRead. -// Keys and values can contain any characters, including \0. -// -// Suitable for caching generated shader bytecode between executions. -// Not tuned for extreme performance but should be reasonably fast. -// Does not support keys or values larger than 2GB, which should be reasonable. -// Keys must have non-zero length; values can have zero length. -class LinearDiskCache { -public: - LinearDiskCache(); - - // Returns the number of items read from the cache. - int OpenAndRead(const char *filename, LinearDiskCacheReader *reader); - void Close(); - void Sync(); - - // Appends a key-value pair to the store. - void Append(const u8 *key, int key_size, const u8 *value, int value_size); - -private: - void WriteHeader(); - bool ValidateHeader(); - - FILE *file_; - int num_entries_; -}; - +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _LINEAR_DISKCACHE +#define _LINEAR_DISKCACHE + +#include "Common.h" + +#include +#include + +// On disk format: +// uint32 'DCAC' +// uint32 version; // svn_rev +// uint32 key_length; +// uint32 value_length; +// .... key; +// .... value; + +class LinearDiskCacheReader { +public: + virtual void Read(const u8 *key, int key_size, const u8 *value, int value_size) = 0; +}; + +// Dead simple unsorted key-value store with append functionality. +// No random read functionality, all reading is done in OpenAndRead. +// Keys and values can contain any characters, including \0. +// +// Suitable for caching generated shader bytecode between executions. +// Not tuned for extreme performance but should be reasonably fast. +// Does not support keys or values larger than 2GB, which should be reasonable. +// Keys must have non-zero length; values can have zero length. +class LinearDiskCache { +public: + LinearDiskCache(); + + // Returns the number of items read from the cache. + int OpenAndRead(const char *filename, LinearDiskCacheReader *reader); + void Close(); + void Sync(); + + // Appends a key-value pair to the store. + void Append(const u8 *key, int key_size, const u8 *value, int value_size); + +private: + void WriteHeader(); + bool ValidateHeader(); + + FILE *file_; + int num_entries_; +}; + #endif // _LINEAR_DISKCACHE \ No newline at end of file diff --git a/Source/Core/Common/Src/OpenCL.cpp b/Source/Core/Common/Src/OpenCL.cpp index 660da5d382..e261ada5cf 100644 --- a/Source/Core/Common/Src/OpenCL.cpp +++ b/Source/Core/Common/Src/OpenCL.cpp @@ -1,253 +1,253 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -// TODO: Make a more centralized version of this (for now every plugin that will use it will create its own context, which is weird). An object maybe? - -#include "OpenCL.h" -#include "Common.h" -#include "Timer.h" - -namespace OpenCL -{ - -#if defined(HAVE_OPENCL) && HAVE_OPENCL -cl_device_id device_id = NULL; -cl_context g_context = NULL; -cl_command_queue g_cmdq = NULL; -#endif - -bool g_bInitialized = false; - -bool Initialize() -{ - if(g_bInitialized) - return true; - -#if defined(HAVE_OPENCL) && HAVE_OPENCL - if(g_context) - return false; - int err; // error code returned from api calls - - // Connect to a compute device - cl_uint numPlatforms; - cl_platform_id platform = NULL; - err = clGetPlatformIDs(0, NULL, &numPlatforms); - - if (err != CL_SUCCESS) - { - HandleCLError(err, "clGetPlatformIDs failed."); - return false; - } - - if (0 < numPlatforms) - { - cl_platform_id* platforms = new cl_platform_id[numPlatforms]; - err = clGetPlatformIDs(numPlatforms, platforms, NULL); - - if (err != CL_SUCCESS) - { - HandleCLError(err, "clGetPlatformIDs failed."); - return false; - } - - char pbuf[100]; - err = clGetPlatformInfo(platforms[0], CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL); - - if (err != CL_SUCCESS) - { - HandleCLError(err, "clGetPlatformInfo failed."); - return false; - } - - platform = platforms[0]; - delete[] platforms; - } - else - { - PanicAlert("No OpenCL platform found."); - return false; - } - - cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; - - cl_context_properties* cprops = (NULL == platform) ? NULL : cps; - - int gpu = 1; // I think we should use CL_DEVICE_TYPE_ALL - - err = clGetDeviceIDs(platform, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL); - if (err != CL_SUCCESS) - { - HandleCLError(err, "Failed to create a device group!"); - return false; - } - - // Create a compute context - g_context = clCreateContext(cprops, 1, &device_id, NULL, NULL, &err); - if (!g_context) - { - HandleCLError(err, "Failed to create a compute context!"); - return false; - } - - // Create a command commands - g_cmdq = clCreateCommandQueue(g_context, device_id, 0, &err); - if (!g_cmdq) - { - HandleCLError(err, "Failed to create a command commands!"); - return false; - } - - NOTICE_LOG(COMMON, "Initialized OpenCL!"); - g_bInitialized = true; - return true; -#else - return false; -#endif -} - -#if defined(HAVE_OPENCL) && HAVE_OPENCL -cl_context GetContext() -{ - return g_context; -} - -cl_command_queue GetCommandQueue() -{ - return g_cmdq; -} - -cl_program CompileProgram(const char *Kernel) -{ - u32 compileStart = Common::Timer::GetTimeMs(); - int err; - cl_program program; - program = clCreateProgramWithSource(OpenCL::g_context, 1, (const char **) & Kernel, NULL, &err); - if (!program) - { - HandleCLError(err, "Error: Failed to create compute program!"); - return NULL; - } - - // Build the program executable - err = clBuildProgram(program , 0, NULL, NULL, NULL, NULL); - if(err != CL_SUCCESS) { - char *errors[16384] = {0}; - err = clGetProgramBuildInfo(program, OpenCL::device_id, CL_PROGRAM_BUILD_LOG, sizeof(errors), - errors, NULL); - ERROR_LOG(COMMON, "Error log:\n%s\n", errors); - return NULL; - } - - NOTICE_LOG(COMMON, "OpenCL CompileProgram took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0); - return program; -} - -cl_kernel CompileKernel(cl_program program, const char *Function) -{ - u32 compileStart = Common::Timer::GetTimeMs(); - int err; - - // Create the compute kernel in the program we wish to run - cl_kernel kernel = clCreateKernel(program, Function, &err); - if (!kernel || err != CL_SUCCESS) - { - HandleCLError(err, "Failed to create compute kernel!"); - return NULL; - } - NOTICE_LOG(COMMON, "OpenCL CompileKernel took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0); - return kernel; -} -#endif - -void Destroy() -{ -#if defined(HAVE_OPENCL) && HAVE_OPENCL - if(!g_context) - return; - clReleaseCommandQueue(g_cmdq); - clReleaseContext(g_context); - g_context = NULL; - g_cmdq = NULL; - - g_bInitialized = false; -#endif -} - -void HandleCLError(cl_int error, char* str) -{ -#if defined(HAVE_OPENCL) && HAVE_OPENCL - - char* name; - switch(error) - { -#define CL_ERROR(x) case (x): name = #x; break - CL_ERROR(CL_SUCCESS); - CL_ERROR(CL_DEVICE_NOT_FOUND); - CL_ERROR(CL_DEVICE_NOT_AVAILABLE); - CL_ERROR(CL_COMPILER_NOT_AVAILABLE); - CL_ERROR(CL_MEM_OBJECT_ALLOCATION_FAILURE); - CL_ERROR(CL_OUT_OF_RESOURCES); - CL_ERROR(CL_OUT_OF_HOST_MEMORY); - CL_ERROR(CL_PROFILING_INFO_NOT_AVAILABLE); - CL_ERROR(CL_MEM_COPY_OVERLAP); - CL_ERROR(CL_IMAGE_FORMAT_MISMATCH); - CL_ERROR(CL_IMAGE_FORMAT_NOT_SUPPORTED); - CL_ERROR(CL_BUILD_PROGRAM_FAILURE); - CL_ERROR(CL_MAP_FAILURE); - CL_ERROR(CL_INVALID_VALUE); - CL_ERROR(CL_INVALID_DEVICE_TYPE); - CL_ERROR(CL_INVALID_PLATFORM); - CL_ERROR(CL_INVALID_DEVICE); - CL_ERROR(CL_INVALID_CONTEXT); - CL_ERROR(CL_INVALID_QUEUE_PROPERTIES); - CL_ERROR(CL_INVALID_COMMAND_QUEUE); - CL_ERROR(CL_INVALID_HOST_PTR); - CL_ERROR(CL_INVALID_MEM_OBJECT); - CL_ERROR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); - CL_ERROR(CL_INVALID_IMAGE_SIZE); - CL_ERROR(CL_INVALID_SAMPLER); - CL_ERROR(CL_INVALID_BINARY); - CL_ERROR(CL_INVALID_BUILD_OPTIONS); - CL_ERROR(CL_INVALID_PROGRAM); - CL_ERROR(CL_INVALID_PROGRAM_EXECUTABLE); - CL_ERROR(CL_INVALID_KERNEL_NAME); - CL_ERROR(CL_INVALID_KERNEL_DEFINITION); - CL_ERROR(CL_INVALID_KERNEL); - CL_ERROR(CL_INVALID_ARG_INDEX); - CL_ERROR(CL_INVALID_ARG_VALUE); - CL_ERROR(CL_INVALID_ARG_SIZE); - CL_ERROR(CL_INVALID_KERNEL_ARGS); - CL_ERROR(CL_INVALID_WORK_DIMENSION); - CL_ERROR(CL_INVALID_WORK_GROUP_SIZE); - CL_ERROR(CL_INVALID_WORK_ITEM_SIZE); - CL_ERROR(CL_INVALID_GLOBAL_OFFSET); - CL_ERROR(CL_INVALID_EVENT_WAIT_LIST); - CL_ERROR(CL_INVALID_EVENT); - CL_ERROR(CL_INVALID_OPERATION); - CL_ERROR(CL_INVALID_GL_OBJECT); - CL_ERROR(CL_INVALID_BUFFER_SIZE); - CL_ERROR(CL_INVALID_MIP_LEVEL); -#undef CL_ERROR - default: - name = "Unknown error code"; - } - if(!str) - str = ""; - ERROR_LOG(COMMON, "OpenCL error: %s %s (%d)", str, name, error); -#endif - } -} +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// TODO: Make a more centralized version of this (for now every plugin that will use it will create its own context, which is weird). An object maybe? + +#include "OpenCL.h" +#include "Common.h" +#include "Timer.h" + +namespace OpenCL +{ + +#if defined(HAVE_OPENCL) && HAVE_OPENCL +cl_device_id device_id = NULL; +cl_context g_context = NULL; +cl_command_queue g_cmdq = NULL; +#endif + +bool g_bInitialized = false; + +bool Initialize() +{ + if(g_bInitialized) + return true; + +#if defined(HAVE_OPENCL) && HAVE_OPENCL + if(g_context) + return false; + int err; // error code returned from api calls + + // Connect to a compute device + cl_uint numPlatforms; + cl_platform_id platform = NULL; + err = clGetPlatformIDs(0, NULL, &numPlatforms); + + if (err != CL_SUCCESS) + { + HandleCLError(err, "clGetPlatformIDs failed."); + return false; + } + + if (0 < numPlatforms) + { + cl_platform_id* platforms = new cl_platform_id[numPlatforms]; + err = clGetPlatformIDs(numPlatforms, platforms, NULL); + + if (err != CL_SUCCESS) + { + HandleCLError(err, "clGetPlatformIDs failed."); + return false; + } + + char pbuf[100]; + err = clGetPlatformInfo(platforms[0], CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL); + + if (err != CL_SUCCESS) + { + HandleCLError(err, "clGetPlatformInfo failed."); + return false; + } + + platform = platforms[0]; + delete[] platforms; + } + else + { + PanicAlert("No OpenCL platform found."); + return false; + } + + cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; + + cl_context_properties* cprops = (NULL == platform) ? NULL : cps; + + int gpu = 1; // I think we should use CL_DEVICE_TYPE_ALL + + err = clGetDeviceIDs(platform, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL); + if (err != CL_SUCCESS) + { + HandleCLError(err, "Failed to create a device group!"); + return false; + } + + // Create a compute context + g_context = clCreateContext(cprops, 1, &device_id, NULL, NULL, &err); + if (!g_context) + { + HandleCLError(err, "Failed to create a compute context!"); + return false; + } + + // Create a command commands + g_cmdq = clCreateCommandQueue(g_context, device_id, 0, &err); + if (!g_cmdq) + { + HandleCLError(err, "Failed to create a command commands!"); + return false; + } + + NOTICE_LOG(COMMON, "Initialized OpenCL!"); + g_bInitialized = true; + return true; +#else + return false; +#endif +} + +#if defined(HAVE_OPENCL) && HAVE_OPENCL +cl_context GetContext() +{ + return g_context; +} + +cl_command_queue GetCommandQueue() +{ + return g_cmdq; +} + +cl_program CompileProgram(const char *Kernel) +{ + u32 compileStart = Common::Timer::GetTimeMs(); + int err; + cl_program program; + program = clCreateProgramWithSource(OpenCL::g_context, 1, (const char **) & Kernel, NULL, &err); + if (!program) + { + HandleCLError(err, "Error: Failed to create compute program!"); + return NULL; + } + + // Build the program executable + err = clBuildProgram(program , 0, NULL, NULL, NULL, NULL); + if(err != CL_SUCCESS) { + char *errors[16384] = {0}; + err = clGetProgramBuildInfo(program, OpenCL::device_id, CL_PROGRAM_BUILD_LOG, sizeof(errors), + errors, NULL); + ERROR_LOG(COMMON, "Error log:\n%s\n", errors); + return NULL; + } + + NOTICE_LOG(COMMON, "OpenCL CompileProgram took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0); + return program; +} + +cl_kernel CompileKernel(cl_program program, const char *Function) +{ + u32 compileStart = Common::Timer::GetTimeMs(); + int err; + + // Create the compute kernel in the program we wish to run + cl_kernel kernel = clCreateKernel(program, Function, &err); + if (!kernel || err != CL_SUCCESS) + { + HandleCLError(err, "Failed to create compute kernel!"); + return NULL; + } + NOTICE_LOG(COMMON, "OpenCL CompileKernel took %.3f seconds", (float)(Common::Timer::GetTimeMs() - compileStart) / 1000.0); + return kernel; +} +#endif + +void Destroy() +{ +#if defined(HAVE_OPENCL) && HAVE_OPENCL + if(!g_context) + return; + clReleaseCommandQueue(g_cmdq); + clReleaseContext(g_context); + g_context = NULL; + g_cmdq = NULL; + + g_bInitialized = false; +#endif +} + +void HandleCLError(cl_int error, char* str) +{ +#if defined(HAVE_OPENCL) && HAVE_OPENCL + + char* name; + switch(error) + { +#define CL_ERROR(x) case (x): name = #x; break + CL_ERROR(CL_SUCCESS); + CL_ERROR(CL_DEVICE_NOT_FOUND); + CL_ERROR(CL_DEVICE_NOT_AVAILABLE); + CL_ERROR(CL_COMPILER_NOT_AVAILABLE); + CL_ERROR(CL_MEM_OBJECT_ALLOCATION_FAILURE); + CL_ERROR(CL_OUT_OF_RESOURCES); + CL_ERROR(CL_OUT_OF_HOST_MEMORY); + CL_ERROR(CL_PROFILING_INFO_NOT_AVAILABLE); + CL_ERROR(CL_MEM_COPY_OVERLAP); + CL_ERROR(CL_IMAGE_FORMAT_MISMATCH); + CL_ERROR(CL_IMAGE_FORMAT_NOT_SUPPORTED); + CL_ERROR(CL_BUILD_PROGRAM_FAILURE); + CL_ERROR(CL_MAP_FAILURE); + CL_ERROR(CL_INVALID_VALUE); + CL_ERROR(CL_INVALID_DEVICE_TYPE); + CL_ERROR(CL_INVALID_PLATFORM); + CL_ERROR(CL_INVALID_DEVICE); + CL_ERROR(CL_INVALID_CONTEXT); + CL_ERROR(CL_INVALID_QUEUE_PROPERTIES); + CL_ERROR(CL_INVALID_COMMAND_QUEUE); + CL_ERROR(CL_INVALID_HOST_PTR); + CL_ERROR(CL_INVALID_MEM_OBJECT); + CL_ERROR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); + CL_ERROR(CL_INVALID_IMAGE_SIZE); + CL_ERROR(CL_INVALID_SAMPLER); + CL_ERROR(CL_INVALID_BINARY); + CL_ERROR(CL_INVALID_BUILD_OPTIONS); + CL_ERROR(CL_INVALID_PROGRAM); + CL_ERROR(CL_INVALID_PROGRAM_EXECUTABLE); + CL_ERROR(CL_INVALID_KERNEL_NAME); + CL_ERROR(CL_INVALID_KERNEL_DEFINITION); + CL_ERROR(CL_INVALID_KERNEL); + CL_ERROR(CL_INVALID_ARG_INDEX); + CL_ERROR(CL_INVALID_ARG_VALUE); + CL_ERROR(CL_INVALID_ARG_SIZE); + CL_ERROR(CL_INVALID_KERNEL_ARGS); + CL_ERROR(CL_INVALID_WORK_DIMENSION); + CL_ERROR(CL_INVALID_WORK_GROUP_SIZE); + CL_ERROR(CL_INVALID_WORK_ITEM_SIZE); + CL_ERROR(CL_INVALID_GLOBAL_OFFSET); + CL_ERROR(CL_INVALID_EVENT_WAIT_LIST); + CL_ERROR(CL_INVALID_EVENT); + CL_ERROR(CL_INVALID_OPERATION); + CL_ERROR(CL_INVALID_GL_OBJECT); + CL_ERROR(CL_INVALID_BUFFER_SIZE); + CL_ERROR(CL_INVALID_MIP_LEVEL); +#undef CL_ERROR + default: + name = "Unknown error code"; + } + if(!str) + str = ""; + ERROR_LOG(COMMON, "OpenCL error: %s %s (%d)", str, name, error); +#endif + } +} diff --git a/Source/Core/Common/Src/OpenCL.h b/Source/Core/Common/Src/OpenCL.h index fcc43ac137..faf9dcf0b4 100644 --- a/Source/Core/Common/Src/OpenCL.h +++ b/Source/Core/Common/Src/OpenCL.h @@ -1,70 +1,70 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef __OPENCL_H__ -#define __OPENCL_H__ - -#include "Common.h" -// Change to #if 1 if you want to test OpenCL (and you have it) on Windows -#if 0 -#pragma comment(lib, "OpenCL.lib") -#define HAVE_OPENCL 1 -#endif - -#if defined(HAVE_OPENCL) && HAVE_OPENCL - -#ifdef __APPLE__ -#include -#else -#include -#endif - -#else - -typedef void *cl_context; -typedef void *cl_command_queue; -typedef void *cl_program; -typedef void *cl_kernel; -typedef void *cl_mem; -typedef void *cl_int; - -#endif - -namespace OpenCL -{ - -#if defined(HAVE_OPENCL) && HAVE_OPENCL -extern cl_device_id device_id; -extern cl_context g_context; -extern cl_command_queue g_cmdq; -#endif - -bool Initialize(); - -cl_context GetContext(); - -cl_command_queue GetCommandQueue(); - -void Destroy(); - -cl_program CompileProgram(const char *Kernel); -cl_kernel CompileKernel(cl_program program, const char *Function); - -void HandleCLError(cl_int error, char* str = 0); -} - -#endif +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __OPENCL_H__ +#define __OPENCL_H__ + +#include "Common.h" +// Change to #if 1 if you want to test OpenCL (and you have it) on Windows +#if 0 +#pragma comment(lib, "OpenCL.lib") +#define HAVE_OPENCL 1 +#endif + +#if defined(HAVE_OPENCL) && HAVE_OPENCL + +#ifdef __APPLE__ +#include +#else +#include +#endif + +#else + +typedef void *cl_context; +typedef void *cl_command_queue; +typedef void *cl_program; +typedef void *cl_kernel; +typedef void *cl_mem; +typedef void *cl_int; + +#endif + +namespace OpenCL +{ + +#if defined(HAVE_OPENCL) && HAVE_OPENCL +extern cl_device_id device_id; +extern cl_context g_context; +extern cl_command_queue g_cmdq; +#endif + +bool Initialize(); + +cl_context GetContext(); + +cl_command_queue GetCommandQueue(); + +void Destroy(); + +cl_program CompileProgram(const char *Kernel); +cl_kernel CompileKernel(cl_program program, const char *Function); + +void HandleCLError(cl_int error, char* str = 0); +} + +#endif diff --git a/Source/Core/Common/Src/SysConf.cpp b/Source/Core/Common/Src/SysConf.cpp index c9a86e6e15..2836fd80fc 100644 --- a/Source/Core/Common/Src/SysConf.cpp +++ b/Source/Core/Common/Src/SysConf.cpp @@ -1,175 +1,173 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include "FileUtil.h" -#include "SysConf.h" - -SysConf::SysConf() -: m_IsValid(false) -{ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "FileUtil.h" +#include "SysConf.h" + +SysConf::SysConf() +: m_IsValid(false) +{ if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX))) - m_IsValid = true; -} + m_IsValid = true; +} void SysConf::Reload() { - if (m_IsValid) - return; - if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX))) - m_IsValid = true; + if (m_IsValid) + return; + if (LoadFromFile(File::GetUserPath(F_WIISYSCONF_IDX))) + m_IsValid = true; +} + +SysConf::~SysConf() +{ + if (!m_IsValid) + return; + + for (size_t i = 0; i < m_Entries.size() - 1; i++) + { + delete [] m_Entries.at(i).data; + m_Entries.at(i).data = NULL; + } +} + +bool SysConf::LoadFromFile(const char *filename) +{ + // Basic check + u64 size = File::GetSize(filename); + if (size == 0) + return false; //most likely: file does not exist + if (size != SYSCONF_SIZE) + { + PanicAlert("Your SYSCONF file is the wrong size - should be 0x%04x (but is 0x%04x)", + SYSCONF_SIZE, size); + return false; + } + FILE* f = fopen(filename, "rb"); + + if (f == NULL) + return false; + bool result = LoadFromFileInternal(f); + if (result) + { + // OK, done! + m_Filename = filename; + } + fclose(f); + return result; +} + +bool SysConf::LoadFromFileInternal(FILE *f) +{ + // Fill in infos + if (fread(&m_Header.version, sizeof(m_Header.version), 1, f) != 1) return false; + if (fread(&m_Header.numEntries, sizeof(m_Header.numEntries), 1, f) != 1) return false; + m_Header.numEntries = Common::swap16(m_Header.numEntries) + 1; + + for (u16 index = 0; index < m_Header.numEntries; index++) + { + SSysConfEntry tmpEntry; + if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false; + tmpEntry.offset = Common::swap16(tmpEntry.offset); + m_Entries.push_back(tmpEntry); + } + + // Last offset is an invalid entry. We ignore it throughout this class + for (size_t i = 0; i < m_Entries.size() - 1; i++) + { + SSysConfEntry& curEntry = m_Entries.at(i); + if (fseek(f, curEntry.offset, SEEK_SET) != 0) return false; + + u8 description = 0; + if (fread(&description, sizeof(description), 1, f) != 1) return false; + // Data type + curEntry.type = (SysconfType)((description & 0xe0) >> 5); + // Length of name in bytes - 1 + curEntry.nameLength = (description & 0x1f) + 1; + // Name + if (fread(&curEntry.name, curEntry.nameLength, 1, f) != 1) return false; + curEntry.name[curEntry.nameLength] = '\0'; + // Get length of data + curEntry.dataLength = 0; + switch (curEntry.type) + { + case Type_BigArray: + if (fread(&curEntry.dataLength, 2, 1, f) != 1) return false; + curEntry.dataLength = Common::swap16(curEntry.dataLength); + break; + case Type_SmallArray: + if (fread(&curEntry.dataLength, 1, 1, f) != 1) return false; + break; + case Type_Byte: + case Type_Bool: + curEntry.dataLength = 1; + break; + case Type_Short: + curEntry.dataLength = 2; + break; + case Type_Long: + curEntry.dataLength = 4; + break; + default: + PanicAlert("Unknown entry type %i in SYSCONF (%s@%x)!", + curEntry.type, curEntry.name, curEntry.offset); + return false; + } + // Fill in the actual data + if (curEntry.dataLength) + { + curEntry.data = new u8[curEntry.dataLength]; + if (fread(curEntry.data, curEntry.dataLength, 1, f) != 1) return false; + } + } + + return true; +} + +bool SysConf::SaveToFile(const char *filename) +{ + FILE *f = fopen(filename, "r+b"); + + if (f == NULL) + return false; + + for (size_t i = 0; i < m_Entries.size() - 1; i++) + { + // Seek to after the name of this entry + if (fseek(f, m_Entries.at(i).offset + m_Entries.at(i).nameLength + 1, SEEK_SET) != 0) return false; + // We may have to write array length value... + if (m_Entries.at(i).type == Type_BigArray) + { + u16 tmpDataLength = Common::swap16(m_Entries.at(i).dataLength); + if (fwrite(&tmpDataLength, 2, 1, f) != 1) return false; + } + else if (m_Entries.at(i).type == Type_SmallArray) + { + if (fwrite(&m_Entries.at(i).dataLength, 1, 1, f) != 1) return false; + } + // Now write the actual data + if (fwrite(m_Entries.at(i).data, m_Entries.at(i).dataLength, 1, f) != 1) return false; + } + + fclose(f); + return true; +} + +bool SysConf::Save() +{ + return SaveToFile(m_Filename.c_str()); } - -SysConf::~SysConf() -{ - if (!m_IsValid) - return; - - Save(); - - for (size_t i = 0; i < m_Entries.size() - 1; i++) - { - delete [] m_Entries.at(i).data; - m_Entries.at(i).data = NULL; - } -} - -bool SysConf::LoadFromFile(const char *filename) -{ - // Basic check - u64 size = File::GetSize(filename); - if (size == 0) - return false; //most likely: file does not exist - if (size != SYSCONF_SIZE) - { - PanicAlert("Your SYSCONF file is the wrong size - should be 0x%04x (but is 0x%04x)", - SYSCONF_SIZE, size); - return false; - } - FILE* f = fopen(filename, "rb"); - - if (f == NULL) - return false; - bool result = LoadFromFileInternal(f); - if (result) - { - // OK, done! - m_Filename = filename; - } - fclose(f); - return result; -} - -bool SysConf::LoadFromFileInternal(FILE *f) -{ - // Fill in infos - if (fread(&m_Header.version, sizeof(m_Header.version), 1, f) != 1) return false; - if (fread(&m_Header.numEntries, sizeof(m_Header.numEntries), 1, f) != 1) return false; - m_Header.numEntries = Common::swap16(m_Header.numEntries) + 1; - - for (u16 index = 0; index < m_Header.numEntries; index++) - { - SSysConfEntry tmpEntry; - if (fread(&tmpEntry.offset, sizeof(tmpEntry.offset), 1, f) != 1) return false; - tmpEntry.offset = Common::swap16(tmpEntry.offset); - m_Entries.push_back(tmpEntry); - } - - // Last offset is an invalid entry. We ignore it throughout this class - for (size_t i = 0; i < m_Entries.size() - 1; i++) - { - SSysConfEntry& curEntry = m_Entries.at(i); - if (fseek(f, curEntry.offset, SEEK_SET) != 0) return false; - - u8 description = 0; - if (fread(&description, sizeof(description), 1, f) != 1) return false; - // Data type - curEntry.type = (SysconfType)((description & 0xe0) >> 5); - // Length of name in bytes - 1 - curEntry.nameLength = (description & 0x1f) + 1; - // Name - if (fread(&curEntry.name, curEntry.nameLength, 1, f) != 1) return false; - curEntry.name[curEntry.nameLength] = '\0'; - // Get length of data - curEntry.dataLength = 0; - switch (curEntry.type) - { - case Type_BigArray: - if (fread(&curEntry.dataLength, 2, 1, f) != 1) return false; - curEntry.dataLength = Common::swap16(curEntry.dataLength); - break; - case Type_SmallArray: - if (fread(&curEntry.dataLength, 1, 1, f) != 1) return false; - break; - case Type_Byte: - case Type_Bool: - curEntry.dataLength = 1; - break; - case Type_Short: - curEntry.dataLength = 2; - break; - case Type_Long: - curEntry.dataLength = 4; - break; - default: - PanicAlert("Unknown entry type %i in SYSCONF (%s@%x)!", - curEntry.type, curEntry.name, curEntry.offset); - return false; - } - // Fill in the actual data - if (curEntry.dataLength) - { - curEntry.data = new u8[curEntry.dataLength]; - if (fread(curEntry.data, curEntry.dataLength, 1, f) != 1) return false; - } - } - - return true; -} - -bool SysConf::SaveToFile(const char *filename) -{ - FILE *f = fopen(filename, "r+b"); - - if (f == NULL) - return false; - - for (size_t i = 0; i < m_Entries.size() - 1; i++) - { - // Seek to after the name of this entry - if (fseek(f, m_Entries.at(i).offset + m_Entries.at(i).nameLength + 1, SEEK_SET) != 0) return false; - // We may have to write array length value... - if (m_Entries.at(i).type == Type_BigArray) - { - u16 tmpDataLength = Common::swap16(m_Entries.at(i).dataLength); - if (fwrite(&tmpDataLength, 2, 1, f) != 1) return false; - } - else if (m_Entries.at(i).type == Type_SmallArray) - { - if (fwrite(&m_Entries.at(i).dataLength, 1, 1, f) != 1) return false; - } - // Now write the actual data - if (fwrite(m_Entries.at(i).data, m_Entries.at(i).dataLength, 1, f) != 1) return false; - } - - fclose(f); - return true; -} - -bool SysConf::Save() -{ - return SaveToFile(m_Filename.c_str()); -} diff --git a/Source/Core/Common/Src/SysConf.h b/Source/Core/Common/Src/SysConf.h index d91cc471ac..5d7c50007e 100644 --- a/Source/Core/Common/Src/SysConf.h +++ b/Source/Core/Common/Src/SysConf.h @@ -1,129 +1,129 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef __SYSCONF_MANAGER_h__ -#define __SYSCONF_MANAGER_h__ - -#include -#include - -// This class is meant to edit the values in a given Wii SYSCONF file -// It currently does not add/remove/rearrange sections, -// instead only modifies exiting sections' data - -#define SYSCONF_SIZE 0x4000 - -enum SysconfType -{ - Type_BigArray = 1, - Type_SmallArray, - Type_Byte, - Type_Short, - Type_Long, - Type_Unknown, - Type_Bool -}; - -struct SSysConfHeader -{ - char version[4]; - u16 numEntries; -}; - -struct SSysConfEntry -{ - u16 offset; - SysconfType type; - u8 nameLength; - char name[32]; - u16 dataLength; - u8* data; - - template - T GetData() { return *(T*)data; } -}; - -class SysConf -{ -private: - SSysConfHeader m_Header; - std::string m_Filename; - std::vector m_Entries; - bool m_IsValid; - -public: - SysConf(); - ~SysConf(); - - bool IsValid() { return m_IsValid; } - - void Reload(); - - template - T GetData(const char* sectionName) - { - if (!m_IsValid) - { - PanicAlert("Trying to read from invalid SYSCONF"); - return 0; - } - - size_t index = 0; - for (; index < m_Entries.size() - 1; index++) - { - if (strcmp(m_Entries.at(index).name, sectionName) == 0) - break; - } - if (index == m_Entries.size() - 1) - { - PanicAlert("Section %s not found in SYSCONF", sectionName); - return 0; - } - - return m_Entries.at(index).GetData(); - } - - template - bool SetData(const char* sectionName, T newValue) - { - if (!m_IsValid) - return false; - - size_t index = 0; - for (; index < m_Entries.size() - 1; index++) - { - if (strcmp(m_Entries.at(index).name, sectionName) == 0) - break; - } - if (index == m_Entries.size() - 1) - { - PanicAlert("Section %s not found in SYSCONF", sectionName); - return false; - } - - *(T*)m_Entries.at(index).data = newValue; - return true; - } - - bool Save(); - bool SaveToFile(const char* filename); - bool LoadFromFile(const char* filename); -private: - bool LoadFromFileInternal(FILE *f); -}; - -#endif // __SYSCONF_MANAGER_h__ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __SYSCONF_MANAGER_h__ +#define __SYSCONF_MANAGER_h__ + +#include +#include + +// This class is meant to edit the values in a given Wii SYSCONF file +// It currently does not add/remove/rearrange sections, +// instead only modifies exiting sections' data + +#define SYSCONF_SIZE 0x4000 + +enum SysconfType +{ + Type_BigArray = 1, + Type_SmallArray, + Type_Byte, + Type_Short, + Type_Long, + Type_Unknown, + Type_Bool +}; + +struct SSysConfHeader +{ + char version[4]; + u16 numEntries; +}; + +struct SSysConfEntry +{ + u16 offset; + SysconfType type; + u8 nameLength; + char name[32]; + u16 dataLength; + u8* data; + + template + T GetData() { return *(T*)data; } +}; + +class SysConf +{ +private: + SSysConfHeader m_Header; + std::string m_Filename; + std::vector m_Entries; + bool m_IsValid; + +public: + SysConf(); + ~SysConf(); + + bool IsValid() { return m_IsValid; } + + void Reload(); + + template + T GetData(const char* sectionName) + { + if (!m_IsValid) + { + PanicAlert("Trying to read from invalid SYSCONF"); + return 0; + } + + size_t index = 0; + for (; index < m_Entries.size() - 1; index++) + { + if (strcmp(m_Entries.at(index).name, sectionName) == 0) + break; + } + if (index == m_Entries.size() - 1) + { + PanicAlert("Section %s not found in SYSCONF", sectionName); + return 0; + } + + return m_Entries.at(index).GetData(); + } + + template + bool SetData(const char* sectionName, T newValue) + { + if (!m_IsValid) + return false; + + size_t index = 0; + for (; index < m_Entries.size() - 1; index++) + { + if (strcmp(m_Entries.at(index).name, sectionName) == 0) + break; + } + if (index == m_Entries.size() - 1) + { + PanicAlert("Section %s not found in SYSCONF", sectionName); + return false; + } + + *(T*)m_Entries.at(index).data = newValue; + return true; + } + + bool Save(); + bool SaveToFile(const char* filename); + bool LoadFromFile(const char* filename); +private: + bool LoadFromFileInternal(FILE *f); +}; + +#endif // __SYSCONF_MANAGER_h__ diff --git a/Source/Core/DolphinWX/Src/MainNoGUI.cpp b/Source/Core/DolphinWX/Src/MainNoGUI.cpp index 84c9a450b3..e7e82277da 100644 --- a/Source/Core/DolphinWX/Src/MainNoGUI.cpp +++ b/Source/Core/DolphinWX/Src/MainNoGUI.cpp @@ -44,15 +44,12 @@ #include "cmdline.h" #include "Thread.h" #include "PowerPC/PowerPC.h" + #include "PluginManager.h" - - +#include "ConfigManager.h" +#include "LogManager.h" #include "BootManager.h" -void* g_pCodeWindow = NULL; -void* main_frame = NULL; -// OK, this thread boundary is DANGEROUS on linux -// wxPostEvent / wxAddPendingEvent is the solution. void Host_NotifyMapLoaded(){} void Host_ShowJitResults(unsigned int address){} @@ -99,7 +96,7 @@ void Host_SysMessage(const char *fmt, ...) msg[len - 1] = '\n'; msg[len] = '\0'; } - fprintf(stderr, msg); + fprintf(stderr, "%s", msg); } void Host_UpdateLeds(int led_bits) @@ -167,6 +164,7 @@ int appleMain(int argc, char *argv[]); @end +volatile bool running; int main(int argc, char *argv[]) { @@ -182,9 +180,10 @@ int main(int argc, char *argv[]) NSEvent *event = [[NSEvent alloc] init]; [thread cocoaThreadStart]; - + running = true; + //cocoa event loop - while(true) + while(running) { event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ]; if(cocoaSendEvent(event)) @@ -212,7 +211,7 @@ int main(int argc, char* argv[]) { gengetopt_args_info args_info; - if (cmdline_parser (argc, argv, &args_info) != 0) + if (cmdline_parser(argc, argv, &args_info) != 0) return(1); if (args_info.inputs_num < 1) @@ -224,30 +223,29 @@ int main(int argc, char* argv[]) updateMainFrameEvent.Init(); cpu_info.Detect(); + + LogManager::Init(); + EventHandler::Init(); + SConfig::Init(); + CPluginManager::Init(); + CPluginManager::GetInstance().ScanForPlugins(); - // check to see if ~/Library/Application Support/Dolphin exists; if not, create it - char AppSupportDir[MAXPATHLEN]; - snprintf(AppSupportDir, sizeof(AppSupportDir), "%s/Library/Application Support", getenv("HOME")); - if (!File::Exists(AppSupportDir) || !File::IsDirectory(AppSupportDir)) - PanicAlert("Could not open ~/Library/Application Support"); - - strncat(AppSupportDir, "/Dolphin", sizeof(AppSupportDir)); - - if (!File::Exists(AppSupportDir)) - File::CreateDir(AppSupportDir); - - if (!File::IsDirectory(AppSupportDir)) - PanicAlert("~/Library/Application Support/Dolphin exists, but is not a directory"); - - chdir(AppSupportDir); - - - BootManager::BootCore(bootFile); - while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) + if (BootManager::BootCore(bootFile)) //no use running the loop when booting fails { - updateMainFrameEvent.Wait(); + while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) + { + updateMainFrameEvent.Wait(); + } } +#if defined(HAVE_COCOA) && HAVE_COCOA + running = false; +#endif + + CPluginManager::Shutdown(); + SConfig::Shutdown(); + EventHandler::Shutdown(); + LogManager::Shutdown(); cmdline_parser_free (&args_info); return(0);