From 636f3b8af6a18ac9c467224b972af8d81eaf0599 Mon Sep 17 00:00:00 2001 From: sniperbeamer Date: Fri, 1 Aug 2008 18:57:18 +0000 Subject: [PATCH] Added pronounceable password generator Improved RNG seeding on Windows Updated AES implementation Removed SHA1 implementation, replaced by QCryptographicHash Replaced ARC4 implementation by the one from KeePass 1.11 Some cleanup git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@216 b624d157-de02-0410-bad0-e51aec6abb33 --- src/Database.h | 2 - src/Kdb3Database.cpp | 58 +- src/Kdb3Database.h | 6 - src/KpxConfig.h | 4 +- src/apg/convert.c | 404 ++++++ src/apg/convert.h | 43 + src/apg/owntypes.h | 49 + src/apg/pronpass.c | 2289 +++++++++++++++++++++++++++++++ src/apg/pronpass.h | 92 ++ src/apg/randpass.c | 162 +++ src/apg/randpass.h | 70 + src/apg/smbl.h | 51 + src/crypto/aes.h | 139 +- src/crypto/aes_edefs.h | 161 +-- src/crypto/aes_modes.c | 280 ++-- src/crypto/aes_tdefs.h | 286 ++-- src/crypto/aescpp.h | 106 +- src/crypto/aescrypt.c | 61 +- src/crypto/aeskey.c | 209 ++- src/crypto/aesopt.h | 532 +++---- src/crypto/aestab.c | 73 +- src/crypto/aestab.h | 75 +- src/crypto/arcfour.cpp | 114 +- src/crypto/arcfour.h | 60 +- src/crypto/sha1.cpp | 258 ---- src/crypto/sha1.h | 119 -- src/crypto/yarrow.cpp | 2 +- src/dialogs/PasswordDlg.cpp | 14 +- src/dialogs/PasswordDlg.h | 1 + src/dialogs/PasswordGenDlg.cpp | 342 +++-- src/dialogs/PasswordGenDlg.h | 23 +- src/forms/PasswordGenDlg.ui | 513 ++++--- src/import/Import_PwManager.cpp | 28 +- src/keepassx.h | 8 +- src/lib/GroupView.cpp | 3 + src/lib/IniReader.cpp | 488 ------- src/lib/IniReader.h | 182 --- src/lib/SecString.cpp | 29 +- src/lib/SecString.h | 4 +- src/lib/random.cpp | 68 +- src/lib/random.h | 22 +- src/lib/tools.cpp | 16 +- src/lib/tools.h | 1 + src/main_macx.cpp | 1 + src/mainwindow.cpp | 2 +- src/src.pro | 356 ++--- 46 files changed, 5168 insertions(+), 2638 deletions(-) create mode 100644 src/apg/convert.c create mode 100644 src/apg/convert.h create mode 100644 src/apg/owntypes.h create mode 100644 src/apg/pronpass.c create mode 100644 src/apg/pronpass.h create mode 100644 src/apg/randpass.c create mode 100644 src/apg/randpass.h create mode 100644 src/apg/smbl.h delete mode 100644 src/crypto/sha1.cpp delete mode 100644 src/crypto/sha1.h delete mode 100644 src/lib/IniReader.cpp delete mode 100644 src/lib/IniReader.h diff --git a/src/Database.h b/src/Database.h index 9e289a7..bc0bc13 100644 --- a/src/Database.h +++ b/src/Database.h @@ -110,7 +110,6 @@ The IEntryHandle interface provides access to Entry data structures without usin class IEntryHandle{ public: virtual void setImage(const quint32& ImageID)=0; - virtual void setOldImage(const quint32& OldImgID)=0; virtual void setTitle(const QString& Title)=0; virtual void setUrl(const QString& URL)=0; virtual void setUsername(const QString& Username)=0; @@ -126,7 +125,6 @@ public: virtual KpxUuid uuid()=0; virtual IGroupHandle* group()=0; virtual quint32 image()=0; - virtual quint32 oldImage()=0; virtual QString title()=0; virtual QString url()=0; virtual QString username()=0; diff --git a/src/Kdb3Database.cpp b/src/Kdb3Database.cpp index 0e5d4e0..b170cf8 100644 --- a/src/Kdb3Database.cpp +++ b/src/Kdb3Database.cpp @@ -64,13 +64,13 @@ void Kdb3Database::removeIcon(int id){ CustomIcons.removeAt(id); // .isNull()==true for(int i=0;iid+builtinIcons()) Entries[i].Image--; } for(int i=0;iid+builtinIcons()) Groups[i].Image--; } @@ -165,10 +165,8 @@ void Kdb3Database::parseCustomIconsMetaStream(const QByteArray& dta){ memcpyFromLEnd32(&Icon,dta.data()+offset); offset+=4; StdEntry* entry=getEntry(EntryUuid); - if(entry){ - entry->OldImage=entry->Image; + if(entry) entry->Image=Icon+BUILTIN_ICONS; - } } for(int i=0;iOldImage=Group->Image; + if(Group) Group->Image=Icon+BUILTIN_ICONS; - } } return; } @@ -224,7 +220,6 @@ void Kdb3Database::parseCustomIconsMetaStreamV3(const QByteArray& dta){ offset+=4; StdEntry* entry=getEntry(EntryUuid); if(entry){ - entry->OldImage=entry->Image; if (Icon>=65) entry->Image=Icon+4; // Since v0.3.2 the BUILTIN_ICONS number has increased by 4 else @@ -239,8 +234,6 @@ void Kdb3Database::parseCustomIconsMetaStreamV3(const QByteArray& dta){ offset+=4; StdGroup* Group=getGroup(GroupId); if(Group){ - Group->OldImage=Group->Image; - Group->Image=Icon; if (Group->Image>=65) Group->Image=Icon+4; // Since v0.3.2 the BUILTIN_ICONS number has increased by 4 else @@ -272,7 +265,6 @@ void Kdb3Database::createGroupTreeStateMetaStream(StdEntry* e){ e->Username="SYSTEM"; e->Comment="KPX_GROUP_TREE_STATE"; e->Url="$"; - e->OldImage=0; e->Image=0; if(Groups.size())e->GroupId=Groups[0].Id; QByteArray bin; @@ -317,7 +309,6 @@ switch(FieldType) break; case 0x0003: memcpyFromLEnd32(&entry->Image, (char*)pData); - entry->OldImage=entry->Image; break; case 0x0004: entry->Title=QString::fromUtf8((char*)pData); @@ -388,7 +379,6 @@ bool Kdb3Database::readGroupField(StdGroup* group,QList& Levels,quint16 break; case 0x0007: memcpyFromLEnd32(&group->Image, (char*)pData); - group->OldImage=group->Image; break; case 0x0008: quint16 Level; @@ -558,8 +548,10 @@ if(Algorithm == Rijndael_Cipher){ } else if(Algorithm == Twofish_Cipher){ CTwofish twofish; - if (twofish.init(FinalKey, 32, EncryptionIV) != true) + if (twofish.init(FinalKey, 32, EncryptionIV) != true){ + error=tr("Unable to initalize the twofish algorithm."); LOAD_RETURN_CLEANUP + } crypto_size = (unsigned long)twofish.padDecrypt((quint8 *)buffer + DB_HEADER_SIZE, total_size - DB_HEADER_SIZE, (quint8 *)buffer + DB_HEADER_SIZE); } @@ -1014,7 +1006,6 @@ IGroupHandle* Kdb3Database::addGroup(const CGroup* group,IGroupHandle* ParentHan } Kdb3Database::StdGroup::StdGroup(const CGroup& other){ - OldImage=0; Index=0; Id=other.Id; Image=other.Image; @@ -1033,11 +1024,9 @@ void Kdb3Database::EntryHandle::setBinaryDesc(const QString& s){Entry->BinaryDes void Kdb3Database::EntryHandle::setComment(const QString& s){Entry->Comment=s;} void Kdb3Database::EntryHandle::setBinary(const QByteArray& s){Entry->Binary=s;} void Kdb3Database::EntryHandle::setImage(const quint32& s){Entry->Image=s;} -void Kdb3Database::EntryHandle::setOldImage(const quint32& s){Entry->OldImage=s;} KpxUuid Kdb3Database::EntryHandle::uuid(){return Entry->Uuid;} IGroupHandle* Kdb3Database::EntryHandle::group(){return Entry->Group->Handle;} quint32 Kdb3Database::EntryHandle::image(){return Entry->Image;} -quint32 Kdb3Database::EntryHandle::oldImage(){return Entry->OldImage;} QString Kdb3Database::EntryHandle::title(){return Entry->Title;} QString Kdb3Database::EntryHandle::url(){return Entry->Url;} QString Kdb3Database::EntryHandle::username(){return Entry->Username;} @@ -1106,24 +1095,13 @@ Kdb3Database::EntryHandle::EntryHandle(Kdb3Database* db){ bool Kdb3Database::GroupHandle::isValid(){return valid;} -void Kdb3Database::GroupHandle::setOldImage(const quint32& s){Group->OldImage=s;} QString Kdb3Database::GroupHandle::title(){return Group->Title;} -quint32 Kdb3Database::GroupHandle::oldImage(){return Group->OldImage;} quint32 Kdb3Database::GroupHandle::image(){return Group->Image;} int Kdb3Database::GroupHandle::index(){return Group->Index;} void Kdb3Database::GroupHandle::setTitle(const QString& Title){Group->Title=Title;} void Kdb3Database::GroupHandle::setExpanded(bool IsExpanded){Group->IsExpanded=IsExpanded;} bool Kdb3Database::GroupHandle::expanded(){return Group->IsExpanded;} -void Kdb3Database::GroupHandle::setImage(const quint32& New) -{ - if(Group->Image < pDB->builtinIcons() && New >= pDB->builtinIcons()) - Group->OldImage=Group->Image; - - if(New < pDB->builtinIcons()) - Group->OldImage=New; - - Group->Image=New; -} +void Kdb3Database::GroupHandle::setImage(const quint32& New){Group->Image=New;} Kdb3Database::GroupHandle::GroupHandle(Kdb3Database* db){ @@ -1220,21 +1198,6 @@ bool Kdb3Database::save(){ } } - -/* This is only a fix for a bug in the implementation of the metastream creation - in KeePassX 0.2.1. to restore lost icons. - It should be removed after a while. - -----------------------------------------------------------------------------------*/ - for(int i=0;i MetaStreams; @@ -1376,7 +1339,6 @@ void Kdb3Database::createCustomIconsMetaStream(StdEntry* e){ e->Username="SYSTEM"; e->Comment="KPX_CUSTOM_ICONS_4"; e->Url="$"; - e->OldImage=0; if(Groups.size())e->GroupId=Groups[0].Id; int Size=12; quint32 NumEntries=0; @@ -1505,7 +1467,7 @@ void Kdb3Database::serializeGroups(QList& GroupList,char* buffer,unsig FieldType = 0x0007; FieldSize = 4; memcpyToLEnd16(buffer+pos, &FieldType); pos += 2; memcpyToLEnd32(buffer+pos, &FieldSize); pos += 4; - memcpyToLEnd32(buffer+pos, &SortedGroups[i]->OldImage); pos += 4; + memcpyToLEnd32(buffer+pos, &SortedGroups[i]->Image); pos += 4; FieldType = 0x0008; FieldSize = 2; memcpyToLEnd16(buffer+pos, &FieldType); pos += 2; @@ -1542,7 +1504,7 @@ void Kdb3Database::serializeEntries(QList& EntryList,char* buffer,unsi FieldType = 0x0003; FieldSize = 4; memcpyToLEnd16(buffer+pos, &FieldType); pos += 2; memcpyToLEnd32(buffer+pos, &FieldSize); pos += 4; - memcpyToLEnd32(buffer+pos,&EntryList[i].OldImage); pos += 4; + memcpyToLEnd32(buffer+pos,&EntryList[i].Image); pos += 4; FieldType = 0x0004; diff --git a/src/Kdb3Database.h b/src/Kdb3Database.h index 41b30c9..63cc233 100644 --- a/src/Kdb3Database.h +++ b/src/Kdb3Database.h @@ -49,7 +49,6 @@ public: public: EntryHandle(Kdb3Database* 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); @@ -67,7 +66,6 @@ public: virtual int visualIndex() const; virtual void setVisualIndex(int i); virtual void setVisualIndexDirectly(int i); - quint32 oldImage(); virtual QString title(); virtual QString url(); virtual QString username(); @@ -96,10 +94,8 @@ public: 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 childs(); @@ -120,7 +116,6 @@ public: class StdEntry:public CEntry{ public: - quint32 OldImage; quint16 Index; EntryHandle* Handle; StdGroup* Group; @@ -130,7 +125,6 @@ public: public: StdGroup():CGroup(){}; StdGroup(const CGroup&); - quint32 OldImage; quint16 Index; StdGroup* Parent; GroupHandle* Handle; diff --git a/src/KpxConfig.h b/src/KpxConfig.h index 9571e1a..6dbc6d5 100644 --- a/src/KpxConfig.h +++ b/src/KpxConfig.h @@ -72,9 +72,10 @@ public: QString mountDir(){return settings.value("Options/MountDir",DEFAULT_MOUNT_DIR).toString();} bool openLastFile(){return settings.value("Options/OpenLastFile",true).toBool();} bool autoSave(){return settings.value("Options/AutoSave",false).toBool();} + int pwGenCategory(){return settings.value("Options/PwGenCategory",0).toInt();} QString pwGenCharList(){return settings.value("Options/PwGenCharList").toString();} int pwGenLength(){return settings.value("Options/PwGenLength",25).toInt();} - QBitArray pwGenOptions(){return stringToBitArray(settings.value("Options/PwGenOptions","1111100001").toString(),10);} + QBitArray pwGenOptions(){return stringToBitArray(settings.value("Options/PwGenOptions","11111000011110").toString(),14);} bool rememberLastKey(){return settings.value("Options/RememberLastKey",true).toBool();} bool saveFileDlgHistory(){return settings.value("Options/SaveFileDlgHistory",true).toBool();} bool saveRelativePaths(){return settings.value("Options/SaveRelativePaths",true).toBool();} @@ -131,6 +132,7 @@ public: void setMountDir(const QString& value){settings.setValue("Options/MountDir",value);} void setOpenLastFile(bool value){settings.setValue("Options/OpenLastFile",value);} void setAutoSave(bool value){settings.setValue("Options/AutoSave",value);} + void setPwGenCategory(int value){settings.setValue("Options/PwGenCategory",value);} void setPwGenCharList(const QString& value){settings.setValue("Options/PwGenCharList",value);} void setPwGenLength(int value){settings.setValue("Options/PwGenLength",value);} void setPwGenOptions(const QBitArray& value){settings.setValue("Options/PwGenOptions",bitArrayToString(value));} diff --git a/src/apg/convert.c b/src/apg/convert.c new file mode 100644 index 0000000..e30dc52 --- /dev/null +++ b/src/apg/convert.c @@ -0,0 +1,404 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "random.h" + +#include "randpass.h" +#include "convert.h" + +/* +** GLOBALS +*/ + +/* small letters */ +char let[26] = + { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'w', 'z' + }; +/* capital letters */ +char clet[26] = + { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'W', 'Z' + }; + +/* +** FUNCTIONS +*/ + +/* +** decapitalize() - This routine replaces all capital letters +** to small letters in the word: +** INPUT: +** char * - word. +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +decapitalize (char *word) +{ + int i = 0; /* counter */ + int j = 0; /* counter */ + int str_len = strlen(word); + for(j = 0; j < str_len; j++) + for(i=0; i < 26; i++) + if(word[j] == clet[i]) + word[j] = let[i]; +} + +#ifndef APGBFM +/* +** capitalize() - This routine designed to modify sullable like this: +** adel ----> Adel +** dot ----> Dot +** etc. +** INPUT: +** char * - syllable. +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +capitalize (char *syllable) +{ + char tmp = 0x00; + int i = 0; + if ( randint(2) == TRUE) + { + (void)memcpy((void *)&tmp, (void *)syllable, sizeof(tmp)); + for(i=0; i < 26; i++) + if ( let[i] == tmp ) + if (is_restricted_symbol(clet[i]) != TRUE) + (void)memcpy ((void *)syllable, (void *)&clet[i], 1); + } +} + +/* +** numerize() - This routine designed to modify single-letter +** syllable like this: +** a ----> 1 or 2 or 3 etc. +** u ----> 1 or 2 or 3 etc. +** etc. +** INPUT: +** char * - single-letter syllable +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +numerize (char *syllable) +{ + char *tmp; + if ( (tmp = (char *)calloc(1, 4)) == NULL) + perror("calloc"); + if ( strlen (syllable) == 1 ) + { + (void) gen_rand_symbol(tmp, S_NB); + (void)memcpy ((void *)syllable, (void *)tmp, 1); + } + free ((void *)tmp); +} +/* +** specialize() - This routine designed to modify single-letter syllable +** like this: +** a ----> # or $ or % etc. +** u ----> # or $ or % etc. +** etc. +** INPUT: +** char * - single-letter syllable. +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +specialize (char *syllable) +{ + char *tmp; + if ( (tmp = (char *)calloc(1, 4)) == NULL) + perror("calloc"); + if ( strlen (syllable) == 1 ) + { + (void) gen_rand_symbol(tmp, S_SS); + (void)memcpy ((void *)syllable, (void *)tmp, 1); + } + free ((void *)tmp); +} + +/* +** symb2name - convert symbol to it's name +** INPUT: +** char * - one symbol syllable +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +symb2name(char * syllable, char * h_syllable) +{ + struct ssymb_names + { + char symbol; + char *name; + }; + static struct ssymb_names ssn[42] = + { + {'1',"ONE"}, + {'2',"TWO"}, + {'3',"THREE"}, + {'4',"FOUR"}, + {'5',"FIVE"}, + {'6',"SIX"}, + {'7',"SEVEN"}, + {'8',"EIGHT"}, + {'9',"NINE"}, + {'0',"ZERO"}, + {33, "EXCLAMATION_POINT"}, + {34, "QUOTATION_MARK"}, + {35, "CROSSHATCH"}, + {36, "DOLLAR_SIGN"}, + {37, "PERCENT_SIGN"}, + {38, "AMPERSAND"}, + {39, "APOSTROPHE"}, + {40, "LEFT_PARENTHESIS"}, + {41, "RIGHT_PARENTHESIS"}, + {42, "ASTERISK"}, + {43, "PLUS_SIGN"}, + {44, "COMMA"}, + {45, "HYPHEN"}, + {46, "PERIOD"}, + {47, "SLASH"}, + {58, "COLON"}, + {59, "SEMICOLON"}, + {60, "LESS_THAN"}, + {61, "EQUAL_SIGN"}, + {62, "GREATER_THAN"}, + {63, "QUESTION_MARK"}, + {64, "AT_SIGN"}, + {91, "LEFT_BRACKET"}, + {92, "BACKSLASH"}, + {93, "RIGHT_BRACKET"}, + {94, "CIRCUMFLEX"}, + {95, "UNDERSCORE"}, + {96, "GRAVE"}, + {123, "LEFT_BRACE"}, + {124, "VERTICAL_BAR"}, + {125, "RIGHT_BRACE"}, + {126, "TILDE"} + }; + int i = 0; + int flag = FALSE; + + if (strlen(syllable) == 1) + { + for (i = 0; i < 42; i++) + { + if(*syllable == ssn[i].symbol) + { + (void)memcpy((void*)h_syllable, (void*)ssn[i].name, strlen(ssn[i].name)); + flag = TRUE; + } + } + if (flag != TRUE) + (void)memcpy((void*)h_syllable, (void*)syllable, strlen(syllable)); + } +} + +/* +** spell_word - spell the word +** INPUT: +** char * - pointer to the word +** char * - pointer to the spelled word +** OUTPUT: +** char * - pointer to the spelled word +** NULL - something is wrong +** NOTES: +** You should free() memory pointed by spelled_word after each use of spell_word +*/ +char * +spell_word(char * word, char * spelled_word) +{ + struct char_spell + { + char symbol; + char *name; + }; + static struct char_spell cs[94] = + { + {'1',"ONE" }, + {'2',"TWO" }, + {'3',"THREE" }, + {'4',"FOUR" }, + {'5',"FIVE" }, + {'6',"SIX" }, + {'7',"SEVEN" }, + {'8',"EIGHT" }, + {'9',"NINE" }, + {'0',"ZERO" }, + {'A', "Alfa" }, + {'B', "Bravo" }, + {'C', "Charlie" }, + {'D', "Delta" }, + {'E', "Echo" }, + {'F', "Foxtrot" }, + {'G', "Golf" }, + {'H', "Hotel" }, + {'I', "India" }, + {'J', "Juliett" }, + {'K', "Kilo" }, + {'L', "Lima" }, + {'M', "Mike" }, + {'N', "November" }, + {'O', "Oscar" }, + {'P', "Papa" }, + {'Q', "Quebec" }, + {'R', "Romeo" }, + {'S', "Sierra" }, + {'T', "Tango" }, + {'U', "Uniform" }, + {'V', "Victor" }, + {'W', "Whiskey" }, + {'X', "X_ray" }, + {'Y', "Yankee" }, + {'Z', "Zulu" }, + {'a', "alfa" }, + {'b', "bravo" }, + {'c', "charlie" }, + {'d', "delta" }, + {'e', "echo" }, + {'f', "foxtrot" }, + {'g', "golf" }, + {'h', "hotel" }, + {'i', "india" }, + {'j', "juliett" }, + {'k', "kilo" }, + {'l', "lima" }, + {'m', "mike" }, + {'n', "november" }, + {'o', "oscar" }, + {'p', "papa" }, + {'q', "quebec" }, + {'r', "romeo" }, + {'s', "sierra" }, + {'t', "tango" }, + {'u', "uniform" }, + {'v', "victor" }, + {'w', "whiskey" }, + {'x', "x_ray" }, + {'y', "yankee" }, + {'z', "zulu" }, + {33, "EXCLAMATION_POINT"}, + {34, "QUOTATION_MARK" }, + {35, "CROSSHATCH" }, + {36, "DOLLAR_SIGN" }, + {37, "PERCENT_SIGN" }, + {38, "AMPERSAND" }, + {39, "APOSTROPHE" }, + {40, "LEFT_PARENTHESIS" }, + {41, "RIGHT_PARENTHESIS"}, + {42, "ASTERISK" }, + {43, "PLUS_SIGN" }, + {44, "COMMA" }, + {45, "HYPHEN" }, + {46, "PERIOD" }, + {47, "SLASH" }, + {58, "COLON" }, + {59, "SEMICOLON" }, + {60, "LESS_THAN" }, + {61, "EQUAL_SIGN" }, + {62, "GREATER_THAN" }, + {63, "QUESTION_MARK" }, + {64, "AT_SIGN" }, + {91, "LEFT_BRACKET" }, + {92, "BACKSLASH" }, + {93, "RIGHT_BRACKET" }, + {94, "CIRCUMFLEX" }, + {95, "UNDERSCORE" }, + {96, "GRAVE" }, + {123, "LEFT_BRACE" }, + {124, "VERTICAL_BAR" }, + {125, "RIGHT_BRACE" }, + {126, "TILDE" } + }; + int s_length = 0; + int i = 0; + int j = 0; + int word_len = strlen(word); + char * tmp_ptr; + char hyphen = '-'; + char zero = 0x00; + + /* Count the length of the spelled word */ + for (i=0; i <= word_len; i++) + for (j=0; j < 94; j++) + if (word[i] == cs[j].symbol) + { + s_length = s_length + strlen(cs[j].name) + 1; + continue; + } + + /* Allocate memory for spelled word */ + if ( (spelled_word = (char *)calloc(1, (size_t)s_length)) == NULL) + return(NULL); + + /* Construct spelled word */ + tmp_ptr = spelled_word; + + for (i=0; i < word_len; i++) + for (j=0; j < 94; j++) + if (word[i] == cs[j].symbol) + { + (void) memcpy((void *)tmp_ptr, (void *)cs[j].name, strlen(cs[j].name)); + tmp_ptr = tmp_ptr + strlen(cs[j].name); + /* Place the hyphen after each symbol */ + (void) memcpy((void *)(tmp_ptr), (void *)&hyphen, 1); + tmp_ptr = tmp_ptr + 1; + continue; + } + + /* Remove hyphen at the end of the word */ + tmp_ptr = tmp_ptr - 1; + (void) memcpy((void *)(tmp_ptr), (void *)&zero, 1); + + return (spelled_word); +} + +#endif /* APGBFM */ diff --git a/src/apg/convert.h b/src/apg/convert.h new file mode 100644 index 0000000..08f0bf0 --- /dev/null +++ b/src/apg/convert.h @@ -0,0 +1,43 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef APG_CONVERT_H +#define APG_CONVERT_H 1 + +void decapitalize (char *word); + +#ifndef APGBFM +void capitalize (char *syllable); +void numerize (char *syllable); +void specialize (char *syllable); +void symb2name(char * syllable, char * h_syllable); +char* spell_word(char * word, char * spelled_word); +#endif /* APGBFM */ + +#endif /* APG_CONVERT_H */ diff --git a/src/apg/owntypes.h b/src/apg/owntypes.h new file mode 100644 index 0000000..6252e5c --- /dev/null +++ b/src/apg/owntypes.h @@ -0,0 +1,49 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef APG_OWN_TYPES_H +#define APG_OWN_TYPES_H 1 + +typedef unsigned int UINT; +typedef unsigned short USHORT; +typedef short int SHORT; +typedef int boolean; +typedef unsigned long int UINT32; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define APG_MAX_PASSWORD_LENGTH 255 + +#endif /* APG_OWN_TYPES_H */ diff --git a/src/apg/pronpass.c b/src/apg/pronpass.c new file mode 100644 index 0000000..6169b1c --- /dev/null +++ b/src/apg/pronpass.c @@ -0,0 +1,2289 @@ +/* +** This module uses code from the NIST implementation of FIPS-181, +** but the algorythm is CHANGED and I think that I CAN +** copyright it. See copiright notes below. +*/ + +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include +#include +#include +#include +#include + +#include "random.h" + +#include "pronpass.h" +#include "randpass.h" +#include "convert.h" + +struct unit +{ + char unit_code[5]; + USHORT flags; +}; + +static struct unit rules[] = +{ {"a", VOWEL}, + {"b", NO_SPECIAL_RULE}, + {"c", NO_SPECIAL_RULE}, + {"d", NO_SPECIAL_RULE}, + {"e", NO_FINAL_SPLIT | VOWEL}, + {"f", NO_SPECIAL_RULE}, + {"g", NO_SPECIAL_RULE}, + {"h", NO_SPECIAL_RULE}, + {"i", VOWEL}, + {"j", NO_SPECIAL_RULE}, + {"k", NO_SPECIAL_RULE}, + {"l", NO_SPECIAL_RULE}, + {"m", NO_SPECIAL_RULE}, + {"n", NO_SPECIAL_RULE}, + {"o", VOWEL}, + {"p", NO_SPECIAL_RULE}, + {"r", NO_SPECIAL_RULE}, + {"s", NO_SPECIAL_RULE}, + {"t", NO_SPECIAL_RULE}, + {"u", VOWEL}, + {"v", NO_SPECIAL_RULE}, + {"w", NO_SPECIAL_RULE}, + {"x", NOT_BEGIN_SYLLABLE}, + {"y", ALTERNATE_VOWEL | VOWEL}, + {"z", NO_SPECIAL_RULE}, + {"ch", NO_SPECIAL_RULE}, + {"gh", NO_SPECIAL_RULE}, + {"ph", NO_SPECIAL_RULE}, + {"rh", NO_SPECIAL_RULE}, + {"sh", NO_SPECIAL_RULE}, + {"th", NO_SPECIAL_RULE}, + {"wh", NO_SPECIAL_RULE}, + {"qu", NO_SPECIAL_RULE}, + {"ck", NOT_BEGIN_SYLLABLE} +}; + +static int digram[][RULE_SIZE] = +{ + {/* aa */ ILLEGAL_PAIR, + /* ab */ ANY_COMBINATION, + /* ac */ ANY_COMBINATION, + /* ad */ ANY_COMBINATION, + /* ae */ ILLEGAL_PAIR, + /* af */ ANY_COMBINATION, + /* ag */ ANY_COMBINATION, + /* ah */ NOT_BEGIN | BREAK | NOT_END, + /* ai */ ANY_COMBINATION, + /* aj */ ANY_COMBINATION, + /* ak */ ANY_COMBINATION, + /* al */ ANY_COMBINATION, + /* am */ ANY_COMBINATION, + /* an */ ANY_COMBINATION, + /* ao */ ILLEGAL_PAIR, + /* ap */ ANY_COMBINATION, + /* ar */ ANY_COMBINATION, + /* as */ ANY_COMBINATION, + /* at */ ANY_COMBINATION, + /* au */ ANY_COMBINATION, + /* av */ ANY_COMBINATION, + /* aw */ ANY_COMBINATION, + /* ax */ ANY_COMBINATION, + /* ay */ ANY_COMBINATION, + /* az */ ANY_COMBINATION, + /* ach */ ANY_COMBINATION, + /* agh */ ILLEGAL_PAIR, + /* aph */ ANY_COMBINATION, + /* arh */ ILLEGAL_PAIR, + /* ash */ ANY_COMBINATION, + /* ath */ ANY_COMBINATION, + /* awh */ ILLEGAL_PAIR, + /* aqu */ BREAK | NOT_END, + /* ack */ ANY_COMBINATION}, + {/* ba */ ANY_COMBINATION, + /* bb */ NOT_BEGIN | BREAK | NOT_END, + /* bc */ NOT_BEGIN | BREAK | NOT_END, + /* bd */ NOT_BEGIN | BREAK | NOT_END, + /* be */ ANY_COMBINATION, + /* bf */ NOT_BEGIN | BREAK | NOT_END, + /* bg */ NOT_BEGIN | BREAK | NOT_END, + /* bh */ NOT_BEGIN | BREAK | NOT_END, + /* bi */ ANY_COMBINATION, + /* bj */ NOT_BEGIN | BREAK | NOT_END, + /* bk */ NOT_BEGIN | BREAK | NOT_END, + /* bl */ BEGIN | SUFFIX | NOT_END, + /* bm */ NOT_BEGIN | BREAK | NOT_END, + /* bn */ NOT_BEGIN | BREAK | NOT_END, + /* bo */ ANY_COMBINATION, + /* bp */ NOT_BEGIN | BREAK | NOT_END, + /* br */ BEGIN | END, + /* bs */ NOT_BEGIN, + /* bt */ NOT_BEGIN | BREAK | NOT_END, + /* bu */ ANY_COMBINATION, + /* bv */ NOT_BEGIN | BREAK | NOT_END, + /* bw */ NOT_BEGIN | BREAK | NOT_END, + /* bx */ ILLEGAL_PAIR, + /* by */ ANY_COMBINATION, + /* bz */ NOT_BEGIN | BREAK | NOT_END, + /* bch */ NOT_BEGIN | BREAK | NOT_END, + /* bgh */ ILLEGAL_PAIR, + /* bph */ NOT_BEGIN | BREAK | NOT_END, + /* brh */ ILLEGAL_PAIR, + /* bsh */ NOT_BEGIN | BREAK | NOT_END, + /* bth */ NOT_BEGIN | BREAK | NOT_END, + /* bwh */ ILLEGAL_PAIR, + /* bqu */ NOT_BEGIN | BREAK | NOT_END, + /* bck */ ILLEGAL_PAIR }, + {/* ca */ ANY_COMBINATION, + /* cb */ NOT_BEGIN | BREAK | NOT_END, + /* cc */ NOT_BEGIN | BREAK | NOT_END, + /* cd */ NOT_BEGIN | BREAK | NOT_END, + /* ce */ ANY_COMBINATION, + /* cf */ NOT_BEGIN | BREAK | NOT_END, + /* cg */ NOT_BEGIN | BREAK | NOT_END, + /* ch */ NOT_BEGIN | BREAK | NOT_END, + /* ci */ ANY_COMBINATION, + /* cj */ NOT_BEGIN | BREAK | NOT_END, + /* ck */ NOT_BEGIN | BREAK | NOT_END, + /* cl */ SUFFIX | NOT_END, + /* cm */ NOT_BEGIN | BREAK | NOT_END, + /* cn */ NOT_BEGIN | BREAK | NOT_END, + /* co */ ANY_COMBINATION, + /* cp */ NOT_BEGIN | BREAK | NOT_END, + /* cr */ NOT_END, + /* cs */ NOT_BEGIN | END, + /* ct */ NOT_BEGIN | PREFIX, + /* cu */ ANY_COMBINATION, + /* cv */ NOT_BEGIN | BREAK | NOT_END, + /* cw */ NOT_BEGIN | BREAK | NOT_END, + /* cx */ ILLEGAL_PAIR, + /* cy */ ANY_COMBINATION, + /* cz */ NOT_BEGIN | BREAK | NOT_END, + /* cch */ ILLEGAL_PAIR, + /* cgh */ ILLEGAL_PAIR, + /* cph */ NOT_BEGIN | BREAK | NOT_END, + /* crh */ ILLEGAL_PAIR, + /* csh */ NOT_BEGIN | BREAK | NOT_END, + /* cth */ NOT_BEGIN | BREAK | NOT_END, + /* cwh */ ILLEGAL_PAIR, + /* cqu */ NOT_BEGIN | SUFFIX | NOT_END, + /* cck */ ILLEGAL_PAIR}, + {/* da */ ANY_COMBINATION, + /* db */ NOT_BEGIN | BREAK | NOT_END, + /* dc */ NOT_BEGIN | BREAK | NOT_END, + /* dd */ NOT_BEGIN, + /* de */ ANY_COMBINATION, + /* df */ NOT_BEGIN | BREAK | NOT_END, + /* dg */ NOT_BEGIN | BREAK | NOT_END, + /* dh */ NOT_BEGIN | BREAK | NOT_END, + /* di */ ANY_COMBINATION, + /* dj */ NOT_BEGIN | BREAK | NOT_END, + /* dk */ NOT_BEGIN | BREAK | NOT_END, + /* dl */ NOT_BEGIN | BREAK | NOT_END, + /* dm */ NOT_BEGIN | BREAK | NOT_END, + /* dn */ NOT_BEGIN | BREAK | NOT_END, + /* do */ ANY_COMBINATION, + /* dp */ NOT_BEGIN | BREAK | NOT_END, + /* dr */ BEGIN | NOT_END, + /* ds */ NOT_BEGIN | END, + /* dt */ NOT_BEGIN | BREAK | NOT_END, + /* du */ ANY_COMBINATION, + /* dv */ NOT_BEGIN | BREAK | NOT_END, + /* dw */ NOT_BEGIN | BREAK | NOT_END, + /* dx */ ILLEGAL_PAIR, + /* dy */ ANY_COMBINATION, + /* dz */ NOT_BEGIN | BREAK | NOT_END, + /* dch */ NOT_BEGIN | BREAK | NOT_END, + /* dgh */ NOT_BEGIN | BREAK | NOT_END, + /* dph */ NOT_BEGIN | BREAK | NOT_END, + /* drh */ ILLEGAL_PAIR, + /* dsh */ NOT_BEGIN | NOT_END, + /* dth */ NOT_BEGIN | PREFIX, + /* dwh */ ILLEGAL_PAIR, + /* dqu */ NOT_BEGIN | BREAK | NOT_END, + /* dck */ ILLEGAL_PAIR }, + {/* ea */ ANY_COMBINATION, + /* eb */ ANY_COMBINATION, + /* ec */ ANY_COMBINATION, + /* ed */ ANY_COMBINATION, + /* ee */ ANY_COMBINATION, + /* ef */ ANY_COMBINATION, + /* eg */ ANY_COMBINATION, + /* eh */ NOT_BEGIN | BREAK | NOT_END, + /* ei */ NOT_END, + /* ej */ ANY_COMBINATION, + /* ek */ ANY_COMBINATION, + /* el */ ANY_COMBINATION, + /* em */ ANY_COMBINATION, + /* en */ ANY_COMBINATION, + /* eo */ BREAK, + /* ep */ ANY_COMBINATION, + /* er */ ANY_COMBINATION, + /* es */ ANY_COMBINATION, + /* et */ ANY_COMBINATION, + /* eu */ ANY_COMBINATION, + /* ev */ ANY_COMBINATION, + /* ew */ ANY_COMBINATION, + /* ex */ ANY_COMBINATION, + /* ey */ ANY_COMBINATION, + /* ez */ ANY_COMBINATION, + /* ech */ ANY_COMBINATION, + /* egh */ NOT_BEGIN | BREAK | NOT_END, + /* eph */ ANY_COMBINATION, + /* erh */ ILLEGAL_PAIR, + /* esh */ ANY_COMBINATION, + /* eth */ ANY_COMBINATION, + /* ewh */ ILLEGAL_PAIR, + /* equ */ BREAK | NOT_END, + /* eck */ ANY_COMBINATION }, + {/* fa */ ANY_COMBINATION, + /* fb */ NOT_BEGIN | BREAK | NOT_END, + /* fc */ NOT_BEGIN | BREAK | NOT_END, + /* fd */ NOT_BEGIN | BREAK | NOT_END, + /* fe */ ANY_COMBINATION, + /* ff */ NOT_BEGIN, + /* fg */ NOT_BEGIN | BREAK | NOT_END, + /* fh */ NOT_BEGIN | BREAK | NOT_END, + /* fi */ ANY_COMBINATION, + /* fj */ NOT_BEGIN | BREAK | NOT_END, + /* fk */ NOT_BEGIN | BREAK | NOT_END, + /* fl */ BEGIN | SUFFIX | NOT_END, + /* fm */ NOT_BEGIN | BREAK | NOT_END, + /* fn */ NOT_BEGIN | BREAK | NOT_END, + /* fo */ ANY_COMBINATION, + /* fp */ NOT_BEGIN | BREAK | NOT_END, + /* fr */ BEGIN | NOT_END, + /* fs */ NOT_BEGIN, + /* ft */ NOT_BEGIN, + /* fu */ ANY_COMBINATION, + /* fv */ NOT_BEGIN | BREAK | NOT_END, + /* fw */ NOT_BEGIN | BREAK | NOT_END, + /* fx */ ILLEGAL_PAIR, + /* fy */ NOT_BEGIN, + /* fz */ NOT_BEGIN | BREAK | NOT_END, + /* fch */ NOT_BEGIN | BREAK | NOT_END, + /* fgh */ NOT_BEGIN | BREAK | NOT_END, + /* fph */ NOT_BEGIN | BREAK | NOT_END, + /* frh */ ILLEGAL_PAIR, + /* fsh */ NOT_BEGIN | BREAK | NOT_END, + /* fth */ NOT_BEGIN | BREAK | NOT_END, + /* fwh */ ILLEGAL_PAIR, + /* fqu */ NOT_BEGIN | BREAK | NOT_END, + /* fck */ ILLEGAL_PAIR }, + {/* ga */ ANY_COMBINATION, + /* gb */ NOT_BEGIN | BREAK | NOT_END, + /* gc */ NOT_BEGIN | BREAK | NOT_END, + /* gd */ NOT_BEGIN | BREAK | NOT_END, + /* ge */ ANY_COMBINATION, + /* gf */ NOT_BEGIN | BREAK | NOT_END, + /* gg */ NOT_BEGIN, + /* gh */ NOT_BEGIN | BREAK | NOT_END, + /* gi */ ANY_COMBINATION, + /* gj */ NOT_BEGIN | BREAK | NOT_END, + /* gk */ ILLEGAL_PAIR, + /* gl */ BEGIN | SUFFIX | NOT_END, + /* gm */ NOT_BEGIN | BREAK | NOT_END, + /* gn */ NOT_BEGIN | BREAK | NOT_END, + /* go */ ANY_COMBINATION, + /* gp */ NOT_BEGIN | BREAK | NOT_END, + /* gr */ BEGIN | NOT_END, + /* gs */ NOT_BEGIN | END, + /* gt */ NOT_BEGIN | BREAK | NOT_END, + /* gu */ ANY_COMBINATION, + /* gv */ NOT_BEGIN | BREAK | NOT_END, + /* gw */ NOT_BEGIN | BREAK | NOT_END, + /* gx */ ILLEGAL_PAIR, + /* gy */ NOT_BEGIN, + /* gz */ NOT_BEGIN | BREAK | NOT_END, + /* gch */ NOT_BEGIN | BREAK | NOT_END, + /* ggh */ ILLEGAL_PAIR, + /* gph */ NOT_BEGIN | BREAK | NOT_END, + /* grh */ ILLEGAL_PAIR, + /* gsh */ NOT_BEGIN, + /* gth */ NOT_BEGIN, + /* gwh */ ILLEGAL_PAIR, + /* gqu */ NOT_BEGIN | BREAK | NOT_END, + /* gck */ ILLEGAL_PAIR }, + {/* ha */ ANY_COMBINATION, + /* hb */ NOT_BEGIN | BREAK | NOT_END, + /* hc */ NOT_BEGIN | BREAK | NOT_END, + /* hd */ NOT_BEGIN | BREAK | NOT_END, + /* he */ ANY_COMBINATION, + /* hf */ NOT_BEGIN | BREAK | NOT_END, + /* hg */ NOT_BEGIN | BREAK | NOT_END, + /* hh */ ILLEGAL_PAIR, + /* hi */ ANY_COMBINATION, + /* hj */ NOT_BEGIN | BREAK | NOT_END, + /* hk */ NOT_BEGIN | BREAK | NOT_END, + /* hl */ NOT_BEGIN | BREAK | NOT_END, + /* hm */ NOT_BEGIN | BREAK | NOT_END, + /* hn */ NOT_BEGIN | BREAK | NOT_END, + /* ho */ ANY_COMBINATION, + /* hp */ NOT_BEGIN | BREAK | NOT_END, + /* hr */ NOT_BEGIN | BREAK | NOT_END, + /* hs */ NOT_BEGIN | BREAK | NOT_END, + /* ht */ NOT_BEGIN | BREAK | NOT_END, + /* hu */ ANY_COMBINATION, + /* hv */ NOT_BEGIN | BREAK | NOT_END, + /* hw */ NOT_BEGIN | BREAK | NOT_END, + /* hx */ ILLEGAL_PAIR, + /* hy */ ANY_COMBINATION, + /* hz */ NOT_BEGIN | BREAK | NOT_END, + /* hch */ NOT_BEGIN | BREAK | NOT_END, + /* hgh */ NOT_BEGIN | BREAK | NOT_END, + /* hph */ NOT_BEGIN | BREAK | NOT_END, + /* hrh */ ILLEGAL_PAIR, + /* hsh */ NOT_BEGIN | BREAK | NOT_END, + /* hth */ NOT_BEGIN | BREAK | NOT_END, + /* hwh */ ILLEGAL_PAIR, + /* hqu */ NOT_BEGIN | BREAK | NOT_END, + /* hck */ ILLEGAL_PAIR }, + {/* ia */ ANY_COMBINATION, + /* ib */ ANY_COMBINATION, + /* ic */ ANY_COMBINATION, + /* id */ ANY_COMBINATION, + /* ie */ NOT_BEGIN, + /* if */ ANY_COMBINATION, + /* ig */ ANY_COMBINATION, + /* ih */ NOT_BEGIN | BREAK | NOT_END, + /* ii */ ILLEGAL_PAIR, + /* ij */ ANY_COMBINATION, + /* ik */ ANY_COMBINATION, + /* il */ ANY_COMBINATION, + /* im */ ANY_COMBINATION, + /* in */ ANY_COMBINATION, + /* io */ BREAK, + /* ip */ ANY_COMBINATION, + /* ir */ ANY_COMBINATION, + /* is */ ANY_COMBINATION, + /* it */ ANY_COMBINATION, + /* iu */ NOT_BEGIN | BREAK | NOT_END, + /* iv */ ANY_COMBINATION, + /* iw */ NOT_BEGIN | BREAK | NOT_END, + /* ix */ ANY_COMBINATION, + /* iy */ NOT_BEGIN | BREAK | NOT_END, + /* iz */ ANY_COMBINATION, + /* ich */ ANY_COMBINATION, + /* igh */ NOT_BEGIN, + /* iph */ ANY_COMBINATION, + /* irh */ ILLEGAL_PAIR, + /* ish */ ANY_COMBINATION, + /* ith */ ANY_COMBINATION, + /* iwh */ ILLEGAL_PAIR, + /* iqu */ BREAK | NOT_END, + /* ick */ ANY_COMBINATION }, + {/* ja */ ANY_COMBINATION, + /* jb */ NOT_BEGIN | BREAK | NOT_END, + /* jc */ NOT_BEGIN | BREAK | NOT_END, + /* jd */ NOT_BEGIN | BREAK | NOT_END, + /* je */ ANY_COMBINATION, + /* jf */ NOT_BEGIN | BREAK | NOT_END, + /* jg */ ILLEGAL_PAIR, + /* jh */ NOT_BEGIN | BREAK | NOT_END, + /* ji */ ANY_COMBINATION, + /* jj */ ILLEGAL_PAIR, + /* jk */ NOT_BEGIN | BREAK | NOT_END, + /* jl */ NOT_BEGIN | BREAK | NOT_END, + /* jm */ NOT_BEGIN | BREAK | NOT_END, + /* jn */ NOT_BEGIN | BREAK | NOT_END, + /* jo */ ANY_COMBINATION, + /* jp */ NOT_BEGIN | BREAK | NOT_END, + /* jr */ NOT_BEGIN | BREAK | NOT_END, + /* js */ NOT_BEGIN | BREAK | NOT_END, + /* jt */ NOT_BEGIN | BREAK | NOT_END, + /* ju */ ANY_COMBINATION, + /* jv */ NOT_BEGIN | BREAK | NOT_END, + /* jw */ NOT_BEGIN | BREAK | NOT_END, + /* jx */ ILLEGAL_PAIR, + /* jy */ NOT_BEGIN, + /* jz */ NOT_BEGIN | BREAK | NOT_END, + /* jch */ NOT_BEGIN | BREAK | NOT_END, + /* jgh */ NOT_BEGIN | BREAK | NOT_END, + /* jph */ NOT_BEGIN | BREAK | NOT_END, + /* jrh */ ILLEGAL_PAIR, + /* jsh */ NOT_BEGIN | BREAK | NOT_END, + /* jth */ NOT_BEGIN | BREAK | NOT_END, + /* jwh */ ILLEGAL_PAIR, + /* jqu */ NOT_BEGIN | BREAK | NOT_END, + /* jck */ ILLEGAL_PAIR }, + {/* ka */ ANY_COMBINATION, + /* kb */ NOT_BEGIN | BREAK | NOT_END, + /* kc */ NOT_BEGIN | BREAK | NOT_END, + /* kd */ NOT_BEGIN | BREAK | NOT_END, + /* ke */ ANY_COMBINATION, + /* kf */ NOT_BEGIN | BREAK | NOT_END, + /* kg */ NOT_BEGIN | BREAK | NOT_END, + /* kh */ NOT_BEGIN | BREAK | NOT_END, + /* ki */ ANY_COMBINATION, + /* kj */ NOT_BEGIN | BREAK | NOT_END, + /* kk */ NOT_BEGIN | BREAK | NOT_END, + /* kl */ SUFFIX | NOT_END, + /* km */ NOT_BEGIN | BREAK | NOT_END, + /* kn */ BEGIN | SUFFIX | NOT_END, + /* ko */ ANY_COMBINATION, + /* kp */ NOT_BEGIN | BREAK | NOT_END, + /* kr */ SUFFIX | NOT_END, + /* ks */ NOT_BEGIN | END, + /* kt */ NOT_BEGIN | BREAK | NOT_END, + /* ku */ ANY_COMBINATION, + /* kv */ NOT_BEGIN | BREAK | NOT_END, + /* kw */ NOT_BEGIN | BREAK | NOT_END, + /* kx */ ILLEGAL_PAIR, + /* ky */ NOT_BEGIN, + /* kz */ NOT_BEGIN | BREAK | NOT_END, + /* kch */ NOT_BEGIN | BREAK | NOT_END, + /* kgh */ NOT_BEGIN | BREAK | NOT_END, + /* kph */ NOT_BEGIN | PREFIX, + /* krh */ ILLEGAL_PAIR, + /* ksh */ NOT_BEGIN, + /* kth */ NOT_BEGIN | BREAK | NOT_END, + /* kwh */ ILLEGAL_PAIR, + /* kqu */ NOT_BEGIN | BREAK | NOT_END, + /* kck */ ILLEGAL_PAIR }, + {/* la */ ANY_COMBINATION, + /* lb */ NOT_BEGIN | PREFIX, + /* lc */ NOT_BEGIN | BREAK | NOT_END, + /* ld */ NOT_BEGIN | PREFIX, + /* le */ ANY_COMBINATION, + /* lf */ NOT_BEGIN | PREFIX, + /* lg */ NOT_BEGIN | PREFIX, + /* lh */ NOT_BEGIN | BREAK | NOT_END, + /* li */ ANY_COMBINATION, + /* lj */ NOT_BEGIN | PREFIX, + /* lk */ NOT_BEGIN | PREFIX, + /* ll */ NOT_BEGIN | PREFIX, + /* lm */ NOT_BEGIN | PREFIX, + /* ln */ NOT_BEGIN | BREAK | NOT_END, + /* lo */ ANY_COMBINATION, + /* lp */ NOT_BEGIN | PREFIX, + /* lr */ NOT_BEGIN | BREAK | NOT_END, + /* ls */ NOT_BEGIN, + /* lt */ NOT_BEGIN | PREFIX, + /* lu */ ANY_COMBINATION, + /* lv */ NOT_BEGIN | PREFIX, + /* lw */ NOT_BEGIN | BREAK | NOT_END, + /* lx */ ILLEGAL_PAIR, + /* ly */ ANY_COMBINATION, + /* lz */ NOT_BEGIN | BREAK | NOT_END, + /* lch */ NOT_BEGIN | PREFIX, + /* lgh */ NOT_BEGIN | BREAK | NOT_END, + /* lph */ NOT_BEGIN | PREFIX, + /* lrh */ ILLEGAL_PAIR, + /* lsh */ NOT_BEGIN | PREFIX, + /* lth */ NOT_BEGIN | PREFIX, + /* lwh */ ILLEGAL_PAIR, + /* lqu */ NOT_BEGIN | BREAK | NOT_END, + /* lck */ ILLEGAL_PAIR }, + {/* ma */ ANY_COMBINATION, + /* mb */ NOT_BEGIN | BREAK | NOT_END, + /* mc */ NOT_BEGIN | BREAK | NOT_END, + /* md */ NOT_BEGIN | BREAK | NOT_END, + /* me */ ANY_COMBINATION, + /* mf */ NOT_BEGIN | BREAK | NOT_END, + /* mg */ NOT_BEGIN | BREAK | NOT_END, + /* mh */ NOT_BEGIN | BREAK | NOT_END, + /* mi */ ANY_COMBINATION, + /* mj */ NOT_BEGIN | BREAK | NOT_END, + /* mk */ NOT_BEGIN | BREAK | NOT_END, + /* ml */ NOT_BEGIN | BREAK | NOT_END, + /* mm */ NOT_BEGIN, + /* mn */ NOT_BEGIN | BREAK | NOT_END, + /* mo */ ANY_COMBINATION, + /* mp */ NOT_BEGIN, + /* mr */ NOT_BEGIN | BREAK | NOT_END, + /* ms */ NOT_BEGIN, + /* mt */ NOT_BEGIN, + /* mu */ ANY_COMBINATION, + /* mv */ NOT_BEGIN | BREAK | NOT_END, + /* mw */ NOT_BEGIN | BREAK | NOT_END, + /* mx */ ILLEGAL_PAIR, + /* my */ ANY_COMBINATION, + /* mz */ NOT_BEGIN | BREAK | NOT_END, + /* mch */ NOT_BEGIN | PREFIX, + /* mgh */ NOT_BEGIN | BREAK | NOT_END, + /* mph */ NOT_BEGIN, + /* mrh */ ILLEGAL_PAIR, + /* msh */ NOT_BEGIN, + /* mth */ NOT_BEGIN, + /* mwh */ ILLEGAL_PAIR, + /* mqu */ NOT_BEGIN | BREAK | NOT_END, + /* mck */ ILLEGAL_PAIR }, + {/* na */ ANY_COMBINATION, + /* nb */ NOT_BEGIN | BREAK | NOT_END, + /* nc */ NOT_BEGIN | BREAK | NOT_END, + /* nd */ NOT_BEGIN, + /* ne */ ANY_COMBINATION, + /* nf */ NOT_BEGIN | BREAK | NOT_END, + /* ng */ NOT_BEGIN | PREFIX, + /* nh */ NOT_BEGIN | BREAK | NOT_END, + /* ni */ ANY_COMBINATION, + /* nj */ NOT_BEGIN | BREAK | NOT_END, + /* nk */ NOT_BEGIN | PREFIX, + /* nl */ NOT_BEGIN | BREAK | NOT_END, + /* nm */ NOT_BEGIN | BREAK | NOT_END, + /* nn */ NOT_BEGIN, + /* no */ ANY_COMBINATION, + /* np */ NOT_BEGIN | BREAK | NOT_END, + /* nr */ NOT_BEGIN | BREAK | NOT_END, + /* ns */ NOT_BEGIN, + /* nt */ NOT_BEGIN, + /* nu */ ANY_COMBINATION, + /* nv */ NOT_BEGIN | BREAK | NOT_END, + /* nw */ NOT_BEGIN | BREAK | NOT_END, + /* nx */ ILLEGAL_PAIR, + /* ny */ NOT_BEGIN, + /* nz */ NOT_BEGIN | BREAK | NOT_END, + /* nch */ NOT_BEGIN | PREFIX, + /* ngh */ NOT_BEGIN | BREAK | NOT_END, + /* nph */ NOT_BEGIN | PREFIX, + /* nrh */ ILLEGAL_PAIR, + /* nsh */ NOT_BEGIN, + /* nth */ NOT_BEGIN, + /* nwh */ ILLEGAL_PAIR, + /* nqu */ NOT_BEGIN | BREAK | NOT_END, + /* nck */ NOT_BEGIN | PREFIX }, + {/* oa */ ANY_COMBINATION, + /* ob */ ANY_COMBINATION, + /* oc */ ANY_COMBINATION, + /* od */ ANY_COMBINATION, + /* oe */ ILLEGAL_PAIR, + /* of */ ANY_COMBINATION, + /* og */ ANY_COMBINATION, + /* oh */ NOT_BEGIN | BREAK | NOT_END, + /* oi */ ANY_COMBINATION, + /* oj */ ANY_COMBINATION, + /* ok */ ANY_COMBINATION, + /* ol */ ANY_COMBINATION, + /* om */ ANY_COMBINATION, + /* on */ ANY_COMBINATION, + /* oo */ ANY_COMBINATION, + /* op */ ANY_COMBINATION, + /* or */ ANY_COMBINATION, + /* os */ ANY_COMBINATION, + /* ot */ ANY_COMBINATION, + /* ou */ ANY_COMBINATION, + /* ov */ ANY_COMBINATION, + /* ow */ ANY_COMBINATION, + /* ox */ ANY_COMBINATION, + /* oy */ ANY_COMBINATION, + /* oz */ ANY_COMBINATION, + /* och */ ANY_COMBINATION, + /* ogh */ NOT_BEGIN, + /* oph */ ANY_COMBINATION, + /* orh */ ILLEGAL_PAIR, + /* osh */ ANY_COMBINATION, + /* oth */ ANY_COMBINATION, + /* owh */ ILLEGAL_PAIR, + /* oqu */ BREAK | NOT_END, + /* ock */ ANY_COMBINATION }, + {/* pa */ ANY_COMBINATION, + /* pb */ NOT_BEGIN | BREAK | NOT_END, + /* pc */ NOT_BEGIN | BREAK | NOT_END, + /* pd */ NOT_BEGIN | BREAK | NOT_END, + /* pe */ ANY_COMBINATION, + /* pf */ NOT_BEGIN | BREAK | NOT_END, + /* pg */ NOT_BEGIN | BREAK | NOT_END, + /* ph */ NOT_BEGIN | BREAK | NOT_END, + /* pi */ ANY_COMBINATION, + /* pj */ NOT_BEGIN | BREAK | NOT_END, + /* pk */ NOT_BEGIN | BREAK | NOT_END, + /* pl */ SUFFIX | NOT_END, + /* pm */ NOT_BEGIN | BREAK | NOT_END, + /* pn */ NOT_BEGIN | BREAK | NOT_END, + /* po */ ANY_COMBINATION, + /* pp */ NOT_BEGIN | PREFIX, + /* pr */ NOT_END, + /* ps */ NOT_BEGIN | END, + /* pt */ NOT_BEGIN | END, + /* pu */ NOT_BEGIN | END, + /* pv */ NOT_BEGIN | BREAK | NOT_END, + /* pw */ NOT_BEGIN | BREAK | NOT_END, + /* px */ ILLEGAL_PAIR, + /* py */ ANY_COMBINATION, + /* pz */ NOT_BEGIN | BREAK | NOT_END, + /* pch */ NOT_BEGIN | BREAK | NOT_END, + /* pgh */ NOT_BEGIN | BREAK | NOT_END, + /* pph */ NOT_BEGIN | BREAK | NOT_END, + /* prh */ ILLEGAL_PAIR, + /* psh */ NOT_BEGIN | BREAK | NOT_END, + /* pth */ NOT_BEGIN | BREAK | NOT_END, + /* pwh */ ILLEGAL_PAIR, + /* pqu */ NOT_BEGIN | BREAK | NOT_END, + /* pck */ ILLEGAL_PAIR }, + {/* ra */ ANY_COMBINATION, + /* rb */ NOT_BEGIN | PREFIX, + /* rc */ NOT_BEGIN | PREFIX, + /* rd */ NOT_BEGIN | PREFIX, + /* re */ ANY_COMBINATION, + /* rf */ NOT_BEGIN | PREFIX, + /* rg */ NOT_BEGIN | PREFIX, + /* rh */ NOT_BEGIN | BREAK | NOT_END, + /* ri */ ANY_COMBINATION, + /* rj */ NOT_BEGIN | PREFIX, + /* rk */ NOT_BEGIN | PREFIX, + /* rl */ NOT_BEGIN | PREFIX, + /* rm */ NOT_BEGIN | PREFIX, + /* rn */ NOT_BEGIN | PREFIX, + /* ro */ ANY_COMBINATION, + /* rp */ NOT_BEGIN | PREFIX, + /* rr */ NOT_BEGIN | PREFIX, + /* rs */ NOT_BEGIN | PREFIX, + /* rt */ NOT_BEGIN | PREFIX, + /* ru */ ANY_COMBINATION, + /* rv */ NOT_BEGIN | PREFIX, + /* rw */ NOT_BEGIN | BREAK | NOT_END, + /* rx */ ILLEGAL_PAIR, + /* ry */ ANY_COMBINATION, + /* rz */ NOT_BEGIN | PREFIX, + /* rch */ NOT_BEGIN | PREFIX, + /* rgh */ NOT_BEGIN | BREAK | NOT_END, + /* rph */ NOT_BEGIN | PREFIX, + /* rrh */ ILLEGAL_PAIR, + /* rsh */ NOT_BEGIN | PREFIX, + /* rth */ NOT_BEGIN | PREFIX, + /* rwh */ ILLEGAL_PAIR, + /* rqu */ NOT_BEGIN | PREFIX | NOT_END, + /* rck */ NOT_BEGIN | PREFIX }, + {/* sa */ ANY_COMBINATION, + /* sb */ NOT_BEGIN | BREAK | NOT_END, + /* sc */ NOT_END, + /* sd */ NOT_BEGIN | BREAK | NOT_END, + /* se */ ANY_COMBINATION, + /* sf */ NOT_BEGIN | BREAK | NOT_END, + /* sg */ NOT_BEGIN | BREAK | NOT_END, + /* sh */ NOT_BEGIN | BREAK | NOT_END, + /* si */ ANY_COMBINATION, + /* sj */ NOT_BEGIN | BREAK | NOT_END, + /* sk */ ANY_COMBINATION, + /* sl */ BEGIN | SUFFIX | NOT_END, + /* sm */ SUFFIX | NOT_END, + /* sn */ PREFIX | SUFFIX | NOT_END, + /* so */ ANY_COMBINATION, + /* sp */ ANY_COMBINATION, + /* sr */ NOT_BEGIN | NOT_END, + /* ss */ NOT_BEGIN | PREFIX, + /* st */ ANY_COMBINATION, + /* su */ ANY_COMBINATION, + /* sv */ NOT_BEGIN | BREAK | NOT_END, + /* sw */ BEGIN | SUFFIX | NOT_END, + /* sx */ ILLEGAL_PAIR, + /* sy */ ANY_COMBINATION, + /* sz */ NOT_BEGIN | BREAK | NOT_END, + /* sch */ BEGIN | SUFFIX | NOT_END, + /* sgh */ NOT_BEGIN | BREAK | NOT_END, + /* sph */ NOT_BEGIN | BREAK | NOT_END, + /* srh */ ILLEGAL_PAIR, + /* ssh */ NOT_BEGIN | BREAK | NOT_END, + /* sth */ NOT_BEGIN | BREAK | NOT_END, + /* swh */ ILLEGAL_PAIR, + /* squ */ SUFFIX | NOT_END, + /* sck */ NOT_BEGIN }, + {/* ta */ ANY_COMBINATION, + /* tb */ NOT_BEGIN | BREAK | NOT_END, + /* tc */ NOT_BEGIN | BREAK | NOT_END, + /* td */ NOT_BEGIN | BREAK | NOT_END, + /* te */ ANY_COMBINATION, + /* tf */ NOT_BEGIN | BREAK | NOT_END, + /* tg */ NOT_BEGIN | BREAK | NOT_END, + /* th */ NOT_BEGIN | BREAK | NOT_END, + /* ti */ ANY_COMBINATION, + /* tj */ NOT_BEGIN | BREAK | NOT_END, + /* tk */ NOT_BEGIN | BREAK | NOT_END, + /* tl */ NOT_BEGIN | BREAK | NOT_END, + /* tm */ NOT_BEGIN | BREAK | NOT_END, + /* tn */ NOT_BEGIN | BREAK | NOT_END, + /* to */ ANY_COMBINATION, + /* tp */ NOT_BEGIN | BREAK | NOT_END, + /* tr */ NOT_END, + /* ts */ NOT_BEGIN | END, + /* tt */ NOT_BEGIN | PREFIX, + /* tu */ ANY_COMBINATION, + /* tv */ NOT_BEGIN | BREAK | NOT_END, + /* tw */ BEGIN | SUFFIX | NOT_END, + /* tx */ ILLEGAL_PAIR, + /* ty */ ANY_COMBINATION, + /* tz */ NOT_BEGIN | BREAK | NOT_END, + /* tch */ NOT_BEGIN, + /* tgh */ NOT_BEGIN | BREAK | NOT_END, + /* tph */ NOT_BEGIN | END, + /* trh */ ILLEGAL_PAIR, + /* tsh */ NOT_BEGIN | END, + /* tth */ NOT_BEGIN | BREAK | NOT_END, + /* twh */ ILLEGAL_PAIR, + /* tqu */ NOT_BEGIN | BREAK | NOT_END, + /* tck */ ILLEGAL_PAIR }, + {/* ua */ NOT_BEGIN | BREAK | NOT_END, + /* ub */ ANY_COMBINATION, + /* uc */ ANY_COMBINATION, + /* ud */ ANY_COMBINATION, + /* ue */ NOT_BEGIN, + /* uf */ ANY_COMBINATION, + /* ug */ ANY_COMBINATION, + /* uh */ NOT_BEGIN | BREAK | NOT_END, + /* ui */ NOT_BEGIN | BREAK | NOT_END, + /* uj */ ANY_COMBINATION, + /* uk */ ANY_COMBINATION, + /* ul */ ANY_COMBINATION, + /* um */ ANY_COMBINATION, + /* un */ ANY_COMBINATION, + /* uo */ NOT_BEGIN | BREAK, + /* up */ ANY_COMBINATION, + /* ur */ ANY_COMBINATION, + /* us */ ANY_COMBINATION, + /* ut */ ANY_COMBINATION, + /* uu */ ILLEGAL_PAIR, + /* uv */ ANY_COMBINATION, + /* uw */ NOT_BEGIN | BREAK | NOT_END, + /* ux */ ANY_COMBINATION, + /* uy */ NOT_BEGIN | BREAK | NOT_END, + /* uz */ ANY_COMBINATION, + /* uch */ ANY_COMBINATION, + /* ugh */ NOT_BEGIN | PREFIX, + /* uph */ ANY_COMBINATION, + /* urh */ ILLEGAL_PAIR, + /* ush */ ANY_COMBINATION, + /* uth */ ANY_COMBINATION, + /* uwh */ ILLEGAL_PAIR, + /* uqu */ BREAK | NOT_END, + /* uck */ ANY_COMBINATION }, + {/* va */ ANY_COMBINATION, + /* vb */ NOT_BEGIN | BREAK | NOT_END, + /* vc */ NOT_BEGIN | BREAK | NOT_END, + /* vd */ NOT_BEGIN | BREAK | NOT_END, + /* ve */ ANY_COMBINATION, + /* vf */ NOT_BEGIN | BREAK | NOT_END, + /* vg */ NOT_BEGIN | BREAK | NOT_END, + /* vh */ NOT_BEGIN | BREAK | NOT_END, + /* vi */ ANY_COMBINATION, + /* vj */ NOT_BEGIN | BREAK | NOT_END, + /* vk */ NOT_BEGIN | BREAK | NOT_END, + /* vl */ NOT_BEGIN | BREAK | NOT_END, + /* vm */ NOT_BEGIN | BREAK | NOT_END, + /* vn */ NOT_BEGIN | BREAK | NOT_END, + /* vo */ ANY_COMBINATION, + /* vp */ NOT_BEGIN | BREAK | NOT_END, + /* vr */ NOT_BEGIN | BREAK | NOT_END, + /* vs */ NOT_BEGIN | BREAK | NOT_END, + /* vt */ NOT_BEGIN | BREAK | NOT_END, + /* vu */ ANY_COMBINATION, + /* vv */ NOT_BEGIN | BREAK | NOT_END, + /* vw */ NOT_BEGIN | BREAK | NOT_END, + /* vx */ ILLEGAL_PAIR, + /* vy */ NOT_BEGIN, + /* vz */ NOT_BEGIN | BREAK | NOT_END, + /* vch */ NOT_BEGIN | BREAK | NOT_END, + /* vgh */ NOT_BEGIN | BREAK | NOT_END, + /* vph */ NOT_BEGIN | BREAK | NOT_END, + /* vrh */ ILLEGAL_PAIR, + /* vsh */ NOT_BEGIN | BREAK | NOT_END, + /* vth */ NOT_BEGIN | BREAK | NOT_END, + /* vwh */ ILLEGAL_PAIR, + /* vqu */ NOT_BEGIN | BREAK | NOT_END, + /* vck */ ILLEGAL_PAIR }, + {/* wa */ ANY_COMBINATION, + /* wb */ NOT_BEGIN | PREFIX, + /* wc */ NOT_BEGIN | BREAK | NOT_END, + /* wd */ NOT_BEGIN | PREFIX | END, + /* we */ ANY_COMBINATION, + /* wf */ NOT_BEGIN | PREFIX, + /* wg */ NOT_BEGIN | PREFIX | END, + /* wh */ NOT_BEGIN | BREAK | NOT_END, + /* wi */ ANY_COMBINATION, + /* wj */ NOT_BEGIN | BREAK | NOT_END, + /* wk */ NOT_BEGIN | PREFIX, + /* wl */ NOT_BEGIN | PREFIX | SUFFIX, + /* wm */ NOT_BEGIN | PREFIX, + /* wn */ NOT_BEGIN | PREFIX, + /* wo */ ANY_COMBINATION, + /* wp */ NOT_BEGIN | PREFIX, + /* wr */ BEGIN | SUFFIX | NOT_END, + /* ws */ NOT_BEGIN | PREFIX, + /* wt */ NOT_BEGIN | PREFIX, + /* wu */ ANY_COMBINATION, + /* wv */ NOT_BEGIN | PREFIX, + /* ww */ NOT_BEGIN | BREAK | NOT_END, + /* wx */ NOT_BEGIN | PREFIX, + /* wy */ ANY_COMBINATION, + /* wz */ NOT_BEGIN | PREFIX, + /* wch */ NOT_BEGIN, + /* wgh */ NOT_BEGIN | BREAK | NOT_END, + /* wph */ NOT_BEGIN, + /* wrh */ ILLEGAL_PAIR, + /* wsh */ NOT_BEGIN, + /* wth */ NOT_BEGIN, + /* wwh */ ILLEGAL_PAIR, + /* wqu */ NOT_BEGIN | BREAK | NOT_END, + /* wck */ NOT_BEGIN }, + {/* xa */ NOT_BEGIN, + /* xb */ NOT_BEGIN | BREAK | NOT_END, + /* xc */ NOT_BEGIN | BREAK | NOT_END, + /* xd */ NOT_BEGIN | BREAK | NOT_END, + /* xe */ NOT_BEGIN, + /* xf */ NOT_BEGIN | BREAK | NOT_END, + /* xg */ NOT_BEGIN | BREAK | NOT_END, + /* xh */ NOT_BEGIN | BREAK | NOT_END, + /* xi */ NOT_BEGIN, + /* xj */ NOT_BEGIN | BREAK | NOT_END, + /* xk */ NOT_BEGIN | BREAK | NOT_END, + /* xl */ NOT_BEGIN | BREAK | NOT_END, + /* xm */ NOT_BEGIN | BREAK | NOT_END, + /* xn */ NOT_BEGIN | BREAK | NOT_END, + /* xo */ NOT_BEGIN, + /* xp */ NOT_BEGIN | BREAK | NOT_END, + /* xr */ NOT_BEGIN | BREAK | NOT_END, + /* xs */ NOT_BEGIN | BREAK | NOT_END, + /* xt */ NOT_BEGIN | BREAK | NOT_END, + /* xu */ NOT_BEGIN, + /* xv */ NOT_BEGIN | BREAK | NOT_END, + /* xw */ NOT_BEGIN | BREAK | NOT_END, + /* xx */ ILLEGAL_PAIR, + /* xy */ NOT_BEGIN, + /* xz */ NOT_BEGIN | BREAK | NOT_END, + /* xch */ NOT_BEGIN | BREAK | NOT_END, + /* xgh */ NOT_BEGIN | BREAK | NOT_END, + /* xph */ NOT_BEGIN | BREAK | NOT_END, + /* xrh */ ILLEGAL_PAIR, + /* xsh */ NOT_BEGIN | BREAK | NOT_END, + /* xth */ NOT_BEGIN | BREAK | NOT_END, + /* xwh */ ILLEGAL_PAIR, + /* xqu */ NOT_BEGIN | BREAK | NOT_END, + /* xck */ ILLEGAL_PAIR }, + {/* ya */ ANY_COMBINATION, + /* yb */ NOT_BEGIN, + /* yc */ NOT_BEGIN | NOT_END, + /* yd */ NOT_BEGIN, + /* ye */ ANY_COMBINATION, + /* yf */ NOT_BEGIN | NOT_END, + /* yg */ NOT_BEGIN, + /* yh */ NOT_BEGIN | BREAK | NOT_END, + /* yi */ BEGIN | NOT_END, + /* yj */ NOT_BEGIN | NOT_END, + /* yk */ NOT_BEGIN, + /* yl */ NOT_BEGIN | NOT_END, + /* ym */ NOT_BEGIN, + /* yn */ NOT_BEGIN, + /* yo */ ANY_COMBINATION, + /* yp */ NOT_BEGIN, + /* yr */ NOT_BEGIN | BREAK | NOT_END, + /* ys */ NOT_BEGIN, + /* yt */ NOT_BEGIN, + /* yu */ ANY_COMBINATION, + /* yv */ NOT_BEGIN | NOT_END, + /* yw */ NOT_BEGIN | BREAK | NOT_END, + /* yx */ NOT_BEGIN, + /* yy */ ILLEGAL_PAIR, + /* yz */ NOT_BEGIN, + /* ych */ NOT_BEGIN | BREAK | NOT_END, + /* ygh */ NOT_BEGIN | BREAK | NOT_END, + /* yph */ NOT_BEGIN | BREAK | NOT_END, + /* yrh */ ILLEGAL_PAIR, + /* ysh */ NOT_BEGIN | BREAK | NOT_END, + /* yth */ NOT_BEGIN | BREAK | NOT_END, + /* ywh */ ILLEGAL_PAIR, + /* yqu */ NOT_BEGIN | BREAK | NOT_END, + /* yck */ ILLEGAL_PAIR }, + {/* za */ ANY_COMBINATION, + /* zb */ NOT_BEGIN | BREAK | NOT_END, + /* zc */ NOT_BEGIN | BREAK | NOT_END, + /* zd */ NOT_BEGIN | BREAK | NOT_END, + /* ze */ ANY_COMBINATION, + /* zf */ NOT_BEGIN | BREAK | NOT_END, + /* zg */ NOT_BEGIN | BREAK | NOT_END, + /* zh */ NOT_BEGIN | BREAK | NOT_END, + /* zi */ ANY_COMBINATION, + /* zj */ NOT_BEGIN | BREAK | NOT_END, + /* zk */ NOT_BEGIN | BREAK | NOT_END, + /* zl */ NOT_BEGIN | BREAK | NOT_END, + /* zm */ NOT_BEGIN | BREAK | NOT_END, + /* zn */ NOT_BEGIN | BREAK | NOT_END, + /* zo */ ANY_COMBINATION, + /* zp */ NOT_BEGIN | BREAK | NOT_END, + /* zr */ NOT_BEGIN | NOT_END, + /* zs */ NOT_BEGIN | BREAK | NOT_END, + /* zt */ NOT_BEGIN, + /* zu */ ANY_COMBINATION, + /* zv */ NOT_BEGIN | BREAK | NOT_END, + /* zw */ SUFFIX | NOT_END, + /* zx */ ILLEGAL_PAIR, + /* zy */ ANY_COMBINATION, + /* zz */ NOT_BEGIN, + /* zch */ NOT_BEGIN | BREAK | NOT_END, + /* zgh */ NOT_BEGIN | BREAK | NOT_END, + /* zph */ NOT_BEGIN | BREAK | NOT_END, + /* zrh */ ILLEGAL_PAIR, + /* zsh */ NOT_BEGIN | BREAK | NOT_END, + /* zth */ NOT_BEGIN | BREAK | NOT_END, + /* zwh */ ILLEGAL_PAIR, + /* zqu */ NOT_BEGIN | BREAK | NOT_END, + /* zck */ ILLEGAL_PAIR }, + {/* cha */ ANY_COMBINATION, + /* chb */ NOT_BEGIN | BREAK | NOT_END, + /* chc */ NOT_BEGIN | BREAK | NOT_END, + /* chd */ NOT_BEGIN | BREAK | NOT_END, + /* che */ ANY_COMBINATION, + /* chf */ NOT_BEGIN | BREAK | NOT_END, + /* chg */ NOT_BEGIN | BREAK | NOT_END, + /* chh */ NOT_BEGIN | BREAK | NOT_END, + /* chi */ ANY_COMBINATION, + /* chj */ NOT_BEGIN | BREAK | NOT_END, + /* chk */ NOT_BEGIN | BREAK | NOT_END, + /* chl */ NOT_BEGIN | BREAK | NOT_END, + /* chm */ NOT_BEGIN | BREAK | NOT_END, + /* chn */ NOT_BEGIN | BREAK | NOT_END, + /* cho */ ANY_COMBINATION, + /* chp */ NOT_BEGIN | BREAK | NOT_END, + /* chr */ NOT_END, + /* chs */ NOT_BEGIN | BREAK | NOT_END, + /* cht */ NOT_BEGIN | BREAK | NOT_END, + /* chu */ ANY_COMBINATION, + /* chv */ NOT_BEGIN | BREAK | NOT_END, + /* chw */ NOT_BEGIN | NOT_END, + /* chx */ ILLEGAL_PAIR, + /* chy */ ANY_COMBINATION, + /* chz */ NOT_BEGIN | BREAK | NOT_END, + /* chch */ ILLEGAL_PAIR, + /* chgh */ NOT_BEGIN | BREAK | NOT_END, + /* chph */ NOT_BEGIN | BREAK | NOT_END, + /* chrh */ ILLEGAL_PAIR, + /* chsh */ NOT_BEGIN | BREAK | NOT_END, + /* chth */ NOT_BEGIN | BREAK | NOT_END, + /* chwh */ ILLEGAL_PAIR, + /* chqu */ NOT_BEGIN | BREAK | NOT_END, + /* chck */ ILLEGAL_PAIR }, + {/* gha */ ANY_COMBINATION, + /* ghb */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghc */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghd */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghe */ ANY_COMBINATION, + /* ghf */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghg */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghh */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghi */ BEGIN | NOT_END, + /* ghj */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghk */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghl */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghm */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghn */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* gho */ BEGIN | NOT_END, + /* ghp */ NOT_BEGIN | BREAK | NOT_END, + /* ghr */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghs */ NOT_BEGIN | PREFIX, + /* ght */ NOT_BEGIN | PREFIX, + /* ghu */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghv */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghw */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghx */ ILLEGAL_PAIR, + /* ghy */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghz */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghch */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghgh */ ILLEGAL_PAIR, + /* ghph */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghrh */ ILLEGAL_PAIR, + /* ghsh */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghth */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghwh */ ILLEGAL_PAIR, + /* ghqu */ NOT_BEGIN | BREAK | PREFIX | NOT_END, + /* ghck */ ILLEGAL_PAIR }, + {/* pha */ ANY_COMBINATION, + /* phb */ NOT_BEGIN | BREAK | NOT_END, + /* phc */ NOT_BEGIN | BREAK | NOT_END, + /* phd */ NOT_BEGIN | BREAK | NOT_END, + /* phe */ ANY_COMBINATION, + /* phf */ NOT_BEGIN | BREAK | NOT_END, + /* phg */ NOT_BEGIN | BREAK | NOT_END, + /* phh */ NOT_BEGIN | BREAK | NOT_END, + /* phi */ ANY_COMBINATION, + /* phj */ NOT_BEGIN | BREAK | NOT_END, + /* phk */ NOT_BEGIN | BREAK | NOT_END, + /* phl */ BEGIN | SUFFIX | NOT_END, + /* phm */ NOT_BEGIN | BREAK | NOT_END, + /* phn */ NOT_BEGIN | BREAK | NOT_END, + /* pho */ ANY_COMBINATION, + /* php */ NOT_BEGIN | BREAK | NOT_END, + /* phr */ NOT_END, + /* phs */ NOT_BEGIN, + /* pht */ NOT_BEGIN, + /* phu */ ANY_COMBINATION, + /* phv */ NOT_BEGIN | NOT_END, + /* phw */ NOT_BEGIN | NOT_END, + /* phx */ ILLEGAL_PAIR, + /* phy */ NOT_BEGIN, + /* phz */ NOT_BEGIN | BREAK | NOT_END, + /* phch */ NOT_BEGIN | BREAK | NOT_END, + /* phgh */ NOT_BEGIN | BREAK | NOT_END, + /* phph */ ILLEGAL_PAIR, + /* phrh */ ILLEGAL_PAIR, + /* phsh */ NOT_BEGIN | BREAK | NOT_END, + /* phth */ NOT_BEGIN | BREAK | NOT_END, + /* phwh */ ILLEGAL_PAIR, + /* phqu */ NOT_BEGIN | BREAK | NOT_END, + /* phck */ ILLEGAL_PAIR }, + {/* rha */ BEGIN | NOT_END, + /* rhb */ ILLEGAL_PAIR, + /* rhc */ ILLEGAL_PAIR, + /* rhd */ ILLEGAL_PAIR, + /* rhe */ BEGIN | NOT_END, + /* rhf */ ILLEGAL_PAIR, + /* rhg */ ILLEGAL_PAIR, + /* rhh */ ILLEGAL_PAIR, + /* rhi */ BEGIN | NOT_END, + /* rhj */ ILLEGAL_PAIR, + /* rhk */ ILLEGAL_PAIR, + /* rhl */ ILLEGAL_PAIR, + /* rhm */ ILLEGAL_PAIR, + /* rhn */ ILLEGAL_PAIR, + /* rho */ BEGIN | NOT_END, + /* rhp */ ILLEGAL_PAIR, + /* rhr */ ILLEGAL_PAIR, + /* rhs */ ILLEGAL_PAIR, + /* rht */ ILLEGAL_PAIR, + /* rhu */ BEGIN | NOT_END, + /* rhv */ ILLEGAL_PAIR, + /* rhw */ ILLEGAL_PAIR, + /* rhx */ ILLEGAL_PAIR, + /* rhy */ BEGIN | NOT_END, + /* rhz */ ILLEGAL_PAIR, + /* rhch */ ILLEGAL_PAIR, + /* rhgh */ ILLEGAL_PAIR, + /* rhph */ ILLEGAL_PAIR, + /* rhrh */ ILLEGAL_PAIR, + /* rhsh */ ILLEGAL_PAIR, + /* rhth */ ILLEGAL_PAIR, + /* rhwh */ ILLEGAL_PAIR, + /* rhqu */ ILLEGAL_PAIR, + /* rhck */ ILLEGAL_PAIR }, + {/* sha */ ANY_COMBINATION, + /* shb */ NOT_BEGIN | BREAK | NOT_END, + /* shc */ NOT_BEGIN | BREAK | NOT_END, + /* shd */ NOT_BEGIN | BREAK | NOT_END, + /* she */ ANY_COMBINATION, + /* shf */ NOT_BEGIN | BREAK | NOT_END, + /* shg */ NOT_BEGIN | BREAK | NOT_END, + /* shh */ ILLEGAL_PAIR, + /* shi */ ANY_COMBINATION, + /* shj */ NOT_BEGIN | BREAK | NOT_END, + /* shk */ NOT_BEGIN, + /* shl */ BEGIN | SUFFIX | NOT_END, + /* shm */ BEGIN | SUFFIX | NOT_END, + /* shn */ BEGIN | SUFFIX | NOT_END, + /* sho */ ANY_COMBINATION, + /* shp */ NOT_BEGIN, + /* shr */ BEGIN | SUFFIX | NOT_END, + /* shs */ NOT_BEGIN | BREAK | NOT_END, + /* sht */ SUFFIX, + /* shu */ ANY_COMBINATION, + /* shv */ NOT_BEGIN | BREAK | NOT_END, + /* shw */ SUFFIX | NOT_END, + /* shx */ ILLEGAL_PAIR, + /* shy */ ANY_COMBINATION, + /* shz */ NOT_BEGIN | BREAK | NOT_END, + /* shch */ NOT_BEGIN | BREAK | NOT_END, + /* shgh */ NOT_BEGIN | BREAK | NOT_END, + /* shph */ NOT_BEGIN | BREAK | NOT_END, + /* shrh */ ILLEGAL_PAIR, + /* shsh */ ILLEGAL_PAIR, + /* shth */ NOT_BEGIN | BREAK | NOT_END, + /* shwh */ ILLEGAL_PAIR, + /* shqu */ NOT_BEGIN | BREAK | NOT_END, + /* shck */ ILLEGAL_PAIR }, + {/* tha */ ANY_COMBINATION, + /* thb */ NOT_BEGIN | BREAK | NOT_END, + /* thc */ NOT_BEGIN | BREAK | NOT_END, + /* thd */ NOT_BEGIN | BREAK | NOT_END, + /* the */ ANY_COMBINATION, + /* thf */ NOT_BEGIN | BREAK | NOT_END, + /* thg */ NOT_BEGIN | BREAK | NOT_END, + /* thh */ NOT_BEGIN | BREAK | NOT_END, + /* thi */ ANY_COMBINATION, + /* thj */ NOT_BEGIN | BREAK | NOT_END, + /* thk */ NOT_BEGIN | BREAK | NOT_END, + /* thl */ NOT_BEGIN | BREAK | NOT_END, + /* thm */ NOT_BEGIN | BREAK | NOT_END, + /* thn */ NOT_BEGIN | BREAK | NOT_END, + /* tho */ ANY_COMBINATION, + /* thp */ NOT_BEGIN | BREAK | NOT_END, + /* thr */ NOT_END, + /* ths */ NOT_BEGIN | END, + /* tht */ NOT_BEGIN | BREAK | NOT_END, + /* thu */ ANY_COMBINATION, + /* thv */ NOT_BEGIN | BREAK | NOT_END, + /* thw */ SUFFIX | NOT_END, + /* thx */ ILLEGAL_PAIR, + /* thy */ ANY_COMBINATION, + /* thz */ NOT_BEGIN | BREAK | NOT_END, + /* thch */ NOT_BEGIN | BREAK | NOT_END, + /* thgh */ NOT_BEGIN | BREAK | NOT_END, + /* thph */ NOT_BEGIN | BREAK | NOT_END, + /* thrh */ ILLEGAL_PAIR, + /* thsh */ NOT_BEGIN | BREAK | NOT_END, + /* thth */ ILLEGAL_PAIR, + /* thwh */ ILLEGAL_PAIR, + /* thqu */ NOT_BEGIN | BREAK | NOT_END, + /* thck */ ILLEGAL_PAIR }, + {/* wha */ BEGIN | NOT_END, + /* whb */ ILLEGAL_PAIR, + /* whc */ ILLEGAL_PAIR, + /* whd */ ILLEGAL_PAIR, + /* whe */ BEGIN | NOT_END, + /* whf */ ILLEGAL_PAIR, + /* whg */ ILLEGAL_PAIR, + /* whh */ ILLEGAL_PAIR, + /* whi */ BEGIN | NOT_END, + /* whj */ ILLEGAL_PAIR, + /* whk */ ILLEGAL_PAIR, + /* whl */ ILLEGAL_PAIR, + /* whm */ ILLEGAL_PAIR, + /* whn */ ILLEGAL_PAIR, + /* who */ BEGIN | NOT_END, + /* whp */ ILLEGAL_PAIR, + /* whr */ ILLEGAL_PAIR, + /* whs */ ILLEGAL_PAIR, + /* wht */ ILLEGAL_PAIR, + /* whu */ ILLEGAL_PAIR, + /* whv */ ILLEGAL_PAIR, + /* whw */ ILLEGAL_PAIR, + /* whx */ ILLEGAL_PAIR, + /* why */ BEGIN | NOT_END, + /* whz */ ILLEGAL_PAIR, + /* whch */ ILLEGAL_PAIR, + /* whgh */ ILLEGAL_PAIR, + /* whph */ ILLEGAL_PAIR, + /* whrh */ ILLEGAL_PAIR, + /* whsh */ ILLEGAL_PAIR, + /* whth */ ILLEGAL_PAIR, + /* whwh */ ILLEGAL_PAIR, + /* whqu */ ILLEGAL_PAIR, + /* whck */ ILLEGAL_PAIR }, + {/* qua */ ANY_COMBINATION, + /* qub */ ILLEGAL_PAIR, + /* quc */ ILLEGAL_PAIR, + /* qud */ ILLEGAL_PAIR, + /* que */ ANY_COMBINATION, + /* quf */ ILLEGAL_PAIR, + /* qug */ ILLEGAL_PAIR, + /* quh */ ILLEGAL_PAIR, + /* qui */ ANY_COMBINATION, + /* quj */ ILLEGAL_PAIR, + /* quk */ ILLEGAL_PAIR, + /* qul */ ILLEGAL_PAIR, + /* qum */ ILLEGAL_PAIR, + /* qun */ ILLEGAL_PAIR, + /* quo */ ANY_COMBINATION, + /* qup */ ILLEGAL_PAIR, + /* qur */ ILLEGAL_PAIR, + /* qus */ ILLEGAL_PAIR, + /* qut */ ILLEGAL_PAIR, + /* quu */ ILLEGAL_PAIR, + /* quv */ ILLEGAL_PAIR, + /* quw */ ILLEGAL_PAIR, + /* qux */ ILLEGAL_PAIR, + /* quy */ ILLEGAL_PAIR, + /* quz */ ILLEGAL_PAIR, + /* quch */ ILLEGAL_PAIR, + /* qugh */ ILLEGAL_PAIR, + /* quph */ ILLEGAL_PAIR, + /* qurh */ ILLEGAL_PAIR, + /* qush */ ILLEGAL_PAIR, + /* quth */ ILLEGAL_PAIR, + /* quwh */ ILLEGAL_PAIR, + /* ququ */ ILLEGAL_PAIR, + /* quck */ ILLEGAL_PAIR }, + {/* cka */ NOT_BEGIN | BREAK | NOT_END, + /* ckb */ NOT_BEGIN | BREAK | NOT_END, + /* ckc */ NOT_BEGIN | BREAK | NOT_END, + /* ckd */ NOT_BEGIN | BREAK | NOT_END, + /* cke */ NOT_BEGIN | BREAK | NOT_END, + /* ckf */ NOT_BEGIN | BREAK | NOT_END, + /* ckg */ NOT_BEGIN | BREAK | NOT_END, + /* ckh */ NOT_BEGIN | BREAK | NOT_END, + /* cki */ NOT_BEGIN | BREAK | NOT_END, + /* ckj */ NOT_BEGIN | BREAK | NOT_END, + /* ckk */ NOT_BEGIN | BREAK | NOT_END, + /* ckl */ NOT_BEGIN | BREAK | NOT_END, + /* ckm */ NOT_BEGIN | BREAK | NOT_END, + /* ckn */ NOT_BEGIN | BREAK | NOT_END, + /* cko */ NOT_BEGIN | BREAK | NOT_END, + /* ckp */ NOT_BEGIN | BREAK | NOT_END, + /* ckr */ NOT_BEGIN | BREAK | NOT_END, + /* cks */ NOT_BEGIN, + /* ckt */ NOT_BEGIN | BREAK | NOT_END, + /* cku */ NOT_BEGIN | BREAK | NOT_END, + /* ckv */ NOT_BEGIN | BREAK | NOT_END, + /* ckw */ NOT_BEGIN | BREAK | NOT_END, + /* ckx */ ILLEGAL_PAIR, + /* cky */ NOT_BEGIN, + /* ckz */ NOT_BEGIN | BREAK | NOT_END, + /* ckch */ NOT_BEGIN | BREAK | NOT_END, + /* ckgh */ NOT_BEGIN | BREAK | NOT_END, + /* ckph */ NOT_BEGIN | BREAK | NOT_END, + /* ckrh */ ILLEGAL_PAIR, + /* cksh */ NOT_BEGIN | BREAK | NOT_END, + /* ckth */ NOT_BEGIN | BREAK | NOT_END, + /* ckwh */ ILLEGAL_PAIR, + /* ckqu */ NOT_BEGIN | BREAK | NOT_END, + /* ckck */ ILLEGAL_PAIR} +}; + +/* +** gen_pron_pass will generate a Random word and place it in the +** buffer word. Also, the hyphenated word will be placed into +** the buffer hyphenated_word. Both word and hyphenated_word must +** be pre-allocated. The words generated will have sizes between +** minlen and maxlen. If restrict is TRUE, words will not be generated that +** appear as login names or as entries in the on-line dictionary. +** This algorithm was initially worded out by Morrie Gasser in 1975. +** Any changes here are minimal so that as many word combinations +** can be produced as possible (and thus keep the words Random). +** The seed is used on first use of the routine. +** The length of the unhyphenated word is returned, or -1 if there +** were an error (length settings are wrong or dictionary checking +** could not be done. +*/ +int +gen_pron_pass (char *word, char *hyphenated_word, USHORT minlen, + USHORT maxlen, unsigned int pass_mode) +{ + + int pwlen; + + /* + * Check for minlen>maxlen. This is an error. + * and a length of 0. + */ + if (minlen > maxlen || minlen > APG_MAX_PASSWORD_LENGTH || + maxlen > APG_MAX_PASSWORD_LENGTH) + return (-1); + /* + * Check for zero length words. This is technically not an error, + * so we take the short cut and return a null word and a length of 0. + */ + if (maxlen == 0) + { + word[0] = '\0'; + hyphenated_word[0] = '\0'; + return (0); + } + + /* + * Find password. + */ + pwlen = gen_word (word, hyphenated_word, get_random (minlen, maxlen), pass_mode); + return (pwlen); +} + + +/* + * This is the routine that returns a Random word -- as + * yet unchecked against the passwd file or the dictionary. + * It collects Random syllables until a predetermined + * word length is found. If a retry threshold is reached, + * another word is tried. Given that the Random number + * generator is uniformly distributed, eventually a word + * will be found if the retry limit is adequately large enough. + */ +int +gen_word (char *word, char *hyphenated_word, USHORT pwlen, unsigned int pass_mode) +{ + USHORT word_length; + USHORT syllable_length; + char *new_syllable; + char *syllable_for_hyph; + USHORT *syllable_units; + USHORT word_size; + USHORT word_place; + USHORT *word_units; + USHORT syllable_size; + UINT tries; + int ch_flag = FALSE; + int dsd = 0; + + /* + * Keep count of retries. + */ + tries = 0; + + /* + * The length of the word in characters. + */ + word_length = 0; + + /* + * The length of the word in character units (each of which is one or + * two characters long. + */ + word_size = 0; + + /* + * Initialize the array storing the word units. Since we know the + * length of the word, we only need one of that length. This method is + * preferable to a static array, since it allows us flexibility in + * choosing arbitrarily long word lengths. Since a word can contain one + * syllable, we should make syllable_units, the array holding the + * analogous units for an individual syllable, the same length. No + * explicit rule limits the length of syllables, but digram rules and + * heuristics do so indirectly. + */ + if ( (word_units = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL || + (syllable_units = (USHORT *) calloc (sizeof (USHORT), pwlen+1))==NULL || + (new_syllable = (char *) calloc (sizeof (USHORT), pwlen+1)) ==NULL || + (syllable_for_hyph = (char *) calloc (sizeof(char), 20))==NULL) + return(-1); + + /* + * Find syllables until the entire word is constructed. + */ + while (word_length < pwlen) + { + /* + * Get the syllable and find its length. + */ + (void) gen_syllable (new_syllable, pwlen - word_length, syllable_units, &syllable_size); + syllable_length = strlen (new_syllable); + + /* + * Append the syllable units to the word units. + */ + for (word_place = 0; word_place <= syllable_size; word_place++) + word_units[word_size + word_place] = syllable_units[word_place]; + word_size += syllable_size + 1; + + /* + * If the word has been improperly formed, throw out + * the syllable. The checks performed here are those + * that must be formed on a word basis. The other + * tests are performed entirely within the syllable. + * Otherwise, append the syllable to the word and + * append the syllable to the hyphenated version of + * the word. + */ + if (improper_word (word_units, word_size) || + ((word_length == 0) && have_initial_y (syllable_units, syllable_size)) || + ((word_length + syllable_length == pwlen) && have_final_split (syllable_units, syllable_size))) + word_size -= syllable_size + 1; + else + { + if (word_length == 0) + { + /* + ** Modify syllable for numeric or capital symbols required + ** Should be done after word quality check. + */ + dsd = randint(2); + if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && dsd == 0) + { + numerize(new_syllable); + ch_flag = TRUE; + } + if ( ((pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1)) + { + specialize(new_syllable); + ch_flag = TRUE; + } + if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE)) + capitalize(new_syllable); + ch_flag = FALSE; + /**/ + (void) strcpy (word, new_syllable); + if (syllable_length == 1) + { + symb2name(new_syllable, syllable_for_hyph); + (void) strcpy (hyphenated_word, syllable_for_hyph); + } + else + { + (void) strcpy (hyphenated_word, new_syllable); + } + (void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1)); + (void)memset ( (void *)syllable_for_hyph, 0, 20); + } + else + { + /* + ** Modify syllable for numeric or capital symbols required + ** Should be done after word quality check. + */ + dsd = randint(2); + if ( ((pass_mode & S_NB) > 0) && (syllable_length == 1) && (dsd == 0)) + { + numerize(new_syllable); + ch_flag = TRUE; + } + if ( ( (pass_mode & S_SS) > 0) && (syllable_length == 1) && (dsd == 1)) + { + specialize(new_syllable); + ch_flag = TRUE; + } + if ( ( (pass_mode & S_CL) > 0) && (ch_flag != TRUE)) + capitalize(new_syllable); + ch_flag = FALSE; + /**/ + (void) strcat (word, new_syllable); + (void) strcat (hyphenated_word, "-"); + if (syllable_length == 1) + { + symb2name(new_syllable, syllable_for_hyph); + (void) strcat (hyphenated_word, syllable_for_hyph); + } + else + { + (void) strcat (hyphenated_word, new_syllable); + } + (void)memset ( (void *)new_syllable, 0, (size_t)(pwlen * sizeof(USHORT)+1)); + (void)memset ( (void *)syllable_for_hyph, 0, 20); + } + word_length += syllable_length; + } + + /* + * Keep track of the times we have tried to get + * syllables. If we have exceeded the threshold, + * reinitialize the pwlen and word_size variables, clear + * out the word arrays, and start from scratch. + */ + tries++; + if (tries > MAX_RETRIES) + { + word_length = 0; + word_size = 0; + tries = 0; + (void) strcpy (word, ""); + (void) strcpy (hyphenated_word, ""); + } + } + + /* + * The units arrays and syllable storage are internal to this + * routine. Since the caller has no need for them, we + * release the space. + */ + free ((char *) new_syllable); + free ((char *) syllable_units); + free ((char *) word_units); + free ((char *) syllable_for_hyph); + + return ((int) word_length); +} + + + +/* + * Check that the word does not contain illegal combinations + * that may span syllables. Specifically, these are: + * 1. An illegal pair of units between syllables. + * 2. Three consecutive vowel units. + * 3. Three consecutive consonant units. + * The checks are made against units (1 or 2 letters), not against + * the individual letters, so three consecutive units can have + * the length of 6 at most. + */ +boolean +improper_word (USHORT *units, USHORT word_size) +{ + USHORT unit_count; + boolean failure; + + failure = FALSE; + + for (unit_count = 0; !failure && (unit_count < word_size); + unit_count++) + { + /* + * Check for ILLEGAL_PAIR. This should have been caught + * for units within a syllable, but in some cases it + * would have gone unnoticed for units between syllables + * (e.g., when saved_unit's in gen_syllable() were not + * used). + */ + if ((unit_count != 0) && + (digram[units[unit_count - 1]][units[unit_count]] & + ILLEGAL_PAIR)) + failure = TRUE; + + /* + * Check for consecutive vowels or consonants. Because + * the initial y of a syllable is treated as a consonant + * rather than as a vowel, we exclude y from the first + * vowel in the vowel test. The only problem comes when + * y ends a syllable and two other vowels start the next, + * like fly-oint. Since such words are still + * pronounceable, we accept this. + */ + if (!failure && (unit_count >= 2)) + { + /* + * Vowel check. + */ + if ((((rules[units[unit_count - 2]].flags & VOWEL) && + !(rules[units[unit_count - 2]].flags & + ALTERNATE_VOWEL)) && + (rules[units[unit_count - 1]].flags & VOWEL) && + (rules[units[unit_count]].flags & VOWEL)) || + /* + * Consonant check. + */ + (!(rules[units[unit_count - 2]].flags & VOWEL) && + !(rules[units[unit_count - 1]].flags & VOWEL) && + !(rules[units[unit_count]].flags & VOWEL))) + failure = TRUE; + } + } + + return (failure); +} + + +/* + * Treating y as a vowel is sometimes a problem. Some words + * get formed that look irregular. One special group is when + * y starts a word and is the only vowel in the first syllable. + * The word ycl is one example. We discard words like these. + */ +boolean +have_initial_y (USHORT *units, USHORT unit_size) +{ + USHORT unit_count; + USHORT vowel_count; + USHORT normal_vowel_count; + + vowel_count = 0; + normal_vowel_count = 0; + + for (unit_count = 0; unit_count <= unit_size; unit_count++) + /* + * Count vowels. + */ + if (rules[units[unit_count]].flags & VOWEL) + { + vowel_count++; + + /* + * Count the vowels that are not: 1. y, 2. at the start of + * the word. + */ + if (!(rules[units[unit_count]].flags & ALTERNATE_VOWEL) || + (unit_count != 0)) + normal_vowel_count++; + } + + return ((vowel_count <= 1) && (normal_vowel_count == 0)); +} + + +/* + * Besides the problem with the letter y, there is one with + * a silent e at the end of words, like face or nice. We + * allow this silent e, but we do not allow it as the only + * vowel at the end of the word or syllables like ble will + * be generated. + */ +boolean +have_final_split (USHORT *units, USHORT unit_size) +{ + USHORT unit_count; + USHORT vowel_count; + + vowel_count = 0; + + /* + * Count all the vowels in the word. + */ + for (unit_count = 0; unit_count <= unit_size; unit_count++) + if (rules[units[unit_count]].flags & VOWEL) + vowel_count++; + + /* + * Return TRUE iff the only vowel was e, found at the end if the + * word. + */ + return ((vowel_count == 1) && + (rules[units[unit_size]].flags & NO_FINAL_SPLIT)); +} + + +/* + * Generate next unit to password, making sure that it follows + * these rules: + * 1. Each syllable must contain exactly 1 or 2 consecutive + * vowels, where y is considered a vowel. + * 2. Syllable end is determined as follows: + * a. Vowel is generated and previous unit is a + * consonant and syllable already has a vowel. In + * this case, new syllable is started and already + * contains a vowel. + * b. A pair determined to be a "break" pair is encountered. + * In this case new syllable is started with second unit + * of this pair. + * c. End of password is encountered. + * d. "begin" pair is encountered legally. New syllable is + * started with this pair. + * e. "end" pair is legally encountered. New syllable has + * nothing yet. + * 3. Try generating another unit if: + * a. third consecutive vowel and not y. + * b. "break" pair generated but no vowel yet in current + * or previous 2 units are "not_end". + * c. "begin" pair generated but no vowel in syllable + * preceding begin pair, or both previous 2 pairs are + * designated "not_end". + * d. "end" pair generated but no vowel in current syllable + * or in "end" pair. + * e. "not_begin" pair generated but new syllable must + * begin (because previous syllable ended as defined in + * 2 above). + * f. vowel is generated and 2a is satisfied, but no syllable + * break is possible in previous 3 pairs. + * g. Second and third units of syllable must begin, and + * first unit is "alternate_vowel". + */ +char * +gen_syllable (char *syllable, USHORT pwlen, USHORT *units_in_syllable, + USHORT *syllable_length) +{ + USHORT unit = 0; + SHORT current_unit = 0; + USHORT vowel_count = 0; + boolean rule_broken; + boolean want_vowel; + boolean want_another_unit; + UINT tries = 0; + USHORT last_unit = 0; + SHORT length_left = 0; + USHORT hold_saved_unit = 0; + static USHORT saved_unit; + static USHORT saved_pair[2]; + + /* + * This is needed if the saved_unit is tries and the syllable then + * discarded because of the retry limit. Since the saved_unit is OK and + * fits in nicely with the preceding syllable, we will always use it. + */ + hold_saved_unit = saved_unit; + + /* + * Loop until valid syllable is found. + */ + do + { + /* + * Try for a new syllable. Initialize all pertinent + * syllable variables. + */ + tries = 0; + saved_unit = hold_saved_unit; + (void) strcpy (syllable, ""); + vowel_count = 0; + current_unit = 0; + length_left = (short int) pwlen; + want_another_unit = TRUE; + + /* + * This loop finds all the units for the syllable. + */ + do + { + want_vowel = FALSE; + + /* + * This loop continues until a valid unit is found for the + * current position within the syllable. + */ + do + { + /* + * If there are saved_unit's from the previous + * syllable, use them up first. + */ + if (saved_unit != 0) + { + /* + * If there were two saved units, the first is + * guaranteed (by checks performed in the previous + * syllable) to be valid. We ignore the checks + * and place it in this syllable manually. + */ + if (saved_unit == 2) + { + units_in_syllable[0] = saved_pair[1]; + if (rules[saved_pair[1]].flags & VOWEL) + vowel_count++; + current_unit++; + (void) strcpy (syllable, rules[saved_pair[1]].unit_code); + length_left -= strlen (syllable); + } + + /* + * The unit becomes the last unit checked in the + * previous syllable. + */ + unit = saved_pair[0]; + + /* + * The saved units have been used. Do not try to + * reuse them in this syllable (unless this particular + * syllable is rejected at which point we start to rebuild + * it with these same saved units. + */ + saved_unit = 0; + } + else + /* + * If we don't have to scoff the saved units, + * we generate a Random one. If we know it has + * to be a vowel, we get one rather than looping + * through until one shows up. + */ + if (want_vowel) + unit = random_unit (VOWEL); + else + unit = random_unit (NO_SPECIAL_RULE); + length_left -= (short int) strlen (rules[unit].unit_code); + + /* + * Prevent having a word longer than expected. + */ + if (length_left < 0) + rule_broken = TRUE; + else + rule_broken = FALSE; + + /* + * First unit of syllable. This is special because the + * digram tests require 2 units and we don't have that yet. + * Nevertheless, we can perform some checks. + */ + if (current_unit == 0) + { + /* + * If the shouldn't begin a syllable, don't + * use it. + */ + if (rules[unit].flags & NOT_BEGIN_SYLLABLE) + rule_broken = TRUE; + else + /* + * If this is the last unit of a word, + * we have a one unit syllable. Since each + * syllable must have a vowel, we make sure + * the unit is a vowel. Otherwise, we + * discard it. + */ + if (length_left == 0) + { + if (rules[unit].flags & VOWEL) + want_another_unit = FALSE; + else + rule_broken = TRUE; + } + } + else + { + /* + * There are some digram tests that are + * universally true. We test them out. + */ + + /* + * Reject ILLEGAL_PAIRS of units. + */ + if ((ALLOWED (ILLEGAL_PAIR)) || + + /* + * Reject units that will be split between syllables + * when the syllable has no vowels in it. + */ + (ALLOWED (BREAK) && (vowel_count == 0)) || + + /* + * Reject a unit that will end a syllable when no + * previous unit was a vowel and neither is this one. + */ + (ALLOWED (END) && (vowel_count == 0) && + !(rules[unit].flags & VOWEL))) + rule_broken = TRUE; + + if (current_unit == 1) + { + /* + * Reject the unit if we are at te starting digram of + * a syllable and it does not fit. + */ + if (ALLOWED (NOT_BEGIN)) + rule_broken = TRUE; + } + else + { + /* + * We are not at the start of a syllable. + * Save the previous unit for later tests. + */ + last_unit = units_in_syllable[current_unit - 1]; + + /* + * Do not allow syllables where the first letter is y + * and the next pair can begin a syllable. This may + * lead to splits where y is left alone in a syllable. + * Also, the combination does not sound to good even + * if not split. + */ + if (((current_unit == 2) && + (ALLOWED (BEGIN)) && + (rules[units_in_syllable[0]].flags & + ALTERNATE_VOWEL)) || + + /* + * If this is the last unit of a word, we should + * reject any digram that cannot end a syllable. + */ + (ALLOWED (NOT_END) && + (length_left == 0)) || + + /* + * Reject the unit if the digram it forms wants + * to break the syllable, but the resulting + * digram that would end the syllable is not + * allowed to end a syllable. + */ + (ALLOWED (BREAK) && + (digram[units_in_syllable + [current_unit - 2]] + [last_unit] & + NOT_END)) || + + /* + * Reject the unit if the digram it forms + * expects a vowel preceding it and there is + * none. + */ + (ALLOWED (PREFIX) && + !(rules[units_in_syllable + [current_unit - 2]].flags & + VOWEL))) + rule_broken = TRUE; + + /* + * The following checks occur when the current unit + * is a vowel and we are not looking at a word ending + * with an e. + */ + if (!rule_broken && + (rules[unit].flags & VOWEL) && + ((length_left > 0) || + !(rules[last_unit].flags & + NO_FINAL_SPLIT))) + { + /* + * Don't allow 3 consecutive vowels in a + * syllable. Although some words formed like this + * are OK, like beau, most are not. + */ + if ((vowel_count > 1) && + (rules[last_unit].flags & VOWEL)) + rule_broken = TRUE; + else + /* + * Check for the case of + * vowels-consonants-vowel, which is only + * legal if the last vowel is an e and we are + * the end of the word (wich is not + * happening here due to a previous check. + */ + if ((vowel_count != 0) && + !(rules[last_unit].flags & VOWEL)) + { + /* + * Try to save the vowel for the next + * syllable, but if the syllable left here + * is not proper (i.e., the resulting last + * digram cannot legally end it), just + * discard it and try for another. + */ + if (digram[units_in_syllable + [current_unit - 2]] + [last_unit] & + NOT_END) + rule_broken = TRUE; + else + { + saved_unit = 1; + saved_pair[0] = unit; + want_another_unit = FALSE; + } + } + } + } + + /* + * The unit picked and the digram formed are legal. + * We now determine if we can end the syllable. It may, + * in some cases, mean the last unit(s) may be deferred to + * the next syllable. We also check here to see if the + * digram formed expects a vowel to follow. + */ + if (!rule_broken && want_another_unit) + { + /* + * This word ends in a silent e. + */ +/******/ if (((vowel_count != 0) && + (rules[unit].flags & NO_FINAL_SPLIT) && + (length_left == 0) && + !(rules[last_unit].flags & VOWEL)) || + + /* + * This syllable ends either because the digram + * is an END pair or we would otherwise exceed + * the length of the word. + */ + (ALLOWED (END) || (length_left == 0))) + { + want_another_unit = FALSE; + } + else + /* + * Since we have a vowel in the syllable + * already, if the digram calls for the end of the + * syllable, we can legally split it off. We also + * make sure that we are not at the end of the + * dangerous because that syllable may not have + * vowels, or it may not be a legal syllable end, + * and the retrying mechanism will loop infinitely + * with the same digram. + */ + if ((vowel_count != 0) && (length_left > 0)) + { + /* + * If we must begin a syllable, we do so if + * the only vowel in THIS syllable is not part + * of the digram we are pushing to the next + * syllable. + */ + if (ALLOWED (BEGIN) && + (current_unit > 1) && + !((vowel_count == 1) && + (rules[last_unit].flags & VOWEL))) + { + saved_unit = 2; + saved_pair[0] = unit; + saved_pair[1] = last_unit; + want_another_unit = FALSE; + } + else + if (ALLOWED (BREAK)) + { + saved_unit = 1; + saved_pair[0] = unit; + want_another_unit = FALSE; + } + } + else + if (ALLOWED (SUFFIX)) + { + want_vowel = TRUE; + } + } + } +/********/ + tries++; + + /* + * If this unit was illegal, redetermine the amount of + * letters left to go in the word. + */ + if (rule_broken) + length_left += (short int) strlen (rules[unit].unit_code); + } + while (rule_broken && (tries <= MAX_RETRIES)); + + /* + * The unit fit OK. + */ + if (tries <= MAX_RETRIES) + { + /* + * If the unit were a vowel, count it in. + * However, if the unit were a y and appear + * at the start of the syllable, treat it + * like a constant (so that words like year can + * appear and not conflict with the 3 consecutive + * vowel rule. + */ + if ((rules[unit].flags & VOWEL) && + ((current_unit > 0) || + !(rules[unit].flags & ALTERNATE_VOWEL))) + vowel_count++; + + /* + * If a unit or units were to be saved, we must + * adjust the syllable formed. Otherwise, we + * append the current unit to the syllable. + */ + switch (saved_unit) + { + case 0: + units_in_syllable[current_unit] = unit; + (void) strcat (syllable, rules[unit].unit_code); + break; + case 1: + current_unit--; + break; + case 2: + (void) strcpy (&syllable[strlen (syllable) - + strlen (rules[last_unit].unit_code)],""); + length_left += (short int) strlen (rules[last_unit].unit_code); + current_unit -= 2; + break; + } + } + else + /* + * Whoops! Too many tries. We set rule_broken so we can + * loop in the outer loop and try another syllable. + */ + rule_broken = TRUE; + + /* + * ...and the syllable length grows. + */ + *syllable_length = current_unit; + + current_unit++; + } + while ((tries <= MAX_RETRIES) && want_another_unit); + } + while (rule_broken || + illegal_placement (units_in_syllable, *syllable_length)); + + return (syllable); +} + + +/* + * This routine goes through an individual syllable and checks + * for illegal combinations of letters that go beyond looking + * at digrams. We look at things like 3 consecutive vowels or + * consonants, or syllables with consonants between vowels (unless + * one of them is the final silent e). + */ +boolean +illegal_placement (USHORT *units, USHORT pwlen) +{ + USHORT vowel_count; + USHORT unit_count; + boolean failure; + + vowel_count = 0; + failure = FALSE; + + for (unit_count = 0; !failure && (unit_count <= pwlen); + unit_count++) + { + if (unit_count >= 1) + { + /* + * Don't allow vowels to be split with consonants in + * a single syllable. If we find such a combination + * (except for the silent e) we have to discard the + * syllable). + */ + if ((!(rules[units[unit_count - 1]].flags & VOWEL) && + (rules[units[unit_count]].flags & VOWEL) && + !((rules[units[unit_count]].flags & NO_FINAL_SPLIT) && + (unit_count == pwlen)) && (vowel_count != 0)) || + /* + * Perform these checks when we have at least 3 units. + */ + ((unit_count >= 2) && + + /* + * Disallow 3 consecutive consonants. + */ + ((!(rules[units[unit_count - 2]].flags & VOWEL) && + !(rules[units[unit_count - 1]].flags & + VOWEL) && + !(rules[units[unit_count]].flags & + VOWEL)) || + + /* + * Disallow 3 consecutive vowels, where the first is + * not a y. + */ + (((rules[units[unit_count - 2]].flags & + VOWEL) && + !((rules[units[0]].flags & + ALTERNATE_VOWEL) && + (unit_count == 2))) && + (rules[units[unit_count - 1]].flags & + VOWEL) && + (rules[units[unit_count]].flags & + VOWEL))))) + failure = TRUE; + } + + /* + * Count the vowels in the syllable. As mentioned somewhere + * above, exclude the initial y of a syllable. Instead, + * treat it as a consonant. + */ + if ((rules[units[unit_count]].flags & VOWEL) && + !((rules[units[0]].flags & ALTERNATE_VOWEL) && + (unit_count == 0) && (pwlen != 0))) + vowel_count++; + } + + return (failure); +} + + + +/* + * This is the standard Random unit generating routine for + * gen_syllable(). It does not reference the digrams, but + * assumes that it contains 34 units in a particular order. + * This routine attempts to return unit indexes with a distribution + * approaching that of the distribution of the 34 units in + * English. In order to do this, a Random number (supposedly + * uniformly distributed) is used to do a table lookup into an + * array containing unit indices. There are 211 entries in + * the array for the random_unit entry point. The probability + * of a particular unit being generated is equal to the + * fraction of those 211 entries that contain that unit index. + * For example, the letter `a' is unit number 1. Since unit + * index 1 appears 10 times in the array, the probability of + * selecting an `a' is 10/211. + * + * Changes may be made to the digram table without affect to this + * procedure providing the letter-to-number correspondence of + * the units does not change. Likewise, the distribution of the + * 34 units may be altered (and the array size may be changed) + * in this procedure without affecting the digram table or any other + * programs using the Random_word subroutine. + */ +static USHORT numbers[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, + 22, + 23, 23, 23, 23, 23, 23, 23, 23, + 24, + 25, + 26, + 27, + 28, + 29, 29, + 30, + 31, + 32, + 33 +}; + + +/* + * This structure has a typical English frequency of vowels. + * The value of an entry is the vowel position (a=0, e=4, i=8, + * o=14, u=19, y=23) in the rules array. The number of times + * the value appears is the frequency. Thus, the letter "a" + * is assumed to appear 2/12 = 1/6 of the time. This array + * may be altered if better data is obtained. The routines that + * use vowel_numbers will adjust to the size difference +automatically. + */ +static USHORT vowel_numbers[] = +{ + 0, 0, 4, 4, 4, 8, 8, 14, 14, 19, 19, 23 +}; + + +/* + * Select a unit (a letter or a consonant group). If a vowel is + * expected, use the vowel_numbers array rather than looping through + * the numbers array until a vowel is found. + */ +USHORT +random_unit (USHORT type) +{ + USHORT number; + + /* + * Sometimes, we are asked to explicitly get a vowel (i.e., if + * a digram pair expects one following it). This is a shortcut + * to do that and avoid looping with rejected consonants. + */ + if (type & VOWEL) + number = vowel_numbers[get_random (0, (sizeof (vowel_numbers) / sizeof (USHORT))-1)]; + else + /* + * Get any letter according to the English distribution. + */ + number = numbers[get_random (0, (sizeof (numbers) / sizeof (USHORT))-1)]; + return (number); +} + + +/* +** get_random() - +** This routine should return a uniformly distributed Random number between +** minlen and maxlen inclusive. The Electronic Code Book form of CAST is +** used to produce the Random number. The inputs to CAST are the old pass- +** word and a pseudoRandom key generated according to the procedure out- +** lined in Appendix C of ANSI X9.17. +** INPUT: +** USHORT - minimum +** USHORT - maximum +** OUTPUT: +** USHORT - random number +** NOTES: +** none. +*/ + +USHORT +get_random (USHORT minlen, USHORT maxlen) +{ + USHORT ret = 0; + ret = minlen + (USHORT) randint ((int) (maxlen - minlen + 1)); + return (ret); +} diff --git a/src/apg/pronpass.h b/src/apg/pronpass.h new file mode 100644 index 0000000..2125dcf --- /dev/null +++ b/src/apg/pronpass.h @@ -0,0 +1,92 @@ +/* +** This module uses code from the NIST implementation of FIPS-181, +** but the algorythm is CHANGED and I think that I CAN +** copyright it. See copiright notes below. +*/ + +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef APG_PRONPASS_H +#define APG_PRONPASS_H 1 + +#ifndef APG_OWN_TYPES_H +#include "owntypes.h" +#endif /* APG_OWN_TYPES_H */ + +//#ifndef APG_RND_H +//#include "rnd.h" +//#endif /* APG_RND_H */ + +#define RULE_SIZE (sizeof(rules)/sizeof(struct unit)) +#define ALLOWED(flag) (digram[units_in_syllable[current_unit -1]][unit] & (flag)) + +#define MAX_UNACCEPTABLE 20 +#define MAX_RETRIES (4 * (int) pwlen + RULE_SIZE) + +#define NOT_BEGIN_SYLLABLE 010 +#define NO_FINAL_SPLIT 04 +#define VOWEL 02 +#define ALTERNATE_VOWEL 01 +#define NO_SPECIAL_RULE 0 + +#define BEGIN 0200 +#define NOT_BEGIN 0100 +#define BREAK 040 +#define PREFIX 020 +#define ILLEGAL_PAIR 010 +#define SUFFIX 04 +#define END 02 +#define NOT_END 01 +#define ANY_COMBINATION 0 + +#ifdef __cplusplus +extern "C" { +#endif + +extern int gen_pron_pass (char *word, char *hyphenated_word, USHORT minlen, + USHORT maxlen, unsigned int pass_mode); + +USHORT random_unit (USHORT type); +USHORT get_random (USHORT minlen, USHORT maxlen); +boolean have_initial_y (USHORT *units, USHORT unit_size); +boolean illegal_placement (USHORT *units, USHORT pwlen); +boolean improper_word (USHORT *units, USHORT word_size); +boolean have_final_split (USHORT *units, USHORT unit_size); +int gen_word (char *word, char *hyphenated_word, USHORT pwlen, + unsigned int pass_mode); +char *gen_syllable(char *syllable, USHORT pwlen, USHORT *units_in_syllable, + USHORT *syllable_length); + +#ifdef __cplusplus +} +#endif + +#endif /* APG_PRONPASS_H */ diff --git a/src/apg/randpass.c b/src/apg/randpass.c new file mode 100644 index 0000000..9cf105f --- /dev/null +++ b/src/apg/randpass.c @@ -0,0 +1,162 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +** randpass.c - Random password generation module of PWGEN program +*/ + +#include +#include +#include +#include + +#include "random.h" + +#include "randpass.h" +#include "owntypes.h" +#include "smbl.h" + +/* +** gen_rand_pass - generates random password of specified type +** INPUT: +** char * - password string. +** int - minimum password length. +** int - maximum password length. +** unsigned int - password generation mode. +** OUTPUT: +** int - password length or -1 on error. +** NOTES: +** none. +*/ +int +gen_rand_pass (char *password_string, int minl, int maxl, unsigned int pass_mode) +{ + int i = 0; + int j = 0; + int length = 0; + char *str_pointer; + int random_weight[94]; + int max_weight = 0; + int max_weight_element_number = 0; + + if (minl > APG_MAX_PASSWORD_LENGTH || maxl > APG_MAX_PASSWORD_LENGTH || + minl < 1 || maxl < 1 || minl > maxl) + return (-1); + for (i = 0; i <= 93; i++) random_weight[i] = 0; + length = minl + randint(maxl-minl+1); + str_pointer = password_string; + + for (i = 0; i < length; i++) + { +/* Asign random weight in weight array if mode is present*/ + for (j = 0; j <= 93 ; j++) + if ( ( (pass_mode & smbl[j].type) > 0) && + !( (S_RS & smbl[j].type) > 0)) + random_weight[j] = 1 + randint(20000); + j = 0; +/* Find an element with maximum weight */ + for (j = 0; j <= 93; j++) + if (random_weight[j] > max_weight) + { + max_weight = random_weight[j]; + max_weight_element_number = j; + } +/* Get password symbol */ + *str_pointer = smbl[max_weight_element_number].ch; + str_pointer++; + max_weight = 0; + max_weight_element_number = 0; + for (j = 0; j <= 93; j++) random_weight[j] = 0; + } + *str_pointer = 0; + return (length); +} + +/* +** gen_rand_symbol - generates random password of specified type +** INPUT: +** char * - symbol. +** unsigned int - symbol type. +** OUTPUT: +** int - password length or -1 on error. +** NOTES: +** none. +*/ +int +gen_rand_symbol (char *symbol, unsigned int mode) +{ + int j = 0; + char *str_pointer; + int random_weight[94]; + int max_weight = 0; + int max_weight_element_number = 0; + + for (j = 0; j <= 93; j++) random_weight[j] = 0; + str_pointer = symbol; + j = 0; +/* Asign random weight in weight array if mode is present*/ + for (j = 0; j <= 93 ; j++) + if ( ( (mode & smbl[j].type) > 0) && + !( (S_RS & smbl[j].type) > 0)) + random_weight[j] = 1 + randint(20000); + j = 0; +/* Find an element with maximum weight */ + for (j = 0; j <= 93; j++) + if (random_weight[j] > max_weight) + { + max_weight = random_weight[j]; + max_weight_element_number = j; + } +/* Get password symbol */ + *str_pointer = smbl[max_weight_element_number].ch; + max_weight = 0; + max_weight_element_number = 0; + return (0); +} + +/* +** is_restricted_symbol - detcts if symbol is restricted rigt now +** INPUT: +** char - symbol. +** OUTPUT: +** int - 0 - not restricted +** 1 - restricted +** NOTES: +** none. +*/ +int +is_restricted_symbol (char symbol) +{ + int j = 0; + for (j = 0; j <= 93 ; j++) + if (symbol == smbl[j].ch) + if ((S_RS & smbl[j].type) > 0) + return(1); + return(0); +} diff --git a/src/apg/randpass.h b/src/apg/randpass.h new file mode 100644 index 0000000..06f0cf3 --- /dev/null +++ b/src/apg/randpass.h @@ -0,0 +1,70 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +** randpass.h +*/ +#ifndef APG_RANDPASS_H +#define APG_RANDPASS_H 1 + +/*#ifndef APG_RND_H +#include "rnd.h" +#endif*/ + +#ifndef APG_OWN_TYPES_H +#include "owntypes.h" +#endif + +#define S_NB 0x01 /* Numeric */ +#define S_SS 0x02 /* Special */ +#define S_CL 0x04 /* Capital */ +#define S_SL 0x08 /* Small */ +#define S_RS 0x10 /* Restricted Symbol*/ + +struct sym + { + char ch; + USHORT type; + }; + +#ifdef __cplusplus +extern "C" { +#endif + +/* char gen_symbol(unsigned short int symbol_class); */ +extern int gen_rand_pass(char* password_string, int minl, + int maxl, unsigned int pass_mode); +extern int gen_rand_symbol (char *symbol, unsigned int mode); +extern int is_restricted_symbol (char symbol); + +#ifdef __cplusplus +} +#endif + +#endif /* RANDPASS_H */ diff --git a/src/apg/smbl.h b/src/apg/smbl.h new file mode 100644 index 0000000..bb94ef5 --- /dev/null +++ b/src/apg/smbl.h @@ -0,0 +1,51 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** Adel I. Mirzazhanov. All rights reserved +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1.Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** 2.Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3.The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +** OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef APG_SMBL_H +#define APG_SMBL_H 1 +struct sym smbl[94] = +{ + {'a', S_SL}, {'b', S_SL}, {'c', S_SL}, {'d', S_SL}, {'e', S_SL}, {'f', S_SL}, + {'g', S_SL}, {'h', S_SL}, {'i', S_SL}, {'j', S_SL}, {'k', S_SL}, {'l', S_SL}, + {'m', S_SL}, {'n', S_SL}, {'o', S_SL}, {'p', S_SL}, {'q', S_SL}, {'r', S_SL}, + {'s', S_SL}, {'t', S_SL}, {'u', S_SL}, {'v', S_SL}, {'w', S_SL}, {'x', S_SL}, + {'y', S_SL}, {'z', S_SL}, {'A', S_CL}, {'B', S_CL}, {'C', S_CL}, {'D', S_CL}, + {'E', S_CL}, {'F', S_CL}, {'G', S_CL}, {'H', S_CL}, {'I', S_CL}, {'J', S_CL}, + {'K', S_CL}, {'L', S_CL}, {'M', S_CL}, {'N', S_CL}, {'O', S_CL}, {'P', S_CL}, + {'Q', S_CL}, {'R', S_CL}, {'S', S_CL}, {'T', S_CL}, {'U', S_CL}, {'V', S_CL}, + {'W', S_CL}, {'X', S_CL}, {'Y', S_CL}, {'Z', S_CL}, {'1', S_NB}, {'2', S_NB}, + {'3', S_NB}, {'4', S_NB}, {'5', S_NB}, {'6', S_NB}, {'7', S_NB}, {'8', S_NB}, + {'9', S_NB}, {'0', S_NB}, {33 , S_SS}, {34 , S_SS}, {35 , S_SS}, {36 , S_SS}, + {37 , S_SS}, {38 , S_SS}, {39 , S_SS}, {40 , S_SS}, {41 , S_SS}, {42 , S_SS}, + {43 , S_SS}, {44 , S_SS}, {45 , S_SS}, {46 , S_SS}, {47 , S_SS}, {58 , S_SS}, + {59 , S_SS}, {60 , S_SS}, {61 , S_SS}, {62 , S_SS}, {63 , S_SS}, {64 , S_SS}, + {91 , S_SS}, {92 , S_SS}, {93 , S_SS}, {94 , S_SS}, {95 , S_SS}, {96 , S_SS}, + {123, S_SS}, {124, S_SS}, {125, S_SS}, {126, S_SS} +}; + +#endif /* APG_SMBL_H */ diff --git a/src/crypto/aes.h b/src/crypto/aes.h index 449a940..beaef63 100644 --- a/src/crypto/aes.h +++ b/src/crypto/aes.h @@ -1,24 +1,28 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - /* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 This file contains the definitions required to use AES in C. See aesopt.h for optimisation details. @@ -30,24 +34,23 @@ #include /* This include is used to find 8 & 32 bit unsigned integer types */ -#include "aes_tdefs.h" +#include "aes_types.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 */ +#define AES_128 /* if a fast 128 bit key scheduler is needed */ +#define AES_192 /* if a fast 192 bit key scheduler is needed */ +#define AES_256 /* if a fast 256 bit key scheduler is needed */ +#define AES_VAR /* if variable key size scheduler is needed */ +#define AES_MODES /* 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 */ @@ -65,11 +68,7 @@ extern "C" #define KS_LENGTH 44 #endif -#if defined( AES_ERR_CHK ) -#define aes_rval int_ret -#else -#define aes_rval void_ret -#endif +#define AES_RETURN INT_RETURN /* the character array 'inf' in the following structures is used */ /* to hold AES context information. This AES code uses cx->inf.b[0] */ @@ -94,81 +93,99 @@ typedef struct /* This routine must be called before first use if non-static */ /* tables are being used */ -aes_rval gen_tabs(void); +AES_RETURN aes_init(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]); +#if defined( AES_128 ) || defined( AES_VAR) +AES_RETURN 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]); +#if defined( AES_192 ) || defined( AES_VAR) +AES_RETURN 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]); +#if defined( AES_256 ) || defined( AES_VAR) +AES_RETURN 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]); +#if defined( AES_VAR ) +AES_RETURN 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]); +AES_RETURN 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]); +#if defined( AES_128 ) || defined( AES_VAR) +AES_RETURN 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]); +#if defined( AES_192 ) || defined( AES_VAR) +AES_RETURN 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]); +#if defined( AES_256 ) || defined( AES_VAR) +AES_RETURN 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]); +#if defined( AES_VAR ) +AES_RETURN 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]); +AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); #endif -#if defined(AES_MODES) +#if defined( AES_MODES ) + +/* Multiple calls to the following subroutines for multiple block */ +/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */ +/* long messages incremantally provided that the context AND the iv */ +/* are preserved between all such calls. For the ECB and CBC modes */ +/* each individual call within a series of incremental calls must */ +/* process only full blocks (i.e. len must be a multiple of 16) but */ +/* the CFB, OFB and CTR mode calls can handle multiple incremental */ +/* calls of any length. Each mode is reset when a new AES key is */ +/* set but ECB and CBC operations can be reset without setting a */ +/* new key by setting a new IV value. To reset CFB, OFB and CTR */ +/* without setting the key, aes_mode_reset() must be called and the */ +/* IV must be set. NOTE: All these calls update the IV on exit so */ +/* this has to be reset if a new operation with the same IV as the */ +/* previous one is required (or decryption follows encryption with */ +/* the same IV array). */ + +AES_RETURN aes_test_alignment_detection(unsigned int n); -aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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, +AES_RETURN 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, +AES_RETURN 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, +AES_RETURN 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_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]); -aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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, +AES_RETURN 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, +AES_RETURN 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); @@ -176,7 +193,7 @@ 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, +AES_RETURN 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 diff --git a/src/crypto/aes_edefs.h b/src/crypto/aes_edefs.h index d25bef8..1c1d091 100644 --- a/src/crypto/aes_edefs.h +++ b/src/crypto/aes_edefs.h @@ -1,25 +1,20 @@ /* --------------------------------------------------------------------------- - Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved. + Copyright (c) 1998-2008, 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: + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: - 1. distributions of this source code include the above copyright - notice, this list of conditions and the following disclaimer; + 1. source code distributions 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; + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; - 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. + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. DISCLAIMER @@ -27,75 +22,86 @@ in respect of its properties, including, but not limited to, correctness and/or fitness for purpose. --------------------------------------------------------------------------- - Issue 31/01/2006 + Issue Date: 20/12/2007 */ -#ifndef EDEFS_H -#define EDEFS_H -#if defined(__cplusplus) -extern "C" -{ -#endif +#ifndef _BRG_ENDIAN_H +#define _BRG_ENDIAN_H -#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ +#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ -#if defined(__GNUC__) || defined(__GNU_LIBRARY__) -# if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -# include -# elif defined( BSD ) && ( BSD >= 199103 ) || defined( __DJGPP__ ) || defined( __CYGWIN32__ ) -# include -# 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 files where endian defines and byteswap functions may reside */ +#if defined( __sun ) +# include +#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) +# include +#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ + defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) +# include +#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) +# if !defined( __MINGW32__ ) && !defined( _AIX ) # include -# if !defined(__BEOS__) +# if !defined( __BEOS__ ) # include # 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 +/* Now attempt to set the define for platform byte order using any */ +/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ +/* seem to encompass most endian symbol definitions */ + +#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) +# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) +# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN # endif +#elif defined( _BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( _LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #endif -/* if the platform is still unknown, try to find its byte order */ -/* from commonly used machine defines */ +#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) +# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif +#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) +# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +/* if the platform byte order could not be determined, then try to */ +/* set this define using common machine defines */ #if !defined(PLATFORM_BYTE_ORDER) #if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ @@ -105,13 +111,13 @@ extern "C" 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__ ) +#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( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ + defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #elif 0 /* **** EDIT HERE IF NECESSARY **** */ @@ -119,12 +125,9 @@ extern "C" #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 +# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order #endif #endif -#if defined(__cplusplus) -} -#endif #endif diff --git a/src/crypto/aes_modes.c b/src/crypto/aes_modes.c index 7ecc7eb..a5bd9a2 100644 --- a/src/crypto/aes_modes.c +++ b/src/crypto/aes_modes.c @@ -1,24 +1,38 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - -#include +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 + + 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 #include #include "aesopt.h" @@ -31,9 +45,6 @@ extern "C" #if defined( _MSC_VER ) && ( _MSC_VER > 800 ) #pragma intrinsic(memcpy) -#define in_line __inline -#else -#define in_line #endif #define BFR_BLOCKS 8 @@ -43,16 +54,12 @@ extern "C" /* 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" +#include "aes_via_ace.h" #pragma pack(16) @@ -83,24 +90,49 @@ aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA; #if defined( _MSC_VER ) && _MSC_VER > 1200 -#define via_cwd(cwd, ty, dir, len) unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4)) +#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; \ +#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]) +/* test the code for detecting and setting pointer alignment */ + +AES_RETURN aes_test_alignment_detection(unsigned int n) /* 4 <= n <= 16 */ +{ uint_8t p[16]; + uint_32t i, count_eq = 0, count_neq = 0; + + if(n < 4 || n > 16) + return EXIT_FAILURE; + + for(i = 0; i < n; ++i) + { + uint_8t *qf = ALIGN_FLOOR(p + i, n), + *qh = ALIGN_CEIL(p + i, n); + + if(qh == qf) + ++count_eq; + else if(qh == qf + n) + ++count_neq; + else + return EXIT_FAILURE; + } + return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS); +} + +AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1]) { - ctx->inf.b[2] = 0; + ctx->inf.b[2] = 0; return EXIT_SUCCESS; } -aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, const aes_encrypt_ctx ctx[1]) { int nb = len >> 4; @@ -111,12 +143,12 @@ aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, if(ctx->inf.b[1] == 0xff) { uint_8t *ksp = (uint_8t*)(ctx->ks); - via_cwd(cwd, hybrid, enc, 2* ctx->inf.b[0] - 192); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(addr_mod_16(ctx)) + if(ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; - if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) { via_ecb_op5(ksp,cwd,ibuf,obuf,nb); } @@ -128,8 +160,8 @@ aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); - op = (addr_mod_16(obuf) ? buf : obuf); + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); @@ -153,7 +185,8 @@ aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, #if !defined( ASSUME_VIA_ACE_PRESENT ) while(nb--) { - aes_encrypt(ibuf, obuf, ctx); + if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; } @@ -161,7 +194,7 @@ aes_rval aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -aes_rval aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, const aes_decrypt_ctx ctx[1]) { int nb = len >> 4; @@ -172,12 +205,12 @@ aes_rval aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, if(ctx->inf.b[1] == 0xff) { uint_8t *ksp = kd_adr(ctx); - via_cwd(cwd, hybrid, dec, 2* ctx->inf.b[0] - 192); + via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); - if(addr_mod_16(ctx)) + if(ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; - if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) { via_ecb_op5(ksp,cwd,ibuf,obuf,nb); } @@ -189,8 +222,8 @@ aes_rval aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); - op = (addr_mod_16(obuf) ? buf : obuf); + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); @@ -214,7 +247,8 @@ aes_rval aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, #if !defined( ASSUME_VIA_ACE_PRESENT ) while(nb--) { - aes_decrypt(ibuf, obuf, ctx); + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; } @@ -222,7 +256,7 @@ aes_rval aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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; @@ -234,18 +268,18 @@ aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, 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); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(addr_mod_16(ctx)) + if(ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; - if(addr_mod_16(iv)) /* ensure an aligned iv */ + if(ALIGN_OFFSET( iv, 16 )) /* 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)) + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 )) { via_cbc_op7(ksp,cwd,ibuf,obuf,nb,ivp,ivp); } @@ -257,8 +291,8 @@ aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); - op = (addr_mod_16(obuf) ? buf : obuf); + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); @@ -284,14 +318,15 @@ aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, #if !defined( ASSUME_VIA_ACE_PRESENT ) # ifdef FAST_BUFFER_OPERATIONS - if(!addr_mod_04(ibuf) && !addr_mod_04(iv)) + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) 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); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; memcpy(obuf, iv, AES_BLOCK_SIZE); ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; @@ -308,7 +343,8 @@ aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, 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); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; memcpy(obuf, iv, AES_BLOCK_SIZE); ibuf += AES_BLOCK_SIZE; obuf += AES_BLOCK_SIZE; @@ -317,7 +353,7 @@ aes_rval aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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; @@ -330,18 +366,18 @@ aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, 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); + via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); - if(addr_mod_16(ctx)) + if(ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; - if(addr_mod_16(iv)) /* ensure an aligned iv */ + if(ALIGN_OFFSET( iv, 16 )) /* 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)) + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 )) { via_cbc_op6(ksp,cwd,ibuf,obuf,nb,ivp); } @@ -353,8 +389,8 @@ aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, { int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb); - ip = (addr_mod_16(ibuf) ? buf : (uint_8t*)ibuf); - op = (addr_mod_16(obuf) ? buf : obuf); + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); @@ -379,11 +415,12 @@ aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, #if !defined( ASSUME_VIA_ACE_PRESENT ) # ifdef FAST_BUFFER_OPERATIONS - if(!addr_mod_04(obuf) && !addr_mod_04(iv)) + if(!ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) while(nb--) { memcpy(tmp, ibuf, AES_BLOCK_SIZE); - aes_decrypt(ibuf, obuf, ctx); + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; lp32(obuf)[0] ^= lp32(iv)[0]; lp32(obuf)[1] ^= lp32(iv)[1]; lp32(obuf)[2] ^= lp32(iv)[2]; @@ -397,7 +434,8 @@ aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, while(nb--) { memcpy(tmp, ibuf, AES_BLOCK_SIZE); - aes_decrypt(ibuf, obuf, ctx); + if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1]; obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3]; obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5]; @@ -414,7 +452,7 @@ aes_rval aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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; @@ -426,7 +464,7 @@ aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); } - if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ + if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ { #if defined( USE_VIA_ACE_IF_PRESENT ) @@ -434,18 +472,18 @@ aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, { 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); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(addr_mod_16(ctx)) + if(ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; - if(addr_mod_16(iv)) /* ensure an aligned iv */ + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) { via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp); ibuf += nb * AES_BLOCK_SIZE; @@ -460,8 +498,8 @@ aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, { 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); + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); @@ -482,11 +520,12 @@ aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, } #else # ifdef FAST_BUFFER_OPERATIONS - if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) && !addr_mod_04(iv)) + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - aes_encrypt(iv, iv, ctx); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; 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]; @@ -500,7 +539,8 @@ aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - aes_encrypt(iv, iv, ctx); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; 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]; @@ -518,8 +558,8 @@ aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, while(cnt < len) { - if(!b_pos) - aes_ecb_encrypt(iv, iv, AES_BLOCK_SIZE, ctx); + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; while(cnt < len && b_pos < AES_BLOCK_SIZE) *obuf++ = iv[b_pos++] ^= *ibuf++, cnt++; @@ -531,7 +571,7 @@ aes_rval aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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; @@ -544,7 +584,7 @@ aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); } - if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ + if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ { #if defined( USE_VIA_ACE_IF_PRESENT ) @@ -552,18 +592,18 @@ aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, { 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); + via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192); - if(addr_mod_16(ctx)) + if(ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; - if(addr_mod_16(iv)) /* ensure an aligned iv */ + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) { via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp); ibuf += nb * AES_BLOCK_SIZE; @@ -578,15 +618,15 @@ aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, { 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); + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); - if(ip != ibuf) + if(ip != ibuf) /* input buffer is not aligned */ memcpy(buf, ibuf, m * AES_BLOCK_SIZE); via_cfb_op6(ksp, cwd, ip, op, m, ivp); - if(op != obuf) + if(op != obuf) /* output buffer is not aligned */ memcpy(obuf, buf, m * AES_BLOCK_SIZE); ibuf += m * AES_BLOCK_SIZE; @@ -600,12 +640,13 @@ aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, } #else # ifdef FAST_BUFFER_OPERATIONS - if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) &&!addr_mod_04(iv)) + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) &&!ALIGN_OFFSET( iv, 4 )) while(cnt + AES_BLOCK_SIZE <= len) { uint_32t t; assert(b_pos == 0); - aes_encrypt(iv, iv, ctx); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; 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; @@ -620,7 +661,8 @@ aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, { uint_8t t; assert(b_pos == 0); - aes_encrypt(iv, iv, ctx); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; 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; @@ -647,8 +689,8 @@ aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, while(cnt < len) { uint_8t t; - if(!b_pos) - aes_ecb_encrypt(iv, iv, AES_BLOCK_SIZE, ctx); + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; while(cnt < len && b_pos < AES_BLOCK_SIZE) t = *ibuf++, *obuf++ = t ^ iv[b_pos], iv[b_pos++] = t, cnt++; @@ -660,7 +702,7 @@ aes_rval aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, return EXIT_SUCCESS; } -aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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; @@ -680,18 +722,18 @@ aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, { 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); + via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192); - if(addr_mod_16(ctx)) + if(ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; - if(addr_mod_16(iv)) /* ensure an aligned iv */ + if(ALIGN_OFFSET( iv, 16 )) /* ensure an aligned iv */ { ivp = liv; memcpy(liv, iv, AES_BLOCK_SIZE); } - if(!addr_mod_16(ibuf) && !addr_mod_16(obuf)) + if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 )) { via_ofb_op6(ksp, cwd, ibuf, obuf, nb, ivp); ibuf += nb * AES_BLOCK_SIZE; @@ -706,8 +748,8 @@ aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, { 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); + ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf); + op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf); if(ip != ibuf) memcpy(buf, ibuf, m * AES_BLOCK_SIZE); @@ -728,11 +770,12 @@ aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, } #else # ifdef FAST_BUFFER_OPERATIONS - if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) && !addr_mod_04(iv)) + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 )) while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - aes_encrypt(iv, iv, ctx); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; 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]; @@ -746,7 +789,8 @@ aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, while(cnt + AES_BLOCK_SIZE <= len) { assert(b_pos == 0); - aes_encrypt(iv, iv, ctx); + if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; 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]; @@ -764,8 +808,8 @@ aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, while(cnt < len) { - if(!b_pos) - aes_ecb_encrypt(iv, iv, AES_BLOCK_SIZE, ctx); + if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; while(cnt < len && b_pos < AES_BLOCK_SIZE) *obuf++ = iv[b_pos++] ^ *ibuf++, cnt++; @@ -779,14 +823,14 @@ aes_rval aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, #define BFR_LENGTH (BFR_BLOCKS * AES_BLOCK_SIZE) -aes_rval aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, +AES_RETURN 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)) + if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET( ctx, 16 )) return EXIT_FAILURE; #else uint_8t buf[BFR_LENGTH]; @@ -795,9 +839,10 @@ aes_rval aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, 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(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; + while(b_pos < AES_BLOCK_SIZE && len) + *obuf++ = *ibuf++ ^ buf[b_pos++], --len; if(len) ctr_inc(cbuf), b_pos = 0; } @@ -819,16 +864,17 @@ aes_rval aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, #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_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); + if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS) + return EXIT_FAILURE; i = 0; ip = buf; # ifdef FAST_BUFFER_OPERATIONS - if(!addr_mod_04(ibuf) && !addr_mod_04(obuf) && !addr_mod_04(ip)) + if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( ip, 4 )) while(i + AES_BLOCK_SIZE <= blen) { lp32(obuf)[0] = lp32(ibuf)[0] ^ lp32(ip)[0]; diff --git a/src/crypto/aes_tdefs.h b/src/crypto/aes_tdefs.h index 89412b8..62906f9 100644 --- a/src/crypto/aes_tdefs.h +++ b/src/crypto/aes_tdefs.h @@ -1,121 +1,223 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - /* - The unsigned integer types defined here are of the form uint_t where - 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_t, a regular expression search - and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t') + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 + + The unsigned integer types defined here are of the form uint_t where + 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_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 +#ifndef _BRG_TYPES_H +#define _BRG_TYPES_H + #if defined(__cplusplus) -extern "C" -{ +extern "C" { #endif #include -#if UCHAR_MAX == 0xff - typedef unsigned char uint_8t; +#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) +# include +# define ptrint_t intptr_t +#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) +# include +# define ptrint_t intptr_t #else -# error Please define uint_8t as an 8-bit unsigned integer type in tdefs.h +# define ptrint_t int #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 +#ifndef BRG_UI8 +# define BRG_UI8 +# if UCHAR_MAX == 255u + typedef unsigned char uint_8t; +# else +# error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h +# endif #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 do not provide -#else -# error Please define uint_32t as a 32-bit unsigned integer type in tdefs.h +#ifndef BRG_UI16 +# define BRG_UI16 +# if USHRT_MAX == 65535u + typedef unsigned short uint_16t; +# else +# error Please define uint_16t as a 16-bit unsigned short type in brg_types.h +# endif #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; +#ifndef BRG_UI32 +# define BRG_UI32 +# if UINT_MAX == 4294967295u +# define li_32(h) 0x##h##u + typedef unsigned int uint_32t; +# elif ULONG_MAX == 4294967295u +# define li_32(h) 0x##h##ul + typedef unsigned long uint_32t; +# elif defined( _CRAY ) +# error This code needs 32-bit data types, which Cray machines do not provide # else -# error Please define uint_64t as an unsigned 64 bit type in tdefs.h +# error Please define uint_32t as a 32-bit unsigned integer type in brg_types.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 +#ifndef BRG_UI64 +# if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 + typedef unsigned __int64 uint_64t; +# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */ +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 + typedef unsigned __int64 uint_64t; +# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# elif defined( __MVS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned int long long uint_64t; +# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u +# if UINT_MAX == 18446744073709551615u +# define BRG_UI64 +# define li_64(h) 0x##h##u + typedef unsigned int uint_64t; +# endif +# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u +# if ULONG_MAX == 18446744073709551615ul +# define BRG_UI64 +# define li_64(h) 0x##h##ul + typedef unsigned long uint_64t; +# endif +# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u +# if ULLONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# endif +# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u +# if ULONG_LONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# endif # 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 +#endif + +#if !defined( BRG_UI64 ) +# if defined( NEED_UINT_64T ) +# error Please define uint_64t as an unsigned 64 bit type in brg_types.h +# endif +#endif + +#ifndef RETURN_VALUES +# define RETURN_VALUES +# if defined( DLL_EXPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllexport ) void __stdcall +# define INT_RETURN __declspec( dllexport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllexport__ ) void +# define INT_RETURN __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_RETURN __declspec( dllimport ) void __stdcall +# define INT_RETURN __declspec( dllimport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllimport__ ) void +# define INT_RETURN __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_RETURN void __cdecl +# define INT_RETURN int __cdecl # else -# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# define VOID_RETURN void +# define INT_RETURN int # endif -#elif defined( __WATCOMC__ ) -# define void_ret void __cdecl -# define int_ret int __cdecl -#else -# define void_ret void -# define int_ret int #endif +/* These defines are used to detect and set the memory alignment of pointers. + Note that offsets are in bytes. + + ALIGN_OFFSET(x,n) return the positive or zero offset of + the memory addressed by the pointer 'x' + from an address that is aligned on an + 'n' byte boundary ('n' is a power of 2) + + ALIGN_FLOOR(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not higher than the memory address + pointed to by 'x' ('n' is a power of 2) + + ALIGN_CEIL(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not lower than the memory address + pointed to by 'x' ('n' is a power of 2) +*/ + +#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1)) +#define ALIGN_FLOOR(x,n) ((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1))) +#define ALIGN_CEIL(x,n) ((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1))) + +/* These defines are used to declare buffers in a way that allows + faster operations on longer variables to be used. In all these + defines 'size' must be a power of 2 and >= 8. NOTE that the + buffer size is in bytes but the type length is in bits + + UNIT_TYPEDEF(x,size) declares a variable 'x' of length + 'size' bits + + BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize' + bytes defined as an array of variables + each of 'size' bits (bsize must be a + multiple of size / 8) + + UNIT_CAST(x,size) casts a variable to a type of + length 'size' bits + + UPTR_CAST(x,size) casts a pointer to a pointer to a + varaiable of length 'size' bits +*/ + +#define UI_TYPE(size) uint_##size##t +#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x +#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)] +#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x)) +#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x)) + #if defined(__cplusplus) } #endif + #endif diff --git a/src/crypto/aescpp.h b/src/crypto/aescpp.h index 471badb..a623035 100644 --- a/src/crypto/aescpp.h +++ b/src/crypto/aescpp.h @@ -1,24 +1,28 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - /* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 This file contains the definitions required to use AES (Rijndael) in C++. */ @@ -34,58 +38,58 @@ class AESencrypt { public: aes_encrypt_ctx cx[1]; - AESencrypt(void) { gen_tabs(); }; -#ifdef AES_128 + AESencrypt(void) { aes_init(); }; +#if defined(AES_128) AESencrypt(const unsigned char key[]) { aes_encrypt_key128(key, cx); } - aes_rval key128(const unsigned char key[]) + AES_RETURN key128(const unsigned char key[]) { return aes_encrypt_key128(key, cx); } #endif -#ifdef AES_192 - aes_rval key192(const unsigned char key[]) +#if defined(AES_192) + AES_RETURN key192(const unsigned char key[]) { return aes_encrypt_key192(key, cx); } #endif -#ifdef AES_256 - aes_rval key256(const unsigned char key[]) +#if defined(AES_256) + AES_RETURN 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) +#if defined(AES_VAR) + AES_RETURN 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 + AES_RETURN 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 + AES_RETURN 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_RETURN mode_reset(void) { return aes_mode_reset(cx); } - aes_rval ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const + AES_RETURN 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, + AES_RETURN 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, + AES_RETURN 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, + AES_RETURN 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, + AES_RETURN 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, + AES_RETURN 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); } @@ -101,39 +105,39 @@ class AESdecrypt { public: aes_decrypt_ctx cx[1]; - AESdecrypt(void) { gen_tabs(); }; -#ifdef AES_128 + AESdecrypt(void) { aes_init(); }; +#if defined(AES_128) AESdecrypt(const unsigned char key[]) { aes_decrypt_key128(key, cx); } - aes_rval key128(const unsigned char key[]) + AES_RETURN key128(const unsigned char key[]) { return aes_decrypt_key128(key, cx); } #endif -#ifdef AES_192 - aes_rval key192(const unsigned char key[]) +#if defined(AES_192) + AES_RETURN key192(const unsigned char key[]) { return aes_decrypt_key192(key, cx); } #endif -#ifdef AES_256 - aes_rval key256(const unsigned char key[]) +#if defined(AES_256) + AES_RETURN 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) +#if defined(AES_VAR) + AES_RETURN 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 + AES_RETURN 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 + AES_RETURN 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 + AES_RETURN 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, + AES_RETURN 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 diff --git a/src/crypto/aescrypt.c b/src/crypto/aescrypt.c index ef58702..1fe1b5a 100644 --- a/src/crypto/aescrypt.c +++ b/src/crypto/aescrypt.c @@ -1,22 +1,29 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 +*/ #include "aesopt.h" #include "aestab.h" @@ -41,7 +48,7 @@ extern "C" #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) +#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 @@ -87,17 +94,15 @@ extern "C" #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]) +AES_RETURN 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); @@ -155,10 +160,7 @@ aes_rval aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encr #endif state_out(out, b0); - -#if defined( AES_ERR_CHK ) return EXIT_SUCCESS; -#endif } #endif @@ -224,17 +226,15 @@ aes_rval aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encr #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]) +AES_RETURN 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); @@ -291,10 +291,7 @@ aes_rval aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decr #endif state_out(out, b0); - -#if defined( AES_ERR_CHK ) return EXIT_SUCCESS; -#endif } #endif diff --git a/src/crypto/aeskey.c b/src/crypto/aeskey.c index 2effb68..4964861 100644 --- a/src/crypto/aeskey.c +++ b/src/crypto/aeskey.c @@ -1,28 +1,35 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 +*/ #include "aesopt.h" #include "aestab.h" #ifdef USE_VIA_ACE_IF_PRESENT -#include "via_ace.h" +# include "aes_via_ace.h" #endif #if defined(__cplusplus) @@ -48,9 +55,22 @@ extern "C" cx->n_col = 8 29 23 19 17 14 */ +#if defined( REDUCE_CODE_SIZE ) +# define ls_box ls_sub + uint_32t ls_sub(const uint_32t t, const uint_32t n); +# define inv_mcol im_sub + uint_32t im_sub(const uint_32t x); +# ifdef ENC_KS_UNROLL +# undef ENC_KS_UNROLL +# endif +# ifdef DEC_KS_UNROLL +# undef DEC_KS_UNROLL +# endif +#endif + #if (FUNCS_IN_C & ENC_KEYING_IN_C) -#if defined(AES_128) || defined(AES_VAR) +#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]; \ @@ -59,7 +79,7 @@ extern "C" k[4*(i)+7] = ss[3] ^= ss[2]; \ } -aes_rval aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) +AES_RETURN 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); @@ -67,17 +87,17 @@ aes_rval aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[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 +#ifdef ENC_KS_UNROLL 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); +#else + { uint_32t i; + for(i = 0; i < 9; ++i) + ke4(cx->ks, i); + } #endif ke4(cx->ks, 9); cx->inf.l = 0; @@ -87,15 +107,12 @@ aes_rval aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) 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) +#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]; \ @@ -110,7 +127,7 @@ aes_rval aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) k[6*(i)+11] = ss[5] ^= ss[4]; \ } -aes_rval aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) +AES_RETURN 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); @@ -120,16 +137,16 @@ aes_rval aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) 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 +#ifdef ENC_KS_UNROLL 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); +#else + { uint_32t i; + for(i = 0; i < 7; ++i) + ke6(cx->ks, i); + } #endif kef6(cx->ks, 7); cx->inf.l = 0; @@ -139,15 +156,12 @@ aes_rval aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) 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) +#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]; \ @@ -164,7 +178,7 @@ aes_rval aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) k[8*(i)+15] = ss[7] ^= ss[6]; \ } -aes_rval aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) +AES_RETURN 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); @@ -176,15 +190,15 @@ aes_rval aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) cx->ks[6] = ss[6] = word_in(key, 6); cx->ks[7] = ss[7] = word_in(key, 7); -#if ENC_UNROLL == NONE +#ifdef ENC_KS_UNROLL + ke8(cx->ks, 0); ke8(cx->ks, 1); + ke8(cx->ks, 2); ke8(cx->ks, 3); + ke8(cx->ks, 4); ke8(cx->ks, 5); +#else { 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; @@ -194,30 +208,21 @@ aes_rval aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif - -#if defined( AES_ERR_CHK ) return EXIT_SUCCESS; -#endif } #endif -#if defined(AES_VAR) +#if defined( AES_VAR ) -aes_rval aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) -{ +AES_RETURN 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 } } @@ -245,7 +250,7 @@ aes_rval aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx #endif #endif -#if defined(AES_128) || defined(AES_VAR) +#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]; \ @@ -311,7 +316,7 @@ aes_rval aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx #endif -aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) +AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) { uint_32t ss[5]; #if defined( d_vars ) d_vars; @@ -321,7 +326,13 @@ aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[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 +#ifdef DEC_KS_UNROLL + 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); +#else { uint_32t i; for(i = 0; i < 10; ++i) k4e(cx->ks, i); @@ -330,12 +341,6 @@ aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) 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; @@ -344,15 +349,12 @@ aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) 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) +#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]; \ @@ -393,7 +395,7 @@ aes_rval aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) 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]) +AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) { uint_32t ss[7]; #if defined( d_vars ) d_vars; @@ -403,7 +405,14 @@ aes_rval aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[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 +#ifdef DEC_KS_UNROLL + 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); +#else 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; @@ -416,13 +425,6 @@ aes_rval aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) 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; @@ -431,15 +433,12 @@ aes_rval aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) 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) +#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]; \ @@ -487,7 +486,7 @@ aes_rval aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) 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]) +AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) { uint_32t ss[9]; #if defined( d_vars ) d_vars; @@ -497,7 +496,16 @@ aes_rval aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[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 +#ifdef DEC_KS_UNROLL + 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); +#else 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); @@ -510,18 +518,8 @@ aes_rval aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) #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; @@ -530,30 +528,21 @@ aes_rval aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif - -#if defined( AES_ERR_CHK ) return EXIT_SUCCESS; -#endif } #endif -#if defined(AES_VAR) +#if defined( AES_VAR ) -aes_rval aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) +AES_RETURN 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 } } diff --git a/src/crypto/aesopt.h b/src/crypto/aesopt.h index 11880f2..5ddaeb6 100644 --- a/src/crypto/aesopt.h +++ b/src/crypto/aesopt.h @@ -1,24 +1,29 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - /* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 + This file contains the compilation options for AES (Rijndael) and code that is common across encryption, key scheduling and table generation. @@ -43,24 +48,24 @@ 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 + AES_RETURN 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, + AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); + AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); + AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); + AES_RETURN 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, + AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); + AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); + AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); + AES_RETURN 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. + you call aes_init() before AES is used so that the tables are initialised. C++ aes class subroutines: @@ -70,20 +75,20 @@ 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 + AES_RETURN key128(const unsigned char *key) + AES_RETURN key192(const unsigned char *key) + AES_RETURN key256(const unsigned char *key) + AES_RETURN 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 + AES_RETURN key128(const unsigned char *key) + AES_RETURN key192(const unsigned char *key) + AES_RETURN key256(const unsigned char *key) + AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const */ #if !defined( _AESOPT_H ) @@ -97,7 +102,7 @@ /* PLATFORM SPECIFIC INCLUDES */ -#include "aes_edefs.h" +#include "aes_endian.h" /* CONFIGURATION - THE USE OF DEFINES @@ -153,40 +158,47 @@ This define will hence be redefined later (in section 4) if necessary */ -#if 1 -#define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER +#if 1 +# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER #elif 0 -#define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN +# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN #elif 0 -#define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN +# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN #else -#error The algorithm byte order is not defined +# error The algorithm byte order is not defined #endif -/* 2. VIA ACE SUPPORT +/* 2. VIA ACE SUPPORT */ + +// DISABLE VIA ACE +/*#if defined( __GNUC__ ) && defined( __i386__ ) \ + || defined( _WIN32 ) && defined( _M_IX86 ) \ + && !(defined( _WIN64 ) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 )) +# define VIA_ACE_POSSIBLE +#endif*/ - Define this option if support for the VIA ACE is required. This uses - inline assembler instructions and is only implemented for the Microsoft, +/* 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 + 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). + 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 later checks below ensure). */ -#if 0 && !defined( _WIN64 ) && !defined( USE_VIA_ACE_IF_PRESENT ) -#define USE_VIA_ACE_IF_PRESENT +#if 1 && defined( VIA_ACE_POSSIBLE ) && !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 +#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT ) +# define ASSUME_VIA_ACE_PRESENT +# endif /* 3. ASSEMBLER SUPPORT @@ -194,39 +206,32 @@ 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 + 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 + 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 + 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 + 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 +#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 +#elif 0 && !defined( ASM_AMD64_C ) +# define ASM_AMD64_C +#endif + +#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \ + && !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 ) +# error Assembler code is only available for x86 and AMD64 systems #endif /* 4. FAST INPUT/OUTPUT OPERATIONS. @@ -246,7 +251,7 @@ words will not cause problems when such accesses are misaligned. */ #if 1 && !defined( _MSC_VER ) -#define SAFE_IO +# define SAFE_IO #endif /* 5. LOOP UNROLLING @@ -261,19 +266,27 @@ to be set independently for encryption and decryption */ #if 1 -#define ENC_UNROLL FULL +# define ENC_UNROLL FULL #elif 0 -#define ENC_UNROLL PARTIAL +# define ENC_UNROLL PARTIAL #else -#define ENC_UNROLL NONE +# define ENC_UNROLL NONE #endif #if 1 -#define DEC_UNROLL FULL +# define DEC_UNROLL FULL #elif 0 -#define DEC_UNROLL PARTIAL +# define DEC_UNROLL PARTIAL #else -#define DEC_UNROLL NONE +# define DEC_UNROLL NONE +#endif + +#if 1 +# define ENC_KS_UNROLL +#endif + +#if 1 +# define DEC_KS_UNROLL #endif /* 6. FAST FINITE FIELD OPERATIONS @@ -282,7 +295,7 @@ field arithmetic (this has no effect if FIXED_TABLES is defined). */ #if 1 -#define FF_TABLES +# define FF_TABLES #endif /* 7. INTERNAL STATE VARIABLE FORMAT @@ -293,20 +306,31 @@ varaibles in arrays. Otherwise individual local variables will be used. */ #if 1 -#define ARRAYS +# 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() + statically into the binary file. Otherwise the subroutine aes_init() must be called to compute them before the code is first used. */ -#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) -#define FIXED_TABLES +#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) +# define FIXED_TABLES #endif -/* 9. TABLE ALIGNMENT +/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES + + In some systems it is better to mask longer values to extract bytes + rather than using a cast. This option allows this choice. +*/ +#if 0 +# define to_byte(x) ((uint_8t)(x)) +#else +# define to_byte(x) ((x) & 0xff) +#endif + +/* 10. 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 @@ -316,11 +340,21 @@ */ #if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) -#define TABLE_ALIGN 32 +# define TABLE_ALIGN 32 #endif -/* 10. TABLE OPTIONS - +/* 11. REDUCE CODE AND TABLE SIZE + + This replaces some expanded macros with function calls if AES_ASM_V2 or + AES_ASM_V2C are defined +*/ + +#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) +# define REDUCE_CODE_SIZE +#endif + +/* 12. 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 @@ -340,35 +374,35 @@ */ #if 1 /* set tables for the normal encryption round */ -#define ENC_ROUND FOUR_TABLES +# define ENC_ROUND FOUR_TABLES #elif 0 -#define ENC_ROUND ONE_TABLE +# define ENC_ROUND ONE_TABLE #else -#define ENC_ROUND NO_TABLES +# define ENC_ROUND NO_TABLES #endif #if 1 /* set tables for the last encryption round */ -#define LAST_ENC_ROUND FOUR_TABLES +# define LAST_ENC_ROUND FOUR_TABLES #elif 0 -#define LAST_ENC_ROUND ONE_TABLE +# define LAST_ENC_ROUND ONE_TABLE #else -#define LAST_ENC_ROUND NO_TABLES +# define LAST_ENC_ROUND NO_TABLES #endif #if 1 /* set tables for the normal decryption round */ -#define DEC_ROUND FOUR_TABLES +# define DEC_ROUND FOUR_TABLES #elif 0 -#define DEC_ROUND ONE_TABLE +# define DEC_ROUND ONE_TABLE #else -#define DEC_ROUND NO_TABLES +# define DEC_ROUND NO_TABLES #endif #if 1 /* set tables for the last decryption round */ -#define LAST_DEC_ROUND FOUR_TABLES +# define LAST_DEC_ROUND FOUR_TABLES #elif 0 -#define LAST_DEC_ROUND ONE_TABLE +# define LAST_DEC_ROUND ONE_TABLE #else -#define LAST_DEC_ROUND NO_TABLES +# define LAST_DEC_ROUND NO_TABLES #endif /* The decryption key schedule can be speeded up with tables in the same @@ -376,11 +410,11 @@ defines to set this requirement. */ #if 1 -#define KEY_SCHED FOUR_TABLES +# define KEY_SCHED FOUR_TABLES #elif 0 -#define KEY_SCHED ONE_TABLE +# define KEY_SCHED ONE_TABLE #else -#define KEY_SCHED NO_TABLES +# define KEY_SCHED NO_TABLES #endif /* ---- END OF USER CONFIGURED OPTIONS ---- */ @@ -397,18 +431,19 @@ #endif #if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT ) -#define 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 +# 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 +#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 @@ -423,20 +458,20 @@ */ #if defined( ARRAYS ) -#define s(x,c) x[c] +# define s(x,c) x[c] #else -#define s(x,c) x##c +# 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 + 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 ) +#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 ) @@ -447,8 +482,8 @@ #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 ) +#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 ) @@ -465,38 +500,38 @@ /* 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 +# 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 +# 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 +# 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 +# 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 +# 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 +# undef DEC_UNROLL +# define DEC_UNROLL NONE #endif #if defined( bswap32 ) -#define aes_sw32 bswap32 +# define aes_sw32 bswap32 #elif defined( bswap_32 ) -#define aes_sw32 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)) +# 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 @@ -511,38 +546,32 @@ */ #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) \ +# 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) to_byte((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) \ +# 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) to_byte((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], \ +# 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); \ +# 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)) - +# 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)) - +# 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 */ @@ -568,80 +597,85 @@ /* 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 +# 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 +# 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 +# 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 & 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 +#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) +# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)) +# if KEY_SCHED == ONE_TABLE +# if !defined( FL1_SET ) && !defined( FL4_SET ) +# define LS1_SET +# endif +# elif KEY_SCHED == FOUR_TABLES +# if !defined( FL4_SET ) +# define LS4_SET +# endif +# 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 #endif /* generic definitions of Rijndael macros that use tables */ @@ -671,39 +705,43 @@ /* 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) +#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) + +#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)) +# 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) +# 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) +# 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)) +# 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) +# 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) +# 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) +# 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) +# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c) +#endif + #endif #if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET ) -#define ISB_SET +# define ISB_SET #endif #endif diff --git a/src/crypto/aestab.c b/src/crypto/aestab.c index aa7a6c1..94027e3 100644 --- a/src/crypto/aestab.c +++ b/src/crypto/aestab.c @@ -1,33 +1,35 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 +*/ #define DO_TABLES #include "aes.h" #include "aesopt.h" -#if defined(__cplusplus) -extern "C" -{ -#endif - #if defined(FIXED_TABLES) #define sb_data(w) {\ @@ -181,11 +183,16 @@ extern "C" #include "aestab.h" +#if defined(__cplusplus) +extern "C" +{ +#endif + #if defined(FIXED_TABLES) /* implemented in case of wrong call for fixed tables */ -aes_rval gen_tabs(void) +AES_RETURN aes_init(void) { return EXIT_SUCCESS; } @@ -252,14 +259,14 @@ static uint_8t fi(const uint_8t x) static int init = 0; -aes_rval gen_tabs(void) +AES_RETURN aes_init(void) { uint_32t i, w; #if defined(FF_TABLES) uint_8t pow[512], log[256]; - if(init) + if(init) return EXIT_SUCCESS; /* log and power tables for GF(2^8) finite field with WPOLY as modular polynomial - the simplest primitive @@ -277,7 +284,7 @@ aes_rval gen_tabs(void) while (w != 1); #else - if(init) + if(init) return EXIT_SUCCESS; #endif @@ -308,7 +315,7 @@ aes_rval gen_tabs(void) #endif w = bytes2word(b, 0, 0, 0); -#if defined( FL1_SET ) /* tables for last encryption round (may also */ +#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 ) @@ -318,7 +325,7 @@ aes_rval gen_tabs(void) 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 */ +#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 ) @@ -331,7 +338,7 @@ aes_rval gen_tabs(void) 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 */ +#if defined( IM1_SET ) /* tables for the inverse mix column operation */ t_set(i,m)[b] = w; #endif #if defined( IM4_SET ) @@ -344,7 +351,7 @@ aes_rval gen_tabs(void) #if defined( ISB_SET ) t_set(i,box)[i] = b; #endif -#if defined( IT1_SET ) /* tables for a normal decryption round */ +#if defined( IT1_SET ) /* tables for a normal decryption round */ t_set(i,n)[i] = w; #endif #if defined( IT4_SET ) @@ -354,7 +361,7 @@ aes_rval gen_tabs(void) 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 */ +#if defined( IL1_SET ) /* tables for last decryption round */ t_set(i,l)[i] = w; #endif #if defined( IL4_SET ) diff --git a/src/crypto/aestab.h b/src/crypto/aestab.h index 9c454f1..a5e7834 100644 --- a/src/crypto/aestab.h +++ b/src/crypto/aestab.h @@ -1,24 +1,28 @@ - /************************************************************************** - * * - * Copyright (C) 2007 by Tarek Saidi * - * Copyright (c) 2003 Dr Brian Gladman, Worcester, UK * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - - /* +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + 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 Date: 20/12/2007 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. @@ -29,7 +33,7 @@ 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 + that control the calls to aes_init() and the aes_init() 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. @@ -69,20 +73,22 @@ #define t_use(m,n) t_##m##n #if defined(FIXED_TABLES) -# if defined( __MSDOS__ ) || defined( __WIN16__ ) +# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ )) /* make tables far data to avoid using too much DGROUP space (PG) */ # define CONST const far -# else +# else # define CONST const # endif #else # define CONST #endif -#if defined(DO_TABLES) -#define EXTERN +#if defined(__cplusplus) +# define EXTERN extern "C" +#elif defined(DO_TABLES) +# define EXTERN #else -#define EXTERN extern +# define EXTERN extern #endif #if defined(_MSC_VER) && defined(TABLE_ALIGN) @@ -91,20 +97,15 @@ #define ALIGN #endif -#if defined(__cplusplus) -extern "C" -{ -#endif - -#if defined( __WATCOMC__) +#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 ) # 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) } +#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) +#define d_4(t,n,b,e,f,g,h) EXTERN 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] @@ -170,8 +171,4 @@ EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH]; d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3); #endif -#if defined(__cplusplus) -} -#endif - #endif diff --git a/src/crypto/arcfour.cpp b/src/crypto/arcfour.cpp index d47c764..7425446 100644 --- a/src/crypto/arcfour.cpp +++ b/src/crypto/arcfour.cpp @@ -1,84 +1,58 @@ -/*************************************************************************** - * 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; version 2 of the License. * +/* + Copyright (C) 2003-2008 Dominik Reichl - * * - * 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. * - ***************************************************************************/ - -#include -#include "arcfour.h" + 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. -static inline void swap_byte(unsigned char *a, unsigned char *b) - { - unsigned char swapByte; + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ - swapByte = *a; - *a = *b; - *b = swapByte; - } +#include "arcfour.h" -void CArcFour::setKey(byte* key_data_ptr, int key_data_len){ -RawKey=QByteArray((const char*)key_data_ptr,key_data_len); +void CArcFour::setKey(quint8* key, int length){ + RawKey = key; + RawKeyLength = length; } -void CArcFour::prepareKey(){ - unsigned char index1; - unsigned char index2; - unsigned char* state; - short counter; +void CArcFour::encrypt(const quint8* src, quint8* dst, int length){ + quint8 S[256]; + quint32 w; + + for(w = 0; w < 256; ++w) + S[w] = static_cast(w); // Fill linearly - state = &key.state[0]; - for(counter = 0; counter < 256; counter++) - state[counter] = counter; - key.x = 0; - key.y = 0; - index1 = 0; - index2 = 0; - for(counter = 0; counter < 256; counter++) - { - index2 = (RawKey.at(index1) + state[counter] + index2) % 256; - swap_byte(&state[counter], &state[index2]); - index1 = (index1 + 1) % RawKey.size(); - } -} + const quint8 btBufDep = static_cast((length & 0xFF) << 1); -void CArcFour::encrypt(const byte* src, byte* dst,int length){ - prepareKey(); - unsigned char x; - unsigned char y; - unsigned char* state; - unsigned char xorIndex; - short counter; + quint8 i = 0, j = 0, t; + quint32 k = 0; + for(w = 0; w < 256; ++w) // Key setup + { + j += S[w] + RawKey[k] + btBufDep; - x = key.x; - y = key.y; + t = S[i]; S[i] = S[j]; S[j] = t; // Swap entries - state = &key.state[0]; - for(counter = 0; counter < length; counter ++) - { - x = (x + 1) % 256; - y = (state[x] + y) % 256; - swap_byte(&state[x], &state[y]); + ++k; + if(k == RawKeyLength) k = 0; + } - xorIndex = (state[x] + state[y]) % 256; + i = 0; j = 0; + for(w = 0; w < length; ++w) // Encrypt PT + { + ++i; + j += S[i]; - dst[counter]=src[counter]^state[xorIndex]; - } - key.x = x; - key.y = y; -} + t = S[i]; S[i] = S[j]; S[j] = t; // Swap entries + t = S[i] + S[j]; // Generate random byte + dst[w] = src[w] ^ S[t]; // XOR with PT + } +} diff --git a/src/crypto/arcfour.h b/src/crypto/arcfour.h index e1c0416..46a0b0d 100644 --- a/src/crypto/arcfour.h +++ b/src/crypto/arcfour.h @@ -1,45 +1,33 @@ -/*************************************************************************** - * 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; version 2 of the License. * +/* + Copyright (C) 2003-2008 Dominik Reichl - * * - * 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. * - ***************************************************************************/ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ #ifndef _ARCFOUR_H_ #define _ARCFOUR_H_ -#ifndef byte -#define byte quint8 -#endif - class CArcFour{ -public: - void encrypt(const byte* src, byte* dst,int length); - inline void decrypt(const byte* src, byte* dst,int length){encrypt(src,dst,length);} //just for readability - void setKey(byte* key, int length); - QByteArray RawKey; -private: - void prepareKey(); - - typedef struct rc4_key{ - byte state[256]; - byte x; - byte y;}rc4_key; - rc4_key key; + public: + void encrypt(const quint8* src, quint8* dst, int length); + inline void decrypt(const quint8* src, quint8* dst, int length){encrypt(src,dst,length);} //just for readability + void setKey(quint8* key, int length); + + private: + quint8* RawKey; + int RawKeyLength; }; - #endif diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp deleted file mode 100644 index 24255ab..0000000 --- a/src/crypto/sha1.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/*************************************************************************** - * Implementation of the SHA-1 algorithm * - * by Dominik Reichl (public domain) * - * * - * Copyright (C) 2007 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; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - -#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); -} diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h deleted file mode 100644 index 455d059..0000000 --- a/src/crypto/sha1.h +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** - * Implementation of the SHA-1 algorithm * - * by Dominik Reichl (no copyright) * - * * - * Copyright (C) 2007 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; version 2 of the License. * - * * - * 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. * - ***************************************************************************/ - - -/* - 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 // Needed for file access -#include // Needed for memset and memcpy -#include // 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 diff --git a/src/crypto/yarrow.cpp b/src/crypto/yarrow.cpp index 1e87990..114e9c0 100644 --- a/src/crypto/yarrow.cpp +++ b/src/crypto/yarrow.cpp @@ -403,7 +403,7 @@ void initYarrow(){ quint8 buffer[100]; for (int i=0; i<2; i++){ - Random::getEntropy(buffer,100); + getEntropy(buffer,100); yarrowUpdateWeak(i,100*8,100,buffer); } } diff --git a/src/dialogs/PasswordDlg.cpp b/src/dialogs/PasswordDlg.cpp index 89a1423..f3949ed 100644 --- a/src/dialogs/PasswordDlg.cpp +++ b/src/dialogs/PasswordDlg.cpp @@ -349,7 +349,7 @@ void PasswordDialog::OnGenKeyFile(){ QString PasswordDialog::password(){ if(Check_Password->isChecked()) - return Edit_Password->text(); + return Password; else return QString(); } @@ -368,6 +368,16 @@ QString PasswordDialog::selectedBookmark(){ void PasswordDialog::OnButtonBack(){ stackedWidget->setCurrentIndex(0); - Edit_PwRepeat->clear(); + Edit_PwRepeat->clear(); } +void PasswordDialog::done(int r){ + // workaround for a Qt crash bug + Password = Edit_Password->text(); + Edit_Password->clear(); + Edit_Password->setEchoMode(QLineEdit::Normal); + Edit_PwRepeat->clear(); + Edit_PwRepeat->setEchoMode(QLineEdit::Normal); + + QDialog::done(r); +} diff --git a/src/dialogs/PasswordDlg.h b/src/dialogs/PasswordDlg.h index ae01475..7f5221f 100644 --- a/src/dialogs/PasswordDlg.h +++ b/src/dialogs/PasswordDlg.h @@ -63,6 +63,7 @@ class PasswordDialog : public QDialog, private Ui_PasswordDlg { void ChangeEchoModeDatabaseKey(); void OnBookmarkTriggered(QAction* action); void OnCheckBoxesChanged(int state); + void done(int r); private: DlgMode Mode; diff --git a/src/dialogs/PasswordGenDlg.cpp b/src/dialogs/PasswordGenDlg.cpp index 44a1393..7083c26 100644 --- a/src/dialogs/PasswordGenDlg.cpp +++ b/src/dialogs/PasswordGenDlg.cpp @@ -22,39 +22,67 @@ #include "dialogs/PasswordGenDlg.h" #include "dialogs/CollectEntropyDlg.h" +#include "apg/randpass.h" +#include "apg/pronpass.h" + bool CGenPwDialog::EntropyCollected=false; CGenPwDialog::CGenPwDialog(QWidget* parent, bool StandAloneMode,Qt::WFlags fl) : QDialog(parent,fl) { setupUi(this); - connect(ButtonGenerate,SIGNAL(clicked()),this,SLOT(OnGeneratePw())); - connect(Radio_1,SIGNAL(toggled(bool)),this,SLOT(OnRadio1StateChanged(bool))); - connect(Radio_2,SIGNAL(toggled(bool)),this,SLOT(OnRadio2StateChanged(bool))); - connect(DialogButtons,SIGNAL(rejected()),this,SLOT(OnCancel())); - connect(DialogButtons,SIGNAL(accepted()),this,SLOT(OnAccept())); - connect(checkBox1,SIGNAL(clicked()),this,SLOT(estimateQuality())); - connect(checkBox2,SIGNAL(clicked()),this,SLOT(estimateQuality())); - connect(checkBox3,SIGNAL(clicked()),this,SLOT(estimateQuality())); - connect(checkBox4,SIGNAL(clicked()),this,SLOT(estimateQuality())); - connect(checkBox5,SIGNAL(clicked()),this,SLOT(estimateQuality())); - connect(checkBox6,SIGNAL(clicked()),this,SLOT(estimateQuality())); - connect(checkBox7,SIGNAL(clicked()),this,SLOT(estimateQuality())); - connect(Spin_Num,SIGNAL(valueChanged(int)),this,SLOT(estimateQuality())); - connect(Check_CollectEntropy,SIGNAL(stateChanged(int)),this,SLOT(OnCollectEntropyChanged(int))); - connect(Edit_chars,SIGNAL(textChanged(const QString&)),this,SLOT(estimateQuality())); - connect(Edit_chars,SIGNAL(textEdited(const QString&)),this,SLOT(OnCharsChanged(const QString&))); + connect(ButtonGenerate, SIGNAL(clicked()), SLOT(OnGeneratePw())); + connect(Radio_1, SIGNAL(toggled(bool)), SLOT(OnRadio1StateChanged(bool))); + connect(Radio_2, SIGNAL(toggled(bool)), SLOT(OnRadio2StateChanged(bool))); + connect(DialogButtons, SIGNAL(rejected()), SLOT(OnCancel())); + connect(DialogButtons, SIGNAL(accepted()), SLOT(OnAccept())); + connect(tabCategory, SIGNAL(currentChanged(int)), SLOT(estimateQuality())); + connect(Radio_1, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(Radio_2, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBox1, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBox2, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBox3, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBox4, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBox5, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBox6, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBox7, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(Edit_chars, SIGNAL(textChanged(const QString&)), SLOT(estimateQuality())); + connect(checkBoxPU, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBoxPL, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBoxPN, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(checkBoxPS, SIGNAL(toggled(bool)), SLOT(estimateQuality())); + connect(Spin_Num, SIGNAL(valueChanged(int)), SLOT(estimateQuality())); + connect(Check_CollectEntropy, SIGNAL(stateChanged(int)), SLOT(OnCollectEntropyChanged(int))); + connect(Edit_chars, SIGNAL(textEdited(const QString&)), SLOT(OnCharsChanged(const QString&))); + connect(ButtonChangeEchoMode, SIGNAL(clicked()), SLOT(SwapEchoMode())); + connect(tabCategory, SIGNAL(currentChanged(int)), SLOT(setGenerateEnabled())); + connect(Radio_1, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(Radio_2, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBox1, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBox2, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBox3, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBox4, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBox5, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBox6, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBox7, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(Edit_chars, SIGNAL(textChanged(const QString&)), SLOT(setGenerateEnabled())); + connect(checkBoxPU, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBoxPL, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBoxPN, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); + connect(checkBoxPS, SIGNAL(toggled(bool)), SLOT(setGenerateEnabled())); if(!StandAloneMode){ AcceptButton=DialogButtons->addButton(QDialogButtonBox::Ok); - AcceptButton->setDisabled(true); + AcceptButton->setEnabled(false); DialogButtons->addButton(QDialogButtonBox::Cancel); + connect(Edit_dest, SIGNAL(textChanged(const QString&)), SLOT(setAcceptEnabled(const QString&))); } else{ DialogButtons->addButton(QDialogButtonBox::Close); AcceptButton=NULL; } + tabCategory->setCurrentIndex(config->pwGenCategory()); QBitArray pwGenOptions=config->pwGenOptions(); Radio_1->setChecked(pwGenOptions.at(0)); Radio_2->setChecked(!pwGenOptions.at(0)); @@ -69,15 +97,33 @@ CGenPwDialog::CGenPwDialog(QWidget* parent, bool StandAloneMode,Qt::WFlags fl) Check_CollectOncePerSession->setChecked(pwGenOptions.at(9)); OnRadio1StateChanged(pwGenOptions.at(0)); OnRadio2StateChanged(!pwGenOptions.at(0)); + if (pwGenOptions.size()>=14){ + checkBoxPU->setChecked(pwGenOptions.at(10)); + checkBoxPL->setChecked(pwGenOptions.at(11)); + checkBoxPN->setChecked(pwGenOptions.at(12)); + checkBoxPS->setChecked(pwGenOptions.at(13)); + } + else{ + checkBoxPU->setChecked(true); + checkBoxPL->setChecked(true); + checkBoxPN->setChecked(true); + checkBoxPS->setChecked(false); + } Spin_Num->setValue(config->pwGenLength()); adjustSize(); setMaximumSize(size()); setMinimumSize(size()); createBanner(&BannerPixmap,getPixmap("dice"),tr("Password Generator"),width()); + + if(!config->showPasswords()) + SwapEchoMode(); + else + ButtonChangeEchoMode->setIcon(getIcon("pwd_show")); } CGenPwDialog::~CGenPwDialog(){ - QBitArray pwGenOptions(10); + config->setPwGenCategory(tabCategory->currentIndex()); + QBitArray pwGenOptions(14); pwGenOptions.setBit(0,Radio_1->isChecked()); pwGenOptions.setBit(1,checkBox1->isChecked()); pwGenOptions.setBit(2,checkBox2->isChecked()); @@ -88,6 +134,10 @@ CGenPwDialog::~CGenPwDialog(){ pwGenOptions.setBit(7,checkBox7->isChecked()); pwGenOptions.setBit(8,Check_CollectEntropy->isChecked()); pwGenOptions.setBit(9,Check_CollectOncePerSession->isChecked()); + pwGenOptions.setBit(10,checkBoxPU->isChecked()); + pwGenOptions.setBit(11,checkBoxPL->isChecked()); + pwGenOptions.setBit(12,checkBoxPN->isChecked()); + pwGenOptions.setBit(13,checkBoxPS->isChecked()); config->setPwGenOptions(pwGenOptions); config->setPwGenLength(Spin_Num->value()); } @@ -118,7 +168,6 @@ void CGenPwDialog::OnRadio1StateChanged(bool state) checkBox6->setDisabled(true); checkBox7->setDisabled(true); } - estimateQuality(); } void CGenPwDialog::OnRadio2StateChanged(bool state){ @@ -126,90 +175,56 @@ void CGenPwDialog::OnRadio2StateChanged(bool state){ Edit_chars->setEnabled(true); else Edit_chars->setDisabled(true); - - estimateQuality(); } void CGenPwDialog::OnGeneratePw() { - /*------------------------------------------------------- - ASCII - ------------------------------------------------------- - "A...Z" 65...90 - "a...z" 97...122 - "0...9" 48...57 - Special Characters 33...47; 58...64; 91...96; 123...126 - "-" 45 - "_" 95 - ------------------------------------------------------- - */ - - int num=0; - char assoctable[255]; - - if(Radio_1->isChecked()){ - if(checkBox1->isChecked()) - num+=AddToAssoctable(assoctable,65,90,num); - if(checkBox2->isChecked()) - num+=AddToAssoctable(assoctable,97,122,num); - if(checkBox3->isChecked()) - num+=AddToAssoctable(assoctable,48,57,num); - if(checkBox4->isChecked()){ - num+=AddToAssoctable(assoctable,33,47,num); - num+=AddToAssoctable(assoctable,58,64,num); - num+=AddToAssoctable(assoctable,91,96,num); - num+=AddToAssoctable(assoctable,123,126,num);} - if(checkBox5->isChecked()) - num+=AddToAssoctable(assoctable,32,32,num); - if(checkBox6->isChecked() && !checkBox4->isChecked()) - num+=AddToAssoctable(assoctable,45,45,num); - if(checkBox7->isChecked() && !checkBox4->isChecked()) - num+=AddToAssoctable(assoctable,95,95,num); + int length = Spin_Num->value(); + char* buffer = new char[length+1]; + + if (tabCategory->currentIndex()==1) + { + unsigned int mode = 0; + if (checkBoxPU->isChecked()) + mode |= S_CL; + if (checkBoxPL->isChecked()) + mode |= S_SL; + if (checkBoxPN->isChecked()) + mode |= S_NB; + if (checkBoxPS->isChecked()) + mode |= S_SS; + + char* hyphenated_word = new char[length*18+1]; + gen_pron_pass(buffer, hyphenated_word, length, length, mode); + delete[] hyphenated_word; } - else{ - QString str=Edit_chars->text(); - for(int i=0;iisChecked() && !checkBox5->isChecked() && + !checkBox6->isChecked() && !checkBox7->isChecked()) + { + unsigned int mode = 0; + if (checkBox1->isChecked()) + mode |= S_CL; + if (checkBox2->isChecked()) + mode |= S_SL; + if (checkBox3->isChecked()) + mode |= S_NB; + if (checkBox4->isChecked()) + mode |= S_SS; + + gen_rand_pass(buffer, length, length, mode); } - if(num==0){ - if(Radio_2->isChecked()) - QMessageBox::information(this,tr("Notice"),tr("You need to enter at least one character"),tr("OK")); - else - QMessageBox::information(this,tr("Notice"),QString::fromUtf8("You need to select at least one character group."),"OK"); - return; - } - int length=Spin_Num->value(); - char* buffer=new char[length+1]; - buffer[length]=0; - - if(Check_CollectEntropy->isChecked()){ - if((Check_CollectOncePerSession->isChecked() && !EntropyCollected) || !Check_CollectOncePerSession->isChecked()){ - CollectEntropyDlg dlg(this); - dlg.exec(); - EntropyCollected=true; - } - } - - unsigned char tmp; - for(int i=0;isetText(buffer); - delete [] buffer; - if(AcceptButton)AcceptButton->setEnabled(true); + delete[] buffer; } int CGenPwDialog::AddToAssoctable(char* table,int start,int end,int pos){ for(int i=start;i<=end;i++){ - table[pos]=i; - pos++; + table[pos]=i; + pos++; } return (end-start)+1; } @@ -226,24 +241,36 @@ bool CGenPwDialog::trim(unsigned char &x, int r){ void CGenPwDialog::estimateQuality(){ int num=0; - if(Radio_1->isChecked()){ - if(checkBox1->isChecked()) + if (tabCategory->currentIndex()==0){ + if(Radio_1->isChecked()){ + if(checkBox1->isChecked()) + num+=26; + if(checkBox2->isChecked()) + num+=26; + if(checkBox3->isChecked()) + num+=10; + if(checkBox4->isChecked()) + num+=32; + if(checkBox5->isChecked()) + num++; + if(checkBox6->isChecked() && !checkBox4->isChecked()) + num++; + if(checkBox7->isChecked() && !checkBox4->isChecked()) + num++; + } + else + num=Edit_chars->text().length(); + } + else{ + if (checkBoxPU->isChecked()) num+=26; - if(checkBox2->isChecked()) + if (checkBoxPL->isChecked()) num+=26; - if(checkBox3->isChecked()) + if (checkBoxPN->isChecked()) num+=10; - if(checkBox4->isChecked()) + if (checkBoxPS->isChecked()) num+=32; - if(checkBox5->isChecked()) - num++; - if(checkBox6->isChecked() && !checkBox4->isChecked()) - num++; - if(checkBox7->isChecked() && !checkBox4->isChecked()) - num++; } - else - num=Edit_chars->text().length(); float bits=0; if(num) @@ -261,8 +288,13 @@ void CGenPwDialog::OnCharsChanged(const QString& str){ int count=0; for(int j=0;jsetDisabled(true); } + +void CGenPwDialog::SwapEchoMode(){ + if(Edit_dest->echoMode()==QLineEdit::Normal){ + Edit_dest->setEchoMode(QLineEdit::Password); + ButtonChangeEchoMode->setIcon(getIcon("pwd_hide")); + } + else{ + Edit_dest->setEchoMode(QLineEdit::Normal); + ButtonChangeEchoMode->setIcon(getIcon("pwd_show")); + } +} + +void CGenPwDialog::generatePasswordInternal(char* buffer, int length){ + /*------------------------------------------------------- + ASCII + ------------------------------------------------------- + "A...Z" 65...90 + "a...z" 97...122 + "0...9" 48...57 + Special Characters 33...47; 58...64; 91...96; 123...126 + "-" 45 + "_" 95 + ------------------------------------------------------- + */ + + int num=0; + char assoctable[255]; + + if(Radio_1->isChecked()){ + if(checkBox1->isChecked()) + num+=AddToAssoctable(assoctable,65,90,num); + if(checkBox2->isChecked()) + num+=AddToAssoctable(assoctable,97,122,num); + if(checkBox3->isChecked()) + num+=AddToAssoctable(assoctable,48,57,num); + if(checkBox4->isChecked()){ + num+=AddToAssoctable(assoctable,33,47,num); + num+=AddToAssoctable(assoctable,58,64,num); + num+=AddToAssoctable(assoctable,91,96,num); + num+=AddToAssoctable(assoctable,123,126,num); + } + if(checkBox5->isChecked()) + num+=AddToAssoctable(assoctable,32,32,num); + if(checkBox6->isChecked() && !checkBox4->isChecked()) + num+=AddToAssoctable(assoctable,45,45,num); + if(checkBox7->isChecked() && !checkBox4->isChecked()) + num+=AddToAssoctable(assoctable,95,95,num); + } + else{ + QString str=Edit_chars->text(); + for(int i=0;iisChecked()){ + if((Check_CollectOncePerSession->isChecked() && !EntropyCollected) || !Check_CollectOncePerSession->isChecked()){ + CollectEntropyDlg dlg(this); + dlg.exec(); + EntropyCollected=true; + } + } + + unsigned char tmp; + for(int i=0;icurrentIndex()==0){ + if (Radio_1->isChecked()){ + enable = checkBox1->isChecked() || checkBox2->isChecked() || checkBox3->isChecked() || + checkBox4->isChecked() || checkBox5->isChecked() || checkBox6->isChecked() || + checkBox7->isChecked(); + } + else{ + enable = !Edit_chars->text().isEmpty(); + } + } + else{ + enable = checkBoxPU->isChecked() || checkBoxPL->isChecked() || + checkBoxPN->isChecked() || checkBoxPS->isChecked(); + } + + ButtonGenerate->setEnabled(enable); +} + +void CGenPwDialog::setAcceptEnabled(const QString& str){ + AcceptButton->setEnabled(!str.isEmpty()); +} diff --git a/src/dialogs/PasswordGenDlg.h b/src/dialogs/PasswordGenDlg.h index 2b84c02..3e8eeec 100644 --- a/src/dialogs/PasswordGenDlg.h +++ b/src/dialogs/PasswordGenDlg.h @@ -28,27 +28,30 @@ class CGenPwDialog : public QDialog, public Ui_GenPwDlg { Q_OBJECT public: - CGenPwDialog(QWidget* parent, bool StandAloneMode, Qt::WFlags fl = 0 ); + CGenPwDialog(QWidget* parent, bool StandAloneMode, Qt::WFlags fl = 0); ~CGenPwDialog(); - + private: int AddToAssoctable(char* table,int start,int end,int pos); bool trim(unsigned char &value,int range); - virtual void paintEvent(QPaintEvent* event); - QPixmap BannerPixmap; + void paintEvent(QPaintEvent* event); + void generatePasswordInternal(char* buffer, int length); + QPixmap BannerPixmap; static bool EntropyCollected; QPushButton* AcceptButton; private slots: - virtual void OnGeneratePw(); - virtual void OnRadio2StateChanged(bool); - virtual void OnRadio1StateChanged(bool); - virtual void OnCancel(); - virtual void OnAccept(); + void OnGeneratePw(); + void OnRadio2StateChanged(bool); + void OnRadio1StateChanged(bool); + void OnCancel(); + void OnAccept(); void estimateQuality(); void OnCollectEntropyChanged(int); void OnCharsChanged(const QString& str); - + void SwapEchoMode(); + void setGenerateEnabled(); + void setAcceptEnabled(const QString& str); }; #endif diff --git a/src/forms/PasswordGenDlg.ui b/src/forms/PasswordGenDlg.ui index 0cf32dd..8208afa 100644 --- a/src/forms/PasswordGenDlg.ui +++ b/src/forms/PasswordGenDlg.ui @@ -6,7 +6,7 @@ 0 0 462 - 466 + 491 @@ -24,7 +24,7 @@ QSizePolicy::Fixed - + 442 50 @@ -32,6 +32,306 @@ + + + + 0 + + + + + 0 + 0 + 440 + 219 + + + + Random + + + + + + Use follo&wing character groups: + + + Alt+W + + + + + + + 6 + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + 6 + + + + + &Lower Letters + + + Alt+L + + + true + + + + + + + U&nderline + + + Alt+N + + + + + + + &Numbers + + + Alt+N + + + true + + + + + + + White &Spaces + + + Alt+S + + + + + + + &Upper Letters + + + Alt+U + + + true + + + + + + + Minus + + + + + + + &Special Characters + + + true + + + + + + + + + Qt::Horizontal + + + + 101 + 108 + + + + + + + + + + Use &only following characters: + + + Alt+O + + + + + + + 6 + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + 255 + + + + + + + + + + + 0 + 0 + 440 + 219 + + + + Pronounceable + + + + + + Qt::Vertical + + + + 20 + 60 + + + + + + + + + + 15 + + + + + Upper Letters + + + + + + + Numbers + + + + + + + Lower Letters + + + + + + + Special Characters + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 60 + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 15 + + + + @@ -41,194 +341,6 @@ 6 - - - - Use follo&wing character groups: - - - Alt+W - - - - - - - 6 - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 30 - 20 - - - - - - - - 6 - - - 6 - - - - - &Lower Letters - - - Alt+L - - - true - - - - - - - U&nderline - - - Alt+N - - - - - - - &Numbers - - - Alt+N - - - true - - - - - - - White &Spaces - - - Alt+S - - - - - - - &Upper Letters - - - Alt+U - - - true - - - - - - - Minus - - - - - - - &Special Characters - - - true - - - - - - - - - Qt::Horizontal - - - - 101 - 108 - - - - - - - - - - Use &only following characters: - - - Alt+O - - - - - - - 6 - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 30 - 20 - - - - - - - - 255 - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 25 - - - - @@ -262,7 +374,7 @@ QSizePolicy::Fixed - + 10 1 @@ -318,7 +430,7 @@ QSizePolicy::Fixed - + 10 20 @@ -338,7 +450,7 @@ Qt::Horizontal - + 40 20 @@ -366,6 +478,13 @@ + + + + + + + @@ -402,7 +521,7 @@ - DialogButtons + tabCategory Radio_1 checkBox1 checkBox2 @@ -413,11 +532,17 @@ checkBox7 Radio_2 Edit_chars + checkBoxPU + checkBoxPL + checkBoxPN + checkBoxPS Spin_Num Check_CollectEntropy Check_CollectOncePerSession Edit_dest + ButtonChangeEchoMode ButtonGenerate + DialogButtons diff --git a/src/import/Import_PwManager.cpp b/src/import/Import_PwManager.cpp index 99801e5..e84d5ba 100644 --- a/src/import/Import_PwManager.cpp +++ b/src/import/Import_PwManager.cpp @@ -21,6 +21,7 @@ #include "Import_PwManager.h" +#include bool Import_PwManager::importDatabase(QWidget* GuiParent, IDatabase* db){ database=db; @@ -80,32 +81,27 @@ bool Import_PwManager::importDatabase(QWidget* GuiParent, IDatabase* db){ byte* xml=new byte[len-offset+1]; xml[len-offset]=0; memcpy(Key,password.toAscii(),pwlen); - char* key_hash=new char[20]; - CSHA1 sha; - sha.Update(Key,pwlen); - sha.Final(); - sha.GetHash((unsigned char*)key_hash); - if(memcmp(key_hash,KeyHash,20)){ - delete[] Key; delete [] key_hash; delete [] buffer; + QCryptographicHash sha(QCryptographicHash::Sha1); + sha.addData((const char*)Key,pwlen); + QByteArray key_hash = sha.result(); + if(memcmp(key_hash.constData(),KeyHash,20)){ + delete[] Key; + delete [] buffer; QMessageBox::critical(GuiParent,tr("Import Failed"),tr("Wrong password.")); return false; } - delete [] key_hash; blowfish.bf_setkey(Key,password.length()); blowfish.bf_decrypt(xml,(byte*)buffer+offset,len-offset); delete [] Key; delete [] buffer; - char* content_hash=new char[20]; - sha.Reset(); - sha.Update(xml,strlen((char*)xml)-1); - sha.Final(); - sha.GetHash((unsigned char*)content_hash); - if(memcmp(content_hash,DataHash,20)){ - delete [] content_hash; delete [] xml; + sha.reset(); + sha.addData((const char*)xml,strlen((char*)xml)-1); + QByteArray content_hash = sha.result(); + if(memcmp(content_hash.constData(),DataHash,20)){ + delete [] xml; QMessageBox::critical(GuiParent,tr("Import Failed"),tr("File is damaged (hash test failed).")); return false; } - delete[] content_hash; if(!parseXmlContent((char*)xml)){ delete [] xml; diff --git a/src/keepassx.h b/src/keepassx.h index 0300cf9..832b307 100644 --- a/src/keepassx.h +++ b/src/keepassx.h @@ -26,7 +26,7 @@ #define APP_CODE_NAME "keepassx" #define APP_SHORT_FUNC "Password Manager" #define APP_LONG_FUNC "Cross Platform Password Manager" -#define APP_VERSION "0.3.2" +#define APP_VERSION "0.4.0b" #define BUILTIN_ICONS 69 @@ -43,12 +43,10 @@ #include #include -#include #include #include #include #include -#include #include #include #include @@ -70,15 +68,11 @@ #include #include #include -#include #include #include -#include #include "crypto/aescpp.h" -#include "crypto/arcfour.h" #include "crypto/blowfish.h" -#include "crypto/sha1.h" #include "crypto/sha256.h" #include "crypto/twoclass.h" #include "crypto/yarrow.h" diff --git a/src/lib/GroupView.cpp b/src/lib/GroupView.cpp index 62e69fd..d8ff099 100644 --- a/src/lib/GroupView.cpp +++ b/src/lib/GroupView.cpp @@ -21,6 +21,9 @@ #include "EntryView.h" #include "GroupView.h" #include "dialogs/EditGroupDlg.h" + +#include + #define INSERT_AREA_WIDTH 4 KeepassGroupView::KeepassGroupView(QWidget* parent):QTreeWidget(parent){ diff --git a/src/lib/IniReader.cpp b/src/lib/IniReader.cpp deleted file mode 100644 index e6ccf00..0000000 --- a/src/lib/IniReader.cpp +++ /dev/null @@ -1,488 +0,0 @@ -// IniFile.cpp: Implementation of the CIniFile class. -// Written by: Adam Clauss -// Email: cabadam@houston.rr.com -// You may use this class/code as you wish in your programs. Feel free to distribute it, and -// email suggested changes to me. -// -// Rewritten by: Shane Hill -// Date: 21/08/2001 -// Email: Shane.Hill@dsto.defence.gov.au -// Reason: Remove dependancy on MFC. Code should compile on any -// platform. -////////////////////////////////////////////////////////////////////// - - -// C++ Includes -#include -#include -#include - -// C Includes -#include -#include -#include - -// Local Includes -#include "IniReader.h" -#include - -#if defined(Q_WS_WIN) -#define iniEOL endl -#else -#define iniEOL '\r' << endl -#endif - -CIniFile::CIniFile( string const iniPath) -{ - Path( iniPath); - caseInsensitive = true; -} - -bool CIniFile::ReadFile() -{ - // Normally you would use ifstream, but the SGI CC compiler has - // a few bugs with ifstream. So ... fstream used. - fstream f; - string line; - string keyname, valuename, value; - string::size_type pLeft, pRight; - - f.open( path.c_str(), ios::in); - if ( f.fail()) - return false; - - while( getline( f, line)) { - // To be compatible with Win32, check for existence of '\r'. - // Win32 files have the '\r' and Unix files don't at the end of a line. - // Note that the '\r' will be written to INI files from - // Unix so that the created INI file can be read under Win32 - // without change. - if( !line.length())continue; - if ( line[line.length() - 1] == '\r') - line = line.substr( 0, line.length() - 1); - - if ( line.length()) { - // Check that the user hasn't openned a binary file by checking the first - // character of each line! - if ( !isprint( line[0])) { - printf( "Failing on char %d\n", line[0]); - f.close(); - return false; - } - if (( pLeft = line.find_first_of(";#[=")) != string::npos) { - switch ( line[pLeft]) { - case '[': - if ((pRight = line.find_last_of("]")) != string::npos && - pRight > pLeft) { - keyname = line.substr( pLeft + 1, pRight - pLeft - 1); - AddKeyName( keyname); - } - break; - - case '=': - valuename = line.substr( 0, pLeft); - value = line.substr( pLeft + 1); - SetValue( keyname, valuename, value); - break; - - case ';': - case '#': - if ( !names.size()) - HeaderComment( line.substr( pLeft + 1)); - else - KeyComment( keyname, line.substr( pLeft + 1)); - break; - } - } - } - } - - f.close(); - if ( names.size()) - return true; - return false; -} - -bool CIniFile::WriteFile() -{ - unsigned commentID, keyID, valueID; - // Normally you would use ofstream, but the SGI CC compiler has - // a few bugs with ofstream. So ... fstream used. - fstream f; - - f.open( path.c_str(), ios::out); - if ( f.fail()) - return false; - - // Write header comments. - for ( commentID = 0; commentID < comments.size(); ++commentID) - f << ';' << comments[commentID] << iniEOL; - if ( comments.size()) - f << iniEOL; - - // Write keys and values. - for ( keyID = 0; keyID < keys.size(); ++keyID) { - f << '[' << names[keyID] << ']' << iniEOL; - // Comments. - for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) - f << ';' << keys[keyID].comments[commentID] << iniEOL; - // Values. - for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; - f << iniEOL; - } - f.close(); - - return true; -} - -long CIniFile::FindKey( string const keyname) const -{ - for ( unsigned keyID = 0; keyID < names.size(); ++keyID) - if ( CheckCase( names[keyID]) == CheckCase( keyname)) - return long(keyID); - return noID; -} - -long CIniFile::FindValue( unsigned const keyID, string const valuename) const -{ - if ( !keys.size() || keyID >= keys.size()) - return noID; - - for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) - return long(valueID); - return noID; -} - -unsigned CIniFile::AddKeyName( string const keyname) -{ - names.resize( names.size() + 1, keyname); - keys.resize( keys.size() + 1); - return names.size() - 1; -} - -string CIniFile::KeyName( unsigned const keyID) const -{ - if ( keyID < names.size()) - return names[keyID]; - else - return ""; -} - -unsigned CIniFile::NumValues( unsigned const keyID) -{ - if ( keyID < keys.size()) - return keys[keyID].names.size(); - return 0; -} - -unsigned CIniFile::NumValues( string const keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].names.size(); -} - -string CIniFile::ValueName( unsigned const keyID, unsigned const valueID) const -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].names[valueID]; - return ""; -} - -string CIniFile::ValueName( string const keyname, unsigned const valueID) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return ValueName( keyID, valueID); -} - -bool CIniFile::SetValue( unsigned const keyID, unsigned const valueID, string const value) -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - keys[keyID].values[valueID] = value; - - return false; -} - -bool CIniFile::SetValue( string const keyname, string const valuename, string const value, bool const create) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) { - if ( create) - keyID = long( AddKeyName( keyname)); - else - return false; - } - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) { - if ( !create) - return false; - keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); - keys[keyID].values.resize( keys[keyID].values.size() + 1, value); - } else - keys[keyID].values[valueID] = value; - - return true; -} - -bool CIniFile::SetValueI( string const keyname, string const valuename, int const value, bool const create) -{ - char svalue[MAX_VALUEDATA]; - - sprintf( svalue, "%d", value); - return SetValue( keyname, valuename, svalue); -} - -bool CIniFile::SetValueF( string const keyname, string const valuename, double const value, bool const create) -{ - char svalue[MAX_VALUEDATA]; - - sprintf( svalue, "%f", value); - return SetValue( keyname, valuename, svalue); -} - -bool CIniFile::SetValueV( string const keyname, string const valuename, char *format, ...) -{ - va_list args; - char value[MAX_VALUEDATA]; - - va_start( args, format); - vsprintf( value, format, args); - va_end( args); - return SetValue( keyname, valuename, value); -} - -string CIniFile::GetValue( unsigned const keyID, unsigned const valueID, string const defValue) const -{ - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].values[valueID]; - return defValue; -} - -string CIniFile::GetValue( string const keyname, string const valuename, string const defValue) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return defValue; - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return defValue; - - return keys[keyID].values[valueID]; -} - -int CIniFile::GetValueI(string const keyname, string const valuename, int const defValue) const -{ - char svalue[MAX_VALUEDATA]; - - sprintf( svalue, "%d", defValue); - return atoi( GetValue( keyname, valuename, svalue).c_str()); -} - -double CIniFile::GetValueF(string const keyname, string const valuename, double const defValue) const -{ - char svalue[MAX_VALUEDATA]; - - sprintf( svalue, "%f", defValue); - return atof( GetValue( keyname, valuename, svalue).c_str()); -} - -// 16 variables may be a bit of over kill, but hey, it's only code. -unsigned CIniFile::GetValueV( string const keyname, string const valuename, char *format, - void *v1, void *v2, void *v3, void *v4, - void *v5, void *v6, void *v7, void *v8, - void *v9, void *v10, void *v11, void *v12, - void *v13, void *v14, void *v15, void *v16) -{ - string value; - // va_list args; - unsigned nVals; - - - value = GetValue( keyname, valuename); - if ( !value.length()) - return false; - // Why is there not vsscanf() function. Linux man pages say that there is - // but no compiler I've seen has it defined. Bummer! - // - // va_start( args, format); - // nVals = vsscanf( value.c_str(), format, args); - // va_end( args); - - nVals = sscanf( value.c_str(), format, - v1, v2, v3, v4, v5, v6, v7, v8, - v9, v10, v11, v12, v13, v14, v15, v16); - - return nVals; -} - -bool CIniFile::DeleteValue( string const keyname, string const valuename) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return false; - - // This looks strange, but is neccessary. - vector::iterator npos = keys[keyID].names.begin() + valueID; - vector::iterator vpos = keys[keyID].values.begin() + valueID; - keys[keyID].names.erase( npos, npos + 1); - keys[keyID].values.erase( vpos, vpos + 1); - - return true; -} - -bool CIniFile::DeleteKey( string const keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - - // Now hopefully this destroys the vector lists within keys. - // Looking at source, this should be the case using the destructor. - // If not, I may have to do it explicitly. Memory leak check should tell. - // memleak_test.cpp shows that the following not required. - //keys[keyID].names.clear(); - //keys[keyID].values.clear(); - - vector::iterator npos = names.begin() + keyID; - vector::iterator kpos = keys.begin() + keyID; - names.erase( npos, npos + 1); - keys.erase( kpos, kpos + 1); - - return true; -} - -void CIniFile::Erase() -{ - // This loop not needed. The vector<> destructor seems to do - // all the work itself. memleak_test.cpp shows this. - //for ( unsigned i = 0; i < keys.size(); ++i) { - // keys[i].names.clear(); - // keys[i].values.clear(); - //} - names.clear(); - keys.clear(); - comments.clear(); -} - -void CIniFile::HeaderComment( string const comment) -{ - comments.resize( comments.size() + 1, comment); -} - -string CIniFile::HeaderComment( unsigned const commentID) const -{ - if ( commentID < comments.size()) - return comments[commentID]; - return ""; -} - -bool CIniFile::DeleteHeaderComment( unsigned commentID) -{ - if ( commentID < comments.size()) { - vector::iterator cpos = comments.begin() + commentID; - comments.erase( cpos, cpos + 1); - return true; - } - return false; -} - -unsigned CIniFile::NumKeyComments( unsigned const keyID) const -{ - if ( keyID < keys.size()) - return keys[keyID].comments.size(); - return 0; -} - -unsigned CIniFile::NumKeyComments( string const keyname) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].comments.size(); -} - -bool CIniFile::KeyComment( unsigned const keyID, string const comment) -{ - if ( keyID < keys.size()) { - keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); - return true; - } - return false; -} - -bool CIniFile::KeyComment( string const keyname, string const comment) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return KeyComment( unsigned(keyID), comment); -} - -string CIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const -{ - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) - return keys[keyID].comments[commentID]; - return ""; -} - -string CIniFile::KeyComment( string const keyname, unsigned const commentID) const -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return KeyComment( unsigned(keyID), commentID); -} - -bool CIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID) -{ - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { - vector::iterator cpos = keys[keyID].comments.begin() + commentID; - keys[keyID].comments.erase( cpos, cpos + 1); - return true; - } - return false; -} - -bool CIniFile::DeleteKeyComment( string const keyname, unsigned const commentID) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComment( unsigned(keyID), commentID); -} - -bool CIniFile::DeleteKeyComments( unsigned const keyID) -{ - if ( keyID < keys.size()) { - keys[keyID].comments.clear(); - return true; - } - return false; -} - -bool CIniFile::DeleteKeyComments( string const keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComments( unsigned(keyID)); -} - -string CIniFile::CheckCase( string s) const -{ - if ( caseInsensitive) - for ( string::size_type i = 0; i < s.length(); ++i) - s[i] = tolower(s[i]); - return s; -} diff --git a/src/lib/IniReader.h b/src/lib/IniReader.h deleted file mode 100644 index e570e51..0000000 --- a/src/lib/IniReader.h +++ /dev/null @@ -1,182 +0,0 @@ -// IniFile.cpp: Implementation of the CIniFile class. -// Written by: Adam Clauss -// Email: cabadam@tamu.edu -// You may use this class/code as you wish in your programs. Feel free to distribute it, and -// email suggested changes to me. -// -// Rewritten by: Shane Hill -// Date: 21/08/2001 -// Email: Shane.Hill@dsto.defence.gov.au -// Reason: Remove dependancy on MFC. Code should compile on any -// platform. Tested on Windows/Linux/Irix -////////////////////////////////////////////////////////////////////// - -#ifndef CIniFile_H -#define CIniFile_H - -// C++ Includes -#include -#include - -// C Includes -#include - -using namespace std; - -#define MAX_KEYNAME 128 -#define MAX_VALUENAME 128 -#define MAX_VALUEDATA 2048 - -class CIniFile -{ -private: - bool caseInsensitive; - string path; - struct key { - vector names; - vector values; - vector comments; - }; - vector keys; - vector names; - vector comments; - string CheckCase( string s) const; - -public: - enum errors{ noID = -1}; - CIniFile( string const iniPath = ""); - virtual ~CIniFile() {} - - // Sets whether or not keynames and valuenames should be case sensitive. - // The default is case insensitive. - void CaseSensitive() {caseInsensitive = false;} - void CaseInsensitive() {caseInsensitive = true;} - - // Sets path of ini file to read and write from. - void Path(string const newPath) {path = newPath;} - string Path() const {return path;} - void SetPath(string const newPath) {Path( newPath);} - - // Reads ini file specified using path. - // Returns true if successful, false otherwise. - bool ReadFile(); - - // Writes data stored in class to ini file. - bool WriteFile(); - - // Deletes all stored ini data. - void Erase(); - void Clear() {Erase();} - void Reset() {Erase();} - - // Returns index of specified key, or noID if not found. - long FindKey( string const keyname) const; - - // Returns index of specified value, in the specified key, or noID if not found. - long FindValue( unsigned const keyID, string const valuename) const; - - // Returns number of keys currently in the ini. - unsigned NumKeys() const {return names.size();} - unsigned GetNumKeys() const {return NumKeys();} - - // Add a key name. - unsigned AddKeyName( string const keyname); - - // Returns key names by index. - string KeyName( unsigned const keyID) const; - string GetKeyName( unsigned const keyID) const {return KeyName(keyID);} - - // Returns number of values stored for specified key. - unsigned NumValues( unsigned const keyID); - unsigned GetNumValues( unsigned const keyID) {return NumValues( keyID);} - unsigned NumValues( string const keyname); - unsigned GetNumValues( string const keyname) {return NumValues( keyname);} - - // Returns value name by index for a given keyname or keyID. - string ValueName( unsigned const keyID, unsigned const valueID) const; - string GetValueName( unsigned const keyID, unsigned const valueID) const { - return ValueName( keyID, valueID); - } - string ValueName( string const keyname, unsigned const valueID) const; - string GetValueName( string const keyname, unsigned const valueID) const { - return ValueName( keyname, valueID); - } - - // Gets value of [keyname] valuename =. - // Overloaded to return string, int, and double. - // Returns defValue if key/value not found. - string GetValue( unsigned const keyID, unsigned const valueID, string const defValue = "") const; - string GetValue(string const keyname, string const valuename, string const defValue = "") const; - int GetValueI(string const keyname, string const valuename, int const defValue = 0) const; - bool GetValueB(string const keyname, string const valuename, bool const defValue = false) const { - return bool( GetValueI( keyname, valuename, int( defValue))); - } - double GetValueF(string const keyname, string const valuename, double const defValue = 0.0) const; - // This is a variable length formatted GetValue routine. All these voids - // are required because there is no vsscanf() like there is a vsprintf(). - // Only a maximum of 8 variable can be read. - unsigned GetValueV( string const keyname, string const valuename, char *format, - void *v1 = 0, void *v2 = 0, void *v3 = 0, void *v4 = 0, - void *v5 = 0, void *v6 = 0, void *v7 = 0, void *v8 = 0, - void *v9 = 0, void *v10 = 0, void *v11 = 0, void *v12 = 0, - void *v13 = 0, void *v14 = 0, void *v15 = 0, void *v16 = 0); - - // Sets value of [keyname] valuename =. - // Specify the optional paramter as false (0) if you do not want it to create - // the key if it doesn't exist. Returns true if data entered, false otherwise. - // Overloaded to accept string, int, and double. - bool SetValue( unsigned const keyID, unsigned const valueID, string const value); - bool SetValue( string const keyname, string const valuename, string const value, bool const create = true); - bool SetValueI( string const keyname, string const valuename, int const value, bool const create = true); - bool SetValueB( string const keyname, string const valuename, bool const value, bool const create = true) { - return SetValueI( keyname, valuename, int(value), create); - } - bool SetValueF( string const keyname, string const valuename, double const value, bool const create = true); - bool SetValueV( string const keyname, string const valuename, char *format, ...); - - // Deletes specified value. - // Returns true if value existed and deleted, false otherwise. - bool DeleteValue( string const keyname, string const valuename); - - // Deletes specified key and all values contained within. - // Returns true if key existed and deleted, false otherwise. - bool DeleteKey(string keyname); - - // Header comment functions. - // Header comments are those comments before the first key. - // - // Number of header comments. - unsigned NumHeaderComments() {return comments.size();} - // Add a header comment. - void HeaderComment( string const comment); - // Return a header comment. - string HeaderComment( unsigned const commentID) const; - // Delete a header comment. - bool DeleteHeaderComment( unsigned commentID); - // Delete all header comments. - void DeleteHeaderComments() {comments.clear();} - - // Key comment functions. - // Key comments are those comments within a key. Any comments - // defined within value names will be added to this list. Therefore, - // these comments will be moved to the top of the key definition when - // the CIniFile::WriteFile() is called. - // - // Number of key comments. - unsigned NumKeyComments( unsigned const keyID) const; - unsigned NumKeyComments( string const keyname) const; - // Add a key comment. - bool KeyComment( unsigned const keyID, string const comment); - bool KeyComment( string const keyname, string const comment); - // Return a key comment. - string KeyComment( unsigned const keyID, unsigned const commentID) const; - string KeyComment( string const keyname, unsigned const commentID) const; - // Delete a key comment. - bool DeleteKeyComment( unsigned const keyID, unsigned const commentID); - bool DeleteKeyComment( string const keyname, unsigned const commentID); - // Delete all comments for a key. - bool DeleteKeyComments( unsigned const keyID); - bool DeleteKeyComments( string const keyname); -}; - -#endif diff --git a/src/lib/SecString.cpp b/src/lib/SecString.cpp index dfa0fc8..cbf1f8d 100644 --- a/src/lib/SecString.cpp +++ b/src/lib/SecString.cpp @@ -18,11 +18,6 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifdef Q_WS_X11 -#include -#include -#endif - using namespace std; CArcFour SecString::RC4; @@ -54,7 +49,7 @@ void SecString::unlock(){ if(!crypt.length()) return; const unsigned char* buffer = new unsigned char[crypt.length()]; - SecString::RC4.decrypt( (byte*)crypt.data(), (unsigned char*)buffer, crypt.length() ); + RC4.decrypt( (byte*)crypt.data(), (unsigned char*)buffer, crypt.length() ); plain = QString::fromUtf8((const char*)buffer, crypt.size()); overwrite((unsigned char*)buffer, crypt.size()); delete [] buffer; @@ -69,7 +64,7 @@ void SecString::setString(QString& str, bool DeleteSource){ QByteArray StrData = str.toUtf8(); int len = StrData.size(); unsigned char* buffer = new unsigned char[len]; - SecString::RC4.encrypt((const unsigned char*)StrData.data(), buffer, len); + RC4.encrypt((const unsigned char*)StrData.data(), buffer, len); crypt = QByteArray((const char*)buffer, len); overwrite(buffer, len); overwrite((unsigned char*)StrData.data(), len); @@ -98,20 +93,8 @@ void SecString::overwrite(QString& str){ } void SecString::generateSessionKey(){ - CArcFour arc; - unsigned char sessionkey[32]; - -#ifdef Q_WS_X11 - -#ifdef PAGESIZE - mlock(sessionkey - sessionkey%PAGESIZE, 32); -#else - mlock(sessionkey, 32); -#endif - -#endif // Q_WS_X11 - - randomize(sessionkey,32); - RC4.setKey(sessionkey,32); - overwrite(sessionkey,32); + quint8* sessionkey = new quint8[32]; + lockPage(sessionkey, 32); + randomize(sessionkey, 32); + RC4.setKey(sessionkey, 32); } diff --git a/src/lib/SecString.h b/src/lib/SecString.h index b3ddb51..7274b79 100644 --- a/src/lib/SecString.h +++ b/src/lib/SecString.h @@ -20,6 +20,8 @@ #ifndef _SECSTRING_H_ #define _SECSTRING_H_ +#include "crypto/arcfour.h" + //! QString based class with in-memory encryption of its content. /*! This class can hold a QString object in an encrypted buffer. To get access to the string it is neccassary to unlock the SecString object. @@ -47,8 +49,8 @@ public: static void generateSessionKey(); private: - bool locked; static CArcFour RC4; + bool locked; QByteArray crypt; QString plain; diff --git a/src/lib/random.cpp b/src/lib/random.cpp index 8c5be78..0cdc646 100644 --- a/src/lib/random.cpp +++ b/src/lib/random.cpp @@ -28,39 +28,56 @@ #include #endif +#include #include +#include #include #include -void Random::getEntropy(quint8* buffer, int length){ +void initStdRand(); +bool getNativeEntropy(quint8* buffer, int length); + +void getEntropy(quint8* buffer, int length){ + if (!getNativeEntropy(buffer, length)) { + qWarning("Entropy collection failed, using fallback"); + initStdRand(); + for(int i=0;i=QSysInfo::WV_XP){ - bool success=false; - HMODULE hLib=LoadLibraryA("ADVAPI32.DLL"); - if (hLib) { - BOOLEAN (APIENTRY *pfn)(void*, ULONG) = (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036"); - if (pfn && pfn(buffer,length)) { - success=true; - } - FreeLibrary(hLib); - } - if (success) - return; - } -#endif + +extern bool getNativeEntropy(quint8* buffer, int length) { + HCRYPTPROV handle; + if (!CryptAcquireContext(&handle, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + return false; - initStdRand(); - for(int i=0;i +#ifndef quint8 +typedef unsigned char quint8; +#endif + +#ifndef quint32 +typedef unsigned int quint32; +#endif -namespace Random { - void getEntropy(quint8* buffer, int length); - void initStdRand(); -}; +#ifdef __cplusplus +extern "C" { +#endif + +void getEntropy(quint8* buffer, int length); +quint32 randint(quint32 n); + +#ifdef __cplusplus +} +#endif #endif diff --git a/src/lib/tools.cpp b/src/lib/tools.cpp index 0edad17..dbbf0e8 100644 --- a/src/lib/tools.cpp +++ b/src/lib/tools.cpp @@ -20,6 +20,12 @@ #include #include +#if defined(Q_WS_X11) || defined(Q_WS_MAC) + #include +#elif defined(Q_WS_WIN) + #include +#endif + void createBanner(QPixmap* Pixmap,const QPixmap* IconAlpha,const QString& Text,int Width){ createBanner(Pixmap,IconAlpha,Text,Width,config->bannerColor1(),config->bannerColor2(),config->bannerTextColor()); } @@ -209,4 +215,12 @@ bool createKeyFile(const QString& filename,QString* error,int length, bool Hex){ return true; } - +bool lockPage(void* addr, int len){ +#if defined(Q_WS_X11) || defined(Q_WS_MAC) + return (mlock(addr, len)==0); +#elif defined(Q_WS_WIN) + return VirtualLock(addr, len); +#else + return false; +#endif +} diff --git a/src/lib/tools.h b/src/lib/tools.h index 6d63bbc..d4838b3 100644 --- a/src/lib/tools.h +++ b/src/lib/tools.h @@ -33,5 +33,6 @@ QString decodeFileError(QFile::FileError Code); QString makePathRelative(const QString& Abs,const QString& Cur); QString getImageFile(const QString& name); bool createKeyFile(const QString& filename,QString* err, int length=32, bool Hex=true); +bool lockPage(void* addr, int len); #endif //TOOLS_H diff --git a/src/main_macx.cpp b/src/main_macx.cpp index 1fc18a2..3a970ce 100644 --- a/src/main_macx.cpp +++ b/src/main_macx.cpp @@ -19,6 +19,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include #include #include "main.h" diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9aeb38b..671be77 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -415,7 +415,7 @@ bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){ QString err; StatusBarGeneral->setText(tr("Loading Database...")); db->setKey(dlg.password(),dlg.keyFile()); - if(db->load(filename)==true){ + if(db->load(filename)){ if (IsLocked) resetLock(); saveLastFilename(filename); diff --git a/src/src.pro b/src/src.pro index a1f2092..41f7ad9 100644 --- a/src/src.pro +++ b/src/src.pro @@ -11,10 +11,10 @@ OBJECTS_DIR = ../build RCC_DIR = ../build/rcc isEqual(DEBUG,1){ - CONFIG += debug + CONFIG += debug } else { - CONFIG += release + CONFIG += release } # lipo and freebsd cannot handle precompiled headers (yet) @@ -29,116 +29,116 @@ win32 : QMAKE_WIN32 = 1 # Platform Specific: Unix (except MacOS X) #------------------------------------------------------------------------------- unix : !macx : !isEqual(QMAKE_WIN32,1){ - isEmpty(PREFIX): PREFIX = /usr - !isEqual(AUTOTYPE,0){ - DEFINES += AUTOTYPE - !isEqual(GLOBAL_AUTOTYPE,0){ - DEFINES += GLOBAL_AUTOTYPE - } - } - TARGET = ../bin/keepassx - target.path = $${PREFIX}/bin - data.files += ../share/keepassx - data.path = $${PREFIX}/share - pixmaps.files = ../share/pixmaps/* - pixmaps.path = $${PREFIX}/share/pixmaps - desktop.files = ../share/applications/* - desktop.path = $${PREFIX}/share/applications - INSTALLS += pixmaps desktop - contains(DEFINES,AUTOTYPE){ - LIBS += -lXtst - SOURCES += lib/HelperX11.cpp lib/AutoType_X11.cpp - HEADERS += lib/HelperX11.h - } - contains(DEFINES,GLOBAL_AUTOTYPE){ - SOURCES += Application_X11.cpp - HEADERS += Application_X11.h - } - SOURCES += main_unix.cpp - } + isEmpty(PREFIX): PREFIX = /usr + !isEqual(AUTOTYPE,0){ + DEFINES += AUTOTYPE + !isEqual(GLOBAL_AUTOTYPE,0){ + DEFINES += GLOBAL_AUTOTYPE + } + } + TARGET = ../bin/keepassx + target.path = $${PREFIX}/bin + data.files += ../share/keepassx + data.path = $${PREFIX}/share + pixmaps.files = ../share/pixmaps/* + pixmaps.path = $${PREFIX}/share/pixmaps + desktop.files = ../share/applications/* + desktop.path = $${PREFIX}/share/applications + INSTALLS += pixmaps desktop + contains(DEFINES,AUTOTYPE){ + LIBS += -lXtst + SOURCES += lib/HelperX11.cpp lib/AutoType_X11.cpp + HEADERS += lib/HelperX11.h + } + contains(DEFINES,GLOBAL_AUTOTYPE){ + SOURCES += Application_X11.cpp + HEADERS += Application_X11.h + } + SOURCES += main_unix.cpp +} #------------------------------------------------------------------------------- # Platform Specific: MacOS X #------------------------------------------------------------------------------- macx { - isEmpty(PREFIX): PREFIX = /Applications - TARGET = ../bin/KeePassX - target.path = $${PREFIX} - data.files += ../share/keepassx - data.path = Contents/Resources - LIBS += -framework CoreFoundation - isEqual(LINK,DYNAMIC){ - isEmpty(QT_FRAMEWORK_DIR): QT_FRAMEWORK_DIR = /Library/Frameworks - private_frameworks.files += $${QT_FRAMEWORK_DIR}/QtCore.framework - private_frameworks.files += $${QT_FRAMEWORK_DIR}/QtGui.framework - private_frameworks.files += $${QT_FRAMEWORK_DIR}/QtXml.framework - private_frameworks.path = Contents/Frameworks - QMAKE_BUNDLE_DATA += private_frameworks - } - isEqual(LINK,STATIC){ - LIBS += -framework Carbon -framework AppKit -lz - } - QMAKE_BUNDLE_DATA += data - ICON = ../share/macx_bundle/icon.icns - CONFIG += app_bundle - isEqual(ARCH,UNIVERSAL){ - CONFIG += x86 ppc - } - isEqual(ARCH,INTEL): CONFIG += x86 - isEqual(ARCH,PPC): CONFIG += ppc - SOURCES += main_macx.cpp + isEmpty(PREFIX): PREFIX = /Applications + TARGET = ../bin/KeePassX + target.path = $${PREFIX} + data.files += ../share/keepassx + data.path = Contents/Resources + LIBS += -framework CoreFoundation + isEqual(LINK,DYNAMIC){ + isEmpty(QT_FRAMEWORK_DIR): QT_FRAMEWORK_DIR = /Library/Frameworks + private_frameworks.files += $${QT_FRAMEWORK_DIR}/QtCore.framework + private_frameworks.files += $${QT_FRAMEWORK_DIR}/QtGui.framework + private_frameworks.files += $${QT_FRAMEWORK_DIR}/QtXml.framework + private_frameworks.path = Contents/Frameworks + QMAKE_BUNDLE_DATA += private_frameworks + } + isEqual(LINK,STATIC){ + LIBS += -framework Carbon -framework AppKit -lz + } + QMAKE_BUNDLE_DATA += data + ICON = ../share/macx_bundle/icon.icns + CONFIG += app_bundle + isEqual(ARCH,UNIVERSAL){ + CONFIG += x86 ppc + } + isEqual(ARCH,INTEL): CONFIG += x86 + isEqual(ARCH,PPC): CONFIG += ppc + SOURCES += main_macx.cpp } #------------------------------------------------------------------------------- # Platform Specific: Windows #------------------------------------------------------------------------------- isEqual(QMAKE_WIN32,1){ - CONFIG += windows - isEmpty(PREFIX): PREFIX = "C:/Program files/KeePassX" - TARGET = ../bin/KeePassX - target.path = $${PREFIX} - data.files += ../share/keepassx/* - data.path = $${PREFIX}/share - !isEqual(INSTALL_QTLIB,0){ - qt_libs.files = $${QMAKE_LIBDIR_QT}/QtCore4.dll $${QMAKE_LIBDIR_QT}/QtGui4.dll $${QMAKE_LIBDIR_QT}/QtXml4.dll - qt_libs.path = $${PREFIX} - INSTALLS += qt_libs - } - RC_FILE = ../share/win_ico/keepassx.rc - QMAKE_LINK_OBJECT_SCRIPT = $${OBJECTS_DIR}/$${QMAKE_LINK_OBJECT_SCRIPT} - SOURCES += main_win32.cpp + CONFIG += windows + isEmpty(PREFIX): PREFIX = "C:/Program files/KeePassX" + TARGET = ../bin/KeePassX + target.path = $${PREFIX} + data.files += ../share/keepassx/* + data.path = $${PREFIX}/share + !isEqual(INSTALL_QTLIB,0){ + qt_libs.files = $${QMAKE_LIBDIR_QT}/QtCore4.dll $${QMAKE_LIBDIR_QT}/QtGui4.dll $${QMAKE_LIBDIR_QT}/QtXml4.dll + qt_libs.path = $${PREFIX} + INSTALLS += qt_libs + } + RC_FILE = ../share/win_ico/keepassx.rc + QMAKE_LINK_OBJECT_SCRIPT = $${OBJECTS_DIR}/$${QMAKE_LINK_OBJECT_SCRIPT} + SOURCES += main_win32.cpp } INSTALLS += target data contains(DEFINES,GLOBAL_AUTOTYPE){ - FORMS += forms/AutoTypeDlg.ui - HEADERS += dialogs/AutoTypeDlg.h - SOURCES += dialogs/AutoTypeDlg.cpp + FORMS += forms/AutoTypeDlg.ui + HEADERS += dialogs/AutoTypeDlg.h lib/AutoTypeTreeWidget.h + SOURCES += dialogs/AutoTypeDlg.cpp lib/AutoTypeTreeWidget.cpp } -FORMS += forms/EditGroupDlg.ui \ - forms/SearchDlg.ui \ - forms/AboutDlg.ui \ - forms/SettingsDlg.ui \ - forms/MainWindow.ui \ - forms/SimplePasswordDlg.ui \ +FORMS += forms/AboutDlg.ui \ + forms/AddBookmarkDlg.ui \ + forms/CalendarDlg.ui \ + forms/CollectEntropyDlg.ui \ + forms/CustomizeDetailViewDlg.ui \ forms/DatabaseSettingsDlg.ui \ - forms/PasswordDlg.ui \ forms/EditEntryDlg.ui \ + forms/EditGroupDlg.ui \ + forms/ExpiredEntriesDlg.ui \ + forms/MainWindow.ui \ + forms/ManageBookmarksDlg.ui \ + forms/PasswordDlg.ui \ forms/PasswordGenDlg.ui \ + forms/SearchDlg.ui \ forms/SelectIconDlg.ui \ - forms/CollectEntropyDlg.ui \ - forms/CustomizeDetailViewDlg.ui \ - forms/CalendarDlg.ui \ + forms/SettingsDlg.ui \ + forms/SimplePasswordDlg.ui \ # forms/TrashCanDlg.ui \ - forms/ExpiredEntriesDlg.ui \ - forms/WorkspaceLockedWidget.ui \ - forms/AddBookmarkDlg.ui \ - forms/ManageBookmarksDlg.ui + forms/WorkspaceLockedWidget.ui TRANSLATIONS += translations/keepassx-de_DE.ts \ translations/keepassx-ru_RU.ts \ @@ -148,124 +148,130 @@ TRANSLATIONS += translations/keepassx-de_DE.ts \ translations/keepassx-ja_JP.ts \ translations/keepassx-xx_XX.ts -HEADERS += lib/UrlLabel.h \ +HEADERS += main.h \ + global.h \ mainwindow.h \ - Kdb3Database.h \ - lib/SecString.h \ - crypto/twoclass.h \ - crypto/twofish.h \ - import/Import.h \ - import/Import_KeePassX_Xml.h \ - import/Import_PwManager.h \ - export/Export_Txt.h \ - export/Export_KeePassX_Xml.h \ - export/Export.h \ - import/Import_KWalletXml.h \ - dialogs/AboutDlg.h \ - dialogs/EditGroupDlg.h \ - dialogs/SearchDlg.h \ - dialogs/SettingsDlg.h \ - dialogs/DatabaseSettingsDlg.h \ - dialogs/PasswordDlg.h \ - dialogs/SimplePasswordDlg.h \ - dialogs/EditEntryDlg.h \ - dialogs/PasswordGenDlg.h \ - dialogs/SelectIconDlg.h \ - dialogs/CollectEntropyDlg.h \ - dialogs/CustomizeDetailViewDlg.h \ - dialogs/CalendarDlg.h \ - dialogs/ExpiredEntriesDlg.h \ -# dialogs/TrashCanDlg.h \ -# lib/random.h \ + KpxConfig.h \ Database.h \ + Kdb3Database.h \ lib/AutoType.h \ + lib/bookmarks.h \ + lib/EntryView.h \ lib/FileDialogs.h \ + lib/GroupView.h \ + lib/random.h \ + lib/SecString.h \ lib/ShortcutWidget.h \ - global.h \ - main.h \ lib/tools.h \ - lib/GroupView.h \ - lib/EntryView.h \ - crypto/arcfour.h \ - crypto/aes_edefs.h \ - crypto/aes_tdefs.h \ + lib/UrlLabel.h \ + lib/WaitAnimationWidget.h \ crypto/aes.h \ + crypto/aescpp.h \ + crypto/aes_endian.h \ + crypto/aes_types.h \ crypto/aesopt.h \ crypto/aestab.h \ - crypto/aescpp.h \ + crypto/arcfour.h \ + crypto/blowfish.h \ crypto/sha256.h \ + crypto/twoclass.h \ + crypto/twofish.h \ crypto/yarrow.h \ - crypto/blowfish.h \ - crypto/sha1.h \ - lib/WaitAnimationWidget.h \ - plugins/interfaces/IFileDialog.h \ - plugins/interfaces/IKdeInit.h \ - plugins/interfaces/IGnomeInit.h \ - plugins/interfaces/IIconTheme.h \ - KpxConfig.h \ + apg/convert.h \ + apg/owntypes.h \ + apg/pronpass.h \ + apg/randpass.h \ + apg/smbl.h \ + dialogs/AboutDlg.h \ dialogs/AddBookmarkDlg.h \ - lib/bookmarks.h \ + dialogs/CalendarDlg.h \ + dialogs/CollectEntropyDlg.h \ + dialogs/CustomizeDetailViewDlg.h \ + dialogs/DatabaseSettingsDlg.h \ + dialogs/EditEntryDlg.h \ + dialogs/EditGroupDlg.h \ + dialogs/ExpiredEntriesDlg.h \ dialogs/ManageBookmarksDlg.h \ - lib/AutoTypeTreeWidget.h + dialogs/PasswordDlg.h \ + dialogs/PasswordGenDlg.h \ + dialogs/SearchDlg.h \ + dialogs/SelectIconDlg.h \ + dialogs/SettingsDlg.h \ + dialogs/SimplePasswordDlg.h \ +# dialogs/TrashCanDlg.h \ + import/Import.h \ +# import/Import_GnuKeyRing.h \ + import/Import_KeePassX_Xml.h \ + import/Import_KWalletXml.h \ + import/Import_PwManager.h \ + export/Export.h \ + export/Export_KeePassX_Xml.h \ + export/Export_Txt.h \ + plugins/interfaces/IFileDialog.h \ + plugins/interfaces/IIconTheme.h \ + plugins/interfaces/IGnomeInit.h \ + plugins/interfaces/IKdeInit.h -SOURCES += lib/UrlLabel.cpp \ - main.cpp \ +SOURCES += main.cpp \ mainwindow.cpp \ + KpxConfig.cpp \ + Database.cpp \ Kdb3Database.cpp \ + lib/bookmarks.cpp \ + lib/EntryView.cpp \ + lib/FileDialogs.cpp \ + lib/GroupView.cpp \ + lib/random.cpp \ lib/SecString.cpp \ + lib/ShortcutWidget.cpp \ + lib/tools.cpp \ + lib/UrlLabel.cpp \ + lib/WaitAnimationWidget.cpp \ + crypto/aescrypt.c \ + crypto/aeskey.c \ + crypto/aes_modes.c \ + crypto/aestab.c \ + crypto/arcfour.cpp \ + crypto/blowfish.cpp \ + crypto/sha256.cpp \ crypto/twoclass.cpp \ crypto/twofish.cpp \ - crypto/blowfish.cpp \ - crypto/sha1.cpp \ - import/Import.cpp \ - import/Import_PwManager.cpp \ - import/Import_KeePassX_Xml.cpp \ - export/Export_Txt.cpp \ - export/Export_KeePassX_Xml.cpp \ - export/Export.cpp \ - import/Import_KWalletXml.cpp \ + crypto/yarrow.cpp \ + apg/convert.c \ + apg/pronpass.c \ + apg/randpass.c \ dialogs/AboutDlg.cpp \ - dialogs/EditGroupDlg.cpp \ - dialogs/SearchDlg.cpp \ - dialogs/SettingsDlg.cpp \ + dialogs/AddBookmarkDlg.cpp \ + dialogs/CalendarDlg.cpp \ + dialogs/CollectEntropyDlg.cpp \ + dialogs/CustomizeDetailViewDlg.cpp \ dialogs/DatabaseSettingsDlg.cpp \ - dialogs/PasswordDlg.cpp \ - dialogs/SimplePasswordDlg.cpp \ dialogs/EditEntryDlg.cpp \ + dialogs/EditGroupDlg.cpp \ + dialogs/ExpiredEntriesDlg.cpp \ + dialogs/ManageBookmarksDlg.cpp \ + dialogs/PasswordDlg.cpp \ dialogs/PasswordGenDlg.cpp \ + dialogs/SearchDlg.cpp \ dialogs/SelectIconDlg.cpp \ - dialogs/CollectEntropyDlg.cpp \ - dialogs/CustomizeDetailViewDlg.cpp \ - dialogs/CalendarDlg.cpp \ - dialogs/ExpiredEntriesDlg.cpp \ + dialogs/SettingsDlg.cpp \ + dialogs/SimplePasswordDlg.cpp \ # dialogs/TrashCanDlg.cpp \ - lib/random.cpp \ - Database.cpp \ - lib/tools.cpp \ - lib/GroupView.cpp \ - lib/EntryView.cpp \ - lib/FileDialogs.cpp \ - crypto/arcfour.cpp \ - lib/ShortcutWidget.cpp \ - crypto/sha256.cpp \ - crypto/yarrow.cpp \ - lib/WaitAnimationWidget.cpp \ - KpxConfig.cpp \ - dialogs/AddBookmarkDlg.cpp \ - lib/bookmarks.cpp \ - dialogs/ManageBookmarksDlg.cpp \ - crypto/aescrypt.c \ - crypto/aeskey.c \ - crypto/aes_modes.c \ - crypto/aestab.c \ - lib/AutoTypeTreeWidget.cpp + import/Import.cpp \ +# import/Import_GnuKeyRing.cpp \ + import/Import_KeePassX_Xml.cpp \ + import/Import_KWalletXml.cpp \ + import/Import_PwManager.cpp \ + export/Export.cpp \ + export/Export_KeePassX_Xml.cpp \ + export/Export_Txt.cpp isEqual(PRECOMPILED,0) { - QMAKE_CXXFLAGS += -include keepassx.h + QMAKE_CXXFLAGS += -include keepassx.h } else { - CONFIG += precompile_header - PRECOMPILED_HEADER = keepassx.h + CONFIG += precompile_header + PRECOMPILED_HEADER = keepassx.h } RESOURCES += res/resources.qrc