First commit for 0.2.3, some old functions still need to be ported to the new back-end api, i.e. import and export.
git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@104 b624d157-de02-0410-bad0-e51aec6abb33master
parent
0286b87a41
commit
21f0fea56a
Before Width: | Height: | Size: 806 B After Width: | Height: | Size: 898 B |
After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
File diff suppressed because it is too large
Load Diff
@ -1,125 +0,0 @@ |
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2005-2006 by Tarek Saidi * |
|
||||||
* tarek.saidi@arcor.de * |
|
||||||
* * |
|
||||||
* 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., * |
|
||||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
|
||||||
***************************************************************************/ |
|
||||||
|
|
||||||
#ifndef _PW_MANAGER_H_ |
|
||||||
#define _PW_MANAGER_H_ |
|
||||||
#define DB_HEADER_SIZE 124 |
|
||||||
#define PWM_DBSIG_1 0x9AA2D903 |
|
||||||
#define PWM_DBSIG_2 0xB54BFB65 |
|
||||||
#define PWM_DBVER_DW 0x00030002 |
|
||||||
#define PWM_FLAG_SHA2 1 |
|
||||||
#define PWM_FLAG_RIJNDAEL 2 |
|
||||||
#define PWM_FLAG_ARCFOUR 4 |
|
||||||
#define PWM_FLAG_TWOFISH 8 |
|
||||||
#define PWM_STD_KEYENCROUNDS 6000 |
|
||||||
|
|
||||||
#include <qcolor.h> |
|
||||||
#include <qobject.h> |
|
||||||
#include <QDateTime> |
|
||||||
#include <QDate> |
|
||||||
#include <QTime> |
|
||||||
#include <QStringList> |
|
||||||
#include <QPixmap> |
|
||||||
#include "lib/SecString.h" |
|
||||||
#include "Database.h" |
|
||||||
|
|
||||||
|
|
||||||
class PwDatabase:public Database{ |
|
||||||
Q_OBJECT |
|
||||||
public: |
|
||||||
PwDatabase(); |
|
||||||
bool openDatabase(QString filename, QString& err); |
|
||||||
bool saveDatabase(); |
|
||||||
bool closeDatabase(); |
|
||||||
void newDatabase(); |
|
||||||
bool CalcMasterKeyByPassword(QString& password); |
|
||||||
bool CalcMasterKeyByFile(QString filename); |
|
||||||
bool CalcMasterKeyByFileAndPw(QString filename, QString& password); |
|
||||||
bool createKeyFile(const QString& filename); |
|
||||||
|
|
||||||
CGroup& group(unsigned long index); |
|
||||||
void setGroup(unsigned long index,CGroup& group); |
|
||||||
int numGroups(); |
|
||||||
CGroup* addGroup(CGroup* parent); |
|
||||||
void deleteGroup(CGroup* pGroup); |
|
||||||
void deleteGroup(unsigned long ID); |
|
||||||
void moveGroup(CGroup* group, CGroup* DstGroup, int pos=-1); |
|
||||||
void moveGroupDirectly(CGroup* group, CGroup* DstGroup); //inserts group directly behind DstGroup on the same level
|
|
||||||
int getGroupIndex(CGroup* group); |
|
||||||
int getGroupIndex(unsigned long ID); |
|
||||||
int getNumberOfChilds(CGroup* pGroup); |
|
||||||
QList<int> getChildIds(CGroup* pGroup); |
|
||||||
|
|
||||||
CEntry& entry(unsigned long index); |
|
||||||
CEntry* getEntry(const KpxUuid& uuid); |
|
||||||
void setEntry(unsigned long index,CEntry& Entry); |
|
||||||
int numEntries(); |
|
||||||
CEntry* cloneEntry(CEntry* pEntry); |
|
||||||
void deleteEntry(CEntry* pEntry); |
|
||||||
void moveEntry(CEntry* pEntry,CGroup* pDstGroup); |
|
||||||
CEntry* addEntry(); |
|
||||||
CEntry* addEntry(CEntry* NewEntry); |
|
||||||
void merge(Database* db2); |
|
||||||
bool isParentGroup(CGroup* Group,CGroup* PotenialParent); |
|
||||||
|
|
||||||
QString getError(); //get first error
|
|
||||||
QString getErrors(); //get all errors in a \n seperated String
|
|
||||||
QPixmap& icon(int index); |
|
||||||
int numIcons(); |
|
||||||
void addIcon(const QPixmap& icon); |
|
||||||
void removeIcon(int Id); |
|
||||||
void replaceIcon(int Id,const QPixmap& icon); |
|
||||||
|
|
||||||
QList<CGroup>Groups; |
|
||||||
QList<CEntry>Entries; |
|
||||||
private: |
|
||||||
bool IsMetaStream(CEntry& Entry); |
|
||||||
bool parseMetaStream(const CEntry& Entry); |
|
||||||
bool parseCustomIconsMetaStream(const QByteArray& data); |
|
||||||
bool parseCustomIconsMetaStreamV1(const QByteArray& data); |
|
||||||
void createCustomIconsMetaStream(CEntry* dst); |
|
||||||
void transformKey(quint8* src,quint8* dst,quint8* seed,int rounds); |
|
||||||
bool readHeader(char* raw); |
|
||||||
bool isGroupIdInUse(quint32 GroupID); |
|
||||||
bool isEntrySidInUse(quint32 sID); |
|
||||||
quint32 getNewGroupId(); |
|
||||||
quint32 getNewEntrySid(); |
|
||||||
bool convHexToBinaryKey(char* HexKey, char* dst); |
|
||||||
QStringList Errors; |
|
||||||
QList<QPixmap> CustomIcons; |
|
||||||
QList<CEntry> UnkownMetaStreams; |
|
||||||
|
|
||||||
signals: |
|
||||||
void iconsModified(); |
|
||||||
|
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void memcpyFromLEnd32(quint32* dst,const char* src); |
|
||||||
void memcpyFromLEnd16(quint16* dst,const char* src); |
|
||||||
void memcpyToLEnd32(char* src,const quint32* dst); |
|
||||||
void memcpyToLEnd16(char* src,const quint16* dst); |
|
||||||
QDateTime dateFromPackedStruct5(const unsigned char* pBytes); |
|
||||||
void dateToPackedStruct5(const QDateTime& datetime, unsigned char* dst); |
|
||||||
|
|
||||||
bool testDatabase(); |
|
||||||
|
|
||||||
#endif |
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,233 @@ |
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2005-2006 by Tarek Saidi * |
||||||
|
* keepassx@gmail.com * |
||||||
|
* * |
||||||
|
* 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., * |
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
||||||
|
***************************************************************************/ |
||||||
|
|
||||||
|
#ifndef _STD_DATABASE_H_ |
||||||
|
#define _STD_DATABASE_H_ |
||||||
|
|
||||||
|
#define DB_HEADER_SIZE 124 |
||||||
|
#define PWM_DBSIG_1 0x9AA2D903 |
||||||
|
#define PWM_DBSIG_2 0xB54BFB65 |
||||||
|
#define PWM_DBVER_DW 0x00030002 |
||||||
|
#define PWM_FLAG_SHA2 1 |
||||||
|
#define PWM_FLAG_RIJNDAEL 2 |
||||||
|
#define PWM_FLAG_ARCFOUR 4 |
||||||
|
#define PWM_FLAG_TWOFISH 8 |
||||||
|
#define PWM_STD_KEYENCROUNDS 6000 |
||||||
|
|
||||||
|
#include <qcolor.h> |
||||||
|
#include <qobject.h> |
||||||
|
#include <QDateTime> |
||||||
|
#include <QDate> |
||||||
|
#include <QTime> |
||||||
|
#include <QStringList> |
||||||
|
#include <QPixmap> |
||||||
|
#include "lib/SecString.h" |
||||||
|
#include "Database.h" |
||||||
|
|
||||||
|
|
||||||
|
void memcpyFromLEnd32(quint32* dst,const char* src); |
||||||
|
void memcpyFromLEnd16(quint16* dst,const char* src); |
||||||
|
void memcpyToLEnd32(char* src,const quint32* dst); |
||||||
|
void memcpyToLEnd16(char* src,const quint16* dst); |
||||||
|
|
||||||
|
//! Implementation of the standard KeePassX database.
|
||||||
|
class StandardDatabase:public ICustomIcons,public IDatabase, public IFilePasswordAuth{ |
||||||
|
Q_OBJECT |
||||||
|
public: |
||||||
|
class StdGroup; |
||||||
|
class StdEntry; |
||||||
|
class EntryHandle:public IEntryHandle{ |
||||||
|
friend class StandardDatabase; |
||||||
|
public: |
||||||
|
EntryHandle(StandardDatabase* db); |
||||||
|
virtual void setImage(const quint32& ImageID); |
||||||
|
void setOldImage(const quint32& OldImgID); |
||||||
|
virtual void setTitle(const QString& Title); |
||||||
|
virtual void setUrl(const QString& URL); |
||||||
|
virtual void setUsername(const QString& Username); |
||||||
|
virtual void setPassword(const SecString& Password); |
||||||
|
virtual void setComment(const QString& Comment); |
||||||
|
virtual void setBinaryDesc(const QString& BinaryDesc); |
||||||
|
virtual void setCreation(const KpxDateTime& Creation); |
||||||
|
virtual void setLastMod(const KpxDateTime& LastMod); |
||||||
|
virtual void setLastAccess(const KpxDateTime& LastAccess); |
||||||
|
virtual void setExpire(const KpxDateTime& Expire); |
||||||
|
virtual void setBinary(const QByteArray& BinaryData); |
||||||
|
virtual KpxUuid uuid(); |
||||||
|
virtual IGroupHandle* group(); |
||||||
|
virtual quint32 image(); |
||||||
|
virtual int index() const; |
||||||
|
quint32 oldImage(); |
||||||
|
virtual QString title(); |
||||||
|
virtual QString url(); |
||||||
|
virtual QString username(); |
||||||
|
virtual SecString password(); |
||||||
|
virtual QString comment(); |
||||||
|
virtual QString binaryDesc(); |
||||||
|
virtual KpxDateTime creation(); |
||||||
|
virtual KpxDateTime lastMod(); |
||||||
|
virtual KpxDateTime lastAccess(); |
||||||
|
virtual KpxDateTime expire(); |
||||||
|
virtual QByteArray binary(); |
||||||
|
virtual quint32 binarySize(); |
||||||
|
virtual bool isValid() const; |
||||||
|
virtual bool operator<(const IEntryHandle*& other); |
||||||
|
private: |
||||||
|
void invalidate(){valid=false;} |
||||||
|
bool valid; |
||||||
|
unsigned int ListIndex; |
||||||
|
KpxUuid Uuid; |
||||||
|
StandardDatabase* pDB; |
||||||
|
StdEntry* Entry; |
||||||
|
}; |
||||||
|
class GroupHandle:public IGroupHandle{ |
||||||
|
friend class StandardDatabase; |
||||||
|
GroupHandle(StandardDatabase* db); |
||||||
|
public: |
||||||
|
virtual void setTitle(const QString& Title); |
||||||
|
virtual void setImage(const quint32& ImageId); |
||||||
|
void setOldImage(const quint32& ImageId);
|
||||||
|
virtual QString title(); |
||||||
|
virtual quint32 image(); |
||||||
|
quint32 oldImage(); |
||||||
|
virtual bool isValid(); |
||||||
|
virtual IGroupHandle* parent(); |
||||||
|
virtual QList<IGroupHandle*> childs(); |
||||||
|
virtual int index(); |
||||||
|
virtual void setIndex(int index); |
||||||
|
virtual int level(); |
||||||
|
private: |
||||||
|
void invalidate(){valid=false;} |
||||||
|
bool valid; |
||||||
|
StdGroup* Group; |
||||||
|
StandardDatabase* pDB; |
||||||
|
}; |
||||||
|
friend class EntryHandle; |
||||||
|
friend class GroupHandle; |
||||||
|
class StdEntry:public CEntry{ |
||||||
|
public: |
||||||
|
quint32 OldImage; |
||||||
|
quint16 Index; |
||||||
|
EntryHandle* Handle; |
||||||
|
StdGroup* Group; |
||||||
|
}; |
||||||
|
class StdGroup:public CGroup{ |
||||||
|
public: |
||||||
|
StdGroup():CGroup(){}; |
||||||
|
StdGroup(const CGroup&); |
||||||
|
quint32 OldImage; |
||||||
|
quint16 Index; |
||||||
|
StdGroup* Parent; |
||||||
|
GroupHandle* Handle; |
||||||
|
QList<StdGroup*> Childs; |
||||||
|
QList<StdEntry*> Entries; |
||||||
|
}; |
||||||
|
virtual bool load(QString identifier); |
||||||
|
virtual bool save(); |
||||||
|
virtual bool close(); |
||||||
|
virtual void create(); |
||||||
|
virtual int numEntries(); |
||||||
|
virtual int numGroups(); |
||||||
|
virtual QString getError(); |
||||||
|
virtual void cleanUpHandles(); |
||||||
|
virtual QPixmap& icon(int index); |
||||||
|
virtual int numIcons(); |
||||||
|
virtual void addIcon(const QPixmap& icon); |
||||||
|
virtual void removeIcon(int index); |
||||||
|
virtual void replaceIcon(int index,const QPixmap& icon); |
||||||
|
virtual int builtinIcons(){return 62;}; |
||||||
|
virtual void authByPwd(QString& password); |
||||||
|
virtual bool authByFile(QFile& file); |
||||||
|
virtual bool authByFileAndPwd(QString& password, QFile& file); |
||||||
|
virtual bool createKeyFile(const QString& filename,int length=32, bool Hex=false); |
||||||
|
virtual QList<IEntryHandle*> search(IGroupHandle* Group,const QString& SearchString, bool CaseSensitve, bool RegExp,bool Recursive,bool* Fields); |
||||||
|
virtual QFile* file(){return File;} |
||||||
|
virtual bool changeFile(const QString& filename); |
||||||
|
|
||||||
|
virtual QList<IEntryHandle*> entries(); |
||||||
|
virtual QList<IEntryHandle*> entries(IGroupHandle* Group); |
||||||
|
virtual IEntryHandle* cloneEntry(const IEntryHandle* entry); |
||||||
|
virtual void deleteEntry(IEntryHandle* entry); |
||||||
|
virtual void deleteEntries(QList<IEntryHandle*> entries); |
||||||
|
virtual IEntryHandle* newEntry(IGroupHandle* group); |
||||||
|
virtual IEntryHandle* addEntry(const CEntry* NewEntry, IGroupHandle* group); |
||||||
|
virtual void moveEntry(IEntryHandle* entry, IGroupHandle* group); |
||||||
|
virtual void deleteLastEntry(); |
||||||
|
|
||||||
|
|
||||||
|
virtual QList<IGroupHandle*> groups(); |
||||||
|
virtual QList<IGroupHandle*> sortedGroups(); |
||||||
|
virtual void deleteGroup(IGroupHandle* group); |
||||||
|
virtual void moveGroup(IGroupHandle* Group,IGroupHandle* NewParent,int Position); |
||||||
|
virtual IGroupHandle* addGroup(const CGroup* Group,IGroupHandle* Parent); |
||||||
|
virtual bool isParent(IGroupHandle* parent, IGroupHandle* child); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private: |
||||||
|
QDateTime dateFromPackedStruct5(const unsigned char* pBytes); |
||||||
|
void dateToPackedStruct5(const QDateTime& datetime, unsigned char* dst); |
||||||
|
bool isMetaStream(StdEntry& Entry); |
||||||
|
bool parseMetaStream(const StdEntry& Entry); |
||||||
|
bool parseCustomIconsMetaStream(const QByteArray& data); |
||||||
|
bool parseCustomIconsMetaStreamV1(const QByteArray& data); |
||||||
|
bool parseCustomIconsMetaStreamV2(const QByteArray& data); |
||||||
|
bool readEntryField(StdEntry* entry, quint16 FieldType, quint32 FieldSize, quint8 *pData); |
||||||
|
bool readGroupField(StdGroup* group,QList<quint32>& Levels,quint16 FieldType, quint32 FieldSize, quint8 *pData); |
||||||
|
bool createGroupTree(QList<quint32>& Levels); |
||||||
|
void createHandles(); |
||||||
|
bool transformKey(quint8* src,quint8* dst,quint8* KeySeed,int rounds); |
||||||
|
void invalidateHandle(StdEntry* entry); |
||||||
|
bool convHexToBinaryKey(char* HexKey, char* dst); |
||||||
|
quint32 getNewGroupId(); |
||||||
|
void serializeEntries(QList<StdEntry>& EntryList,char* buffer,unsigned int& pos); |
||||||
|
void serializeGroups(QList<StdGroup>& GroupList,char* buffer,unsigned int& pos); |
||||||
|
void createCustomIconsMetaStream(StdEntry* e); |
||||||
|
void appendChildsToGroupList(QList<StdGroup*>& list,StdGroup& group); |
||||||
|
void appendChildsToGroupList(QList<IGroupHandle*>& list,StdGroup& group); |
||||||
|
bool searchStringContains(const QString& search, const QString& string,bool Cs, bool RegExp); |
||||||
|
void getEntriesRecursive(IGroupHandle* Group, QList<IEntryHandle*>& EntryList); |
||||||
|
void rebuildIndices(QList<StdGroup*>& list); |
||||||
|
|
||||||
|
StdEntry* getEntry(const KpxUuid& uuid); |
||||||
|
StdEntry* getEntry(EntryHandle* handle); |
||||||
|
int getEntryListIndex(EntryHandle* handle); |
||||||
|
EntryHandle* getHandle(StdEntry* entry); |
||||||
|
|
||||||
|
StdGroup* getGroup(quint32 Id); |
||||||
|
void deleteGroup(StdGroup* group); |
||||||
|
|
||||||
|
QList<EntryHandle> EntryHandles; |
||||||
|
QList<GroupHandle> GroupHandles; |
||||||
|
QList<StdEntry> Entries; |
||||||
|
QList<StdGroup> Groups; |
||||||
|
StdGroup RootGroup; |
||||||
|
QList<QPixmap>CustomIcons; |
||||||
|
QFile* File; |
||||||
|
QString error; |
||||||
|
QList<StdEntry> UnknownMetaStreams; |
||||||
|
unsigned int KeyTransfRounds; |
||||||
|
CryptAlgorithm Algorithm; |
||||||
|
quint8 RawMasterKey[32]; |
||||||
|
quint8 MasterKey[32]; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,197 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
|
||||||
|
This file contains the definitions required to use AES in C. See aesopt.h |
||||||
|
for optimisation details. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _AES_H |
||||||
|
#define _AES_H |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
|
||||||
|
/* This include is used to find 8 & 32 bit unsigned integer types */ |
||||||
|
#include "aes_tdefs.h" |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
#define AES_128 /* define if AES with 128 bit keys is needed */ |
||||||
|
#define AES_192 /* define if AES with 192 bit keys is needed */ |
||||||
|
#define AES_256 /* define if AES with 256 bit keys is needed */ |
||||||
|
#define AES_VAR /* define if a variable key size is needed */ |
||||||
|
#define AES_MODES /* define if support is needed for modes */ |
||||||
|
|
||||||
|
/* The following must also be set in assembler files if being used */ |
||||||
|
|
||||||
|
#define AES_ENCRYPT /* if support for encryption is needed */ |
||||||
|
#define AES_DECRYPT /* if support for decryption is needed */ |
||||||
|
#define AES_ERR_CHK /* for parameter checks & error return codes */ |
||||||
|
#define AES_REV_DKS /* define to reverse decryption key schedule */ |
||||||
|
|
||||||
|
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */ |
||||||
|
#define N_COLS 4 /* the number of columns in the state */ |
||||||
|
|
||||||
|
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ |
||||||
|
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */ |
||||||
|
/* or 44, 52 or 60 32-bit words. */ |
||||||
|
|
||||||
|
#if defined( AES_VAR ) || defined( AES_256 ) |
||||||
|
#define KS_LENGTH 60 |
||||||
|
#elif defined( AES_192 ) |
||||||
|
#define KS_LENGTH 52 |
||||||
|
#else |
||||||
|
#define KS_LENGTH 44 |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
#define aes_rval int_ret |
||||||
|
#else |
||||||
|
#define aes_rval void_ret |
||||||
|
#endif |
||||||
|
|
||||||
|
/* the character array 'inf' in the following structures is used */ |
||||||
|
/* to hold AES context information. This AES code uses cx->inf.b[0] */ |
||||||
|
/* to hold the number of rounds multiplied by 16. The other three */ |
||||||
|
/* elements can be used by code that implements additional modes */ |
||||||
|
|
||||||
|
typedef union |
||||||
|
{ uint_32t l; |
||||||
|
uint_8t b[4]; |
||||||
|
} aes_inf; |
||||||
|
|
||||||
|
typedef struct |
||||||
|
{ uint_32t ks[KS_LENGTH]; |
||||||
|
aes_inf inf; |
||||||
|
} aes_encrypt_ctx; |
||||||
|
|
||||||
|
typedef struct |
||||||
|
{ uint_32t ks[KS_LENGTH]; |
||||||
|
aes_inf inf; |
||||||
|
} aes_decrypt_ctx; |
||||||
|
|
||||||
|
/* This routine must be called before first use if non-static */ |
||||||
|
/* tables are being used */ |
||||||
|
|
||||||
|
aes_rval gen_tabs(void); |
||||||
|
|
||||||
|
/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */ |
||||||
|
/* those in the range 128 <= key_len <= 256 are given in bits */ |
||||||
|
|
||||||
|
#if defined( AES_ENCRYPT ) |
||||||
|
|
||||||
|
#if defined(AES_128) || defined(AES_VAR) |
||||||
|
aes_rval aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_192) || defined(AES_VAR) |
||||||
|
aes_rval aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_256) || defined(AES_VAR) |
||||||
|
aes_rval aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_VAR) |
||||||
|
aes_rval aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
aes_rval aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_DECRYPT ) |
||||||
|
|
||||||
|
#if defined(AES_128) || defined(AES_VAR) |
||||||
|
aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_192) || defined(AES_VAR) |
||||||
|
aes_rval aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_256) || defined(AES_VAR) |
||||||
|
aes_rval aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_VAR) |
||||||
|
aes_rval aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); |
||||||
|
#endif |
||||||
|
|
||||||
|
aes_rval aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_MODES) |
||||||
|
|
||||||
|
aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, const aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
aes_rval aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, const aes_decrypt_ctx cx[1]); |
||||||
|
|
||||||
|
aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, const aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, const aes_decrypt_ctx cx[1]); |
||||||
|
|
||||||
|
aes_rval aes_mode_reset(aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
#define aes_ofb_encrypt aes_ofb_crypt |
||||||
|
#define aes_ofb_decrypt aes_ofb_crypt |
||||||
|
|
||||||
|
aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
typedef void cbuf_inc(unsigned char *cbuf); |
||||||
|
|
||||||
|
#define aes_ctr_encrypt aes_ctr_crypt |
||||||
|
#define aes_ctr_decrypt aes_ctr_crypt |
||||||
|
|
||||||
|
aes_rval aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,130 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef EDEFS_H |
||||||
|
#define EDEFS_H |
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ |
||||||
|
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ |
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__GNU_LIBRARY__) |
||||||
|
# if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) |
||||||
|
# include <sys/endian.h> |
||||||
|
# elif defined( BSD ) && ( BSD >= 199103 ) || defined( __DJGPP__ ) || defined( __CYGWIN32__ ) |
||||||
|
# include <machine/endian.h> |
||||||
|
# elif defined(__APPLE__) |
||||||
|
# if defined(__BIG_ENDIAN__) && !defined( BIG_ENDIAN ) |
||||||
|
# define BIG_ENDIAN |
||||||
|
# elif defined(__LITTLE_ENDIAN__) && !defined( LITTLE_ENDIAN ) |
||||||
|
# define LITTLE_ENDIAN |
||||||
|
# endif |
||||||
|
# elif !defined( __MINGW32__ ) |
||||||
|
# include <endian.h> |
||||||
|
# if !defined(__BEOS__) |
||||||
|
# include <byteswap.h> |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined(PLATFORM_BYTE_ORDER) |
||||||
|
# if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN) |
||||||
|
# if defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
# elif defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
# elif defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
# endif |
||||||
|
# elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN) |
||||||
|
# if defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
# elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
# elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
# endif |
||||||
|
# elif defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__) |
||||||
|
# if defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
# elif !defined(__LITTLE_ENDIAN__) && defined(__BIG_ENDIAN__) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
# elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
# elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
# endif |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* if the platform is still unknown, try to find its byte order */ |
||||||
|
/* from commonly used machine defines */ |
||||||
|
|
||||||
|
#if !defined(PLATFORM_BYTE_ORDER) |
||||||
|
|
||||||
|
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ |
||||||
|
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
|
||||||
|
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
|
||||||
|
defined( vax ) || defined( vms ) || defined( VMS ) || \
|
||||||
|
defined( __VMS ) || defined( _M_X64 ) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
|
||||||
|
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ |
||||||
|
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
|
||||||
|
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
|
||||||
|
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||||
|
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||||
|
defined( __TANDEM ) || defined( THINK_C ) || defined( __VMCMS__ ) || \
|
||||||
|
defined( __VOS__ ) |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
|
||||||
|
#elif 0 /* **** EDIT HERE IF NECESSARY **** */ |
||||||
|
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
#elif 0 /* **** EDIT HERE IF NECESSARY **** */ |
||||||
|
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
#else |
||||||
|
# error Please edit edefs.h (lines 117 or 119) to set the platform byte order |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
||||||
|
#endif |
@ -0,0 +1,891 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
|
||||||
|
These subroutines implement multiple block AES modes for ECB, CBC, CFB, |
||||||
|
OFB and CTR encryption, The code provides support for the VIA Advanced
|
||||||
|
Cryptography Engine (ACE). |
||||||
|
|
||||||
|
NOTE: In the following subroutines, the AES contexts (ctx) must be |
||||||
|
16 byte aligned if VIA ACE is being used |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <memory.h> |
||||||
|
#include <assert.h> |
||||||
|
|
||||||
|
#include "aesopt.h" |
||||||
|
|
||||||
|
#if defined( AES_MODES ) |
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) |
||||||
|
#pragma intrinsic(memcpy) |
||||||
|
#define in_line __inline |
||||||
|
#else |
||||||
|
#define in_line |
||||||
|
#endif |
||||||
|
|
||||||
|
#define BFR_BLOCKS 8 |
||||||
|
|
||||||
|
/* These values are used to detect long word alignment in order to */ |
||||||
|
/* speed up some buffer operations. This facility may not work on */ |
||||||
|
/* some machines so this define can be commented out if necessary */ |
||||||
|
|
||||||
|
#define FAST_BUFFER_OPERATIONS |
||||||
|
#pragma warning( disable : 4311 4312 ) |
||||||
|
|
||||||
|
#define lp08(x) ((uint_8t*)(x)) |
||||||
|
#define lp32(x) ((uint_32t*)(x)) |
||||||
|
#define addr_mod_04(x) ((unsigned long)(x) & 3) |
||||||
|
#define addr_mod_16(x) ((unsigned long)(x) & 15) |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
#include "via_ace.h" |
||||||
|
|
||||||
|
#pragma pack(16) |
||||||
|
|
||||||
|
aligned_array(unsigned long, enc_gen_table, 12, 16) = NEH_ENC_GEN_DATA; |
||||||
|
aligned_array(unsigned long, enc_load_table, 12, 16) = NEH_ENC_LOAD_DATA; |
||||||
|
aligned_array(unsigned long, enc_hybrid_table, 12, 16) = NEH_ENC_HYBRID_DATA; |
||||||
|
aligned_array(unsigned long, dec_gen_table, 12, 16) = NEH_DEC_GEN_DATA; |
||||||
|
aligned_array(unsigned long, dec_load_table, 12, 16) = NEH_DEC_LOAD_DATA; |
||||||
|
aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA; |
||||||
|
|
||||||
|
/* NOTE: These control word macros must only be used after */ |
||||||
|
/* a key has been set up because they depend on key size */ |
||||||
|
|
||||||
|
#if NEH_KEY_TYPE == NEH_LOAD |
||||||
|
#define kd_adr(c) ((uint_8t*)(c)->ks) |
||||||
|
#elif NEH_KEY_TYPE == NEH_GENERATE |
||||||
|
#define kd_adr(c) ((uint_8t*)(c)->ks + (c)->inf.b[0]) |
||||||
|
#else |
||||||
|
#define kd_adr(c) ((uint_8t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0)) |
||||||
|
#endif |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#define aligned_array(type, name, no, stride) type name[no] |
||||||
|
#define aligned_auto(type, name, no, stride) type name[no] |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && _MSC_VER > 1200 |
||||||
|
|
||||||
|
#define via_cwd(cwd, ty, dir, len) unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4)) |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#define via_cwd(cwd, ty, dir, len) \ |
||||||
|
aligned_auto(unsigned long, cwd, 4, 16); \
|
||||||
|
cwd[1] = cwd[2] = cwd[3] = 0; \
|
||||||
|
cwd[0] = neh_##dir##_##ty##_key(len) |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
aes_rval aes_mode_reset(aes_encrypt_ctx ctx[1]) |
||||||
|
{ |
||||||
|
ctx->inf.b[2] = 0;
|
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, const aes_encrypt_ctx ctx[1]) |
||||||
|
{ int nb = len >> 4; |
||||||
|
|
||||||
|
if(len & (AES_BLOCK_SIZE - 1)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ uint_8t *ksp = (uint_8t*)(ctx->ks); |
||||||
|
via_cwd(cwd, hybrid, enc, 2* ctx->inf.b[0] - 192);
|
||||||
|
|
||||||
|
if(addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) |
||||||
|
{ |
||||||
|
via_ecb_op5(ksp,cwd,ibuf,obuf,nb); |
||||||
|
} |
||||||
|
else |
||||||
|
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); |
||||||
|
uint_8t *ip, *op; |
||||||
|
|
||||||
|
while(nb) |
||||||
|
{ |
||||||
|
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); |
||||||
|
|
||||||
|
ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); |
||||||
|
op = (addr_mod_16(obuf) ? buf : obuf); |
||||||
|
|
||||||
|
if(ip != ibuf) |
||||||
|
memcpy(buf, ibuf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
via_ecb_op5(ksp,cwd,ip,op,m); |
||||||
|
|
||||||
|
if(op != obuf) |
||||||
|
memcpy(obuf, buf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
ibuf += m * AES_BLOCK_SIZE; |
||||||
|
obuf += m * AES_BLOCK_SIZE; |
||||||
|
nb -= m; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined( ASSUME_VIA_ACE_PRESENT ) |
||||||
|
while(nb--) |
||||||
|
{ |
||||||
|
aes_encrypt(ibuf, obuf, ctx); |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, const aes_decrypt_ctx ctx[1]) |
||||||
|
{ int nb = len >> 4; |
||||||
|
|
||||||
|
if(len & (AES_BLOCK_SIZE - 1)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ uint_8t *ksp = kd_adr(ctx); |
||||||
|
via_cwd(cwd, hybrid, dec, 2* ctx->inf.b[0] - 192);
|
||||||
|
|
||||||
|
if(addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) |
||||||
|
{ |
||||||
|
via_ecb_op5(ksp,cwd,ibuf,obuf,nb); |
||||||
|
} |
||||||
|
else |
||||||
|
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); |
||||||
|
uint_8t *ip, *op; |
||||||
|
|
||||||
|
while(nb) |
||||||
|
{ |
||||||
|
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); |
||||||
|
|
||||||
|
ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); |
||||||
|
op = (addr_mod_16(obuf) ? buf : obuf); |
||||||
|
|
||||||
|
if(ip != ibuf) |
||||||
|
memcpy(buf, ibuf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
via_ecb_op5(ksp,cwd,ip,op,m); |
||||||
|
|
||||||
|
if(op != obuf) |
||||||
|
memcpy(obuf, buf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
ibuf += m * AES_BLOCK_SIZE; |
||||||
|
obuf += m * AES_BLOCK_SIZE; |
||||||
|
nb -= m; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined( ASSUME_VIA_ACE_PRESENT ) |
||||||
|
while(nb--) |
||||||
|
{ |
||||||
|
aes_decrypt(ibuf, obuf, ctx); |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, const aes_encrypt_ctx ctx[1]) |
||||||
|
{ int nb = len >> 4; |
||||||
|
|
||||||
|
if(len & (AES_BLOCK_SIZE - 1)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv; |
||||||
|
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16); |
||||||
|
via_cwd(cwd, hybrid, enc, 2* ctx->inf.b[0] - 192);
|
||||||
|
|
||||||
|
if(addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
if(addr_mod_16(iv)) /* ensure an aligned iv */ |
||||||
|
{ |
||||||
|
ivp = liv; |
||||||
|
memcpy(liv, iv, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
if(!addr_mod_16(ibuf) && !addr_mod_16(obuf) && !addr_mod_16(iv)) |
||||||
|
{ |
||||||
|
via_cbc_op7(ksp,cwd,ibuf,obuf,nb,ivp,ivp); |
||||||
|
} |
||||||
|
else |
||||||
|
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); |
||||||
|
uint_8t *ip, *op; |
||||||
|
|
||||||
|
while(nb) |
||||||
|
{ |
||||||
|
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); |
||||||
|
|
||||||
|
ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); |
||||||
|
op = (addr_mod_16(obuf) ? buf : obuf); |
||||||
|
|
||||||
|
if(ip != ibuf) |
||||||
|
memcpy(buf, ibuf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
via_cbc_op7(ksp,cwd,ip,op,m,ivp,ivp); |
||||||
|
|
||||||
|
if(op != obuf) |
||||||
|
memcpy(obuf, buf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
ibuf += m * AES_BLOCK_SIZE; |
||||||
|
obuf += m * AES_BLOCK_SIZE; |
||||||
|
nb -= m; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(iv != ivp) |
||||||
|
memcpy(iv, ivp, AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined( ASSUME_VIA_ACE_PRESENT ) |
||||||
|
# ifdef FAST_BUFFER_OPERATIONS |
||||||
|
if(!addr_mod_04(ibuf) && !addr_mod_04(iv)) |
||||||
|
while(nb--) |
||||||
|
{ |
||||||
|
lp32(iv)[0] ^= lp32(ibuf)[0]; |
||||||
|
lp32(iv)[1] ^= lp32(ibuf)[1]; |
||||||
|
lp32(iv)[2] ^= lp32(ibuf)[2]; |
||||||
|
lp32(iv)[3] ^= lp32(ibuf)[3]; |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
memcpy(obuf, iv, AES_BLOCK_SIZE); |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else |
||||||
|
# endif |
||||||
|
while(nb--) |
||||||
|
{ |
||||||
|
iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1]; |
||||||
|
iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3]; |
||||||
|
iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5]; |
||||||
|
iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7]; |
||||||
|
iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9]; |
||||||
|
iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11]; |
||||||
|
iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13]; |
||||||
|
iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15]; |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
memcpy(obuf, iv, AES_BLOCK_SIZE); |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, const aes_decrypt_ctx ctx[1]) |
||||||
|
{ unsigned char tmp[AES_BLOCK_SIZE]; |
||||||
|
int nb = len >> 4; |
||||||
|
|
||||||
|
if(len & (AES_BLOCK_SIZE - 1)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ uint_8t *ksp = kd_adr(ctx), *ivp = iv; |
||||||
|
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16); |
||||||
|
via_cwd(cwd, hybrid, dec, 2* ctx->inf.b[0] - 192);
|
||||||
|
|
||||||
|
if(addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
if(addr_mod_16(iv)) /* ensure an aligned iv */ |
||||||
|
{ |
||||||
|
ivp = liv; |
||||||
|
memcpy(liv, iv, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
if(!addr_mod_16(ibuf) && !addr_mod_16(obuf) && !addr_mod_16(iv)) |
||||||
|
{ |
||||||
|
via_cbc_op6(ksp,cwd,ibuf,obuf,nb,ivp); |
||||||
|
} |
||||||
|
else |
||||||
|
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); |
||||||
|
uint_8t *ip, *op; |
||||||
|
|
||||||
|
while(nb) |
||||||
|
{ |
||||||
|
int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); |
||||||
|
|
||||||
|
ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); |
||||||
|
op = (addr_mod_16(obuf) ? buf : obuf); |
||||||
|
|
||||||
|
if(ip != ibuf) |
||||||
|
memcpy(buf, ibuf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
via_cbc_op6(ksp,cwd,ip,op,m,ivp); |
||||||
|
|
||||||
|
if(op != obuf) |
||||||
|
memcpy(obuf, buf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
ibuf += m * AES_BLOCK_SIZE; |
||||||
|
obuf += m * AES_BLOCK_SIZE; |
||||||
|
nb -= m; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(iv != ivp) |
||||||
|
memcpy(iv, ivp, AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined( ASSUME_VIA_ACE_PRESENT ) |
||||||
|
# ifdef FAST_BUFFER_OPERATIONS |
||||||
|
if(!addr_mod_04(obuf) && !addr_mod_04(iv)) |
||||||
|
while(nb--) |
||||||
|
{ |
||||||
|
memcpy(tmp, ibuf, AES_BLOCK_SIZE); |
||||||
|
aes_decrypt(ibuf, obuf, ctx); |
||||||
|
lp32(obuf)[0] ^= lp32(iv)[0]; |
||||||
|
lp32(obuf)[1] ^= lp32(iv)[1]; |
||||||
|
lp32(obuf)[2] ^= lp32(iv)[2]; |
||||||
|
lp32(obuf)[3] ^= lp32(iv)[3]; |
||||||
|
memcpy(iv, tmp, AES_BLOCK_SIZE); |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else |
||||||
|
# endif |
||||||
|
while(nb--) |
||||||
|
{ |
||||||
|
memcpy(tmp, ibuf, AES_BLOCK_SIZE); |
||||||
|
aes_decrypt(ibuf, obuf, ctx); |
||||||
|
obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1]; |
||||||
|
obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3]; |
||||||
|
obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5]; |
||||||
|
obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7]; |
||||||
|
obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9]; |
||||||
|
obuf[10] ^= iv[10]; obuf[11] ^= iv[11]; |
||||||
|
obuf[12] ^= iv[12]; obuf[13] ^= iv[13]; |
||||||
|
obuf[14] ^= iv[14]; obuf[15] ^= iv[15]; |
||||||
|
memcpy(iv, tmp, AES_BLOCK_SIZE); |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) |
||||||
|
{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; |
||||||
|
|
||||||
|
if(b_pos) /* complete any partial block */ |
||||||
|
{ |
||||||
|
while(b_pos < AES_BLOCK_SIZE && cnt < len) |
||||||
|
*obuf++ = iv[b_pos++] ^= *ibuf++, cnt++; |
||||||
|
|
||||||
|
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); |
||||||
|
} |
||||||
|
|
||||||
|
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ |
||||||
|
{ |
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ int m; |
||||||
|
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv; |
||||||
|
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16); |
||||||
|
via_cwd(cwd, hybrid, enc, 2* ctx->inf.b[0] - 192); |
||||||
|
|
||||||
|
if(addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
if(addr_mod_16(iv)) /* ensure an aligned iv */ |
||||||
|
{ |
||||||
|
ivp = liv; |
||||||
|
memcpy(liv, iv, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) |
||||||
|
{ |
||||||
|
via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp); |
||||||
|
ibuf += nb * AES_BLOCK_SIZE; |
||||||
|
obuf += nb * AES_BLOCK_SIZE; |
||||||
|
cnt += nb * AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else /* input, output or both are unaligned */ |
||||||
|
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); |
||||||
|
uint_8t *ip, *op; |
||||||
|
|
||||||
|
while(nb) |
||||||
|
{ |
||||||
|
m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; |
||||||
|
|
||||||
|
ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); |
||||||
|
op = (addr_mod_16(obuf) ? buf : obuf); |
||||||
|
|
||||||
|
if(ip != ibuf) |
||||||
|
memcpy(buf, ibuf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
via_cfb_op7(ksp, cwd, ip, op, m, ivp, ivp); |
||||||
|
|
||||||
|
if(op != obuf) |
||||||
|
memcpy(obuf, buf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
ibuf += m * AES_BLOCK_SIZE; |
||||||
|
obuf += m * AES_BLOCK_SIZE; |
||||||
|
cnt += m * AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(ivp != iv) |
||||||
|
memcpy(iv, ivp, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
#else |
||||||
|
# ifdef FAST_BUFFER_OPERATIONS |
||||||
|
if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) && !addr_mod_04(iv)) |
||||||
|
while(cnt + AES_BLOCK_SIZE <= len) |
||||||
|
{ |
||||||
|
assert(b_pos == 0); |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0]; |
||||||
|
lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1]; |
||||||
|
lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2]; |
||||||
|
lp32(obuf)[3] = lp32(iv)[3] ^= lp32(ibuf)[3]; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
cnt += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else |
||||||
|
# endif |
||||||
|
while(cnt + AES_BLOCK_SIZE <= len) |
||||||
|
{ |
||||||
|
assert(b_pos == 0); |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1]; |
||||||
|
obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3]; |
||||||
|
obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5]; |
||||||
|
obuf[ 6] = iv[ 6] ^= ibuf[ 6]; obuf[ 7] = iv[ 7] ^= ibuf[ 7]; |
||||||
|
obuf[ 8] = iv[ 8] ^= ibuf[ 8]; obuf[ 9] = iv[ 9] ^= ibuf[ 9]; |
||||||
|
obuf[10] = iv[10] ^= ibuf[10]; obuf[11] = iv[11] ^= ibuf[11]; |
||||||
|
obuf[12] = iv[12] ^= ibuf[12]; obuf[13] = iv[13] ^= ibuf[13]; |
||||||
|
obuf[14] = iv[14] ^= ibuf[14]; obuf[15] = iv[15] ^= ibuf[15]; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
cnt += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
while(cnt < len) |
||||||
|
{ |
||||||
|
if(!b_pos) |
||||||
|
aes_ecb_encrypt(iv, iv, AES_BLOCK_SIZE, ctx); |
||||||
|
|
||||||
|
while(cnt < len && b_pos < AES_BLOCK_SIZE) |
||||||
|
*obuf++ = iv[b_pos++] ^= *ibuf++, cnt++; |
||||||
|
|
||||||
|
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); |
||||||
|
} |
||||||
|
|
||||||
|
ctx->inf.b[2] = b_pos; |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) |
||||||
|
{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; |
||||||
|
|
||||||
|
if(b_pos) /* complete any partial block */ |
||||||
|
{ uint_8t t; |
||||||
|
|
||||||
|
while(b_pos < AES_BLOCK_SIZE && cnt < len) |
||||||
|
t = *ibuf++, *obuf++ = t ^ iv[b_pos], iv[b_pos++] = t, cnt++; |
||||||
|
|
||||||
|
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); |
||||||
|
} |
||||||
|
|
||||||
|
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ |
||||||
|
{ |
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ int m; |
||||||
|
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv; |
||||||
|
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16); |
||||||
|
via_cwd(cwd, hybrid, dec, 2* ctx->inf.b[0] - 192); |
||||||
|
|
||||||
|
if(addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
if(addr_mod_16(iv)) /* ensure an aligned iv */ |
||||||
|
{ |
||||||
|
ivp = liv; |
||||||
|
memcpy(liv, iv, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) |
||||||
|
{ |
||||||
|
via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp); |
||||||
|
ibuf += nb * AES_BLOCK_SIZE; |
||||||
|
obuf += nb * AES_BLOCK_SIZE; |
||||||
|
cnt += nb * AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else /* input, output or both are unaligned */ |
||||||
|
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); |
||||||
|
uint_8t *ip, *op; |
||||||
|
|
||||||
|
while(nb) |
||||||
|
{ |
||||||
|
m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; |
||||||
|
|
||||||
|
ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); |
||||||
|
op = (addr_mod_16(obuf) ? buf : op); |
||||||
|
|
||||||
|
if(ip != ibuf) |
||||||
|
memcpy(buf, ibuf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
via_cfb_op6(ksp, cwd, ip, op, m, ivp); |
||||||
|
|
||||||
|
if(op != obuf) |
||||||
|
memcpy(obuf, buf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
ibuf += m * AES_BLOCK_SIZE; |
||||||
|
obuf += m * AES_BLOCK_SIZE; |
||||||
|
cnt += m * AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(ivp != iv) |
||||||
|
memcpy(iv, ivp, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
#else |
||||||
|
# ifdef FAST_BUFFER_OPERATIONS |
||||||
|
if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) &&!addr_mod_04(iv)) |
||||||
|
while(cnt + AES_BLOCK_SIZE <= len) |
||||||
|
{ uint_32t t; |
||||||
|
|
||||||
|
assert(b_pos == 0); |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
t = lp32(ibuf)[0], lp32(obuf)[0] = t ^ lp32(iv)[0], lp32(iv)[0] = t; |
||||||
|
t = lp32(ibuf)[1], lp32(obuf)[1] = t ^ lp32(iv)[1], lp32(iv)[1] = t; |
||||||
|
t = lp32(ibuf)[2], lp32(obuf)[2] = t ^ lp32(iv)[2], lp32(iv)[2] = t; |
||||||
|
t = lp32(ibuf)[3], lp32(obuf)[3] = t ^ lp32(iv)[3], lp32(iv)[3] = t; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
cnt += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else |
||||||
|
# endif |
||||||
|
while(cnt + AES_BLOCK_SIZE <= len) |
||||||
|
{ uint_8t t; |
||||||
|
|
||||||
|
assert(b_pos == 0); |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
t = ibuf[ 0], obuf[ 0] = t ^ iv[ 0], iv[ 0] = t; |
||||||
|
t = ibuf[ 1], obuf[ 1] = t ^ iv[ 1], iv[ 1] = t; |
||||||
|
t = ibuf[ 2], obuf[ 2] = t ^ iv[ 2], iv[ 2] = t; |
||||||
|
t = ibuf[ 3], obuf[ 3] = t ^ iv[ 3], iv[ 3] = t; |
||||||
|
t = ibuf[ 4], obuf[ 4] = t ^ iv[ 4], iv[ 4] = t; |
||||||
|
t = ibuf[ 5], obuf[ 5] = t ^ iv[ 5], iv[ 5] = t; |
||||||
|
t = ibuf[ 6], obuf[ 6] = t ^ iv[ 6], iv[ 6] = t; |
||||||
|
t = ibuf[ 7], obuf[ 7] = t ^ iv[ 7], iv[ 7] = t; |
||||||
|
t = ibuf[ 8], obuf[ 8] = t ^ iv[ 8], iv[ 8] = t; |
||||||
|
t = ibuf[ 9], obuf[ 9] = t ^ iv[ 9], iv[ 9] = t; |
||||||
|
t = ibuf[10], obuf[10] = t ^ iv[10], iv[10] = t; |
||||||
|
t = ibuf[11], obuf[11] = t ^ iv[11], iv[11] = t; |
||||||
|
t = ibuf[12], obuf[12] = t ^ iv[12], iv[12] = t; |
||||||
|
t = ibuf[13], obuf[13] = t ^ iv[13], iv[13] = t; |
||||||
|
t = ibuf[14], obuf[14] = t ^ iv[14], iv[14] = t; |
||||||
|
t = ibuf[15], obuf[15] = t ^ iv[15], iv[15] = t; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
cnt += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
while(cnt < len) |
||||||
|
{ uint_8t t; |
||||||
|
|
||||||
|
if(!b_pos) |
||||||
|
aes_ecb_encrypt(iv, iv, AES_BLOCK_SIZE, ctx); |
||||||
|
|
||||||
|
while(cnt < len && b_pos < AES_BLOCK_SIZE) |
||||||
|
t = *ibuf++, *obuf++ = t ^ iv[b_pos], iv[b_pos++] = t, cnt++; |
||||||
|
|
||||||
|
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); |
||||||
|
} |
||||||
|
|
||||||
|
ctx->inf.b[2] = b_pos; |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *iv, aes_encrypt_ctx ctx[1]) |
||||||
|
{ int cnt = 0, b_pos = (int)ctx->inf.b[2], nb; |
||||||
|
|
||||||
|
if(b_pos) /* complete any partial block */ |
||||||
|
{ |
||||||
|
while(b_pos < AES_BLOCK_SIZE && cnt < len) |
||||||
|
*obuf++ = iv[b_pos++] ^ *ibuf++, cnt++; |
||||||
|
|
||||||
|
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); |
||||||
|
} |
||||||
|
|
||||||
|
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ |
||||||
|
{ |
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
|
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ int m; |
||||||
|
uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv; |
||||||
|
aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16); |
||||||
|
via_cwd(cwd, hybrid, enc, 2* ctx->inf.b[0] - 192); |
||||||
|
|
||||||
|
if(addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
|
||||||
|
if(addr_mod_16(iv)) /* ensure an aligned iv */ |
||||||
|
{ |
||||||
|
ivp = liv; |
||||||
|
memcpy(liv, iv, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) |
||||||
|
{ |
||||||
|
via_ofb_op6(ksp, cwd, ibuf, obuf, nb, ivp); |
||||||
|
ibuf += nb * AES_BLOCK_SIZE; |
||||||
|
obuf += nb * AES_BLOCK_SIZE; |
||||||
|
cnt += nb * AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else /* input, output or both are unaligned */ |
||||||
|
{ aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16); |
||||||
|
uint_8t *ip, *op; |
||||||
|
|
||||||
|
while(nb) |
||||||
|
{ |
||||||
|
m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m; |
||||||
|
|
||||||
|
ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); |
||||||
|
op = (addr_mod_16(obuf) ? buf : obuf); |
||||||
|
|
||||||
|
if(ip != ibuf) |
||||||
|
memcpy(buf, ibuf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
via_ofb_op6(ksp, cwd, ip, op, m, ivp); |
||||||
|
|
||||||
|
if(op != obuf) |
||||||
|
memcpy(obuf, buf, m * AES_BLOCK_SIZE); |
||||||
|
|
||||||
|
ibuf += m * AES_BLOCK_SIZE; |
||||||
|
obuf += m * AES_BLOCK_SIZE; |
||||||
|
cnt += m * AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(ivp != iv) |
||||||
|
memcpy(iv, ivp, AES_BLOCK_SIZE); |
||||||
|
} |
||||||
|
#else |
||||||
|
# ifdef FAST_BUFFER_OPERATIONS |
||||||
|
if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) && !addr_mod_04(iv)) |
||||||
|
while(cnt + AES_BLOCK_SIZE <= len) |
||||||
|
{ |
||||||
|
assert(b_pos == 0); |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
lp32(obuf)[0] = lp32(iv)[0] ^ lp32(ibuf)[0]; |
||||||
|
lp32(obuf)[1] = lp32(iv)[1] ^ lp32(ibuf)[1]; |
||||||
|
lp32(obuf)[2] = lp32(iv)[2] ^ lp32(ibuf)[2]; |
||||||
|
lp32(obuf)[3] = lp32(iv)[3] ^ lp32(ibuf)[3]; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
cnt += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else |
||||||
|
# endif |
||||||
|
while(cnt + AES_BLOCK_SIZE <= len) |
||||||
|
{ |
||||||
|
assert(b_pos == 0); |
||||||
|
aes_encrypt(iv, iv, ctx); |
||||||
|
obuf[ 0] = iv[ 0] ^ ibuf[ 0]; obuf[ 1] = iv[ 1] ^ ibuf[ 1]; |
||||||
|
obuf[ 2] = iv[ 2] ^ ibuf[ 2]; obuf[ 3] = iv[ 3] ^ ibuf[ 3]; |
||||||
|
obuf[ 4] = iv[ 4] ^ ibuf[ 4]; obuf[ 5] = iv[ 5] ^ ibuf[ 5]; |
||||||
|
obuf[ 6] = iv[ 6] ^ ibuf[ 6]; obuf[ 7] = iv[ 7] ^ ibuf[ 7]; |
||||||
|
obuf[ 8] = iv[ 8] ^ ibuf[ 8]; obuf[ 9] = iv[ 9] ^ ibuf[ 9]; |
||||||
|
obuf[10] = iv[10] ^ ibuf[10]; obuf[11] = iv[11] ^ ibuf[11]; |
||||||
|
obuf[12] = iv[12] ^ ibuf[12]; obuf[13] = iv[13] ^ ibuf[13]; |
||||||
|
obuf[14] = iv[14] ^ ibuf[14]; obuf[15] = iv[15] ^ ibuf[15]; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
cnt += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
while(cnt < len) |
||||||
|
{ |
||||||
|
if(!b_pos) |
||||||
|
aes_ecb_encrypt(iv, iv, AES_BLOCK_SIZE, ctx); |
||||||
|
|
||||||
|
while(cnt < len && b_pos < AES_BLOCK_SIZE) |
||||||
|
*obuf++ = iv[b_pos++] ^ *ibuf++, cnt++; |
||||||
|
|
||||||
|
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); |
||||||
|
} |
||||||
|
|
||||||
|
ctx->inf.b[2] = b_pos; |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
#define BFR_LENGTH (BFR_BLOCKS * AES_BLOCK_SIZE) |
||||||
|
|
||||||
|
aes_rval aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, |
||||||
|
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1]) |
||||||
|
{ uint_8t *ip; |
||||||
|
int i, blen, b_pos = (int)(ctx->inf.b[2]); |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
aligned_auto(uint_8t, buf, BFR_LENGTH, 16); |
||||||
|
if(ctx->inf.b[1] == 0xff && addr_mod_16(ctx)) |
||||||
|
return EXIT_FAILURE; |
||||||
|
#else |
||||||
|
uint_8t buf[BFR_LENGTH]; |
||||||
|
#endif |
||||||
|
|
||||||
|
if(b_pos) |
||||||
|
{ |
||||||
|
memcpy(buf, cbuf, AES_BLOCK_SIZE); |
||||||
|
aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx); |
||||||
|
while(b_pos < AES_BLOCK_SIZE && len--) |
||||||
|
*obuf++ = *ibuf++ ^ buf[b_pos++]; |
||||||
|
if(len) |
||||||
|
ctr_inc(cbuf), b_pos = 0; |
||||||
|
} |
||||||
|
|
||||||
|
while(len) |
||||||
|
{ |
||||||
|
blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen; |
||||||
|
|
||||||
|
for(i = 0, ip = buf; i < (blen >> 4); ++i) |
||||||
|
{ |
||||||
|
memcpy(ip, cbuf, AES_BLOCK_SIZE); |
||||||
|
ctr_inc(cbuf); |
||||||
|
ip += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
|
||||||
|
if(blen & (AES_BLOCK_SIZE - 1)) |
||||||
|
memcpy(ip, cbuf, AES_BLOCK_SIZE), i++; |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
if(ctx->inf.b[1] == 0xff) |
||||||
|
{ |
||||||
|
via_cwd(cwd, hybrid, enc, 2* ctx->inf.b[0] - 192); |
||||||
|
via_ecb_op5((ctx->ks),cwd,buf,buf,i); |
||||||
|
} |
||||||
|
else |
||||||
|
#endif |
||||||
|
aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx); |
||||||
|
|
||||||
|
i = 0; ip = buf; |
||||||
|
# ifdef FAST_BUFFER_OPERATIONS |
||||||
|
if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) && !addr_mod_04(ip)) |
||||||
|
while(i + AES_BLOCK_SIZE <= blen) |
||||||
|
{ |
||||||
|
lp32(obuf)[0] = lp32(ibuf)[0] ^ lp32(ip)[0]; |
||||||
|
lp32(obuf)[1] = lp32(ibuf)[1] ^ lp32(ip)[1]; |
||||||
|
lp32(obuf)[2] = lp32(ibuf)[2] ^ lp32(ip)[2]; |
||||||
|
lp32(obuf)[3] = lp32(ibuf)[3] ^ lp32(ip)[3]; |
||||||
|
i += AES_BLOCK_SIZE; |
||||||
|
ip += AES_BLOCK_SIZE; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
else |
||||||
|
#endif |
||||||
|
while(i + AES_BLOCK_SIZE <= blen) |
||||||
|
{ |
||||||
|
obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1]; |
||||||
|
obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3]; |
||||||
|
obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5]; |
||||||
|
obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7]; |
||||||
|
obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9]; |
||||||
|
obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11]; |
||||||
|
obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13]; |
||||||
|
obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15]; |
||||||
|
i += AES_BLOCK_SIZE; |
||||||
|
ip += AES_BLOCK_SIZE; |
||||||
|
ibuf += AES_BLOCK_SIZE; |
||||||
|
obuf += AES_BLOCK_SIZE; |
||||||
|
} |
||||||
|
|
||||||
|
while(i++ < blen) |
||||||
|
*obuf++ = *ibuf++ ^ ip[b_pos++]; |
||||||
|
} |
||||||
|
|
||||||
|
ctx->inf.b[2] = b_pos; |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
||||||
|
#endif |
@ -0,0 +1,131 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
|
||||||
|
The unsigned integer types defined here are of the form uint_<nn>t where
|
||||||
|
<nn> is the length of the type; for example, the unsigned 32-bit type is
|
||||||
|
'uint_32t'. These are NOT the same as the 'C99 integer types' that are
|
||||||
|
defined in the inttypes.h and stdint.h headers since attempts to use these
|
||||||
|
types have shown that support for them is still highly variable. However,
|
||||||
|
since the latter are of the form uint<nn>_t, a regular expression search
|
||||||
|
and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')
|
||||||
|
can be used to convert the types used here to the C99 standard types. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef TDEFS_H |
||||||
|
#define TDEFS_H |
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <limits.h> |
||||||
|
|
||||||
|
#if UCHAR_MAX == 0xff |
||||||
|
typedef unsigned char uint_8t; |
||||||
|
#else |
||||||
|
# error Please define uint_8t as an 8-bit unsigned integer type in tdefs.h |
||||||
|
#endif |
||||||
|
|
||||||
|
#if USHRT_MAX == 0xffff |
||||||
|
typedef unsigned short uint_16t; |
||||||
|
#else |
||||||
|
# error Please define uint_16t as a 16-bit unsigned short type in tdefs.h |
||||||
|
#endif |
||||||
|
|
||||||
|
#if UINT_MAX == 0xffffffff |
||||||
|
typedef unsigned int uint_32t; |
||||||
|
#elif ULONG_MAX == 0xfffffffful |
||||||
|
typedef unsigned long uint_32t; |
||||||
|
#elif defined( _CRAY ) |
||||||
|
# error This code needs 32-bit data types, which Cray machines don't provide |
||||||
|
#else |
||||||
|
# error Please define uint_32t as a 32-bit unsigned integer type in tdefs.h |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( NEED_UINT_64T ) |
||||||
|
# define li_64(h) 0x##h##ull |
||||||
|
# if defined( _MSC_VER ) |
||||||
|
# if _MSC_VER < 1310 |
||||||
|
typedef unsigned __int64 uint_64t; |
||||||
|
# undef li_64 |
||||||
|
# define li_64(h) 0x##h##ui64 |
||||||
|
# else |
||||||
|
typedef unsigned long long uint_64t; |
||||||
|
# endif |
||||||
|
# elif defined( __BORLANDC__ ) && !defined( __MSDOS__ ) |
||||||
|
typedef __int64 uint_64t; |
||||||
|
# elif defined( __sun ) && defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful |
||||||
|
typedef unsigned long long uint_64t; |
||||||
|
# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX == 0xffffffffffffffffull |
||||||
|
typedef unsigned long long uint_64t; |
||||||
|
# elif defined( ULLONG_MAX ) && ULLONG_MAX == 0xffffffffffffffffull |
||||||
|
typedef unsigned long long uint_64t; |
||||||
|
# elif defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffffffffffful |
||||||
|
typedef unsigned long uint_64t; |
||||||
|
# elif defined( UINT_MAX ) && UINT_MAX == 0xffffffffffffffff |
||||||
|
typedef unsigned int uint_64t; |
||||||
|
# else |
||||||
|
# error Please define uint_64t as an unsigned 64 bit type in tdefs.h |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( DLL_EXPORT ) |
||||||
|
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) |
||||||
|
# define void_ret __declspec( dllexport ) void __stdcall |
||||||
|
# define int_ret __declspec( dllexport ) int __stdcall |
||||||
|
# elif defined( __GNUC__ ) |
||||||
|
# define void_ret __declspec( __dllexport__ ) void |
||||||
|
# define int_ret __declspec( __dllexport__ ) int |
||||||
|
# else |
||||||
|
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers |
||||||
|
# endif |
||||||
|
#elif defined( DLL_IMPORT ) |
||||||
|
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) |
||||||
|
# define void_ret __declspec( dllimport ) void __stdcall |
||||||
|
# define int_ret __declspec( dllimport ) int __stdcall |
||||||
|
# elif defined( __GNUC__ ) |
||||||
|
# define void_ret __declspec( __dllimport__ ) void |
||||||
|
# define int_ret __declspec( __dllimport__ ) int |
||||||
|
# else |
||||||
|
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers |
||||||
|
# endif |
||||||
|
#elif defined( __WATCOMC__ ) |
||||||
|
# define void_ret void __cdecl |
||||||
|
# define int_ret int __cdecl |
||||||
|
#else |
||||||
|
# define void_ret void |
||||||
|
# define int_ret int |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
||||||
|
#endif |
@ -0,0 +1,153 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
|
||||||
|
This file contains the definitions required to use AES (Rijndael) in C++. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _AESCPP_H |
||||||
|
#define _AESCPP_H |
||||||
|
|
||||||
|
#include "aes.h" |
||||||
|
|
||||||
|
#if defined( AES_ENCRYPT ) |
||||||
|
|
||||||
|
class AESencrypt |
||||||
|
{ |
||||||
|
public: |
||||||
|
aes_encrypt_ctx cx[1]; |
||||||
|
AESencrypt(void) { gen_tabs(); }; |
||||||
|
#ifdef AES_128 |
||||||
|
AESencrypt(const unsigned char key[]) |
||||||
|
{ aes_encrypt_key128(key, cx); } |
||||||
|
aes_rval key128(const unsigned char key[]) |
||||||
|
{ return aes_encrypt_key128(key, cx); } |
||||||
|
#endif |
||||||
|
#ifdef AES_192 |
||||||
|
aes_rval key192(const unsigned char key[]) |
||||||
|
{ return aes_encrypt_key192(key, cx); } |
||||||
|
#endif |
||||||
|
#ifdef AES_256 |
||||||
|
aes_rval key256(const unsigned char key[]) |
||||||
|
{ return aes_encrypt_key256(key, cx); } |
||||||
|
#endif |
||||||
|
#ifdef AES_VAR |
||||||
|
aes_rval key(const unsigned char key[], int key_len) |
||||||
|
{ return aes_encrypt_key(key, key_len, cx); } |
||||||
|
#endif |
||||||
|
aes_rval encrypt(const unsigned char in[], unsigned char out[]) const |
||||||
|
{ return aes_encrypt(in, out, cx); } |
||||||
|
#ifndef AES_MODES |
||||||
|
aes_rval ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const |
||||||
|
{ while(nb--) |
||||||
|
{ aes_encrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; } |
||||||
|
} |
||||||
|
#endif |
||||||
|
#ifdef AES_MODES |
||||||
|
aes_rval mode_reset(void) { return aes_mode_reset(cx); } |
||||||
|
|
||||||
|
aes_rval ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const |
||||||
|
{ return aes_ecb_encrypt(in, out, nb, cx); } |
||||||
|
|
||||||
|
aes_rval cbc_encrypt(const unsigned char in[], unsigned char out[], int nb,
|
||||||
|
unsigned char iv[]) const |
||||||
|
{ return aes_cbc_encrypt(in, out, nb, iv, cx); } |
||||||
|
|
||||||
|
aes_rval cfb_encrypt(const unsigned char in[], unsigned char out[], int nb,
|
||||||
|
unsigned char iv[]) |
||||||
|
{ return aes_cfb_encrypt(in, out, nb, iv, cx); } |
||||||
|
|
||||||
|
aes_rval cfb_decrypt(const unsigned char in[], unsigned char out[], int nb,
|
||||||
|
unsigned char iv[]) |
||||||
|
{ return aes_cfb_decrypt(in, out, nb, iv, cx); } |
||||||
|
|
||||||
|
aes_rval ofb_crypt(const unsigned char in[], unsigned char out[], int nb,
|
||||||
|
unsigned char iv[]) |
||||||
|
{ return aes_ofb_crypt(in, out, nb, iv, cx); } |
||||||
|
|
||||||
|
typedef void ctr_fn(unsigned char ctr[]); |
||||||
|
|
||||||
|
aes_rval ctr_crypt(const unsigned char in[], unsigned char out[], int nb,
|
||||||
|
unsigned char iv[], ctr_fn cf) |
||||||
|
{ return aes_ctr_crypt(in, out, nb, iv, cf, cx); } |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_DECRYPT ) |
||||||
|
|
||||||
|
class AESdecrypt |
||||||
|
{ |
||||||
|
public: |
||||||
|
aes_decrypt_ctx cx[1]; |
||||||
|
AESdecrypt(void) { gen_tabs(); }; |
||||||
|
#ifdef AES_128 |
||||||
|
AESdecrypt(const unsigned char key[]) |
||||||
|
{ aes_decrypt_key128(key, cx); } |
||||||
|
aes_rval key128(const unsigned char key[]) |
||||||
|
{ return aes_decrypt_key128(key, cx); } |
||||||
|
#endif |
||||||
|
#ifdef AES_192 |
||||||
|
aes_rval key192(const unsigned char key[]) |
||||||
|
{ return aes_decrypt_key192(key, cx); } |
||||||
|
#endif |
||||||
|
#ifdef AES_256 |
||||||
|
aes_rval key256(const unsigned char key[]) |
||||||
|
{ return aes_decrypt_key256(key, cx); } |
||||||
|
#endif |
||||||
|
#ifdef AES_VAR |
||||||
|
aes_rval key(const unsigned char key[], int key_len) |
||||||
|
{ return aes_decrypt_key(key, key_len, cx); } |
||||||
|
#endif |
||||||
|
aes_rval decrypt(const unsigned char in[], unsigned char out[]) const |
||||||
|
{ return aes_decrypt(in, out, cx); } |
||||||
|
#ifndef AES_MODES |
||||||
|
aes_rval ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const |
||||||
|
{ while(nb--) |
||||||
|
{ aes_decrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; } |
||||||
|
} |
||||||
|
#endif |
||||||
|
#ifdef AES_MODES |
||||||
|
|
||||||
|
aes_rval ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const |
||||||
|
{ return aes_ecb_decrypt(in, out, nb, cx); } |
||||||
|
|
||||||
|
aes_rval cbc_decrypt(const unsigned char in[], unsigned char out[], int nb,
|
||||||
|
unsigned char iv[]) const |
||||||
|
{ return aes_cbc_decrypt(in, out, nb, iv, cx); } |
||||||
|
#endif |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,316 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "aesopt.h" |
||||||
|
#include "aestab.h" |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c]) |
||||||
|
#define so(y,x,c) word_out(y, c, s(x,c)) |
||||||
|
|
||||||
|
#if defined(ARRAYS) |
||||||
|
#define locals(y,x) x[4],y[4] |
||||||
|
#else |
||||||
|
#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 |
||||||
|
#endif |
||||||
|
|
||||||
|
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ |
||||||
|
s(y,2) = s(x,2); s(y,3) = s(x,3); |
||||||
|
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) |
||||||
|
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) |
||||||
|
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) |
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & ENCRYPTION_IN_C) |
||||||
|
|
||||||
|
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||||
|
Pentium optimiation with small code but this is poor for decryption |
||||||
|
so we need to control this with the following VC++ pragmas |
||||||
|
*/ |
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && !defined( _WIN64 ) |
||||||
|
#pragma optimize( "s", on ) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Given the column (c) of the output state variable, the following
|
||||||
|
macros give the input state variables which are needed in its |
||||||
|
computation for each row (r) of the state. All the alternative |
||||||
|
macros give the same end values but expand into different ways |
||||||
|
of calculating these values. In particular the complex macro |
||||||
|
used for dynamically variable block sizes is designed to expand |
||||||
|
to a compile time constant whenever possible but will expand to |
||||||
|
conditional clauses on some branches (I am grateful to Frank |
||||||
|
Yellin for this construction) |
||||||
|
*/ |
||||||
|
|
||||||
|
#define fwd_var(x,r,c)\ |
||||||
|
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||||
|
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
|
||||||
|
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||||
|
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))) |
||||||
|
|
||||||
|
#if defined(FT4_SET) |
||||||
|
#undef dec_fmvars |
||||||
|
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c)) |
||||||
|
#elif defined(FT1_SET) |
||||||
|
#undef dec_fmvars |
||||||
|
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c)) |
||||||
|
#else |
||||||
|
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c))) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(FL4_SET) |
||||||
|
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c)) |
||||||
|
#elif defined(FL1_SET) |
||||||
|
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c)) |
||||||
|
#else |
||||||
|
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c)) |
||||||
|
#endif |
||||||
|
|
||||||
|
aes_rval aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]) |
||||||
|
{ uint_32t locals(b0, b1); |
||||||
|
const uint_32t *kp; |
||||||
|
#if defined( dec_fmvars ) |
||||||
|
dec_fmvars; /* declare variables for fwd_mcol() if needed */ |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 ) |
||||||
|
return EXIT_FAILURE; |
||||||
|
#endif |
||||||
|
|
||||||
|
kp = cx->ks; |
||||||
|
state_in(b0, in, kp); |
||||||
|
|
||||||
|
#if (ENC_UNROLL == FULL) |
||||||
|
|
||||||
|
switch(cx->inf.b[0]) |
||||||
|
{ |
||||||
|
case 14 * 16: |
||||||
|
round(fwd_rnd, b1, b0, kp + 1 * N_COLS); |
||||||
|
round(fwd_rnd, b0, b1, kp + 2 * N_COLS); |
||||||
|
kp += 2 * N_COLS; |
||||||
|
case 12 * 16: |
||||||
|
round(fwd_rnd, b1, b0, kp + 1 * N_COLS); |
||||||
|
round(fwd_rnd, b0, b1, kp + 2 * N_COLS); |
||||||
|
kp += 2 * N_COLS; |
||||||
|
case 10 * 16: |
||||||
|
round(fwd_rnd, b1, b0, kp + 1 * N_COLS); |
||||||
|
round(fwd_rnd, b0, b1, kp + 2 * N_COLS); |
||||||
|
round(fwd_rnd, b1, b0, kp + 3 * N_COLS); |
||||||
|
round(fwd_rnd, b0, b1, kp + 4 * N_COLS); |
||||||
|
round(fwd_rnd, b1, b0, kp + 5 * N_COLS); |
||||||
|
round(fwd_rnd, b0, b1, kp + 6 * N_COLS); |
||||||
|
round(fwd_rnd, b1, b0, kp + 7 * N_COLS); |
||||||
|
round(fwd_rnd, b0, b1, kp + 8 * N_COLS); |
||||||
|
round(fwd_rnd, b1, b0, kp + 9 * N_COLS); |
||||||
|
round(fwd_lrnd, b0, b1, kp +10 * N_COLS); |
||||||
|
} |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#if (ENC_UNROLL == PARTIAL) |
||||||
|
{ uint_32t rnd; |
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) |
||||||
|
{ |
||||||
|
kp += N_COLS; |
||||||
|
round(fwd_rnd, b1, b0, kp); |
||||||
|
kp += N_COLS; |
||||||
|
round(fwd_rnd, b0, b1, kp); |
||||||
|
} |
||||||
|
kp += N_COLS; |
||||||
|
round(fwd_rnd, b1, b0, kp); |
||||||
|
#else |
||||||
|
{ uint_32t rnd; |
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) |
||||||
|
{ |
||||||
|
kp += N_COLS; |
||||||
|
round(fwd_rnd, b1, b0, kp); |
||||||
|
l_copy(b0, b1); |
||||||
|
} |
||||||
|
#endif |
||||||
|
kp += N_COLS; |
||||||
|
round(fwd_lrnd, b0, b1, kp); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
state_out(out, b0); |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & DECRYPTION_IN_C) |
||||||
|
|
||||||
|
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||||
|
Pentium optimiation with small code but this is poor for decryption |
||||||
|
so we need to control this with the following VC++ pragmas |
||||||
|
*/ |
||||||
|
|
||||||
|
#if defined( _MSC_VER ) && !defined( _WIN64 ) |
||||||
|
#pragma optimize( "t", on ) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Given the column (c) of the output state variable, the following
|
||||||
|
macros give the input state variables which are needed in its |
||||||
|
computation for each row (r) of the state. All the alternative |
||||||
|
macros give the same end values but expand into different ways |
||||||
|
of calculating these values. In particular the complex macro |
||||||
|
used for dynamically variable block sizes is designed to expand |
||||||
|
to a compile time constant whenever possible but will expand to |
||||||
|
conditional clauses on some branches (I am grateful to Frank |
||||||
|
Yellin for this construction) |
||||||
|
*/ |
||||||
|
|
||||||
|
#define inv_var(x,r,c)\ |
||||||
|
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||||
|
: r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
|
||||||
|
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||||
|
: ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))) |
||||||
|
|
||||||
|
#if defined(IT4_SET) |
||||||
|
#undef dec_imvars |
||||||
|
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c)) |
||||||
|
#elif defined(IT1_SET) |
||||||
|
#undef dec_imvars |
||||||
|
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c)) |
||||||
|
#else |
||||||
|
#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(IL4_SET) |
||||||
|
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c)) |
||||||
|
#elif defined(IL1_SET) |
||||||
|
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c)) |
||||||
|
#else |
||||||
|
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* This code can work with the decryption key schedule in the */ |
||||||
|
/* order that is used for encrytpion (where the 1st decryption */ |
||||||
|
/* round key is at the high end ot the schedule) or with a key */ |
||||||
|
/* schedule that has been reversed to put the 1st decryption */ |
||||||
|
/* round key at the low end of the schedule in memory (when */ |
||||||
|
/* AES_REV_DKS is defined) */ |
||||||
|
|
||||||
|
#ifdef AES_REV_DKS |
||||||
|
#define key_ofs 0 |
||||||
|
#define rnd_key(n) (kp + n * N_COLS) |
||||||
|
#else |
||||||
|
#define key_ofs 1 |
||||||
|
#define rnd_key(n) (kp - n * N_COLS) |
||||||
|
#endif |
||||||
|
|
||||||
|
aes_rval aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]) |
||||||
|
{ uint_32t locals(b0, b1); |
||||||
|
#if defined( dec_imvars ) |
||||||
|
dec_imvars; /* declare variables for inv_mcol() if needed */ |
||||||
|
#endif |
||||||
|
const uint_32t *kp; |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 ) |
||||||
|
return EXIT_FAILURE; |
||||||
|
#endif |
||||||
|
|
||||||
|
kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0); |
||||||
|
state_in(b0, in, kp); |
||||||
|
|
||||||
|
#if (DEC_UNROLL == FULL) |
||||||
|
|
||||||
|
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2)); |
||||||
|
switch(cx->inf.b[0]) |
||||||
|
{ |
||||||
|
case 14 * 16: |
||||||
|
round(inv_rnd, b1, b0, rnd_key(-13)); |
||||||
|
round(inv_rnd, b0, b1, rnd_key(-12)); |
||||||
|
case 12 * 16: |
||||||
|
round(inv_rnd, b1, b0, rnd_key(-11)); |
||||||
|
round(inv_rnd, b0, b1, rnd_key(-10)); |
||||||
|
case 10 * 16: |
||||||
|
round(inv_rnd, b1, b0, rnd_key(-9)); |
||||||
|
round(inv_rnd, b0, b1, rnd_key(-8)); |
||||||
|
round(inv_rnd, b1, b0, rnd_key(-7)); |
||||||
|
round(inv_rnd, b0, b1, rnd_key(-6)); |
||||||
|
round(inv_rnd, b1, b0, rnd_key(-5)); |
||||||
|
round(inv_rnd, b0, b1, rnd_key(-4)); |
||||||
|
round(inv_rnd, b1, b0, rnd_key(-3)); |
||||||
|
round(inv_rnd, b0, b1, rnd_key(-2)); |
||||||
|
round(inv_rnd, b1, b0, rnd_key(-1)); |
||||||
|
round(inv_lrnd, b0, b1, rnd_key( 0)); |
||||||
|
} |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#if (DEC_UNROLL == PARTIAL) |
||||||
|
{ uint_32t rnd; |
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) |
||||||
|
{ |
||||||
|
kp = rnd_key(1); |
||||||
|
round(inv_rnd, b1, b0, kp); |
||||||
|
kp = rnd_key(1); |
||||||
|
round(inv_rnd, b0, b1, kp); |
||||||
|
} |
||||||
|
kp = rnd_key(1); |
||||||
|
round(inv_rnd, b1, b0, kp); |
||||||
|
#else |
||||||
|
{ uint_32t rnd; |
||||||
|
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) |
||||||
|
{ |
||||||
|
kp = rnd_key(1); |
||||||
|
round(inv_rnd, b1, b0, kp); |
||||||
|
l_copy(b0, b1); |
||||||
|
} |
||||||
|
#endif |
||||||
|
kp = rnd_key(1); |
||||||
|
round(inv_lrnd, b0, b1, kp); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
state_out(out, b0); |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,578 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "aesopt.h" |
||||||
|
#include "aestab.h" |
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT |
||||||
|
#include "via_ace.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Initialise the key schedule from the user supplied key. The key
|
||||||
|
length can be specified in bytes, with legal values of 16, 24 |
||||||
|
and 32, or in bits, with legal values of 128, 192 and 256. These |
||||||
|
values correspond with Nk values of 4, 6 and 8 respectively. |
||||||
|
|
||||||
|
The following macros implement a single cycle in the key |
||||||
|
schedule generation process. The number of cycles needed |
||||||
|
for each cx->n_col and nk value is: |
||||||
|
|
||||||
|
nk = 4 5 6 7 8 |
||||||
|
------------------------------ |
||||||
|
cx->n_col = 4 10 9 8 7 7 |
||||||
|
cx->n_col = 5 14 11 10 9 9 |
||||||
|
cx->n_col = 6 19 15 12 11 11 |
||||||
|
cx->n_col = 7 21 19 16 13 14 |
||||||
|
cx->n_col = 8 29 23 19 17 14 |
||||||
|
*/ |
||||||
|
|
||||||
|
#if (FUNCS_IN_C & ENC_KEYING_IN_C) |
||||||
|
|
||||||
|
#if defined(AES_128) || defined(AES_VAR) |
||||||
|
|
||||||
|
#define ke4(k,i) \ |
||||||
|
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||||
|
k[4*(i)+6] = ss[2] ^= ss[1]; \
|
||||||
|
k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) |
||||||
|
{ uint_32t ss[4]; |
||||||
|
|
||||||
|
cx->ks[0] = ss[0] = word_in(key, 0); |
||||||
|
cx->ks[1] = ss[1] = word_in(key, 1); |
||||||
|
cx->ks[2] = ss[2] = word_in(key, 2); |
||||||
|
cx->ks[3] = ss[3] = word_in(key, 3); |
||||||
|
|
||||||
|
#if ENC_UNROLL == NONE |
||||||
|
{ uint_32t i; |
||||||
|
for(i = 0; i < 9; ++i) |
||||||
|
ke4(cx->ks, i); |
||||||
|
} |
||||||
|
#else |
||||||
|
ke4(cx->ks, 0); ke4(cx->ks, 1); |
||||||
|
ke4(cx->ks, 2); ke4(cx->ks, 3); |
||||||
|
ke4(cx->ks, 4); ke4(cx->ks, 5); |
||||||
|
ke4(cx->ks, 6); ke4(cx->ks, 7); |
||||||
|
ke4(cx->ks, 8); |
||||||
|
#endif |
||||||
|
ke4(cx->ks, 9); |
||||||
|
cx->inf.l = 0; |
||||||
|
cx->inf.b[0] = 10 * 16; |
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT |
||||||
|
if(VIA_ACE_AVAILABLE) |
||||||
|
cx->inf.b[1] = 0xff; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_192) || defined(AES_VAR) |
||||||
|
|
||||||
|
#define kef6(k,i) \ |
||||||
|
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||||
|
k[6*(i)+ 8] = ss[2] ^= ss[1]; \
|
||||||
|
k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define ke6(k,i) \ |
||||||
|
{ kef6(k,i); \
|
||||||
|
k[6*(i)+10] = ss[4] ^= ss[3]; \
|
||||||
|
k[6*(i)+11] = ss[5] ^= ss[4]; \
|
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) |
||||||
|
{ uint_32t ss[6]; |
||||||
|
|
||||||
|
cx->ks[0] = ss[0] = word_in(key, 0); |
||||||
|
cx->ks[1] = ss[1] = word_in(key, 1); |
||||||
|
cx->ks[2] = ss[2] = word_in(key, 2); |
||||||
|
cx->ks[3] = ss[3] = word_in(key, 3); |
||||||
|
cx->ks[4] = ss[4] = word_in(key, 4); |
||||||
|
cx->ks[5] = ss[5] = word_in(key, 5); |
||||||
|
|
||||||
|
#if ENC_UNROLL == NONE |
||||||
|
{ uint_32t i; |
||||||
|
for(i = 0; i < 7; ++i) |
||||||
|
ke6(cx->ks, i); |
||||||
|
} |
||||||
|
#else |
||||||
|
ke6(cx->ks, 0); ke6(cx->ks, 1); |
||||||
|
ke6(cx->ks, 2); ke6(cx->ks, 3); |
||||||
|
ke6(cx->ks, 4); ke6(cx->ks, 5); |
||||||
|
ke6(cx->ks, 6); |
||||||
|
#endif |
||||||
|
kef6(cx->ks, 7); |
||||||
|
cx->inf.l = 0; |
||||||
|
cx->inf.b[0] = 12 * 16; |
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT |
||||||
|
if(VIA_ACE_AVAILABLE) |
||||||
|
cx->inf.b[1] = 0xff; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_256) || defined(AES_VAR) |
||||||
|
|
||||||
|
#define kef8(k,i) \ |
||||||
|
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||||
|
k[8*(i)+10] = ss[2] ^= ss[1]; \
|
||||||
|
k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define ke8(k,i) \ |
||||||
|
{ kef8(k,i); \
|
||||||
|
k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
|
||||||
|
k[8*(i)+13] = ss[5] ^= ss[4]; \
|
||||||
|
k[8*(i)+14] = ss[6] ^= ss[5]; \
|
||||||
|
k[8*(i)+15] = ss[7] ^= ss[6]; \
|
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) |
||||||
|
{ uint_32t ss[8]; |
||||||
|
|
||||||
|
cx->ks[0] = ss[0] = word_in(key, 0); |
||||||
|
cx->ks[1] = ss[1] = word_in(key, 1); |
||||||
|
cx->ks[2] = ss[2] = word_in(key, 2); |
||||||
|
cx->ks[3] = ss[3] = word_in(key, 3); |
||||||
|
cx->ks[4] = ss[4] = word_in(key, 4); |
||||||
|
cx->ks[5] = ss[5] = word_in(key, 5); |
||||||
|
cx->ks[6] = ss[6] = word_in(key, 6); |
||||||
|
cx->ks[7] = ss[7] = word_in(key, 7); |
||||||
|
|
||||||
|
#if ENC_UNROLL == NONE |
||||||
|
{ uint_32t i; |
||||||
|
for(i = 0; i < 6; ++i) |
||||||
|
ke8(cx->ks, i); |
||||||
|
} |
||||||
|
#else |
||||||
|
ke8(cx->ks, 0); ke8(cx->ks, 1); |
||||||
|
ke8(cx->ks, 2); ke8(cx->ks, 3); |
||||||
|
ke8(cx->ks, 4); ke8(cx->ks, 5); |
||||||
|
#endif |
||||||
|
kef8(cx->ks, 6); |
||||||
|
cx->inf.l = 0; |
||||||
|
cx->inf.b[0] = 14 * 16; |
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT |
||||||
|
if(VIA_ACE_AVAILABLE) |
||||||
|
cx->inf.b[1] = 0xff; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_VAR) |
||||||
|
|
||||||
|
aes_rval aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) |
||||||
|
{ |
||||||
|
switch(key_len) |
||||||
|
{ |
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
case 16: case 128: return aes_encrypt_key128(key, cx); |
||||||
|
case 24: case 192: return aes_encrypt_key192(key, cx); |
||||||
|
case 32: case 256: return aes_encrypt_key256(key, cx); |
||||||
|
default: return EXIT_FAILURE; |
||||||
|
#else |
||||||
|
case 16: case 128: aes_encrypt_key128(key, cx); return; |
||||||
|
case 24: case 192: aes_encrypt_key192(key, cx); return; |
||||||
|
case 32: case 256: aes_encrypt_key256(key, cx); return; |
||||||
|
#endif |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if (FUNCS_IN_C & DEC_KEYING_IN_C) |
||||||
|
|
||||||
|
/* this is used to store the decryption round keys */ |
||||||
|
/* in forward or reverse order */ |
||||||
|
|
||||||
|
#ifdef AES_REV_DKS |
||||||
|
#define v(n,i) ((n) - (i) + 2 * ((i) & 3)) |
||||||
|
#else |
||||||
|
#define v(n,i) (i) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if DEC_ROUND == NO_TABLES |
||||||
|
#define ff(x) (x) |
||||||
|
#else |
||||||
|
#define ff(x) inv_mcol(x) |
||||||
|
#if defined( dec_imvars ) |
||||||
|
#define d_vars dec_imvars |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_128) || defined(AES_VAR) |
||||||
|
|
||||||
|
#define k4e(k,i) \ |
||||||
|
{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
|
||||||
|
k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
|
||||||
|
k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#if 1 |
||||||
|
|
||||||
|
#define kdf4(k,i) \ |
||||||
|
{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
|
||||||
|
ss[1] = ss[1] ^ ss[3]; \
|
||||||
|
ss[2] = ss[2] ^ ss[3]; \
|
||||||
|
ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[i % 4] ^= ss[4]; \
|
||||||
|
ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
|
||||||
|
ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
|
||||||
|
ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
|
||||||
|
ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kd4(k,i) \ |
||||||
|
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
|
||||||
|
k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||||
|
k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
|
||||||
|
k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
|
||||||
|
k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kdl4(k,i) \ |
||||||
|
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
|
||||||
|
k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
|
||||||
|
k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
|
||||||
|
k[v(40,(4*(i))+6)] = ss[0]; \
|
||||||
|
k[v(40,(4*(i))+7)] = ss[1]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#define kdf4(k,i) \ |
||||||
|
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
|
||||||
|
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
|
||||||
|
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
|
||||||
|
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kd4(k,i) \ |
||||||
|
{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kdl4(k,i) \ |
||||||
|
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) |
||||||
|
{ uint_32t ss[5]; |
||||||
|
#if defined( d_vars ) |
||||||
|
d_vars; |
||||||
|
#endif |
||||||
|
cx->ks[v(40,(0))] = ss[0] = word_in(key, 0); |
||||||
|
cx->ks[v(40,(1))] = ss[1] = word_in(key, 1); |
||||||
|
cx->ks[v(40,(2))] = ss[2] = word_in(key, 2); |
||||||
|
cx->ks[v(40,(3))] = ss[3] = word_in(key, 3); |
||||||
|
|
||||||
|
#if DEC_UNROLL == NONE |
||||||
|
{ uint_32t i; |
||||||
|
for(i = 0; i < 10; ++i) |
||||||
|
k4e(cx->ks, i); |
||||||
|
#if !(DEC_ROUND == NO_TABLES) |
||||||
|
for(i = N_COLS; i < 10 * N_COLS; ++i) |
||||||
|
cx->ks[i] = inv_mcol(cx->ks[i]); |
||||||
|
#endif |
||||||
|
} |
||||||
|
#else |
||||||
|
kdf4(cx->ks, 0); kd4(cx->ks, 1); |
||||||
|
kd4(cx->ks, 2); kd4(cx->ks, 3); |
||||||
|
kd4(cx->ks, 4); kd4(cx->ks, 5); |
||||||
|
kd4(cx->ks, 6); kd4(cx->ks, 7); |
||||||
|
kd4(cx->ks, 8); kdl4(cx->ks, 9); |
||||||
|
#endif |
||||||
|
cx->inf.l = 0; |
||||||
|
cx->inf.b[0] = 10 * 16; |
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT |
||||||
|
if(VIA_ACE_AVAILABLE) |
||||||
|
cx->inf.b[1] = 0xff; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_192) || defined(AES_VAR) |
||||||
|
|
||||||
|
#define k6ef(k,i) \ |
||||||
|
{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
|
||||||
|
k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
|
||||||
|
k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define k6e(k,i) \ |
||||||
|
{ k6ef(k,i); \
|
||||||
|
k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
|
||||||
|
k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kdf6(k,i) \ |
||||||
|
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
|
||||||
|
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
|
||||||
|
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
|
||||||
|
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
|
||||||
|
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
|
||||||
|
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kd6(k,i) \ |
||||||
|
{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
|
||||||
|
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
|
||||||
|
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kdl6(k,i) \ |
||||||
|
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
|
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) |
||||||
|
{ uint_32t ss[7]; |
||||||
|
#if defined( d_vars ) |
||||||
|
d_vars; |
||||||
|
#endif |
||||||
|
cx->ks[v(48,(0))] = ss[0] = word_in(key, 0); |
||||||
|
cx->ks[v(48,(1))] = ss[1] = word_in(key, 1); |
||||||
|
cx->ks[v(48,(2))] = ss[2] = word_in(key, 2); |
||||||
|
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3); |
||||||
|
|
||||||
|
#if DEC_UNROLL == NONE |
||||||
|
cx->ks[v(48,(4))] = ss[4] = word_in(key, 4); |
||||||
|
cx->ks[v(48,(5))] = ss[5] = word_in(key, 5); |
||||||
|
{ uint_32t i; |
||||||
|
|
||||||
|
for(i = 0; i < 7; ++i) |
||||||
|
k6e(cx->ks, i); |
||||||
|
k6ef(cx->ks, 7); |
||||||
|
#if !(DEC_ROUND == NO_TABLES) |
||||||
|
for(i = N_COLS; i < 12 * N_COLS; ++i) |
||||||
|
cx->ks[i] = inv_mcol(cx->ks[i]); |
||||||
|
#endif |
||||||
|
} |
||||||
|
#else |
||||||
|
cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4)); |
||||||
|
cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5)); |
||||||
|
kdf6(cx->ks, 0); kd6(cx->ks, 1); |
||||||
|
kd6(cx->ks, 2); kd6(cx->ks, 3); |
||||||
|
kd6(cx->ks, 4); kd6(cx->ks, 5); |
||||||
|
kd6(cx->ks, 6); kdl6(cx->ks, 7); |
||||||
|
#endif |
||||||
|
cx->inf.l = 0; |
||||||
|
cx->inf.b[0] = 12 * 16; |
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT |
||||||
|
if(VIA_ACE_AVAILABLE) |
||||||
|
cx->inf.b[1] = 0xff; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_256) || defined(AES_VAR) |
||||||
|
|
||||||
|
#define k8ef(k,i) \ |
||||||
|
{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||||
|
k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
|
||||||
|
k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
|
||||||
|
k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define k8e(k,i) \ |
||||||
|
{ k8ef(k,i); \
|
||||||
|
k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
|
||||||
|
k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
|
||||||
|
k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
|
||||||
|
k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kdf8(k,i) \ |
||||||
|
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
|
||||||
|
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
|
||||||
|
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
|
||||||
|
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
|
||||||
|
ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
|
||||||
|
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
|
||||||
|
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
|
||||||
|
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kd8(k,i) \ |
||||||
|
{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||||
|
ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
|
||||||
|
ss[8] = ls_box(ss[3],0); \
|
||||||
|
ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
|
||||||
|
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
|
||||||
|
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
|
||||||
|
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
|
||||||
|
} |
||||||
|
|
||||||
|
#define kdl8(k,i) \ |
||||||
|
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
|
||||||
|
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
|
||||||
|
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
|
||||||
|
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
|
||||||
|
} |
||||||
|
|
||||||
|
aes_rval aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) |
||||||
|
{ uint_32t ss[9]; |
||||||
|
#if defined( d_vars ) |
||||||
|
d_vars; |
||||||
|
#endif |
||||||
|
cx->ks[v(56,(0))] = ss[0] = word_in(key, 0); |
||||||
|
cx->ks[v(56,(1))] = ss[1] = word_in(key, 1); |
||||||
|
cx->ks[v(56,(2))] = ss[2] = word_in(key, 2); |
||||||
|
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3); |
||||||
|
|
||||||
|
#if DEC_UNROLL == NONE |
||||||
|
cx->ks[v(56,(4))] = ss[4] = word_in(key, 4); |
||||||
|
cx->ks[v(56,(5))] = ss[5] = word_in(key, 5); |
||||||
|
cx->ks[v(56,(6))] = ss[6] = word_in(key, 6); |
||||||
|
cx->ks[v(56,(7))] = ss[7] = word_in(key, 7); |
||||||
|
{ uint_32t i; |
||||||
|
|
||||||
|
for(i = 0; i < 6; ++i) |
||||||
|
k8e(cx->ks, i); |
||||||
|
k8ef(cx->ks, 6); |
||||||
|
#if !(DEC_ROUND == NO_TABLES) |
||||||
|
for(i = N_COLS; i < 14 * N_COLS; ++i) |
||||||
|
cx->ks[i] = inv_mcol(cx->ks[i]); |
||||||
|
|
||||||
|
#endif |
||||||
|
} |
||||||
|
#else |
||||||
|
cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4)); |
||||||
|
cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5)); |
||||||
|
cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6)); |
||||||
|
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7)); |
||||||
|
kdf8(cx->ks, 0); kd8(cx->ks, 1); |
||||||
|
kd8(cx->ks, 2); kd8(cx->ks, 3); |
||||||
|
kd8(cx->ks, 4); kd8(cx->ks, 5); |
||||||
|
kdl8(cx->ks, 6); |
||||||
|
#endif |
||||||
|
cx->inf.l = 0; |
||||||
|
cx->inf.b[0] = 14 * 16; |
||||||
|
|
||||||
|
#ifdef USE_VIA_ACE_IF_PRESENT |
||||||
|
if(VIA_ACE_AVAILABLE) |
||||||
|
cx->inf.b[1] = 0xff; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(AES_VAR) |
||||||
|
|
||||||
|
aes_rval aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) |
||||||
|
{ |
||||||
|
switch(key_len) |
||||||
|
{ |
||||||
|
#if defined( AES_ERR_CHK ) |
||||||
|
case 16: case 128: return aes_decrypt_key128(key, cx); |
||||||
|
case 24: case 192: return aes_decrypt_key192(key, cx); |
||||||
|
case 32: case 256: return aes_decrypt_key256(key, cx); |
||||||
|
default: return EXIT_FAILURE; |
||||||
|
#else |
||||||
|
case 16: case 128: aes_decrypt_key128(key, cx); return; |
||||||
|
case 24: case 192: aes_decrypt_key192(key, cx); return; |
||||||
|
case 32: case 256: aes_decrypt_key256(key, cx); return; |
||||||
|
#endif |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,719 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
|
||||||
|
This file contains the compilation options for AES (Rijndael) and code |
||||||
|
that is common across encryption, key scheduling and table generation. |
||||||
|
|
||||||
|
OPERATION |
||||||
|
|
||||||
|
These source code files implement the AES algorithm Rijndael designed by |
||||||
|
Joan Daemen and Vincent Rijmen. This version is designed for the standard |
||||||
|
block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24 |
||||||
|
and 32 bytes). |
||||||
|
|
||||||
|
This version is designed for flexibility and speed using operations on |
||||||
|
32-bit words rather than operations on bytes. It can be compiled with |
||||||
|
either big or little endian internal byte order but is faster when the |
||||||
|
native byte order for the processor is used. |
||||||
|
|
||||||
|
THE CIPHER INTERFACE |
||||||
|
|
||||||
|
The cipher interface is implemented as an array of bytes in which lower |
||||||
|
AES bit sequence indexes map to higher numeric significance within bytes. |
||||||
|
|
||||||
|
uint_8t (an unsigned 8-bit type) |
||||||
|
uint_32t (an unsigned 32-bit type) |
||||||
|
struct aes_encrypt_ctx (structure for the cipher encryption context) |
||||||
|
struct aes_decrypt_ctx (structure for the cipher decryption context) |
||||||
|
aes_rval the function return type |
||||||
|
|
||||||
|
C subroutine calls: |
||||||
|
|
||||||
|
aes_rval aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); |
||||||
|
aes_rval aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); |
||||||
|
aes_rval aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); |
||||||
|
aes_rval aes_encrypt(const unsigned char *in, unsigned char *out, |
||||||
|
const aes_encrypt_ctx cx[1]); |
||||||
|
|
||||||
|
aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); |
||||||
|
aes_rval aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); |
||||||
|
aes_rval aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); |
||||||
|
aes_rval aes_decrypt(const unsigned char *in, unsigned char *out, |
||||||
|
const aes_decrypt_ctx cx[1]); |
||||||
|
|
||||||
|
IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that |
||||||
|
you call gen_tabs() before AES is used so that the tables are initialised. |
||||||
|
|
||||||
|
C++ aes class subroutines: |
||||||
|
|
||||||
|
Class AESencrypt for encryption |
||||||
|
|
||||||
|
Construtors: |
||||||
|
AESencrypt(void) |
||||||
|
AESencrypt(const unsigned char *key) - 128 bit key |
||||||
|
Members: |
||||||
|
aes_rval key128(const unsigned char *key) |
||||||
|
aes_rval key192(const unsigned char *key) |
||||||
|
aes_rval key256(const unsigned char *key) |
||||||
|
aes_rval encrypt(const unsigned char *in, unsigned char *out) const |
||||||
|
|
||||||
|
Class AESdecrypt for encryption |
||||||
|
Construtors: |
||||||
|
AESdecrypt(void) |
||||||
|
AESdecrypt(const unsigned char *key) - 128 bit key |
||||||
|
Members: |
||||||
|
aes_rval key128(const unsigned char *key) |
||||||
|
aes_rval key192(const unsigned char *key) |
||||||
|
aes_rval key256(const unsigned char *key) |
||||||
|
aes_rval decrypt(const unsigned char *in, unsigned char *out) const |
||||||
|
*/ |
||||||
|
|
||||||
|
#if !defined( _AESOPT_H ) |
||||||
|
#define _AESOPT_H |
||||||
|
|
||||||
|
#if defined( __cplusplus ) |
||||||
|
#include "aescpp.h" |
||||||
|
#else |
||||||
|
#include "aes.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
/* PLATFORM SPECIFIC INCLUDES */ |
||||||
|
|
||||||
|
#include "aes_edefs.h" |
||||||
|
|
||||||
|
/* CONFIGURATION - THE USE OF DEFINES
|
||||||
|
|
||||||
|
Later in this section there are a number of defines that control the |
||||||
|
operation of the code. In each section, the purpose of each define is |
||||||
|
explained so that the relevant form can be included or excluded by |
||||||
|
setting either 1's or 0's respectively on the branches of the related |
||||||
|
#if clauses. The following local defines should not be changed. |
||||||
|
*/ |
||||||
|
|
||||||
|
#define ENCRYPTION_IN_C 1 |
||||||
|
#define DECRYPTION_IN_C 2 |
||||||
|
#define ENC_KEYING_IN_C 4 |
||||||
|
#define DEC_KEYING_IN_C 8 |
||||||
|
|
||||||
|
#define NO_TABLES 0 |
||||||
|
#define ONE_TABLE 1 |
||||||
|
#define FOUR_TABLES 4 |
||||||
|
#define NONE 0 |
||||||
|
#define PARTIAL 1 |
||||||
|
#define FULL 2 |
||||||
|
|
||||||
|
/* --- START OF USER CONFIGURED OPTIONS --- */ |
||||||
|
|
||||||
|
/* 1. BYTE ORDER WITHIN 32 BIT WORDS
|
||||||
|
|
||||||
|
The fundamental data processing units in Rijndael are 8-bit bytes. The |
||||||
|
input, output and key input are all enumerated arrays of bytes in which |
||||||
|
bytes are numbered starting at zero and increasing to one less than the |
||||||
|
number of bytes in the array in question. This enumeration is only used |
||||||
|
for naming bytes and does not imply any adjacency or order relationship |
||||||
|
from one byte to another. When these inputs and outputs are considered |
||||||
|
as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to |
||||||
|
byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. |
||||||
|
In this implementation bits are numbered from 0 to 7 starting at the |
||||||
|
numerically least significant end of each byte (bit n represents 2^n). |
||||||
|
|
||||||
|
However, Rijndael can be implemented more efficiently using 32-bit |
||||||
|
words by packing bytes into words so that bytes 4*n to 4*n+3 are placed |
||||||
|
into word[n]. While in principle these bytes can be assembled into words |
||||||
|
in any positions, this implementation only supports the two formats in |
||||||
|
which bytes in adjacent positions within words also have adjacent byte |
||||||
|
numbers. This order is called big-endian if the lowest numbered bytes |
||||||
|
in words have the highest numeric significance and little-endian if the |
||||||
|
opposite applies. |
||||||
|
|
||||||
|
This code can work in either order irrespective of the order used by the |
||||||
|
machine on which it runs. Normally the internal byte order will be set |
||||||
|
to the order of the processor on which the code is to be run but this |
||||||
|
define can be used to reverse this in special situations |
||||||
|
|
||||||
|
WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set. |
||||||
|
This define will hence be redefined later (in section 4) if necessary |
||||||
|
*/ |
||||||
|
|
||||||
|
#if 1 |
||||||
|
#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER |
||||||
|
#elif 0 |
||||||
|
#define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN |
||||||
|
#elif 0 |
||||||
|
#define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN |
||||||
|
#else |
||||||
|
#error The algorithm byte order is not defined |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 2. VIA ACE SUPPORT
|
||||||
|
|
||||||
|
Define this option if support for the VIA ACE is required. This uses
|
||||||
|
inline assembler instructions and is only implemented for the Microsoft,
|
||||||
|
Intel and GCC compilers. If VIA ACE is known to be present, then defining |
||||||
|
ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
|
||||||
|
code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if |
||||||
|
it is detected (both present and enabled) but the normal AES code will
|
||||||
|
also be present.
|
||||||
|
|
||||||
|
When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
|
||||||
|
aligned; other input/output buffers do not need to be 16 byte aligned
|
||||||
|
but there are very large performance gains if this can be arranged.
|
||||||
|
VIA ACE also requires the decryption key schedule to be in reverse
|
||||||
|
order (which the following defines ensure). |
||||||
|
*/ |
||||||
|
|
||||||
|
#if 0 && !defined( _WIN64 ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||||
|
#define USE_VIA_ACE_IF_PRESENT |
||||||
|
#endif |
||||||
|
|
||||||
|
#if 0 && !defined( _WIN64 ) && !defined( ASSUME_VIA_ACE_PRESENT )
|
||||||
|
#define ASSUME_VIA_ACE_PRESENT |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 3. ASSEMBLER SUPPORT
|
||||||
|
|
||||||
|
This define (which can be on the command line) enables the use of the |
||||||
|
assembler code routines for encryption, decryption and key scheduling |
||||||
|
as follows: |
||||||
|
|
||||||
|
ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
|
||||||
|
encryption and decryption and but with key scheduling in C |
||||||
|
ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for |
||||||
|
encryption, decryption and key scheduling |
||||||
|
ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for |
||||||
|
encryption and decryption and but with key scheduling in C |
||||||
|
ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for |
||||||
|
encryption and decryption and but with key scheduling in C |
||||||
|
|
||||||
|
Change one 'if 0' below to 'if 1' to select the version or define
|
||||||
|
as a compilation option. |
||||||
|
*/ |
||||||
|
|
||||||
|
#if defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ) |
||||||
|
# if defined( _M_IX86 ) |
||||||
|
# if 0 && !defined( ASM_X86_V1C ) |
||||||
|
# define ASM_X86_V1C |
||||||
|
# elif 0 && !defined( ASM_X86_V2 ) |
||||||
|
# define ASM_X86_V2 |
||||||
|
# elif 0 && !defined( ASM_X86_V2C ) |
||||||
|
# define ASM_X86_V2C |
||||||
|
# endif |
||||||
|
# else |
||||||
|
# error Assembler code is only available for x86 and AMD64 systems |
||||||
|
# endif |
||||||
|
#elif defined( ASM_AMD64_C ) |
||||||
|
# if defined( _M_X64 ) |
||||||
|
# if 0 && !defined( ASM_AMD64_C ) |
||||||
|
# define ASM_AMD64_C |
||||||
|
# endif |
||||||
|
# else |
||||||
|
# error Assembler code is only available for x86 and AMD64 systems |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 4. FAST INPUT/OUTPUT OPERATIONS.
|
||||||
|
|
||||||
|
On some machines it is possible to improve speed by transferring the |
||||||
|
bytes in the input and output arrays to and from the internal 32-bit |
||||||
|
variables by addressing these arrays as if they are arrays of 32-bit |
||||||
|
words. On some machines this will always be possible but there may |
||||||
|
be a large performance penalty if the byte arrays are not aligned on |
||||||
|
the normal word boundaries. On other machines this technique will |
||||||
|
lead to memory access errors when such 32-bit word accesses are not |
||||||
|
properly aligned. The option SAFE_IO avoids such problems but will |
||||||
|
often be slower on those machines that support misaligned access |
||||||
|
(especially so if care is taken to align the input and output byte |
||||||
|
arrays on 32-bit word boundaries). If SAFE_IO is not defined it is |
||||||
|
assumed that access to byte arrays as if they are arrays of 32-bit |
||||||
|
words will not cause problems when such accesses are misaligned. |
||||||
|
*/ |
||||||
|
#if 1 && !defined( _MSC_VER ) |
||||||
|
#define SAFE_IO |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 5. LOOP UNROLLING
|
||||||
|
|
||||||
|
The code for encryption and decrytpion cycles through a number of rounds |
||||||
|
that can be implemented either in a loop or by expanding the code into a |
||||||
|
long sequence of instructions, the latter producing a larger program but |
||||||
|
one that will often be much faster. The latter is called loop unrolling. |
||||||
|
There are also potential speed advantages in expanding two iterations in |
||||||
|
a loop with half the number of iterations, which is called partial loop |
||||||
|
unrolling. The following options allow partial or full loop unrolling |
||||||
|
to be set independently for encryption and decryption |
||||||
|
*/ |
||||||
|
#if 1 |
||||||
|
#define ENC_UNROLL FULL |
||||||
|
#elif 0 |
||||||
|
#define ENC_UNROLL PARTIAL |
||||||
|
#else |
||||||
|
#define ENC_UNROLL NONE |
||||||
|
#endif |
||||||
|
|
||||||
|
#if 1 |
||||||
|
#define DEC_UNROLL FULL |
||||||
|
#elif 0 |
||||||
|
#define DEC_UNROLL PARTIAL |
||||||
|
#else |
||||||
|
#define DEC_UNROLL NONE |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 6. FAST FINITE FIELD OPERATIONS
|
||||||
|
|
||||||
|
If this section is included, tables are used to provide faster finite |
||||||
|
field arithmetic (this has no effect if FIXED_TABLES is defined). |
||||||
|
*/ |
||||||
|
#if 1 |
||||||
|
#define FF_TABLES |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 7. INTERNAL STATE VARIABLE FORMAT
|
||||||
|
|
||||||
|
The internal state of Rijndael is stored in a number of local 32-bit |
||||||
|
word varaibles which can be defined either as an array or as individual |
||||||
|
names variables. Include this section if you want to store these local |
||||||
|
varaibles in arrays. Otherwise individual local variables will be used. |
||||||
|
*/ |
||||||
|
#if 1 |
||||||
|
#define ARRAYS |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 8. FIXED OR DYNAMIC TABLES
|
||||||
|
|
||||||
|
When this section is included the tables used by the code are compiled |
||||||
|
statically into the binary file. Otherwise the subroutine gen_tabs() |
||||||
|
must be called to compute them before the code is first used. |
||||||
|
*/ |
||||||
|
#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) |
||||||
|
#define FIXED_TABLES |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 9. TABLE ALIGNMENT
|
||||||
|
|
||||||
|
On some sytsems speed will be improved by aligning the AES large lookup |
||||||
|
tables on particular boundaries. This define should be set to a power of |
||||||
|
two giving the desired alignment. It can be left undefined if alignment |
||||||
|
is not needed. This option is specific to the Microsft VC++ compiler - |
||||||
|
it seems to sometimes cause trouble for the VC++ version 6 compiler. |
||||||
|
*/ |
||||||
|
|
||||||
|
#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) |
||||||
|
#define TABLE_ALIGN 32 |
||||||
|
#endif |
||||||
|
|
||||||
|
/* 10. TABLE OPTIONS
|
||||||
|
|
||||||
|
This cipher proceeds by repeating in a number of cycles known as 'rounds' |
||||||
|
which are implemented by a round function which can optionally be speeded |
||||||
|
up using tables. The basic tables are each 256 32-bit words, with either |
||||||
|
one or four tables being required for each round function depending on |
||||||
|
how much speed is required. The encryption and decryption round functions |
||||||
|
are different and the last encryption and decrytpion round functions are |
||||||
|
different again making four different round functions in all. |
||||||
|
|
||||||
|
This means that: |
||||||
|
1. Normal encryption and decryption rounds can each use either 0, 1 |
||||||
|
or 4 tables and table spaces of 0, 1024 or 4096 bytes each. |
||||||
|
2. The last encryption and decryption rounds can also use either 0, 1 |
||||||
|
or 4 tables and table spaces of 0, 1024 or 4096 bytes each. |
||||||
|
|
||||||
|
Include or exclude the appropriate definitions below to set the number |
||||||
|
of tables used by this implementation. |
||||||
|
*/ |
||||||
|
|
||||||
|
#if 1 /* set tables for the normal encryption round */ |
||||||
|
#define ENC_ROUND FOUR_TABLES |
||||||
|
#elif 0 |
||||||
|
#define ENC_ROUND ONE_TABLE |
||||||
|
#else |
||||||
|
#define ENC_ROUND NO_TABLES |
||||||
|
#endif |
||||||
|
|
||||||
|
#if 1 /* set tables for the last encryption round */ |
||||||
|
#define LAST_ENC_ROUND FOUR_TABLES |
||||||
|
#elif 0 |
||||||
|
#define LAST_ENC_ROUND ONE_TABLE |
||||||
|
#else |
||||||
|
#define LAST_ENC_ROUND NO_TABLES |
||||||
|
#endif |
||||||
|
|
||||||
|
#if 1 /* set tables for the normal decryption round */ |
||||||
|
#define DEC_ROUND FOUR_TABLES |
||||||
|
#elif 0 |
||||||
|
#define DEC_ROUND ONE_TABLE |
||||||
|
#else |
||||||
|
#define DEC_ROUND NO_TABLES |
||||||
|
#endif |
||||||
|
|
||||||
|
#if 1 /* set tables for the last decryption round */ |
||||||
|
#define LAST_DEC_ROUND FOUR_TABLES |
||||||
|
#elif 0 |
||||||
|
#define LAST_DEC_ROUND ONE_TABLE |
||||||
|
#else |
||||||
|
#define LAST_DEC_ROUND NO_TABLES |
||||||
|
#endif |
||||||
|
|
||||||
|
/* The decryption key schedule can be speeded up with tables in the same
|
||||||
|
way that the round functions can. Include or exclude the following |
||||||
|
defines to set this requirement. |
||||||
|
*/ |
||||||
|
#if 1 |
||||||
|
#define KEY_SCHED FOUR_TABLES |
||||||
|
#elif 0 |
||||||
|
#define KEY_SCHED ONE_TABLE |
||||||
|
#else |
||||||
|
#define KEY_SCHED NO_TABLES |
||||||
|
#endif |
||||||
|
|
||||||
|
/* ---- END OF USER CONFIGURED OPTIONS ---- */ |
||||||
|
|
||||||
|
/* VIA ACE support is only available for VC++ and GCC */ |
||||||
|
|
||||||
|
#if !defined( _MSC_VER ) && !defined( __GNUC__ ) |
||||||
|
# if defined( ASSUME_VIA_ACE_PRESENT ) |
||||||
|
# undef ASSUME_VIA_ACE_PRESENT |
||||||
|
# endif |
||||||
|
# if defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
# undef USE_VIA_ACE_IF_PRESENT |
||||||
|
# endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT ) |
||||||
|
#define USE_VIA_ACE_IF_PRESENT |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS ) |
||||||
|
#define AES_REV_DKS |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Assembler support requires the use of platform byte order */ |
||||||
|
|
||||||
|
#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER) |
||||||
|
#undef ALGORITHM_BYTE_ORDER |
||||||
|
#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER |
||||||
|
#endif |
||||||
|
|
||||||
|
/* In this implementation the columns of the state array are each held in
|
||||||
|
32-bit words. The state array can be held in various ways: in an array |
||||||
|
of words, in a number of individual word variables or in a number of |
||||||
|
processor registers. The following define maps a variable name x and |
||||||
|
a column number c to the way the state array variable is to be held. |
||||||
|
The first define below maps the state into an array x[c] whereas the |
||||||
|
second form maps the state into a number of individual variables x0, |
||||||
|
x1, etc. Another form could map individual state colums to machine |
||||||
|
register names. |
||||||
|
*/ |
||||||
|
|
||||||
|
#if defined( ARRAYS ) |
||||||
|
#define s(x,c) x[c] |
||||||
|
#else |
||||||
|
#define s(x,c) x##c |
||||||
|
#endif |
||||||
|
|
||||||
|
/* This implementation provides subroutines for encryption, decryption
|
||||||
|
and for setting the three key lengths (separately) for encryption |
||||||
|
and decryption. Since not all functions are needed, masks are set
|
||||||
|
up here to determine which will be implemented in C |
||||||
|
*/ |
||||||
|
|
||||||
|
#if !defined( AES_ENCRYPT ) |
||||||
|
# define EFUNCS_IN_C 0 |
||||||
|
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) |
||||||
|
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) |
||||||
|
# define EFUNCS_IN_C ENC_KEYING_IN_C |
||||||
|
#elif !defined( ASM_X86_V2 ) |
||||||
|
# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C ) |
||||||
|
#else |
||||||
|
# define EFUNCS_IN_C 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
#if !defined( AES_DECRYPT ) |
||||||
|
# define DFUNCS_IN_C 0 |
||||||
|
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) |
||||||
|
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
|
||||||
|
# define DFUNCS_IN_C DEC_KEYING_IN_C |
||||||
|
#elif !defined( ASM_X86_V2 ) |
||||||
|
# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C ) |
||||||
|
#else |
||||||
|
# define DFUNCS_IN_C 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C ) |
||||||
|
|
||||||
|
/* END OF CONFIGURATION OPTIONS */ |
||||||
|
|
||||||
|
#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) |
||||||
|
|
||||||
|
/* Disable or report errors on some combinations of options */ |
||||||
|
|
||||||
|
#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES |
||||||
|
#undef LAST_ENC_ROUND |
||||||
|
#define LAST_ENC_ROUND NO_TABLES |
||||||
|
#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES |
||||||
|
#undef LAST_ENC_ROUND |
||||||
|
#define LAST_ENC_ROUND ONE_TABLE |
||||||
|
#endif |
||||||
|
|
||||||
|
#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE |
||||||
|
#undef ENC_UNROLL |
||||||
|
#define ENC_UNROLL NONE |
||||||
|
#endif |
||||||
|
|
||||||
|
#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES |
||||||
|
#undef LAST_DEC_ROUND |
||||||
|
#define LAST_DEC_ROUND NO_TABLES |
||||||
|
#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES |
||||||
|
#undef LAST_DEC_ROUND |
||||||
|
#define LAST_DEC_ROUND ONE_TABLE |
||||||
|
#endif |
||||||
|
|
||||||
|
#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE |
||||||
|
#undef DEC_UNROLL |
||||||
|
#define DEC_UNROLL NONE |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( bswap32 ) |
||||||
|
#define aes_sw32 bswap32 |
||||||
|
#elif defined( bswap_32 ) |
||||||
|
#define aes_sw32 bswap_32 |
||||||
|
#else |
||||||
|
#define brot(x,n) (((uint_32t)(x) << n) | ((uint_32t)(x) >> (32 - n))) |
||||||
|
#define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00)) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* upr(x,n): rotates bytes within words by n positions, moving bytes to
|
||||||
|
higher index positions with wrap around into low positions |
||||||
|
ups(x,n): moves bytes by n positions to higher index positions in |
||||||
|
words but without wrap around |
||||||
|
bval(x,n): extracts a byte from a word |
||||||
|
|
||||||
|
WARNING: The definitions given here are intended only for use with |
||||||
|
unsigned variables and with shift counts that are compile |
||||||
|
time constants |
||||||
|
*/ |
||||||
|
|
||||||
|
#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN ) |
||||||
|
#define upr(x,n) (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n)))) |
||||||
|
#define ups(x,n) ((uint_32t) (x) << (8 * (n))) |
||||||
|
#define bval(x,n) ((uint_8t)((x) >> (8 * (n)))) |
||||||
|
#define bytes2word(b0, b1, b2, b3) \ |
||||||
|
(((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0)) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN ) |
||||||
|
#define upr(x,n) (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n)))) |
||||||
|
#define ups(x,n) ((uint_32t) (x) >> (8 * (n))) |
||||||
|
#define bval(x,n) ((uint_8t)((x) >> (24 - 8 * (n)))) |
||||||
|
#define bytes2word(b0, b1, b2, b3) \ |
||||||
|
(((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3)) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( SAFE_IO ) |
||||||
|
|
||||||
|
#define word_in(x,c) bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \ |
||||||
|
((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3]) |
||||||
|
#define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \ |
||||||
|
((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); } |
||||||
|
|
||||||
|
#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER ) |
||||||
|
|
||||||
|
#define word_in(x,c) (*((uint_32t*)(x)+(c))) |
||||||
|
#define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v)) |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#define word_in(x,c) aes_sw32(*((uint_32t*)(x)+(c))) |
||||||
|
#define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v)) |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
/* the finite field modular polynomial and elements */ |
||||||
|
|
||||||
|
#define WPOLY 0x011b |
||||||
|
#define BPOLY 0x1b |
||||||
|
|
||||||
|
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ |
||||||
|
|
||||||
|
#define m1 0x80808080 |
||||||
|
#define m2 0x7f7f7f7f |
||||||
|
#define gf_mulx(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY)) |
||||||
|
|
||||||
|
/* The following defines provide alternative definitions of gf_mulx that might
|
||||||
|
give improved performance if a fast 32-bit multiply is not available. Note |
||||||
|
that a temporary variable u needs to be defined where gf_mulx is used. |
||||||
|
|
||||||
|
#define gf_mulx(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) |
||||||
|
#define m4 (0x01010101 * BPOLY) |
||||||
|
#define gf_mulx(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Work out which tables are needed for the different options */ |
||||||
|
|
||||||
|
#if defined( ASM_X86_V1C ) |
||||||
|
#if defined( ENC_ROUND ) |
||||||
|
#undef ENC_ROUND |
||||||
|
#endif |
||||||
|
#define ENC_ROUND FOUR_TABLES |
||||||
|
#if defined( LAST_ENC_ROUND ) |
||||||
|
#undef LAST_ENC_ROUND |
||||||
|
#endif |
||||||
|
#define LAST_ENC_ROUND FOUR_TABLES |
||||||
|
#if defined( DEC_ROUND ) |
||||||
|
#undef DEC_ROUND |
||||||
|
#endif |
||||||
|
#define DEC_ROUND FOUR_TABLES |
||||||
|
#if defined( LAST_DEC_ROUND ) |
||||||
|
#undef LAST_DEC_ROUND |
||||||
|
#endif |
||||||
|
#define LAST_DEC_ROUND FOUR_TABLES |
||||||
|
#if defined( KEY_SCHED ) |
||||||
|
#undef KEY_SCHED |
||||||
|
#define KEY_SCHED FOUR_TABLES |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C ) |
||||||
|
#if ENC_ROUND == ONE_TABLE |
||||||
|
#define FT1_SET |
||||||
|
#elif ENC_ROUND == FOUR_TABLES |
||||||
|
#define FT4_SET |
||||||
|
#else |
||||||
|
#define SBX_SET |
||||||
|
#endif |
||||||
|
#if LAST_ENC_ROUND == ONE_TABLE |
||||||
|
#define FL1_SET |
||||||
|
#elif LAST_ENC_ROUND == FOUR_TABLES |
||||||
|
#define FL4_SET |
||||||
|
#elif !defined( SBX_SET ) |
||||||
|
#define SBX_SET |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C ) |
||||||
|
#if DEC_ROUND == ONE_TABLE |
||||||
|
#define IT1_SET |
||||||
|
#elif DEC_ROUND == FOUR_TABLES |
||||||
|
#define IT4_SET |
||||||
|
#else |
||||||
|
#define ISB_SET |
||||||
|
#endif |
||||||
|
#if LAST_DEC_ROUND == ONE_TABLE |
||||||
|
#define IL1_SET |
||||||
|
#elif LAST_DEC_ROUND == FOUR_TABLES |
||||||
|
#define IL4_SET |
||||||
|
#elif !defined(ISB_SET) |
||||||
|
#define ISB_SET |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if (FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C) |
||||||
|
#if KEY_SCHED == ONE_TABLE |
||||||
|
#define LS1_SET |
||||||
|
#elif KEY_SCHED == FOUR_TABLES |
||||||
|
#define LS4_SET |
||||||
|
#elif !defined( SBX_SET ) |
||||||
|
#define SBX_SET |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if (FUNCS_IN_C & DEC_KEYING_IN_C) |
||||||
|
#if KEY_SCHED == ONE_TABLE |
||||||
|
#define IM1_SET |
||||||
|
#elif KEY_SCHED == FOUR_TABLES |
||||||
|
#define IM4_SET |
||||||
|
#elif !defined( SBX_SET ) |
||||||
|
#define SBX_SET |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
/* generic definitions of Rijndael macros that use tables */ |
||||||
|
|
||||||
|
#define no_table(x,box,vf,rf,c) bytes2word( \ |
||||||
|
box[bval(vf(x,0,c),rf(0,c))], \
|
||||||
|
box[bval(vf(x,1,c),rf(1,c))], \
|
||||||
|
box[bval(vf(x,2,c),rf(2,c))], \
|
||||||
|
box[bval(vf(x,3,c),rf(3,c))]) |
||||||
|
|
||||||
|
#define one_table(x,op,tab,vf,rf,c) \ |
||||||
|
( tab[bval(vf(x,0,c),rf(0,c))] \
|
||||||
|
^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
|
||||||
|
^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
|
||||||
|
^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) |
||||||
|
|
||||||
|
#define four_tables(x,tab,vf,rf,c) \ |
||||||
|
( tab[0][bval(vf(x,0,c),rf(0,c))] \
|
||||||
|
^ tab[1][bval(vf(x,1,c),rf(1,c))] \
|
||||||
|
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
|
||||||
|
^ tab[3][bval(vf(x,3,c),rf(3,c))]) |
||||||
|
|
||||||
|
#define vf1(x,r,c) (x) |
||||||
|
#define rf1(r,c) (r) |
||||||
|
#define rf2(r,c) ((8+r-c)&3) |
||||||
|
|
||||||
|
/* perform forward and inverse column mix operation on four bytes in long word x in */ |
||||||
|
/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ |
||||||
|
|
||||||
|
#if defined( FM4_SET ) /* not currently used */ |
||||||
|
#define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0) |
||||||
|
#elif defined( FM1_SET ) /* not currently used */ |
||||||
|
#define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0) |
||||||
|
#else |
||||||
|
#define dec_fmvars uint_32t g2 |
||||||
|
#define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1)) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( IM4_SET ) |
||||||
|
#define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0) |
||||||
|
#elif defined( IM1_SET ) |
||||||
|
#define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0) |
||||||
|
#else |
||||||
|
#define dec_imvars uint_32t g2, g4, g9 |
||||||
|
#define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \ |
||||||
|
(x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1)) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( FL4_SET ) |
||||||
|
#define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c) |
||||||
|
#elif defined( LS4_SET ) |
||||||
|
#define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c) |
||||||
|
#elif defined( FL1_SET ) |
||||||
|
#define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c) |
||||||
|
#elif defined( LS1_SET ) |
||||||
|
#define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c) |
||||||
|
#else |
||||||
|
#define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET ) |
||||||
|
#define ISB_SET |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,388 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
*/ |
||||||
|
|
||||||
|
#define DO_TABLES |
||||||
|
|
||||||
|
#include "aes.h" |
||||||
|
#include "aesopt.h" |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(FIXED_TABLES) |
||||||
|
|
||||||
|
#define sb_data(w) {\ |
||||||
|
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||||
|
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||||
|
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
|
||||||
|
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
|
||||||
|
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
|
||||||
|
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
|
||||||
|
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
|
||||||
|
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
|
||||||
|
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
|
||||||
|
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
|
||||||
|
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
|
||||||
|
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
|
||||||
|
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
|
||||||
|
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
|
||||||
|
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
|
||||||
|
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
|
||||||
|
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
|
||||||
|
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
|
||||||
|
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
|
||||||
|
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
|
||||||
|
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
|
||||||
|
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
|
||||||
|
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
|
||||||
|
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
|
||||||
|
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
|
||||||
|
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
|
||||||
|
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
|
||||||
|
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
|
||||||
|
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
|
||||||
|
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
|
||||||
|
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
|
||||||
|
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } |
||||||
|
|
||||||
|
#define isb_data(w) {\ |
||||||
|
w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
|
||||||
|
w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
|
||||||
|
w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
|
||||||
|
w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
|
||||||
|
w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
|
||||||
|
w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
|
||||||
|
w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
|
||||||
|
w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
|
||||||
|
w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
|
||||||
|
w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
|
||||||
|
w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
|
||||||
|
w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
|
||||||
|
w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
|
||||||
|
w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
|
||||||
|
w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
|
||||||
|
w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
|
||||||
|
w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
|
||||||
|
w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
|
||||||
|
w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
|
||||||
|
w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
|
||||||
|
w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
|
||||||
|
w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
|
||||||
|
w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
|
||||||
|
w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
|
||||||
|
w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
|
||||||
|
w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
|
||||||
|
w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
|
||||||
|
w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
|
||||||
|
w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
|
||||||
|
w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
|
||||||
|
w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
|
||||||
|
w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) } |
||||||
|
|
||||||
|
#define mm_data(w) {\ |
||||||
|
w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
|
||||||
|
w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
|
||||||
|
w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
|
||||||
|
w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
|
||||||
|
w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
|
||||||
|
w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
|
||||||
|
w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
|
||||||
|
w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
|
||||||
|
w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
|
||||||
|
w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
|
||||||
|
w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
|
||||||
|
w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
|
||||||
|
w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
|
||||||
|
w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
|
||||||
|
w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
|
||||||
|
w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
|
||||||
|
w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
|
||||||
|
w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
|
||||||
|
w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
|
||||||
|
w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
|
||||||
|
w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
|
||||||
|
w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
|
||||||
|
w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
|
||||||
|
w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
|
||||||
|
w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
|
||||||
|
w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
|
||||||
|
w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
|
||||||
|
w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
|
||||||
|
w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
|
||||||
|
w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
|
||||||
|
w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
|
||||||
|
w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) } |
||||||
|
|
||||||
|
#define rc_data(w) {\ |
||||||
|
w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
|
||||||
|
w(0x1b), w(0x36) } |
||||||
|
|
||||||
|
#define h0(x) (x) |
||||||
|
|
||||||
|
#define w0(p) bytes2word(p, 0, 0, 0) |
||||||
|
#define w1(p) bytes2word(0, p, 0, 0) |
||||||
|
#define w2(p) bytes2word(0, 0, p, 0) |
||||||
|
#define w3(p) bytes2word(0, 0, 0, p) |
||||||
|
|
||||||
|
#define u0(p) bytes2word(f2(p), p, p, f3(p)) |
||||||
|
#define u1(p) bytes2word(f3(p), f2(p), p, p) |
||||||
|
#define u2(p) bytes2word(p, f3(p), f2(p), p) |
||||||
|
#define u3(p) bytes2word(p, p, f3(p), f2(p)) |
||||||
|
|
||||||
|
#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) |
||||||
|
#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) |
||||||
|
#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) |
||||||
|
#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(FIXED_TABLES) || !defined(FF_TABLES) |
||||||
|
|
||||||
|
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) |
||||||
|
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) |
||||||
|
#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ |
||||||
|
^ (((x>>5) & 4) * WPOLY)) |
||||||
|
#define f3(x) (f2(x) ^ x) |
||||||
|
#define f9(x) (f8(x) ^ x) |
||||||
|
#define fb(x) (f8(x) ^ f2(x) ^ x) |
||||||
|
#define fd(x) (f8(x) ^ f4(x) ^ x) |
||||||
|
#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#define f2(x) ((x) ? pow[log[x] + 0x19] : 0) |
||||||
|
#define f3(x) ((x) ? pow[log[x] + 0x01] : 0) |
||||||
|
#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0) |
||||||
|
#define fb(x) ((x) ? pow[log[x] + 0x68] : 0) |
||||||
|
#define fd(x) ((x) ? pow[log[x] + 0xee] : 0) |
||||||
|
#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0) |
||||||
|
#define fi(x) ((x) ? pow[ 255 - log[x]] : 0) |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#include "aestab.h" |
||||||
|
|
||||||
|
#if defined(FIXED_TABLES) |
||||||
|
|
||||||
|
/* implemented in case of wrong call for fixed tables */ |
||||||
|
|
||||||
|
aes_rval gen_tabs(void) |
||||||
|
{ |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
#else /* dynamic table generation */ |
||||||
|
|
||||||
|
#if !defined(FF_TABLES) |
||||||
|
|
||||||
|
/* Generate the tables for the dynamic table option
|
||||||
|
|
||||||
|
It will generally be sensible to use tables to compute finite |
||||||
|
field multiplies and inverses but where memory is scarse this |
||||||
|
code might sometimes be better. But it only has effect during |
||||||
|
initialisation so its pretty unimportant in overall terms. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* return 2 ^ (n - 1) where n is the bit number of the highest bit
|
||||||
|
set in x with x in the range 1 < x < 0x00000200. This form is |
||||||
|
used so that locals within fi can be bytes rather than words |
||||||
|
*/ |
||||||
|
|
||||||
|
static uint_8t hibit(const uint_32t x) |
||||||
|
{ uint_8t r = (uint_8t)((x >> 1) | (x >> 2)); |
||||||
|
|
||||||
|
r |= (r >> 2); |
||||||
|
r |= (r >> 4); |
||||||
|
return (r + 1) >> 1; |
||||||
|
} |
||||||
|
|
||||||
|
/* return the inverse of the finite field element x */ |
||||||
|
|
||||||
|
static uint_8t fi(const uint_8t x) |
||||||
|
{ uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; |
||||||
|
|
||||||
|
if(x < 2) return x; |
||||||
|
|
||||||
|
for(;;) |
||||||
|
{ |
||||||
|
if(!n1) return v1; |
||||||
|
|
||||||
|
while(n2 >= n1) |
||||||
|
{ |
||||||
|
n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); |
||||||
|
} |
||||||
|
|
||||||
|
if(!n2) return v2; |
||||||
|
|
||||||
|
while(n1 >= n2) |
||||||
|
{ |
||||||
|
n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
/* The forward and inverse affine transformations used in the S-box */ |
||||||
|
|
||||||
|
#define fwd_affine(x) \ |
||||||
|
(w = (uint_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(uint_8t)(w^(w>>8))) |
||||||
|
|
||||||
|
#define inv_affine(x) \ |
||||||
|
(w = (uint_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(uint_8t)(w^(w>>8))) |
||||||
|
|
||||||
|
static int init = 0; |
||||||
|
|
||||||
|
aes_rval gen_tabs(void) |
||||||
|
{ uint_32t i, w; |
||||||
|
|
||||||
|
#if defined(FF_TABLES) |
||||||
|
|
||||||
|
uint_8t pow[512], log[256]; |
||||||
|
|
||||||
|
if(init)
|
||||||
|
return EXIT_SUCCESS; |
||||||
|
/* log and power tables for GF(2^8) finite field with
|
||||||
|
WPOLY as modular polynomial - the simplest primitive |
||||||
|
root is 0x03, used here to generate the tables |
||||||
|
*/ |
||||||
|
|
||||||
|
i = 0; w = 1; |
||||||
|
do |
||||||
|
{ |
||||||
|
pow[i] = (uint_8t)w; |
||||||
|
pow[i + 255] = (uint_8t)w; |
||||||
|
log[w] = (uint_8t)i++; |
||||||
|
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); |
||||||
|
} |
||||||
|
while (w != 1); |
||||||
|
|
||||||
|
#else |
||||||
|
if(init)
|
||||||
|
return EXIT_SUCCESS; |
||||||
|
#endif |
||||||
|
|
||||||
|
for(i = 0, w = 1; i < RC_LENGTH; ++i) |
||||||
|
{ |
||||||
|
t_set(r,c)[i] = bytes2word(w, 0, 0, 0); |
||||||
|
w = f2(w); |
||||||
|
} |
||||||
|
|
||||||
|
for(i = 0; i < 256; ++i) |
||||||
|
{ uint_8t b; |
||||||
|
|
||||||
|
b = fwd_affine(fi((uint_8t)i)); |
||||||
|
w = bytes2word(f2(b), b, b, f3(b)); |
||||||
|
|
||||||
|
#if defined( SBX_SET ) |
||||||
|
t_set(s,box)[i] = b; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( FT1_SET ) /* tables for a normal encryption round */ |
||||||
|
t_set(f,n)[i] = w; |
||||||
|
#endif |
||||||
|
#if defined( FT4_SET ) |
||||||
|
t_set(f,n)[0][i] = w; |
||||||
|
t_set(f,n)[1][i] = upr(w,1); |
||||||
|
t_set(f,n)[2][i] = upr(w,2); |
||||||
|
t_set(f,n)[3][i] = upr(w,3); |
||||||
|
#endif |
||||||
|
w = bytes2word(b, 0, 0, 0); |
||||||
|
|
||||||
|
#if defined( FL1_SET ) /* tables for last encryption round (may also */ |
||||||
|
t_set(f,l)[i] = w; /* be used in the key schedule) */ |
||||||
|
#endif |
||||||
|
#if defined( FL4_SET ) |
||||||
|
t_set(f,l)[0][i] = w; |
||||||
|
t_set(f,l)[1][i] = upr(w,1); |
||||||
|
t_set(f,l)[2][i] = upr(w,2); |
||||||
|
t_set(f,l)[3][i] = upr(w,3); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is */ |
||||||
|
t_set(l,s)[i] = w; /* not of the required form */ |
||||||
|
#endif |
||||||
|
#if defined( LS4_SET ) |
||||||
|
t_set(l,s)[0][i] = w; |
||||||
|
t_set(l,s)[1][i] = upr(w,1); |
||||||
|
t_set(l,s)[2][i] = upr(w,2); |
||||||
|
t_set(l,s)[3][i] = upr(w,3); |
||||||
|
#endif |
||||||
|
|
||||||
|
b = fi(inv_affine((uint_8t)i)); |
||||||
|
w = bytes2word(fe(b), f9(b), fd(b), fb(b)); |
||||||
|
|
||||||
|
#if defined( IM1_SET ) /* tables for the inverse mix column operation */ |
||||||
|
t_set(i,m)[b] = w; |
||||||
|
#endif |
||||||
|
#if defined( IM4_SET ) |
||||||
|
t_set(i,m)[0][b] = w; |
||||||
|
t_set(i,m)[1][b] = upr(w,1); |
||||||
|
t_set(i,m)[2][b] = upr(w,2); |
||||||
|
t_set(i,m)[3][b] = upr(w,3); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( ISB_SET ) |
||||||
|
t_set(i,box)[i] = b; |
||||||
|
#endif |
||||||
|
#if defined( IT1_SET ) /* tables for a normal decryption round */ |
||||||
|
t_set(i,n)[i] = w; |
||||||
|
#endif |
||||||
|
#if defined( IT4_SET ) |
||||||
|
t_set(i,n)[0][i] = w; |
||||||
|
t_set(i,n)[1][i] = upr(w,1); |
||||||
|
t_set(i,n)[2][i] = upr(w,2); |
||||||
|
t_set(i,n)[3][i] = upr(w,3); |
||||||
|
#endif |
||||||
|
w = bytes2word(b, 0, 0, 0); |
||||||
|
#if defined( IL1_SET ) /* tables for last decryption round */ |
||||||
|
t_set(i,l)[i] = w; |
||||||
|
#endif |
||||||
|
#if defined( IL4_SET ) |
||||||
|
t_set(i,l)[0][i] = w; |
||||||
|
t_set(i,l)[1][i] = upr(w,1); |
||||||
|
t_set(i,l)[2][i] = upr(w,2); |
||||||
|
t_set(i,l)[3][i] = upr(w,3); |
||||||
|
#endif |
||||||
|
} |
||||||
|
init = 1; |
||||||
|
return EXIT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
@ -0,0 +1,186 @@ |
|||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. |
||||||
|
|
||||||
|
LICENSE TERMS |
||||||
|
|
||||||
|
The free distribution and use of this software in both source and binary |
||||||
|
form is allowed (with or without changes) provided that: |
||||||
|
|
||||||
|
1. distributions of this source code include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer; |
||||||
|
|
||||||
|
2. distributions in binary form include the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer |
||||||
|
in the documentation and/or other associated materials; |
||||||
|
|
||||||
|
3. the copyright holder's name is not used to endorse products |
||||||
|
built using this software without specific written permission. |
||||||
|
|
||||||
|
ALTERNATIVELY, provided that this notice is retained in full, this product |
||||||
|
may be distributed under the terms of the GNU General Public License (GPL), |
||||||
|
in which case the provisions of the GPL apply INSTEAD OF those given above. |
||||||
|
|
||||||
|
DISCLAIMER |
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties |
||||||
|
in respect of its properties, including, but not limited to, correctness |
||||||
|
and/or fitness for purpose. |
||||||
|
--------------------------------------------------------------------------- |
||||||
|
Issue 31/01/2006 |
||||||
|
|
||||||
|
This file contains the code for declaring the tables needed to implement |
||||||
|
AES. The file aesopt.h is assumed to be included before this header file. |
||||||
|
If there are no global variables, the definitions here can be used to put |
||||||
|
the AES tables in a structure so that a pointer can then be added to the |
||||||
|
AES context to pass them to the AES routines that need them. If this |
||||||
|
facility is used, the calling program has to ensure that this pointer is |
||||||
|
managed appropriately. In particular, the value of the t_dec(in,it) item |
||||||
|
in the table structure must be set to zero in order to ensure that the |
||||||
|
tables are initialised. In practice the three code sequences in aeskey.c |
||||||
|
that control the calls to gen_tabs() and the gen_tabs() routine itself will |
||||||
|
have to be changed for a specific implementation. If global variables are |
||||||
|
available it will generally be preferable to use them with the precomputed |
||||||
|
FIXED_TABLES option that uses static global tables. |
||||||
|
|
||||||
|
The following defines can be used to control the way the tables |
||||||
|
are defined, initialised and used in embedded environments that |
||||||
|
require special features for these purposes |
||||||
|
|
||||||
|
the 't_dec' construction is used to declare fixed table arrays |
||||||
|
the 't_set' construction is used to set fixed table values |
||||||
|
the 't_use' construction is used to access fixed table values |
||||||
|
|
||||||
|
256 byte tables: |
||||||
|
|
||||||
|
t_xxx(s,box) => forward S box |
||||||
|
t_xxx(i,box) => inverse S box |
||||||
|
|
||||||
|
256 32-bit word OR 4 x 256 32-bit word tables: |
||||||
|
|
||||||
|
t_xxx(f,n) => forward normal round |
||||||
|
t_xxx(f,l) => forward last round |
||||||
|
t_xxx(i,n) => inverse normal round |
||||||
|
t_xxx(i,l) => inverse last round |
||||||
|
t_xxx(l,s) => key schedule table |
||||||
|
t_xxx(i,m) => key schedule table |
||||||
|
|
||||||
|
Other variables and tables: |
||||||
|
|
||||||
|
t_xxx(r,c) => the rcon table |
||||||
|
*/ |
||||||
|
|
||||||
|
#if !defined( _AESTAB_H ) |
||||||
|
#define _AESTAB_H |
||||||
|
|
||||||
|
#define t_dec(m,n) t_##m##n |
||||||
|
#define t_set(m,n) t_##m##n |
||||||
|
#define t_use(m,n) t_##m##n |
||||||
|
|
||||||
|
#if defined(FIXED_TABLES) |
||||||
|
# if defined( __MSDOS__ ) || defined( __WIN16__ ) |
||||||
|
/* make tables far data to avoid using too much DGROUP space (PG) */ |
||||||
|
# define CONST const far |
||||||
|
# else |
||||||
|
# define CONST const |
||||||
|
# endif |
||||||
|
#else |
||||||
|
# define CONST |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(DO_TABLES) |
||||||
|
#define EXTERN |
||||||
|
#else |
||||||
|
#define EXTERN extern |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(TABLE_ALIGN) |
||||||
|
#define ALIGN __declspec(align(TABLE_ALIGN)) |
||||||
|
#else |
||||||
|
#define ALIGN |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
extern "C" |
||||||
|
{ |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( __WATCOMC__) |
||||||
|
# define XP_DIR __cdecl |
||||||
|
#else |
||||||
|
# define XP_DIR |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(DO_TABLES) && defined(FIXED_TABLES) |
||||||
|
#define d_1(t,n,b,e) ALIGN CONST XP_DIR t n[256] = b(e) |
||||||
|
#define d_4(t,n,b,e,f,g,h) ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) } |
||||||
|
EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0); |
||||||
|
#else |
||||||
|
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] |
||||||
|
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] |
||||||
|
EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH]; |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( SBX_SET ) |
||||||
|
d_1(uint_8t, t_dec(s,box), sb_data, h0); |
||||||
|
#endif |
||||||
|
#if defined( ISB_SET ) |
||||||
|
d_1(uint_8t, t_dec(i,box), isb_data, h0); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( FT1_SET ) |
||||||
|
d_1(uint_32t, t_dec(f,n), sb_data, u0); |
||||||
|
#endif |
||||||
|
#if defined( FT4_SET ) |
||||||
|
d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( FL1_SET ) |
||||||
|
d_1(uint_32t, t_dec(f,l), sb_data, w0); |
||||||
|
#endif |
||||||
|
#if defined( FL4_SET ) |
||||||
|
d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( IT1_SET ) |
||||||
|
d_1(uint_32t, t_dec(i,n), isb_data, v0); |
||||||
|
#endif |
||||||
|
#if defined( IT4_SET ) |
||||||
|
d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( IL1_SET ) |
||||||
|
d_1(uint_32t, t_dec(i,l), isb_data, w0); |
||||||
|
#endif |
||||||
|
#if defined( IL4_SET ) |
||||||
|
d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( LS1_SET ) |
||||||
|
#if defined( FL1_SET ) |
||||||
|
#undef LS1_SET |
||||||
|
#else |
||||||
|
d_1(uint_32t, t_dec(l,s), sb_data, w0); |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( LS4_SET ) |
||||||
|
#if defined( FL4_SET ) |
||||||
|
#undef LS4_SET |
||||||
|
#else |
||||||
|
d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3); |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined( IM1_SET ) |
||||||
|
d_1(uint_32t, t_dec(i,m), mm_data, v0); |
||||||
|
#endif |
||||||
|
#if defined( IM4_SET ) |
||||||
|
d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(__cplusplus) |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -1,541 +0,0 @@ |
|||||||
/* 2003.05.02: Derived from libgcrypt-1.1.12 by Michael Buesch */ |
|
||||||
|
|
||||||
/* blowfish.c - Blowfish encryption
|
|
||||||
* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. |
|
||||||
* |
|
||||||
* This file is part of Libgcrypt. |
|
||||||
* |
|
||||||
* Libgcrypt is free software; you can redistribute it and/or modify |
|
||||||
* it under the terms of the GNU Lesser general Public License as |
|
||||||
* published by the Free Software Foundation; either version 2.1 of |
|
||||||
* the License, or (at your option) any later version. |
|
||||||
* |
|
||||||
* Libgcrypt 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 Lesser General Public License for more details. |
|
||||||
* |
|
||||||
* You should have received a copy of the GNU Lesser General Public |
|
||||||
* License along with this program; if not, write to the Free Software |
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
|
||||||
* |
|
||||||
* For a description of the algorithm, see: |
|
||||||
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. |
|
||||||
* ISBN 0-471-11709-9. Pages 336 ff. |
|
||||||
*/ |
|
||||||
|
|
||||||
/* Test values:
|
|
||||||
* key "abcdefghijklmnopqrstuvwxyz"; |
|
||||||
* plain "BLOWFISH" |
|
||||||
* cipher 32 4E D0 FE F4 13 A2 03 |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <string.h> |
|
||||||
#include <stdlib.h> |
|
||||||
|
|
||||||
#include "blowfish.h" |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* precomputed S boxes */ |
|
||||||
static const uint32_t ks0[256] = { |
|
||||||
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, |
|
||||||
0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, |
|
||||||
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, |
|
||||||
0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, |
|
||||||
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, |
|
||||||
0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, |
|
||||||
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, |
|
||||||
0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, |
|
||||||
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, |
|
||||||
0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, |
|
||||||
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, |
|
||||||
0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, |
|
||||||
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, |
|
||||||
0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, |
|
||||||
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, |
|
||||||
0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, |
|
||||||
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, |
|
||||||
0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, |
|
||||||
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, |
|
||||||
0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, |
|
||||||
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, |
|
||||||
0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, |
|
||||||
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, |
|
||||||
0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, |
|
||||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, |
|
||||||
0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, |
|
||||||
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, |
|
||||||
0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, |
|
||||||
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, |
|
||||||
0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, |
|
||||||
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, |
|
||||||
0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, |
|
||||||
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, |
|
||||||
0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, |
|
||||||
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, |
|
||||||
0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, |
|
||||||
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, |
|
||||||
0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, |
|
||||||
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, |
|
||||||
0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, |
|
||||||
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, |
|
||||||
0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, |
|
||||||
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A |
|
||||||
}; |
|
||||||
|
|
||||||
static const uint32_t ks1[256] = { |
|
||||||
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, |
|
||||||
0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, |
|
||||||
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, |
|
||||||
0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, |
|
||||||
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, |
|
||||||
0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, |
|
||||||
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, |
|
||||||
0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, |
|
||||||
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, |
|
||||||
0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, |
|
||||||
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, |
|
||||||
0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, |
|
||||||
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, |
|
||||||
0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, |
|
||||||
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, |
|
||||||
0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, |
|
||||||
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, |
|
||||||
0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, |
|
||||||
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, |
|
||||||
0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, |
|
||||||
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, |
|
||||||
0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, |
|
||||||
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, |
|
||||||
0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, |
|
||||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, |
|
||||||
0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, |
|
||||||
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, |
|
||||||
0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, |
|
||||||
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, |
|
||||||
0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, |
|
||||||
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, |
|
||||||
0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, |
|
||||||
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, |
|
||||||
0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, |
|
||||||
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, |
|
||||||
0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, |
|
||||||
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, |
|
||||||
0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, |
|
||||||
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, |
|
||||||
0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, |
|
||||||
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, |
|
||||||
0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, |
|
||||||
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 |
|
||||||
}; |
|
||||||
|
|
||||||
static const uint32_t ks2[256] = { |
|
||||||
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, |
|
||||||
0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, |
|
||||||
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, |
|
||||||
0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, |
|
||||||
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, |
|
||||||
0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, |
|
||||||
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, |
|
||||||
0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, |
|
||||||
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, |
|
||||||
0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, |
|
||||||
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, |
|
||||||
0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, |
|
||||||
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, |
|
||||||
0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, |
|
||||||
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, |
|
||||||
0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, |
|
||||||
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, |
|
||||||
0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, |
|
||||||
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, |
|
||||||
0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, |
|
||||||
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, |
|
||||||
0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, |
|
||||||
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, |
|
||||||
0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, |
|
||||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, |
|
||||||
0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, |
|
||||||
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, |
|
||||||
0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, |
|
||||||
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, |
|
||||||
0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, |
|
||||||
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, |
|
||||||
0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, |
|
||||||
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, |
|
||||||
0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, |
|
||||||
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, |
|
||||||
0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, |
|
||||||
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, |
|
||||||
0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, |
|
||||||
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, |
|
||||||
0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, |
|
||||||
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, |
|
||||||
0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, |
|
||||||
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 |
|
||||||
}; |
|
||||||
|
|
||||||
static const uint32_t ks3[256] = { |
|
||||||
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, |
|
||||||
0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, |
|
||||||
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, |
|
||||||
0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, |
|
||||||
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, |
|
||||||
0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, |
|
||||||
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, |
|
||||||
0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, |
|
||||||
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, |
|
||||||
0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, |
|
||||||
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, |
|
||||||
0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, |
|
||||||
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, |
|
||||||
0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, |
|
||||||
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, |
|
||||||
0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, |
|
||||||
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, |
|
||||||
0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, |
|
||||||
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, |
|
||||||
0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, |
|
||||||
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, |
|
||||||
0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, |
|
||||||
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, |
|
||||||
0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, |
|
||||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, |
|
||||||
0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, |
|
||||||
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, |
|
||||||
0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, |
|
||||||
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, |
|
||||||
0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, |
|
||||||
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, |
|
||||||
0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, |
|
||||||
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, |
|
||||||
0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, |
|
||||||
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, |
|
||||||
0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, |
|
||||||
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, |
|
||||||
0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, |
|
||||||
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, |
|
||||||
0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, |
|
||||||
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, |
|
||||||
0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, |
|
||||||
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 |
|
||||||
}; |
|
||||||
|
|
||||||
static const uint32_t ps[BLOWFISH_ROUNDS + 2] = { |
|
||||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, |
|
||||||
0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, |
|
||||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B |
|
||||||
}; |
|
||||||
|
|
||||||
Blowfish::Blowfish() |
|
||||||
{ static bool mustSelfTest = false; |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::burn_stack(int bytes) |
|
||||||
{ |
|
||||||
char buf[64]; |
|
||||||
|
|
||||||
memset(buf, 0, sizeof buf); |
|
||||||
bytes -= sizeof buf; |
|
||||||
if (bytes > 0) |
|
||||||
burn_stack(bytes); |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::do_encrypt(uint32_t * ret_xl, uint32_t * ret_xr) |
|
||||||
{ |
|
||||||
#if BLOWFISH_ROUNDS == 16 |
|
||||||
uint32_t xl, xr, *s0, *s1, *s2, *s3, *p; |
|
||||||
|
|
||||||
xl = *ret_xl; |
|
||||||
xr = *ret_xr; |
|
||||||
p = bc.p; |
|
||||||
s0 = bc.s0; |
|
||||||
s1 = bc.s1; |
|
||||||
s2 = bc.s2; |
|
||||||
s3 = bc.s3; |
|
||||||
|
|
||||||
R(xl, xr, 0, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 1, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 2, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 3, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 4, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 5, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 6, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 7, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 8, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 9, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 10, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 11, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 12, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 13, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 14, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 15, p, s0, s1, s2, s3); |
|
||||||
|
|
||||||
xl ^= p[BLOWFISH_ROUNDS]; |
|
||||||
xr ^= p[BLOWFISH_ROUNDS + 1]; |
|
||||||
|
|
||||||
*ret_xl = xr; |
|
||||||
*ret_xr = xl; |
|
||||||
|
|
||||||
#else |
|
||||||
uint32_t xl, xr, temp, *p; |
|
||||||
int i; |
|
||||||
|
|
||||||
xl = *ret_xl; |
|
||||||
xr = *ret_xr; |
|
||||||
p = bc.p; |
|
||||||
|
|
||||||
for (i = 0; i < BLOWFISH_ROUNDS; i++) { |
|
||||||
xl ^= p[i]; |
|
||||||
xr ^= function_F(xl); |
|
||||||
temp = xl; |
|
||||||
xl = xr; |
|
||||||
xr = temp; |
|
||||||
} |
|
||||||
temp = xl; |
|
||||||
xl = xr; |
|
||||||
xr = temp; |
|
||||||
|
|
||||||
xr ^= p[BLOWFISH_ROUNDS]; |
|
||||||
xl ^= p[BLOWFISH_ROUNDS + 1]; |
|
||||||
|
|
||||||
*ret_xl = xl; |
|
||||||
*ret_xr = xr; |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::do_decrypt(uint32_t * ret_xl, uint32_t * ret_xr) |
|
||||||
{ |
|
||||||
#if BLOWFISH_ROUNDS == 16 |
|
||||||
uint32_t xl, xr, *s0, *s1, *s2, *s3, *p; |
|
||||||
|
|
||||||
xl = *ret_xl; |
|
||||||
xr = *ret_xr; |
|
||||||
p = bc.p; |
|
||||||
s0 = bc.s0; |
|
||||||
s1 = bc.s1; |
|
||||||
s2 = bc.s2; |
|
||||||
s3 = bc.s3; |
|
||||||
|
|
||||||
R(xl, xr, 17, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 16, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 15, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 14, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 13, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 12, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 11, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 10, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 9, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 8, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 7, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 6, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 5, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 4, p, s0, s1, s2, s3); |
|
||||||
R(xl, xr, 3, p, s0, s1, s2, s3); |
|
||||||
R(xr, xl, 2, p, s0, s1, s2, s3); |
|
||||||
|
|
||||||
xl ^= p[1]; |
|
||||||
xr ^= p[0]; |
|
||||||
|
|
||||||
*ret_xl = xr; |
|
||||||
*ret_xr = xl; |
|
||||||
|
|
||||||
#else |
|
||||||
uint32_t xl, xr, temp, *p; |
|
||||||
int i; |
|
||||||
|
|
||||||
xl = *ret_xl; |
|
||||||
xr = *ret_xr; |
|
||||||
p = bc.p; |
|
||||||
|
|
||||||
for (i = BLOWFISH_ROUNDS + 1; i > 1; i--) { |
|
||||||
xl ^= p[i]; |
|
||||||
xr ^= function_F(xl); |
|
||||||
temp = xl; |
|
||||||
xl = xr; |
|
||||||
xr = temp; |
|
||||||
} |
|
||||||
|
|
||||||
temp = xl; |
|
||||||
xl = xr; |
|
||||||
xr = temp; |
|
||||||
|
|
||||||
xr ^= p[1]; |
|
||||||
xl ^= p[0]; |
|
||||||
|
|
||||||
*ret_xl = xl; |
|
||||||
*ret_xr = xr; |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::do_encrypt_block(byte * outbuf, byte * inbuf) |
|
||||||
{ |
|
||||||
uint32_t d1, d2; |
|
||||||
|
|
||||||
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; |
|
||||||
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; |
|
||||||
do_encrypt(&d1, &d2); |
|
||||||
outbuf[0] = (d1 >> 24) & 0xff; |
|
||||||
outbuf[1] = (d1 >> 16) & 0xff; |
|
||||||
outbuf[2] = (d1 >> 8) & 0xff; |
|
||||||
outbuf[3] = d1 & 0xff; |
|
||||||
outbuf[4] = (d2 >> 24) & 0xff; |
|
||||||
outbuf[5] = (d2 >> 16) & 0xff; |
|
||||||
outbuf[6] = (d2 >> 8) & 0xff; |
|
||||||
outbuf[7] = d2 & 0xff; |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::encrypt_block(byte * outbuf, byte * inbuf) |
|
||||||
{ |
|
||||||
do_encrypt_block(outbuf, inbuf); |
|
||||||
burn_stack(64); |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::do_decrypt_block(byte * outbuf, byte * inbuf) |
|
||||||
{ |
|
||||||
uint32_t d1, d2; |
|
||||||
|
|
||||||
d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; |
|
||||||
d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; |
|
||||||
do_decrypt(&d1, &d2); |
|
||||||
outbuf[0] = (d1 >> 24) & 0xff; |
|
||||||
outbuf[1] = (d1 >> 16) & 0xff; |
|
||||||
outbuf[2] = (d1 >> 8) & 0xff; |
|
||||||
outbuf[3] = d1 & 0xff; |
|
||||||
outbuf[4] = (d2 >> 24) & 0xff; |
|
||||||
outbuf[5] = (d2 >> 16) & 0xff; |
|
||||||
outbuf[6] = (d2 >> 8) & 0xff; |
|
||||||
outbuf[7] = d2 & 0xff; |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::decrypt_block(byte * outbuf, byte * inbuf) |
|
||||||
{ |
|
||||||
do_decrypt_block(outbuf, inbuf); |
|
||||||
burn_stack(64); |
|
||||||
} |
|
||||||
|
|
||||||
int Blowfish::do_bf_setkey(byte * key, unsigned int keylen) |
|
||||||
{ |
|
||||||
int i, j; |
|
||||||
uint32_t data, datal, datar; |
|
||||||
|
|
||||||
for (i = 0; i < BLOWFISH_ROUNDS + 2; ++i) |
|
||||||
bc.p[i] = ps[i]; |
|
||||||
for (i = 0; i < 256; ++i) { |
|
||||||
bc.s0[i] = ks0[i]; |
|
||||||
bc.s1[i] = ks1[i]; |
|
||||||
bc.s2[i] = ks2[i]; |
|
||||||
bc.s3[i] = ks3[i]; |
|
||||||
} |
|
||||||
|
|
||||||
for (i = j = 0; i < BLOWFISH_ROUNDS + 2; ++i) { |
|
||||||
#ifdef KEEPASS_BIG_ENDIAN |
|
||||||
((byte *) & data)[0] = key[j]; |
|
||||||
((byte *) & data)[1] = key[(j + 1) % keylen]; |
|
||||||
((byte *) & data)[2] = key[(j + 2) % keylen]; |
|
||||||
((byte *) & data)[3] = key[(j + 3) % keylen]; |
|
||||||
#else |
|
||||||
((byte *) & data)[3] = key[j]; |
|
||||||
((byte *) & data)[2] = key[(j + 1) % keylen]; |
|
||||||
((byte *) & data)[1] = key[(j + 2) % keylen]; |
|
||||||
((byte *) & data)[0] = key[(j + 3) % keylen]; |
|
||||||
#endif |
|
||||||
bc.p[i] ^= data; |
|
||||||
j = (j + 4) % keylen; |
|
||||||
} |
|
||||||
|
|
||||||
datal = datar = 0; |
|
||||||
for (i = 0; i < BLOWFISH_ROUNDS + 2; i += 2) { |
|
||||||
do_encrypt(&datal, &datar); |
|
||||||
bc.p[i] = datal; |
|
||||||
bc.p[i + 1] = datar; |
|
||||||
} |
|
||||||
for (i = 0; i < 256; i += 2) { |
|
||||||
do_encrypt(&datal, &datar); |
|
||||||
bc.s0[i] = datal; |
|
||||||
bc.s0[i + 1] = datar; |
|
||||||
} |
|
||||||
for (i = 0; i < 256; i += 2) { |
|
||||||
do_encrypt(&datal, &datar); |
|
||||||
bc.s1[i] = datal; |
|
||||||
bc.s1[i + 1] = datar; |
|
||||||
} |
|
||||||
for (i = 0; i < 256; i += 2) { |
|
||||||
do_encrypt(&datal, &datar); |
|
||||||
bc.s2[i] = datal; |
|
||||||
bc.s2[i + 1] = datar; |
|
||||||
} |
|
||||||
for (i = 0; i < 256; i += 2) { |
|
||||||
do_encrypt(&datal, &datar); |
|
||||||
bc.s3[i] = datal; |
|
||||||
bc.s3[i + 1] = datar; |
|
||||||
} |
|
||||||
|
|
||||||
/* Check for weak key. A weak key is a key in which a value in */ |
|
||||||
/* the P-array (here c) occurs more than once per table. */ |
|
||||||
for (i = 0; i < 255; ++i) { |
|
||||||
for (j = i + 1; j < 256; ++j) { |
|
||||||
if ((bc.s0[i] == bc.s0[j]) || (bc.s1[i] == bc.s1[j]) || |
|
||||||
(bc.s2[i] == bc.s2[j]) || (bc.s3[i] == bc.s3[j])) |
|
||||||
return 1; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int Blowfish::bf_setkey(byte * key, unsigned int keylen) |
|
||||||
{ |
|
||||||
int rc = do_bf_setkey(key, keylen); |
|
||||||
burn_stack(64); |
|
||||||
return rc; |
|
||||||
} |
|
||||||
|
|
||||||
int Blowfish::bf_encrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len) |
|
||||||
{ |
|
||||||
if (inbuf_len % 8) |
|
||||||
return 1; |
|
||||||
|
|
||||||
unsigned int i = 0; |
|
||||||
while (i < inbuf_len) { |
|
||||||
encrypt_block(outbuf + i, inbuf + i); |
|
||||||
i += 8; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int Blowfish::bf_decrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len) |
|
||||||
{ |
|
||||||
if (inbuf_len % 8) |
|
||||||
return 1; |
|
||||||
|
|
||||||
unsigned int i = 0; |
|
||||||
while (i < inbuf_len) { |
|
||||||
decrypt_block(outbuf + i, inbuf + i); |
|
||||||
i += 8; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
void Blowfish::padNull(string *buf) |
|
||||||
{ |
|
||||||
buf->append(1, (char)0x01); |
|
||||||
string::size_type append_null = 8 - (buf->length() % 8); |
|
||||||
buf->append(append_null, (char)0x00); |
|
||||||
} |
|
||||||
|
|
||||||
bool Blowfish::unpadNull(string *buf) |
|
||||||
{ |
|
||||||
if (buf->size() % 8) |
|
||||||
return false; |
|
||||||
string::size_type pos = buf->length() - 1; |
|
||||||
while ((*buf)[pos] != (char)0x01) { |
|
||||||
if (pos == 0) |
|
||||||
return false; |
|
||||||
--pos; |
|
||||||
} |
|
||||||
buf->erase(pos, buf->length() - pos); |
|
||||||
return true; |
|
||||||
} |
|
@ -1,115 +0,0 @@ |
|||||||
/***************************************************************************
|
|
||||||
* * |
|
||||||
* copyright (C) 2003, 2004 by Michael Buesch * |
|
||||||
* email: mbuesch@freenet.de * |
|
||||||
* * |
|
||||||
* blowfish.c - Blowfish encryption * |
|
||||||
* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. * |
|
||||||
* * |
|
||||||
* This program is free software; you can redistribute it and/or modify * |
|
||||||
* it under the terms of the GNU General Public License version 2 * |
|
||||||
* as published by the Free Software Foundation. * |
|
||||||
* * |
|
||||||
***************************************************************************/ |
|
||||||
|
|
||||||
#ifndef BLOWFISH_H |
|
||||||
#define BLOWFISH_H |
|
||||||
|
|
||||||
#include "global.h" |
|
||||||
#include <qglobal.h> |
|
||||||
//#include <stdint.h>
|
|
||||||
#include <string> |
|
||||||
using std::string; |
|
||||||
|
|
||||||
#define BLOWFISH_BLOCKSIZE 8 |
|
||||||
#define BLOWFISH_ROUNDS 16 |
|
||||||
#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */ |
|
||||||
|
|
||||||
#define uint8_t quint8 |
|
||||||
#define uint16_t quint16 |
|
||||||
#define uint32_t quint32 |
|
||||||
#define byte quint8 |
|
||||||
|
|
||||||
/** blowfish encryption algorithm.
|
|
||||||
* Derived from libgcrypt-1.1.12 |
|
||||||
*/ |
|
||||||
|
|
||||||
class Blowfish |
|
||||||
{ |
|
||||||
struct BLOWFISH_context |
|
||||||
{ |
|
||||||
uint32_t s0[256]; |
|
||||||
uint32_t s1[256]; |
|
||||||
uint32_t s2[256]; |
|
||||||
uint32_t s3[256]; |
|
||||||
uint32_t p[BLOWFISH_ROUNDS+2]; |
|
||||||
}; |
|
||||||
|
|
||||||
public: |
|
||||||
Blowfish(); |
|
||||||
|
|
||||||
/** set key to encrypt. if return == 1, it is a weak key. */ |
|
||||||
int bf_setkey( byte *key, unsigned int keylen ); |
|
||||||
/** encrypt inbuf and return it in outbuf.
|
|
||||||
* inbuf and outbuf have to be: buf % 8 == 0 |
|
||||||
* You may check this with getPaddedLen() and pad with NULL. |
|
||||||
*/ |
|
||||||
int bf_encrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len ); |
|
||||||
/** decrypt inbuf and return it in outbuf.
|
|
||||||
* inbuf and outbuf have to be: buf % 8 == 0 |
|
||||||
* You may check this with getPaddedLen() and pad with NULL. |
|
||||||
*/ |
|
||||||
int bf_decrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len ); |
|
||||||
/** returns the length, the sting has to be padded to */ |
|
||||||
static unsigned int getPaddedLen(unsigned int inLen) |
|
||||||
{ return ((8 - (inLen % 8)) + inLen); } |
|
||||||
/** pad up to 8 bytes. */ |
|
||||||
static void padNull(string *buf); |
|
||||||
/** remove padded data */ |
|
||||||
static bool unpadNull(string *buf); |
|
||||||
|
|
||||||
protected: |
|
||||||
#if BLOWFISH_ROUNDS != 16 |
|
||||||
uint32_t function_F( uint32_t x) |
|
||||||
{ |
|
||||||
uint16_t a, b, c, d; |
|
||||||
#ifdef KEEPASS_BIG_ENDIAN |
|
||||||
a = ((byte *) & x)[0]; |
|
||||||
b = ((byte *) & x)[1]; |
|
||||||
c = ((byte *) & x)[2]; |
|
||||||
d = ((byte *) & x)[3]; |
|
||||||
#else |
|
||||||
a = ((byte *) & x)[3]; |
|
||||||
b = ((byte *) & x)[2]; |
|
||||||
c = ((byte *) & x)[1]; |
|
||||||
d = ((byte *) & x)[0]; |
|
||||||
#endif |
|
||||||
return ((bc.s0[a] + bc.s1[b]) ^ bc.s2[c]) + bc.s3[d]; |
|
||||||
} |
|
||||||
#endif |
|
||||||
void R(uint32_t &l, uint32_t &r, uint32_t i, uint32_t *p, |
|
||||||
uint32_t *s0, uint32_t *s1, uint32_t *s2, uint32_t *s3) |
|
||||||
{ |
|
||||||
l ^= p[i]; |
|
||||||
#ifdef KEEPASS_BIG_ENDIAN |
|
||||||
r ^= (( s0[((byte*)&l)[0]] + s1[((byte*)&l)[1]]) |
|
||||||
^ s2[((byte*)&l)[2]]) + s3[((byte*)&l)[3]]; |
|
||||||
#else |
|
||||||
r ^= (( s0[((byte*)&l)[3]] + s1[((byte*)&l)[2]]) |
|
||||||
^ s2[((byte*)&l)[1]]) + s3[((byte*)&l)[0]]; |
|
||||||
#endif |
|
||||||
} |
|
||||||
void encrypt_block(byte *outbuf, byte *inbuf); |
|
||||||
void decrypt_block(byte *outbuf, byte *inbuf); |
|
||||||
void burn_stack(int bytes); |
|
||||||
void do_encrypt(uint32_t *ret_xl, uint32_t *ret_xr); |
|
||||||
void do_decrypt(uint32_t *ret_xl, uint32_t *ret_xr); |
|
||||||
void do_encrypt_block(byte *outbuf, byte *inbuf); |
|
||||||
void do_decrypt_block(byte *outbuf, byte *inbuf); |
|
||||||
int do_bf_setkey(byte *key, unsigned int keylen); |
|
||||||
|
|
||||||
protected: |
|
||||||
struct BLOWFISH_context bc; |
|
||||||
}; |
|
||||||
|
|
||||||
#endif |
|
File diff suppressed because it is too large
Load Diff
@ -1,158 +0,0 @@ |
|||||||
#ifndef _RIJNDAEL_H_ |
|
||||||
#define _RIJNDAEL_H_ |
|
||||||
|
|
||||||
// This file is based on Szymon Stefanek's Rijndael implementation.
|
|
||||||
// All I have done is changed the variable type definitions, not more.
|
|
||||||
// The original header is below.
|
|
||||||
|
|
||||||
//
|
|
||||||
// File : rijndael.h
|
|
||||||
// Creation date : Sun Nov 5 2000 03:21:05 CEST
|
|
||||||
// Author : Szymon Stefanek (stefanek@tin.it)
|
|
||||||
//
|
|
||||||
// Another implementation of the Rijndael cipher.
|
|
||||||
// This is intended to be an easily usable library file.
|
|
||||||
// This code is public domain.
|
|
||||||
// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Original Copyright notice:
|
|
||||||
//
|
|
||||||
// rijndael-alg-fst.c v2.4 April '2000
|
|
||||||
// rijndael-alg-fst.h
|
|
||||||
// rijndael-api-fst.c
|
|
||||||
// rijndael-api-fst.h
|
|
||||||
//
|
|
||||||
// Optimised ANSI C code
|
|
||||||
//
|
|
||||||
// authors: v1.0: Antoon Bosselaers
|
|
||||||
// v2.0: Vincent Rijmen, K.U.Leuven
|
|
||||||
// v2.3: Paulo Barreto
|
|
||||||
// v2.4: Vincent Rijmen, K.U.Leuven
|
|
||||||
//
|
|
||||||
// This code is placed in the public domain.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// This implementation works on 128 , 192 , 256 bit keys
|
|
||||||
// and on 128 bit blocks
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Example of usage:
|
|
||||||
//
|
|
||||||
// // Input data
|
|
||||||
// unsigned char key[32]; // The key
|
|
||||||
// initializeYour256BitKey(); // Obviously initialized with sth
|
|
||||||
// const unsigned char * plainText = getYourPlainText(); // Your plain text
|
|
||||||
// int plainTextLen = strlen(plainText); // Plain text length
|
|
||||||
//
|
|
||||||
// // Encrypting
|
|
||||||
// Rijndael rin;
|
|
||||||
// unsigned char output[plainTextLen + 16];
|
|
||||||
//
|
|
||||||
// rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes);
|
|
||||||
// // It is a good idea to check the error code
|
|
||||||
// int len = rin.padEncrypt(plainText,len,output);
|
|
||||||
// if(len >= 0)useYourEncryptedText();
|
|
||||||
// else encryptError(len);
|
|
||||||
//
|
|
||||||
// // Decrypting: we can reuse the same object
|
|
||||||
// unsigned char output2[len];
|
|
||||||
// rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes));
|
|
||||||
// len = rin.padDecrypt(output,len,output2);
|
|
||||||
// if(len >= 0)useYourDecryptedText();
|
|
||||||
// else decryptError(len);
|
|
||||||
//
|
|
||||||
|
|
||||||
#define _MAX_KEY_COLUMNS (256/32) |
|
||||||
#define _MAX_ROUNDS 14 |
|
||||||
#define MAX_IV_SIZE 16 |
|
||||||
|
|
||||||
#include <qglobal.h> |
|
||||||
|
|
||||||
// Error codes
|
|
||||||
#define RIJNDAEL_SUCCESS 0 |
|
||||||
#define RIJNDAEL_UNSUPPORTED_MODE -1 |
|
||||||
#define RIJNDAEL_UNSUPPORTED_DIRECTION -2 |
|
||||||
#define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3 |
|
||||||
#define RIJNDAEL_BAD_KEY -4 |
|
||||||
#define RIJNDAEL_NOT_INITIALIZED -5 |
|
||||||
#define RIJNDAEL_BAD_DIRECTION -6 |
|
||||||
#define RIJNDAEL_CORRUPTED_DATA -7 |
|
||||||
|
|
||||||
class Rijndael |
|
||||||
{
|
|
||||||
public: |
|
||||||
enum Direction { Encrypt , Decrypt }; |
|
||||||
enum Mode { ECB , CBC , CFB1 }; |
|
||||||
enum KeyLength { Key16Bytes , Key24Bytes , Key32Bytes }; |
|
||||||
//
|
|
||||||
// Creates a Rijndael cipher object
|
|
||||||
// You have to call init() before you can encrypt or decrypt stuff
|
|
||||||
//
|
|
||||||
Rijndael(); |
|
||||||
~Rijndael(); |
|
||||||
protected: |
|
||||||
// Internal stuff
|
|
||||||
enum State { Valid , Invalid }; |
|
||||||
|
|
||||||
State m_state; |
|
||||||
Mode m_mode; |
|
||||||
Direction m_direction; |
|
||||||
quint8 m_initVector[MAX_IV_SIZE]; |
|
||||||
quint32 m_uRounds; |
|
||||||
quint8 m_expandedKey[_MAX_ROUNDS+1][4][4]; |
|
||||||
public: |
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// API
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// init(): Initializes the crypt session
|
|
||||||
// Returns RIJNDAEL_SUCCESS or an error code
|
|
||||||
// mode : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1
|
|
||||||
// You have to use the same mode for encrypting and decrypting
|
|
||||||
// dir : Rijndael::Encrypt or Rijndael::Decrypt
|
|
||||||
// A cipher instance works only in one direction
|
|
||||||
// (Well , it could be easily modified to work in both
|
|
||||||
// directions with a single init() call, but it looks
|
|
||||||
// useless to me...anyway , it is a matter of generating
|
|
||||||
// two expanded keys)
|
|
||||||
// key : array of unsigned octets , it can be 16 , 24 or 32 bytes long
|
|
||||||
// this CAN be binary data (it is not expected to be null terminated)
|
|
||||||
// keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes
|
|
||||||
// initVector: initialization vector, you will usually use 0 here
|
|
||||||
int init(Mode mode,Direction dir,const quint8 *key,KeyLength keyLen,quint8 * initVector = 0); |
|
||||||
// Encrypts the input array (can be binary data)
|
|
||||||
// The input array length must be a multiple of 16 bytes, the remaining part
|
|
||||||
// is DISCARDED.
|
|
||||||
// so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer
|
|
||||||
// Input len is in BITS!
|
|
||||||
// outBuffer must be at least inputLen / 8 bytes long.
|
|
||||||
// Returns the encrypted buffer length in BITS or an error code < 0 in case of error
|
|
||||||
int blockEncrypt(const quint8 *input, int inputLen, quint8 *outBuffer); |
|
||||||
// Encrypts the input array (can be binary data)
|
|
||||||
// The input array can be any length , it is automatically padded on a 16 byte boundary.
|
|
||||||
// Input len is in BYTES!
|
|
||||||
// outBuffer must be at least (inputLen + 16) bytes long
|
|
||||||
// Returns the encrypted buffer length in BYTES or an error code < 0 in case of error
|
|
||||||
int padEncrypt(const quint8 *input, int inputOctets, quint8 *outBuffer); |
|
||||||
// Decrypts the input vector
|
|
||||||
// Input len is in BITS!
|
|
||||||
// outBuffer must be at least inputLen / 8 bytes long
|
|
||||||
// Returns the decrypted buffer length in BITS and an error code < 0 in case of error
|
|
||||||
int blockDecrypt(const quint8 *input, int inputLen, quint8 *outBuffer); |
|
||||||
// Decrypts the input vector
|
|
||||||
// Input len is in BYTES!
|
|
||||||
// outBuffer must be at least inputLen bytes long
|
|
||||||
// Returns the decrypted buffer length in BYTES and an error code < 0 in case of error
|
|
||||||
int padDecrypt(const quint8 *input, int inputOctets, quint8 *outBuffer); |
|
||||||
protected: |
|
||||||
void keySched(quint8 key[_MAX_KEY_COLUMNS][4]); |
|
||||||
void keyEncToDec(); |
|
||||||
void encrypt(const quint8 a[16], quint8 b[16]); |
|
||||||
void decrypt(const quint8 a[16], quint8 b[16]); |
|
||||||
}; |
|
||||||
|
|
||||||
#endif // _RIJNDAEL_H_
|
|
@ -1,257 +0,0 @@ |
|||||||
/*
|
|
||||||
100% free public domain implementation of the SHA-1 algorithm |
|
||||||
by Dominik Reichl <dominik.reichl@t-online.de> |
|
||||||
|
|
||||||
Version 1.5 - 2005-01-01 |
|
||||||
- 64-bit compiler compatibility added |
|
||||||
- Made variable wiping optional (define SHA1_WIPE_VARIABLES) |
|
||||||
- Removed unnecessary variable initializations |
|
||||||
- ROL32 improvement for the Microsoft compiler (using _rotl) |
|
||||||
|
|
||||||
======== Test Vectors (from FIPS PUB 180-1) ======== |
|
||||||
|
|
||||||
SHA1("abc") = |
|
||||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D |
|
||||||
|
|
||||||
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = |
|
||||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 |
|
||||||
|
|
||||||
SHA1(A million repetitions of "a") = |
|
||||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F |
|
||||||
*/ |
|
||||||
#include "global.h" |
|
||||||
#include "sha1.h" |
|
||||||
|
|
||||||
#define SHA1_MAX_FILE_BUFFER 8000 |
|
||||||
|
|
||||||
// Rotate x bits to the left
|
|
||||||
#ifndef ROL32 |
|
||||||
#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits)))) |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifdef KEEPASS_LITTLE_ENDIAN |
|
||||||
#define SHABLK0(i) (m_block->l[i] = \ |
|
||||||
(ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)) |
|
||||||
#else |
|
||||||
#define SHABLK0(i) (m_block->l[i]) |
|
||||||
#endif |
|
||||||
|
|
||||||
#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \ |
|
||||||
^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) |
|
||||||
|
|
||||||
// SHA-1 rounds
|
|
||||||
#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); } |
|
||||||
#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); } |
|
||||||
#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); } |
|
||||||
#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); } |
|
||||||
#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); } |
|
||||||
|
|
||||||
CSHA1::CSHA1() |
|
||||||
{ |
|
||||||
m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace; |
|
||||||
|
|
||||||
Reset(); |
|
||||||
} |
|
||||||
|
|
||||||
CSHA1::~CSHA1() |
|
||||||
{ |
|
||||||
Reset(); |
|
||||||
} |
|
||||||
|
|
||||||
void CSHA1::Reset() |
|
||||||
{ |
|
||||||
// SHA1 initialization constants
|
|
||||||
m_state[0] = 0x67452301; |
|
||||||
m_state[1] = 0xEFCDAB89; |
|
||||||
m_state[2] = 0x98BADCFE; |
|
||||||
m_state[3] = 0x10325476; |
|
||||||
m_state[4] = 0xC3D2E1F0; |
|
||||||
|
|
||||||
m_count[0] = 0; |
|
||||||
m_count[1] = 0; |
|
||||||
} |
|
||||||
void CSHA1::Update(unsigned char* data, int len){ |
|
||||||
|
|
||||||
quint_32 i, j; |
|
||||||
|
|
||||||
j = (m_count[0] >> 3) & 63; |
|
||||||
|
|
||||||
if((m_count[0] += len << 3) < (len << 3)) m_count[1]++; |
|
||||||
|
|
||||||
m_count[1] += (len >> 29); |
|
||||||
|
|
||||||
if((j + len) > 63) |
|
||||||
{ |
|
||||||
i = 64 - j; |
|
||||||
memcpy(&m_buffer[j], data, i); |
|
||||||
Transform(m_state, m_buffer); |
|
||||||
|
|
||||||
for( ; i + 63 < len; i += 64) Transform(m_state, &data[i]); |
|
||||||
|
|
||||||
j = 0; |
|
||||||
} |
|
||||||
else i = 0; |
|
||||||
|
|
||||||
memcpy(&m_buffer[j], &data[i], len - i); |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
void CSHA1::Transform(quint_32 *state, quint_8 *buffer) |
|
||||||
{ |
|
||||||
// Copy state[] to working vars
|
|
||||||
quint_32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4]; |
|
||||||
|
|
||||||
memcpy(m_block, buffer, 64); |
|
||||||
|
|
||||||
// 4 rounds of 20 operations each. Loop unrolled.
|
|
||||||
_R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3); |
|
||||||
_R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7); |
|
||||||
_R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11); |
|
||||||
_R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15); |
|
||||||
_R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19); |
|
||||||
_R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23); |
|
||||||
_R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27); |
|
||||||
_R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31); |
|
||||||
_R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35); |
|
||||||
_R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39); |
|
||||||
_R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43); |
|
||||||
_R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47); |
|
||||||
_R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51); |
|
||||||
_R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55); |
|
||||||
_R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59); |
|
||||||
_R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63); |
|
||||||
_R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67); |
|
||||||
_R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71); |
|
||||||
_R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75); |
|
||||||
_R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79); |
|
||||||
|
|
||||||
// Add the working vars back into state
|
|
||||||
state[0] += a; |
|
||||||
state[1] += b; |
|
||||||
state[2] += c; |
|
||||||
state[3] += d; |
|
||||||
state[4] += e; |
|
||||||
|
|
||||||
// Wipe variables
|
|
||||||
#ifdef SHA1_WIPE_VARIABLES |
|
||||||
a = b = c = d = e = 0; |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
// Hash in file contents
|
|
||||||
bool CSHA1::HashFile(char *szFileName) |
|
||||||
{ |
|
||||||
unsigned long ulFileSize, ulRest, ulBlocks; |
|
||||||
unsigned long i; |
|
||||||
quint_8 uData[SHA1_MAX_FILE_BUFFER]; |
|
||||||
FILE *fIn; |
|
||||||
|
|
||||||
if(szFileName == NULL) return false; |
|
||||||
|
|
||||||
fIn = fopen(szFileName, "rb"); |
|
||||||
if(fIn == NULL) return false; |
|
||||||
|
|
||||||
fseek(fIn, 0, SEEK_END); |
|
||||||
ulFileSize = (unsigned long)ftell(fIn); |
|
||||||
fseek(fIn, 0, SEEK_SET); |
|
||||||
|
|
||||||
if(ulFileSize != 0) |
|
||||||
{ |
|
||||||
ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER; |
|
||||||
ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER; |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
ulBlocks = 0; |
|
||||||
ulRest = 0; |
|
||||||
} |
|
||||||
|
|
||||||
for(i = 0; i < ulBlocks; i++) |
|
||||||
{ |
|
||||||
fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn); |
|
||||||
Update((quint_8 *)uData, SHA1_MAX_FILE_BUFFER); |
|
||||||
} |
|
||||||
|
|
||||||
if(ulRest != 0) |
|
||||||
{ |
|
||||||
fread(uData, 1, ulRest, fIn); |
|
||||||
Update((quint_8 *)uData, ulRest); |
|
||||||
} |
|
||||||
|
|
||||||
fclose(fIn); fIn = NULL; |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void CSHA1::Final() |
|
||||||
{ |
|
||||||
quint_32 i; |
|
||||||
quint_8 finalcount[8]; |
|
||||||
|
|
||||||
for(i = 0; i < 8; i++) |
|
||||||
finalcount[i] = (quint_8)((m_count[((i >= 4) ? 0 : 1)] |
|
||||||
>> ((3 - (i & 3)) * 8) ) & 255); // Endian independent
|
|
||||||
|
|
||||||
Update((quint_8 *)"\200", 1); |
|
||||||
|
|
||||||
while ((m_count[0] & 504) != 448) |
|
||||||
Update((quint_8 *)"\0", 1); |
|
||||||
|
|
||||||
Update(finalcount, 8); // Cause a SHA1Transform()
|
|
||||||
|
|
||||||
for(i = 0; i < 20; i++) |
|
||||||
{ |
|
||||||
m_digest[i] = (quint_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255); |
|
||||||
} |
|
||||||
|
|
||||||
// Wipe variables for security reasons
|
|
||||||
#ifdef SHA1_WIPE_VARIABLES |
|
||||||
i = 0; |
|
||||||
memset(m_buffer, 0, 64); |
|
||||||
memset(m_state, 0, 20); |
|
||||||
memset(m_count, 0, 8); |
|
||||||
memset(finalcount, 0, 8); |
|
||||||
Transform(m_state, m_buffer); |
|
||||||
#endif |
|
||||||
} |
|
||||||
|
|
||||||
// Get the final hash as a pre-formatted string
|
|
||||||
void CSHA1::ReportHash(char *szReport, unsigned char uReportType) |
|
||||||
{ |
|
||||||
unsigned char i; |
|
||||||
char szTemp[16]; |
|
||||||
|
|
||||||
if(szReport == NULL) return; |
|
||||||
|
|
||||||
if(uReportType == REPORT_HEX) |
|
||||||
{ |
|
||||||
sprintf(szTemp, "%02X", m_digest[0]); |
|
||||||
strcat(szReport, szTemp); |
|
||||||
|
|
||||||
for(i = 1; i < 20; i++) |
|
||||||
{ |
|
||||||
sprintf(szTemp, " %02X", m_digest[i]); |
|
||||||
strcat(szReport, szTemp); |
|
||||||
} |
|
||||||
} |
|
||||||
else if(uReportType == REPORT_DIGIT) |
|
||||||
{ |
|
||||||
sprintf(szTemp, "%u", m_digest[0]); |
|
||||||
strcat(szReport, szTemp); |
|
||||||
|
|
||||||
for(i = 1; i < 20; i++) |
|
||||||
{ |
|
||||||
sprintf(szTemp, " %u", m_digest[i]); |
|
||||||
strcat(szReport, szTemp); |
|
||||||
} |
|
||||||
} |
|
||||||
else strcpy(szReport, "Error: Unknown report type!"); |
|
||||||
} |
|
||||||
|
|
||||||
// Get the raw message digest
|
|
||||||
void CSHA1::GetHash(quint_8 *puDest) |
|
||||||
{ |
|
||||||
memcpy(puDest, m_digest, 20); |
|
||||||
} |
|
@ -1,99 +0,0 @@ |
|||||||
/*
|
|
||||||
100% free public domain implementation of the SHA-1 algorithm |
|
||||||
by Dominik Reichl <dominik.reichl@t-online.de> |
|
||||||
|
|
||||||
Version 1.5 - 2005-01-01 |
|
||||||
- 64-bit compiler compatibility added |
|
||||||
- Made variable wiping optional (define SHA1_WIPE_VARIABLES) |
|
||||||
- Removed unnecessary variable initializations |
|
||||||
- ROL32 improvement for the Microsoft compiler (using _rotl) |
|
||||||
|
|
||||||
======== Test Vectors (from FIPS PUB 180-1) ======== |
|
||||||
|
|
||||||
SHA1("abc") = |
|
||||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D |
|
||||||
|
|
||||||
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = |
|
||||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 |
|
||||||
|
|
||||||
SHA1(A million repetitions of "a") = |
|
||||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef ___SHA1_HDR___ |
|
||||||
#define ___SHA1_HDR___ |
|
||||||
|
|
||||||
#include <stdio.h> // Needed for file access |
|
||||||
#include <memory.h> // Needed for memset and memcpy |
|
||||||
#include <string.h> // Needed for strcat and strcpy |
|
||||||
|
|
||||||
|
|
||||||
// If you're compiling big endian, just comment out the following line
|
|
||||||
|
|
||||||
|
|
||||||
// #define or #undef this, if you want the CSHA1 class to wipe all
|
|
||||||
// temporary variables after processing
|
|
||||||
#define SHA1_WIPE_VARIABLES |
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Define 8- and 32-bit variables
|
|
||||||
|
|
||||||
#ifndef quint_32 |
|
||||||
#define quint_8 unsigned char |
|
||||||
#if (ULONG_MAX == 0xFFFFFFFF) |
|
||||||
#define quint_32 unsigned long |
|
||||||
#else |
|
||||||
#define quint_32 unsigned int |
|
||||||
#endif |
|
||||||
#endif |
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Declare SHA1 workspace
|
|
||||||
|
|
||||||
typedef union |
|
||||||
{ |
|
||||||
quint_8 c[64]; |
|
||||||
quint_32 l[16]; |
|
||||||
} SHA1_WORKSPACE_BLOCK; |
|
||||||
|
|
||||||
class CSHA1 |
|
||||||
{ |
|
||||||
public: |
|
||||||
// Two different formats for ReportHash(...)
|
|
||||||
enum |
|
||||||
{ |
|
||||||
REPORT_HEX = 0, |
|
||||||
REPORT_DIGIT = 1 |
|
||||||
}; |
|
||||||
|
|
||||||
// Constructor and Destructor
|
|
||||||
CSHA1(); |
|
||||||
~CSHA1(); |
|
||||||
|
|
||||||
quint_32 m_state[5]; |
|
||||||
quint_32 m_count[2]; |
|
||||||
quint_8 m_buffer[64]; |
|
||||||
quint_8 m_digest[20]; |
|
||||||
|
|
||||||
void Reset(); |
|
||||||
|
|
||||||
// Update the hash value
|
|
||||||
void Update(unsigned char* data, int len); |
|
||||||
bool HashFile(char *szFileName); |
|
||||||
|
|
||||||
// Finalize hash and report
|
|
||||||
void Final(); |
|
||||||
void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX); |
|
||||||
void GetHash(quint_8 *puDest); |
|
||||||
|
|
||||||
private: |
|
||||||
// Private SHA-1 transformation
|
|
||||||
void Transform(quint_32 *state, quint_8 *buffer); |
|
||||||
|
|
||||||
// Member variables
|
|
||||||
quint_8 m_workspace[64]; |
|
||||||
SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above
|
|
||||||
}; |
|
||||||
|
|
||||||
#endif |
|
@ -1,32 +1,49 @@ |
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2005-2006 by Tarek Saidi * |
||||||
|
* based on the FIPS-180-2 compliant SHA-256 implementation of * |
||||||
|
* 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., * |
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
||||||
|
***************************************************************************/ |
||||||
|
|
||||||
#ifndef _SHA256_H |
#ifndef _SHA256_H |
||||||
#define _SHA256_H |
#define _SHA256_H |
||||||
|
|
||||||
#ifndef uint8 |
#include <qglobal.h> |
||||||
#define uint8 unsigned char |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifndef uint32 |
|
||||||
#define uint32 unsigned long int |
|
||||||
#endif |
|
||||||
|
|
||||||
typedef struct |
typedef struct |
||||||
{ |
{ |
||||||
uint32 total[2]; |
quint32 total[2]; |
||||||
uint32 state[8]; |
quint32 state[8]; |
||||||
uint8 buffer[64]; |
quint8 buffer[64]; |
||||||
} |
}sha256_context; |
||||||
sha256_context; |
|
||||||
|
|
||||||
#ifdef __cplusplus |
|
||||||
extern "C" { //Für C++ Kompalibilität
|
|
||||||
#endif |
|
||||||
|
|
||||||
extern void sha256_starts( sha256_context *ctx ); |
extern void sha256_starts( sha256_context *ctx ); |
||||||
extern void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ); |
extern void sha256_update( sha256_context *ctx, const quint8 *input, quint32 length ); |
||||||
extern void sha256_finish( sha256_context *ctx, uint8 digest[32] ); |
extern void sha256_finish( sha256_context *ctx, quint8 digest[32] ); |
||||||
|
|
||||||
|
class SHA256{ |
||||||
|
public: |
||||||
|
SHA256(){sha256_starts(&ctx);} |
||||||
|
void update(void* input,quint32 length){sha256_update(&ctx,(quint8*)input,length);} |
||||||
|
void finish(void* digest){sha256_finish(&ctx,(quint8*)digest);} |
||||||
|
static void hashBuffer(void* input, void* digest,quint32 length); |
||||||
|
private: |
||||||
|
sha256_context ctx;
|
||||||
|
}; |
||||||
|
|
||||||
#ifdef __cplusplus |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
#endif /* sha256.h */ |
#endif /* sha256.h */ |
||||||
|
@ -0,0 +1,88 @@ |
|||||||
|
/* macros.h
|
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
/* nettle, low-level cryptographics library
|
||||||
|
* |
||||||
|
* Copyright (C) 2001 Niels Möller |
||||||
|
*
|
||||||
|
* The nettle library is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2.1 of the License, or (at your |
||||||
|
* option) any later version. |
||||||
|
*
|
||||||
|
* The nettle library 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 Lesser General Public |
||||||
|
* License for more details. |
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with the nettle library; see the file COPYING.LIB. If not, write to |
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
||||||
|
* MA 02111-1307, USA. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef NETTLE_MACROS_H_INCLUDED |
||||||
|
#define NETTLE_MACROS_H_INCLUDED |
||||||
|
|
||||||
|
/* Reads a 32-bit integer, in network, big-endian, byte order */ |
||||||
|
#define READ_UINT32(p) \ |
||||||
|
( (((uint32_t) (p)[0]) << 24) \
|
||||||
|
| (((uint32_t) (p)[1]) << 16) \
|
||||||
|
| (((uint32_t) (p)[2]) << 8) \
|
||||||
|
| ((uint32_t) (p)[3])) |
||||||
|
|
||||||
|
#define WRITE_UINT32(p, i) \ |
||||||
|
do { \
|
||||||
|
(p)[0] = ((i) >> 24) & 0xff; \
|
||||||
|
(p)[1] = ((i) >> 16) & 0xff; \
|
||||||
|
(p)[2] = ((i) >> 8) & 0xff; \
|
||||||
|
(p)[3] = (i) & 0xff; \
|
||||||
|
} while(0) |
||||||
|
|
||||||
|
/* Analogous macros, for 24 and 16 bit numbers */ |
||||||
|
#define READ_UINT24(p) \ |
||||||
|
( (((uint32_t) (p)[0]) << 16) \
|
||||||
|
| (((uint32_t) (p)[1]) << 8) \
|
||||||
|
| ((uint32_t) (p)[2])) |
||||||
|
|
||||||
|
#define WRITE_UINT24(p, i) \ |
||||||
|
do { \
|
||||||
|
(p)[0] = ((i) >> 16) & 0xff; \
|
||||||
|
(p)[1] = ((i) >> 8) & 0xff; \
|
||||||
|
(p)[2] = (i) & 0xff; \
|
||||||
|
} while(0) |
||||||
|
|
||||||
|
#define READ_UINT16(p) \ |
||||||
|
( (((uint32_t) (p)[0]) << 8) \
|
||||||
|
| ((uint32_t) (p)[1])) |
||||||
|
|
||||||
|
#define WRITE_UINT16(p, i) \ |
||||||
|
do { \
|
||||||
|
(p)[0] = ((i) >> 8) & 0xff; \
|
||||||
|
(p)[1] = (i) & 0xff; \
|
||||||
|
} while(0) |
||||||
|
|
||||||
|
/* And the other, little-endian, byteorder */ |
||||||
|
#define LE_READ_UINT32(p) \ |
||||||
|
( (((uint32_t) (p)[3]) << 24) \
|
||||||
|
| (((uint32_t) (p)[2]) << 16) \
|
||||||
|
| (((uint32_t) (p)[1]) << 8) \
|
||||||
|
| ((uint32_t) (p)[0])) |
||||||
|
|
||||||
|
#define LE_WRITE_UINT32(p, i) \ |
||||||
|
do { \
|
||||||
|
(p)[3] = ((i) >> 24) & 0xff; \
|
||||||
|
(p)[2] = ((i) >> 16) & 0xff; \
|
||||||
|
(p)[1] = ((i) >> 8) & 0xff; \
|
||||||
|
(p)[0] = (i) & 0xff; \
|
||||||
|
} while(0) |
||||||
|
|
||||||
|
/* Macro to make it easier to loop over several blocks. */ |
||||||
|
#define FOR_BLOCKS(length, dst, src, blocksize) \ |
||||||
|
assert( !((length) % (blocksize))); \
|
||||||
|
for (; (length); ((length) -= (blocksize), \
|
||||||
|
(dst) += (blocksize), \
|
||||||
|
(src) += (blocksize)) ) |
||||||
|
|
||||||
|
#endif /* NETTLE_MACROS_H_INCLUDED */ |
File diff suppressed because it is too large
Load Diff
Reference in new issue