mirror of https://github.com/libAthena/athena.git
Remove EC and BN code in preparation due to licensing issues
This commit is contained in:
parent
6d8da2bcc0
commit
99dcef42f1
|
@ -100,8 +100,8 @@ add_library(athena-wiisave EXCLUDE_FROM_ALL
|
|||
src/athena/WiiSave.cpp
|
||||
src/athena/WiiSaveReader.cpp
|
||||
src/athena/WiiSaveWriter.cpp
|
||||
src/bn.cpp
|
||||
src/ec.cpp
|
||||
# src/bn.cpp
|
||||
# src/ec.cpp
|
||||
src/md5.cpp
|
||||
src/sha1.cpp
|
||||
src/aes.cpp
|
||||
|
@ -113,8 +113,8 @@ add_library(athena-wiisave EXCLUDE_FROM_ALL
|
|||
include/athena/WiiSaveReader.hpp
|
||||
include/athena/WiiSaveWriter.hpp
|
||||
include/aes.hpp
|
||||
include/bn.h
|
||||
include/ec.h
|
||||
# include/bn.h
|
||||
# include/ec.h
|
||||
include/md5.h
|
||||
include/sha1.h
|
||||
)
|
||||
|
|
2
Doxyfile
2
Doxyfile
|
@ -768,7 +768,7 @@ WARN_LOGFILE =
|
|||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = include/Athena
|
||||
INPUT = include/athena
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
|
|
|
@ -195,7 +195,7 @@ template <>
|
|||
inline std::unique_ptr<YAMLNode> ValToNode(const atInt64& val)
|
||||
{
|
||||
char str[32];
|
||||
snprintf(str, 32, "0x%016llX", val);
|
||||
snprintf(str, 32, "0x%016" PRIX64, val);
|
||||
YAMLNode* ret = new YAMLNode(YAML_SCALAR_NODE);
|
||||
ret->m_scalarString = str;
|
||||
return std::unique_ptr<YAMLNode>(ret);
|
||||
|
@ -215,7 +215,7 @@ template <>
|
|||
inline std::unique_ptr<YAMLNode> ValToNode(const atUint64& val)
|
||||
{
|
||||
char str[32];
|
||||
snprintf(str, 32, "0x%016llX", val);
|
||||
snprintf(str, 32, "0x%016" PRIX64, val);
|
||||
YAMLNode* ret = new YAMLNode(YAML_SCALAR_NODE);
|
||||
ret->m_scalarString = str;
|
||||
return std::unique_ptr<YAMLNode>(ret);
|
||||
|
|
|
@ -10,6 +10,11 @@ namespace athena
|
|||
{
|
||||
namespace io
|
||||
{
|
||||
/** @brief The IStreamReader class defines a basic API for reading from streams, Implementors are provided with one pure virtual
|
||||
* function that must be implemented in order to interact with the stream.
|
||||
*
|
||||
* Most implementing classes will only need to implement IStreamReader::readUBytesToBuf(void*, atUint64) for basic stream intearaction
|
||||
*/
|
||||
class IStreamReader : public IStream
|
||||
{
|
||||
public:
|
||||
|
@ -26,7 +31,7 @@ public:
|
|||
*
|
||||
* @return The current Stream Endianness
|
||||
*/
|
||||
inline Endian endian() const
|
||||
inline Endian endian() const
|
||||
{return m_endian;}
|
||||
|
||||
/** @brief Returns whether the stream is BigEndian
|
||||
|
@ -51,10 +56,18 @@ public:
|
|||
*/
|
||||
virtual void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current)=0;
|
||||
|
||||
/** @brief Sets the buffer's position relative to the next 64-byte aligned position.<br />
|
||||
*/
|
||||
inline void seekAlign64() {seek(ROUND_UP_64(position()), SeekOrigin::Begin);}
|
||||
|
||||
/** @brief Sets the buffers position relative to the next 32-byte aligned position.<br />
|
||||
*/
|
||||
inline void seekAlign32() {seek(ROUND_UP_32(position()), SeekOrigin::Begin);}
|
||||
|
||||
/** @brief Sets the buffer's position relative to the next 16-byte aligned position.<br />
|
||||
*/
|
||||
inline void seekAlign16() {seek(ROUND_UP_16(position()), SeekOrigin::Begin); }
|
||||
|
||||
/** @brief Returns whether or not the stream is at the end.
|
||||
*
|
||||
* @return True if at end; False otherwise.
|
||||
|
@ -68,9 +81,9 @@ public:
|
|||
*/
|
||||
virtual atUint64 position() const=0;
|
||||
|
||||
/** @brief Returns whether or not the stream is at the end.
|
||||
/** @brief Returns the length of the file.
|
||||
*
|
||||
* @return True if at end; False otherwise.
|
||||
* @return True length of the file.
|
||||
*/
|
||||
virtual atUint64 length() const=0;
|
||||
|
||||
|
@ -117,7 +130,7 @@ public:
|
|||
|
||||
/** @brief Reads a byte at the current position and advances the current position.
|
||||
*
|
||||
* @return The buffer at the current position from the given length.
|
||||
* @return The buffer at the current position from the given length.
|
||||
*/
|
||||
inline std::unique_ptr<atUint8[]> readUBytes(atUint64 length)
|
||||
{
|
||||
|
@ -126,7 +139,20 @@ public:
|
|||
return std::unique_ptr<atUint8[]>(buf);
|
||||
}
|
||||
|
||||
/** @brief Attempts to read a fixed length of data into a pre-allocated buffer.
|
||||
* @param buf The buffer to read into
|
||||
* @param len The length of the buffer
|
||||
* @return How much data was actually read, useful for detecting read errors.
|
||||
*/
|
||||
inline atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);}
|
||||
|
||||
|
||||
/** @brief Attempts to read a fixed length of data into a pre-allocated buffer, this function is client defined
|
||||
* and must be implemented.
|
||||
* @param buf The buffer to read into
|
||||
* @param len The length of the buffer
|
||||
* @return How much data was actually read, useful for detecting read errors.
|
||||
*/
|
||||
virtual atUint64 readUBytesToBuf(void* buf, atUint64 len)=0;
|
||||
|
||||
/** @brief Reads a Int16 and swaps to endianness specified by setEndian depending on platform
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "utf8proc.h"
|
||||
#include "IStream.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace athena
|
||||
{
|
||||
|
@ -1032,7 +1033,15 @@ public:
|
|||
inline void writeValBig(const std::wstring& val) {writeWStringBig(val);}
|
||||
|
||||
inline void fill(atUint8 val, atUint64 length)
|
||||
{for (atUint64 l=0 ; l<length ; ++l) writeUBytes(&val, 1);}
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
std::unique_ptr<atUint8[]> tmp(new atUint8[length]);
|
||||
memset(tmp.get(), val, length);
|
||||
writeUBytes(tmp.get(), length);
|
||||
}
|
||||
|
||||
inline void fill(atInt8 val, atUint64 length)
|
||||
{fill((atUint8)val, length);}
|
||||
|
||||
|
|
|
@ -11,13 +11,13 @@ namespace athena
|
|||
namespace io
|
||||
{
|
||||
|
||||
/*! \class MemoryWriter
|
||||
* \brief A Stream class for writing data to a memory position
|
||||
/*! @class MemoryWriter
|
||||
* @brief A Stream class for writing data to a memory position
|
||||
*
|
||||
* A Class for writing binary data to a file or memory stream,
|
||||
* all work is done using a memory buffer, and not written directly to the disk
|
||||
* this allows for fast, flexible code as well as the ability to quickly modify data
|
||||
* \sa Stream
|
||||
* @sa Stream
|
||||
*/
|
||||
class MemoryWriter : public IStreamWriter
|
||||
{
|
||||
|
@ -25,78 +25,78 @@ public:
|
|||
|
||||
virtual ~MemoryWriter();
|
||||
|
||||
/*! \brief This constructor references an existing buffer to write to in-place.
|
||||
/*! @brief This constructor references an existing buffer to write to in-place.
|
||||
*
|
||||
* \param data The existing buffer
|
||||
* \param length The length of the existing buffer
|
||||
* @param data The existing buffer
|
||||
* @param length The length of the existing buffer
|
||||
*/
|
||||
explicit MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership = false);
|
||||
|
||||
/*! \brief Sets the buffers position relative to the specified position.<br />
|
||||
/*! @brief Sets the buffers position relative to the specified position.<br />
|
||||
* It seeks relative to the current position by default.
|
||||
* \param position where in the buffer to seek
|
||||
* \param origin The Origin to seek \sa SeekOrigin
|
||||
* @param position where in the buffer to seek
|
||||
* @param origin The Origin to seek @sa SeekOrigin
|
||||
*/
|
||||
void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current);
|
||||
|
||||
|
||||
/*! \brief Returns the current position in the stream.
|
||||
/*! @brief Returns the current position in the stream.
|
||||
*
|
||||
* \return Int64 The current position in the stream.
|
||||
* @return Int64 The current position in the stream.
|
||||
*/
|
||||
inline atUint64 position() const
|
||||
{return m_position;}
|
||||
|
||||
/*! \brief Returns whether or not the stream is at the end.
|
||||
/*! @brief Returns whether or not the stream is at the end.
|
||||
*
|
||||
* \return bool True if at end; False otherwise.
|
||||
* @return bool True if at end; False otherwise.
|
||||
*/
|
||||
inline atUint64 length() const
|
||||
{return m_length;}
|
||||
|
||||
inline bool isOpen() const {return true;}
|
||||
|
||||
/*! \brief Sets the buffer to the given one, deleting the current one if it owns it.<br />
|
||||
* \param data The new buffer.
|
||||
* \param length The length of the new buffer.
|
||||
* \param takeOwnership Whether the Stream now owns the buffer.
|
||||
* \throw IOException
|
||||
/** @brief Sets the buffer to the given one, deleting the current one if it owns it.<br />
|
||||
* @param data The new buffer.
|
||||
* @param length The length of the new buffer.
|
||||
* @param takeOwnership Whether the Stream now owns the buffer.
|
||||
*/
|
||||
void setData(atUint8* data, atUint64 length, bool takeOwnership = false);
|
||||
|
||||
|
||||
/*! \brief Returns a copy of the current buffer.<br />
|
||||
/*! @brief Returns a copy of the current buffer.<br />
|
||||
* Changes to the copy do not affect the buffer so it's perfectly safe to
|
||||
* directly edit the buffer and use setData to set the new information.<br />
|
||||
* \return Uint8* The copy of the buffer.
|
||||
* @return Uint8* The copy of the buffer.
|
||||
*/
|
||||
atUint8* data() const;
|
||||
|
||||
/*! \brief Sets the target file
|
||||
/*! @brief Sets the target file
|
||||
*
|
||||
* \param filepath The path to write to.
|
||||
* @param filepath The path to write to.
|
||||
*/
|
||||
inline void setFilepath(const std::string& filepath)
|
||||
{m_filepath = filepath;}
|
||||
|
||||
/*! \brief
|
||||
/*! @brief
|
||||
* Returns the target file
|
||||
*/
|
||||
inline std::string filepath() const
|
||||
{return m_filepath;}
|
||||
|
||||
|
||||
/*! \brief Saves the file to the specified file.
|
||||
/*! @brief Saves the file to the specified file.
|
||||
*
|
||||
* \param filename If not empty, the filename to save to
|
||||
* @param filename If not empty, the filename to save to
|
||||
*/
|
||||
void save(const std::string& filename = "");
|
||||
|
||||
/*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length
|
||||
/*! @brief Writes the given buffer with the specified length, buffers can be bigger than the length
|
||||
* however it's undefined behavior to try and write a buffer which is smaller than the given length.
|
||||
* If you are needing to fill in an area please use IStreamWriter::fill(atUint64) instead.
|
||||
*
|
||||
* \param data The buffer to write
|
||||
* \param length The amount to write
|
||||
* @param data The buffer to write
|
||||
* @param length The amount to write
|
||||
*/
|
||||
void writeUBytes(const atUint8* data, atUint64 len);
|
||||
|
||||
|
@ -113,42 +113,42 @@ class MemoryCopyWriter : public MemoryWriter
|
|||
{
|
||||
public:
|
||||
|
||||
/*! \brief This constructor copies an existing buffer to write to.
|
||||
/*! @brief This constructor copies an existing buffer to write to.
|
||||
*
|
||||
* \param data The existing buffer
|
||||
* \param length The length of the existing buffer
|
||||
* @param data The existing buffer
|
||||
* @param length The length of the existing buffer
|
||||
*/
|
||||
explicit MemoryCopyWriter(atUint8* data=nullptr, atUint64 length=0x10);
|
||||
|
||||
/*! \brief This constructor creates an instance from a file on disk.
|
||||
/*! @brief This constructor creates an instance from a file on disk.
|
||||
*
|
||||
* \param filename The file to create the stream from
|
||||
* @param filename The file to create the stream from
|
||||
*/
|
||||
MemoryCopyWriter(const std::string& filename);
|
||||
|
||||
/*! \brief Sets the buffers position relative to the specified position.<br />
|
||||
/*! @brief Sets the buffers position relative to the specified position.<br />
|
||||
* It seeks relative to the current position by default.
|
||||
* \param position where in the buffer to seek
|
||||
* \param origin The Origin to seek \sa SeekOrigin
|
||||
* @param position where in the buffer to seek
|
||||
* @param origin The Origin to seek @sa SeekOrigin
|
||||
*/
|
||||
void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current);
|
||||
|
||||
/*! \brief Sets the buffer to the given one, deleting the current one.<br />
|
||||
/*! @brief Sets the buffer to the given one, deleting the current one.<br />
|
||||
* <b>BEWARE:</b> As this deletes the current buffer it WILL cause a loss of data
|
||||
* if that was not the intent.<br />
|
||||
* Once you pass the data to setData <b>DO NOT</b> delete the buffer
|
||||
* as Stream now owns the address, this is done to keep memory usage down.
|
||||
* \param data The new buffer.
|
||||
* \param length The length of the new buffer.
|
||||
* \throw IOException
|
||||
* @param data The new buffer.
|
||||
* @param length The length of the new buffer.
|
||||
* @throw IOException
|
||||
*/
|
||||
void setData(const atUint8* data, atUint64 length);
|
||||
|
||||
/*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length
|
||||
/*! @brief Writes the given buffer with the specified length, buffers can be bigger than the length
|
||||
* however it's undefined behavior to try and write a buffer which is smaller than the given length.
|
||||
*
|
||||
* \param data The buffer to write
|
||||
* \param length The amount to write
|
||||
* @param data The buffer to write
|
||||
* @param length The amount to write
|
||||
*/
|
||||
void writeUBytes(const atUint8* data, atUint64 len);
|
||||
|
||||
|
|
|
@ -1,45 +1,15 @@
|
|||
#ifndef TYPES_HPP
|
||||
#define TYPES_HPP
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// 8 bits integer types
|
||||
#if UCHAR_MAX == 0xFF
|
||||
typedef signed char atInt8;
|
||||
typedef unsigned char atUint8;
|
||||
#else
|
||||
#error No 8 bits integer type for this platform
|
||||
#endif
|
||||
|
||||
// 16 bits integer types
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef signed short atInt16;
|
||||
typedef unsigned short atUint16;
|
||||
#elif UINT_MAX == 0xFFFF
|
||||
typedef signed int atInt16;
|
||||
typedef unsigned int atUint16;
|
||||
#elif ULONG_MAX == 0xFFFF
|
||||
typedef signed long atInt16;
|
||||
typedef unsigned long atUint16;
|
||||
#else
|
||||
#error No 16 bits integer type for this platform
|
||||
#endif
|
||||
|
||||
// 32 bits integer types
|
||||
#if USHRT_MAX == 0xFFFFFFFF
|
||||
typedef signed short atInt32;
|
||||
typedef unsigned short atUint32;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef signed int atInt32;
|
||||
typedef unsigned int atUint32;
|
||||
#elif ULONG_MAX == 0xFFFFFFFF
|
||||
typedef signed long atInt32;
|
||||
typedef unsigned long atUint32;
|
||||
#else
|
||||
#error No 32 bits integer type for this platform
|
||||
#endif
|
||||
|
||||
typedef signed long long atInt64;
|
||||
typedef unsigned long long atUint64;
|
||||
using atInt8 = int8_t;
|
||||
using atUint8 = uint8_t;
|
||||
using atInt16 = int16_t;
|
||||
using atUint16 = uint16_t;
|
||||
using atInt32 = int32_t;
|
||||
using atUint32 = uint32_t;
|
||||
using atInt64 = int64_t;
|
||||
using atUint64 = uint64_t;
|
||||
|
||||
// Vector types
|
||||
#if __SSE__
|
||||
|
@ -124,15 +94,6 @@ typedef union alignas(16)
|
|||
double vec[4];
|
||||
} atVec4d;
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
#else // __cplusplus
|
||||
#define NULL (void*)0
|
||||
#endif
|
||||
#endif // NULL
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) ((void)x)
|
||||
#endif // UNUSED
|
||||
|
|
15
include/bn.h
15
include/bn.h
|
@ -1,15 +0,0 @@
|
|||
#ifndef BN_H
|
||||
#define BN_H
|
||||
|
||||
#ifndef __DOXYGEN_IGNORE__
|
||||
|
||||
#include "athena/Types.hpp"
|
||||
int bn_compare(atUint8* a, atUint8* b, atUint32 n);
|
||||
void bn_sub_modulus(atUint8* a, atUint8* N, atUint32 n);
|
||||
void bn_add(atUint8* d, atUint8* a, atUint8* b, atUint8* N, atUint32 n);
|
||||
void bn_mul(atUint8* d, atUint8* a, atUint8* b, atUint8* N, atUint32 n);
|
||||
void bn_exp(atUint8* d, atUint8* a, atUint8* N, atUint32 n, atUint8* e, atUint32 en);
|
||||
void bn_inv(atUint8* d, atUint8* a, atUint8* N, atUint32 n);
|
||||
|
||||
#endif // __DOXYGEN_IGNORE__
|
||||
#endif // BN_H
|
10
include/ec.h
10
include/ec.h
|
@ -1,10 +0,0 @@
|
|||
#ifndef EC_H
|
||||
#define EC_H
|
||||
#include "athena/Types.hpp"
|
||||
|
||||
bool check_ec(atUint8* ng, atUint8* ap, atUint8* sig, atUint8* sig_hash);
|
||||
void make_ec_cert(atUint8* cert, atUint8* sig, char* signer, char* name, atUint8* priv, atUint32 key_id);
|
||||
void generate_ecdsa(atUint8* R, atUint8* S, atUint8* k, atUint8* hash);
|
||||
|
||||
#endif // EC_H
|
||||
|
|
@ -280,7 +280,7 @@ void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length)
|
|||
return;
|
||||
}
|
||||
|
||||
memcpy((atInt8*)(m_data + m_position), data, length);
|
||||
memcpy(reinterpret_cast<atInt8*>(m_data + m_position), data, length);
|
||||
|
||||
m_position += length;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length)
|
|||
if (m_position + length > m_length)
|
||||
resize(m_position + length);
|
||||
|
||||
memcpy((atInt8*)(m_data + m_position), data, length);
|
||||
memcpy(reinterpret_cast<atInt8*>(m_data + m_position), data, length);
|
||||
|
||||
m_position += length;
|
||||
}
|
||||
|
|
|
@ -306,10 +306,11 @@ void WiiSaveReader::readCerts(atUint32 totalSize)
|
|||
|
||||
hash = getSha1(data.get(), dataSize);
|
||||
atUint8* hash2 = getSha1(hash, 20);
|
||||
|
||||
#if 0
|
||||
std::cout << "validating..." << std::endl;
|
||||
std::cout << (check_ec(ngCert.get(), apCert.get(), sig.get(), hash2) ? "ok" : "invalid") << "...";
|
||||
std::cout << "done" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
WiiFile* WiiSaveReader::buildTree(std::vector<WiiFile*> files)
|
||||
|
|
|
@ -194,6 +194,7 @@ void WiiSaveWriter::writeImage(WiiImage* image)
|
|||
|
||||
void WiiSaveWriter::writeCerts(atUint32 filesSize, atUint32 ngId, atUint8* ngPriv, atUint8* ngSig, atUint32 ngKeyId)
|
||||
{
|
||||
#if 0
|
||||
atUint8 sig[0x40];
|
||||
atUint8 ngCert[0x180];
|
||||
atUint8 apCert[0x180];
|
||||
|
@ -245,6 +246,7 @@ void WiiSaveWriter::writeCerts(atUint32 filesSize, atUint32 ngId, atUint8* ngPri
|
|||
base::writeBytes((atInt8*)sig, 0x40);
|
||||
base::writeBytes((atInt8*)ngCert, 0x180);
|
||||
base::writeBytes((atInt8*)apCert, 0x180);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // io
|
||||
|
|
122
src/bn.cpp
122
src/bn.cpp
|
@ -1,122 +0,0 @@
|
|||
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
// Licensed under the terms of the GNU GPL, version 2
|
||||
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bn.h"
|
||||
|
||||
static void bn_zero(atUint8* d, atUint32 n)
|
||||
{
|
||||
memset(d, 0, n);
|
||||
}
|
||||
|
||||
static void bn_copy(atUint8* d, atUint8* a, atUint32 n)
|
||||
{
|
||||
memcpy(d, a, n);
|
||||
}
|
||||
|
||||
int bn_compare(atUint8* a, atUint8* b, atUint32 n)
|
||||
{
|
||||
atUint32 i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (a[i] < b[i])
|
||||
return -1;
|
||||
|
||||
if (a[i] > b[i])
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bn_sub_modulus(atUint8* a, atUint8* N, atUint32 n)
|
||||
{
|
||||
atUint32 i;
|
||||
atUint32 dig;
|
||||
atUint8 c;
|
||||
|
||||
c = 0;
|
||||
|
||||
for (i = n - 1; i < n; i--)
|
||||
{
|
||||
dig = N[i] + c;
|
||||
c = (a[i] < dig);
|
||||
a[i] -= dig;
|
||||
}
|
||||
}
|
||||
|
||||
void bn_add(atUint8* d, atUint8* a, atUint8* b, atUint8* N, atUint32 n)
|
||||
{
|
||||
atUint32 i;
|
||||
atUint32 dig;
|
||||
atUint8 c;
|
||||
|
||||
c = 0;
|
||||
|
||||
for (i = n - 1; i < n; i--)
|
||||
{
|
||||
dig = a[i] + b[i] + c;
|
||||
c = (dig >= 0x100);
|
||||
d[i] = dig;
|
||||
}
|
||||
|
||||
if (c)
|
||||
bn_sub_modulus(d, N, n);
|
||||
|
||||
if (bn_compare(d, N, n) >= 0)
|
||||
bn_sub_modulus(d, N, n);
|
||||
}
|
||||
|
||||
void bn_mul(atUint8* d, atUint8* a, atUint8* b, atUint8* N, atUint32 n)
|
||||
{
|
||||
atUint32 i;
|
||||
atUint8 mask;
|
||||
|
||||
bn_zero(d, n);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
for (mask = 0x80; mask != 0; mask >>= 1)
|
||||
{
|
||||
bn_add(d, d, d, N, n);
|
||||
|
||||
if ((a[i] & mask) != 0)
|
||||
bn_add(d, d, b, N, n);
|
||||
}
|
||||
}
|
||||
|
||||
void bn_exp(atUint8* d, atUint8* a, atUint8* N, atUint32 n, atUint8* e, atUint32 en)
|
||||
{
|
||||
atUint8 t[512];
|
||||
atUint32 i;
|
||||
atUint8 mask;
|
||||
|
||||
bn_zero(d, n);
|
||||
d[n - 1] = 1;
|
||||
|
||||
for (i = 0; i < en; i++)
|
||||
for (mask = 0x80; mask != 0; mask >>= 1)
|
||||
{
|
||||
bn_mul(t, d, d, N, n);
|
||||
|
||||
if ((e[i] & mask) != 0)
|
||||
bn_mul(d, t, a, N, n);
|
||||
else
|
||||
bn_copy(d, t, n);
|
||||
}
|
||||
}
|
||||
|
||||
// only for prime N -- stupid but lazy, see if I care
|
||||
void bn_inv(atUint8* d, atUint8* a, atUint8* N, atUint32 n)
|
||||
{
|
||||
atUint8 t[512], s[512];
|
||||
|
||||
bn_copy(t, N, n);
|
||||
bn_zero(s, n);
|
||||
s[n - 1] = 2;
|
||||
bn_sub_modulus(t, s, n);
|
||||
bn_exp(d, a, N, n, t, n);
|
||||
}
|
451
src/ec.cpp
451
src/ec.cpp
|
@ -1,451 +0,0 @@
|
|||
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
// Licensed under the terms of the GNU GPL, version 2
|
||||
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
|
||||
|
||||
// TODO: Clean this code up and prune
|
||||
// NOTE: It's pretty much been gutted from it's original form, does the original license even apply anymore?
|
||||
|
||||
// Not all of these headers are necessary, figure out which ones are actually used and prune those that are irrelevant.
|
||||
#include <string.h>
|
||||
#include "athena/Utility.hpp"
|
||||
|
||||
#include "bn.h"
|
||||
#include "ec.h"
|
||||
#include "sha1.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 atUint8 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 atUint8 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(atUint8* d, atUint8* a)
|
||||
{
|
||||
memcpy(d, a, 30);
|
||||
}
|
||||
|
||||
static void elt_zero(atUint8* d)
|
||||
{
|
||||
memset(d, 0, 30);
|
||||
}
|
||||
|
||||
static int elt_is_zero(atUint8* d)
|
||||
{
|
||||
atUint32 i;
|
||||
|
||||
for (i = 0; i < 30; i++)
|
||||
if (d[i] != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void elt_add(atUint8* d, atUint8* a, atUint8* b)
|
||||
{
|
||||
atUint32 i;
|
||||
|
||||
for (i = 0; i < 30; i++)
|
||||
d[i] = a[i] ^ b[i];
|
||||
}
|
||||
|
||||
static void elt_mul_x(atUint8* d, atUint8* a)
|
||||
{
|
||||
atUint8 carry, x, y;
|
||||
atUint32 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(atUint8* d, atUint8* a, atUint8* b)
|
||||
{
|
||||
atUint32 i, n;
|
||||
atUint8 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 atUint8 square[16] = { 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 };
|
||||
|
||||
static void elt_square_to_wide(atUint8* d, atUint8* a)
|
||||
{
|
||||
atUint32 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(atUint8* d)
|
||||
{
|
||||
atUint32 i;
|
||||
atUint8 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(atUint8* d, atUint8* a)
|
||||
{
|
||||
atUint8 wide[60];
|
||||
|
||||
elt_square_to_wide(wide, a);
|
||||
wide_reduce(wide);
|
||||
|
||||
elt_copy(d, wide + 30);
|
||||
}
|
||||
|
||||
static void itoh_tsujii(atUint8* d, atUint8* a, atUint8* b, atUint32 j)
|
||||
{
|
||||
atUint8 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(atUint8* d, atUint8* a)
|
||||
{
|
||||
atUint8 t[30];
|
||||
atUint8 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(atUint8* p)
|
||||
{
|
||||
return elt_is_zero(p) && elt_is_zero(p + 30);
|
||||
}
|
||||
|
||||
static void point_double(atUint8* r, atUint8* p)
|
||||
{
|
||||
atUint8 s[30], t[30];
|
||||
atUint8* 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(atUint8* r, atUint8* p, atUint8* q)
|
||||
{
|
||||
atUint8 s[30], t[30], u[30];
|
||||
atUint8* 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(atUint8* d, atUint8* a, atUint8* b) // a is bignum
|
||||
{
|
||||
atUint32 i;
|
||||
atUint8 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 generate_ecdsa(atUint8* R, atUint8* S, atUint8* k, atUint8* hash)
|
||||
{
|
||||
atUint8 e[30];
|
||||
atUint8 kk[30];
|
||||
atUint8 m[30];
|
||||
atUint8 minv[30];
|
||||
atUint8 mG[60];
|
||||
//FILE *fp;
|
||||
|
||||
elt_zero(e);
|
||||
memcpy(e + 10, hash, 20);
|
||||
|
||||
athena::utility::fillRandom(m, sizeof(m));
|
||||
m[0] = 0;
|
||||
|
||||
// R = (mG).x
|
||||
|
||||
point_mul(mG, m, ec_G);
|
||||
elt_copy(R, mG);
|
||||
|
||||
if (bn_compare(R, ec_N, 30) >= 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);
|
||||
}
|
||||
|
||||
bool check_ecdsa(atUint8* Q, atUint8* R, atUint8* S, atUint8* hash)
|
||||
{
|
||||
atUint8 Sinv[30];
|
||||
atUint8 e[30];
|
||||
atUint8 w1[30], w2[30];
|
||||
atUint8 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(atUint8* k, atUint8* Q)
|
||||
{
|
||||
point_mul(Q, k, ec_G);
|
||||
}
|
||||
|
||||
bool check_ec(atUint8* ng, atUint8* ap, atUint8* sig, atUint8* sig_hash)
|
||||
{
|
||||
atUint8* ap_hash;
|
||||
atUint8* ng_Q, *ap_R, *ap_S;
|
||||
atUint8* ap_Q, *sig_R, *sig_S;
|
||||
|
||||
ng_Q = ng + 0x0108;
|
||||
ap_R = ap + 0x04;
|
||||
ap_S = ap + 0x22;
|
||||
|
||||
|
||||
ap_hash = getSha1(ap + 0x80, 0x100);
|
||||
ap_Q = ap + 0x0108;
|
||||
sig_R = sig;
|
||||
sig_S = sig + 30;
|
||||
|
||||
return check_ecdsa(ng_Q, ap_R, ap_S, ap_hash)
|
||||
&& check_ecdsa(ap_Q, sig_R, sig_S, sig_hash);
|
||||
}
|
||||
|
||||
void make_ec_cert(atUint8* cert, atUint8* sig, char* signer, char* name, atUint8* priv, atUint32 key_id)
|
||||
{
|
||||
memset(cert, 0, 0x180);
|
||||
*(atUint32*)(cert) = 0x10002;
|
||||
|
||||
if (!athena::utility::isSystemBigEndian())
|
||||
*(atUint32*)(cert) = athena::utility::swapU32(*(atUint32*)(cert));
|
||||
|
||||
memcpy((char*)cert + 4, sig, 60);
|
||||
strcpy((char*)cert + 0x80, signer);
|
||||
*(atUint32*)(cert + 0xc0) = 2;
|
||||
|
||||
if (!athena::utility::isSystemBigEndian())
|
||||
*(atUint32*)(cert + 0xc0) = athena::utility::swapU32(*(atUint32*)(cert + 0xc0));
|
||||
|
||||
strcpy((char*)cert + 0xc4, name);
|
||||
*(atUint32*)(cert + 0x104) = key_id;
|
||||
|
||||
if (!athena::utility::isSystemBigEndian())
|
||||
*(atUint32*)(cert + 0x104) = athena::utility::swapU32(*(atUint32*)(cert + 0x104));
|
||||
|
||||
ec_priv_to_pub(priv, cert + 0x108);
|
||||
}
|
Loading…
Reference in New Issue