From 929d5c3bca37f737dc2514564ea51c0a16124211 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sun, 8 Jan 2012 04:08:02 +0000 Subject: [PATCH] initial import of 'tito' library git-svn-id: svn://ttmath.org/publicrep/tito/src@361 e52654a7-88a9-db11-a3e9-0013d4bc506e --- Makefile | 26 + Makefile.dep | 7 + Makefile.o.dep | 1 + aes.cpp | 1308 ++++++++++++++++++++++++++++++++++++++++++++++++ aes.h | 239 +++++++++ base64.cpp | 281 +++++++++++ base64.h | 90 ++++ crypto.cpp | 163 ++++++ crypto.h | 130 +++++ misc.cpp | 181 +++++++ misc.h | 83 +++ 11 files changed, 2509 insertions(+) create mode 100755 Makefile create mode 100755 Makefile.dep create mode 100755 Makefile.o.dep create mode 100755 aes.cpp create mode 100755 aes.h create mode 100755 base64.cpp create mode 100755 base64.h create mode 100755 crypto.cpp create mode 100755 crypto.h create mode 100755 misc.cpp create mode 100755 misc.h diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..3035a72 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +include Makefile.o.dep + + +all: tito.a + +tito.a: $(o) + ar rcs tito.a $(o) + + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $< + + + +depend: + makedepend $(CXXFLAGS) -Y. -f- *.cpp > Makefile.dep + echo -n "o = " > Makefile.o.dep + ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep + + +clean: + rm -f *.o + rm -f *.a + + +include Makefile.dep diff --git a/Makefile.dep b/Makefile.dep new file mode 100755 index 0000000..3e30878 --- /dev/null +++ b/Makefile.dep @@ -0,0 +1,7 @@ +# DO NOT DELETE + +edanticaes.o: aes.h +edanticbase64.o: base64.h +edanticcrypto.o: crypto.h aes.h base64.h /home/tomek/roboczy/ezc/src/utf8.h +edanticcrypto.o: misc.h +edanticmisc.o: misc.h diff --git a/Makefile.o.dep b/Makefile.o.dep new file mode 100755 index 0000000..082a117 --- /dev/null +++ b/Makefile.o.dep @@ -0,0 +1 @@ +o = aes.o base64.o crypto.o misc.o diff --git a/aes.cpp b/aes.cpp new file mode 100755 index 0000000..a1b135d --- /dev/null +++ b/aes.cpp @@ -0,0 +1,1308 @@ +/* + * This file is a part of Tito - a cryptography library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 "aes.h" + + +namespace Tito +{ + + + +AES::uint8 AES::sbox[16][16] = { + { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 }, + { 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 }, + { 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 }, + { 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 }, + { 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 }, + { 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf }, + { 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 }, + { 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 }, + { 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 }, + { 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb }, + { 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 }, + { 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 }, + { 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a }, + { 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e }, + { 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf }, + { 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }}; + + +AES::uint8 AES::invsbox[16][16] = { + { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb }, + { 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb }, + { 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e }, + { 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 }, + { 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 }, + { 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 }, + { 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 }, + { 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b }, + { 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 }, + { 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e }, + { 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b }, + { 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 }, + { 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f }, + { 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef }, + { 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 }, + { 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }}; + + + +int AES::mixcolumntab[4][4] = { + {2, 3, 1, 1}, + {1, 2, 3, 1}, + {1, 1, 2, 3}, + {3, 1, 1, 2}}; + + +int AES::invmixcolumntab[4][4] = { + {14, 11, 13, 9}, + {9, 14, 11, 13}, + {13, 9, 14, 11}, + {11, 13, 9, 14}}; + + + +AES::uint8 AES::Rcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + + + +AES::uint8 AES::gf_mul9[16][16] = { + { 0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77 }, + { 0x90,0x99,0x82,0x8b,0xb4,0xbd,0xa6,0xaf,0xd8,0xd1,0xca,0xc3,0xfc,0xf5,0xee,0xe7 }, + { 0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c }, + { 0xab,0xa2,0xb9,0xb0,0x8f,0x86,0x9d,0x94,0xe3,0xea,0xf1,0xf8,0xc7,0xce,0xd5,0xdc }, + { 0x76,0x7f,0x64,0x6d,0x52,0x5b,0x40,0x49,0x3e,0x37,0x2c,0x25,0x1a,0x13,0x08,0x01 }, + { 0xe6,0xef,0xf4,0xfd,0xc2,0xcb,0xd0,0xd9,0xae,0xa7,0xbc,0xb5,0x8a,0x83,0x98,0x91 }, + { 0x4d,0x44,0x5f,0x56,0x69,0x60,0x7b,0x72,0x05,0x0c,0x17,0x1e,0x21,0x28,0x33,0x3a }, + { 0xdd,0xd4,0xcf,0xc6,0xf9,0xf0,0xeb,0xe2,0x95,0x9c,0x87,0x8e,0xb1,0xb8,0xa3,0xaa }, + { 0xec,0xe5,0xfe,0xf7,0xc8,0xc1,0xda,0xd3,0xa4,0xad,0xb6,0xbf,0x80,0x89,0x92,0x9b }, + { 0x7c,0x75,0x6e,0x67,0x58,0x51,0x4a,0x43,0x34,0x3d,0x26,0x2f,0x10,0x19,0x02,0x0b }, + { 0xd7,0xde,0xc5,0xcc,0xf3,0xfa,0xe1,0xe8,0x9f,0x96,0x8d,0x84,0xbb,0xb2,0xa9,0xa0 }, + { 0x47,0x4e,0x55,0x5c,0x63,0x6a,0x71,0x78,0x0f,0x06,0x1d,0x14,0x2b,0x22,0x39,0x30 }, + { 0x9a,0x93,0x88,0x81,0xbe,0xb7,0xac,0xa5,0xd2,0xdb,0xc0,0xc9,0xf6,0xff,0xe4,0xed }, + { 0x0a,0x03,0x18,0x11,0x2e,0x27,0x3c,0x35,0x42,0x4b,0x50,0x59,0x66,0x6f,0x74,0x7d }, + { 0xa1,0xa8,0xb3,0xba,0x85,0x8c,0x97,0x9e,0xe9,0xe0,0xfb,0xf2,0xcd,0xc4,0xdf,0xd6 }, + { 0x31,0x38,0x23,0x2a,0x15,0x1c,0x07,0x0e,0x79,0x70,0x6b,0x62,0x5d,0x54,0x4f,0x46 }}; + + +AES::uint8 AES::gf_mul11[16][16] = { + { 0x00,0x0b,0x16,0x1d,0x2c,0x27,0x3a,0x31,0x58,0x53,0x4e,0x45,0x74,0x7f,0x62,0x69 }, + { 0xb0,0xbb,0xa6,0xad,0x9c,0x97,0x8a,0x81,0xe8,0xe3,0xfe,0xf5,0xc4,0xcf,0xd2,0xd9 }, + { 0x7b,0x70,0x6d,0x66,0x57,0x5c,0x41,0x4a,0x23,0x28,0x35,0x3e,0x0f,0x04,0x19,0x12 }, + { 0xcb,0xc0,0xdd,0xd6,0xe7,0xec,0xf1,0xfa,0x93,0x98,0x85,0x8e,0xbf,0xb4,0xa9,0xa2 }, + { 0xf6,0xfd,0xe0,0xeb,0xda,0xd1,0xcc,0xc7,0xae,0xa5,0xb8,0xb3,0x82,0x89,0x94,0x9f }, + { 0x46,0x4d,0x50,0x5b,0x6a,0x61,0x7c,0x77,0x1e,0x15,0x08,0x03,0x32,0x39,0x24,0x2f }, + { 0x8d,0x86,0x9b,0x90,0xa1,0xaa,0xb7,0xbc,0xd5,0xde,0xc3,0xc8,0xf9,0xf2,0xef,0xe4 }, + { 0x3d,0x36,0x2b,0x20,0x11,0x1a,0x07,0x0c,0x65,0x6e,0x73,0x78,0x49,0x42,0x5f,0x54 }, + { 0xf7,0xfc,0xe1,0xea,0xdb,0xd0,0xcd,0xc6,0xaf,0xa4,0xb9,0xb2,0x83,0x88,0x95,0x9e }, + { 0x47,0x4c,0x51,0x5a,0x6b,0x60,0x7d,0x76,0x1f,0x14,0x09,0x02,0x33,0x38,0x25,0x2e }, + { 0x8c,0x87,0x9a,0x91,0xa0,0xab,0xb6,0xbd,0xd4,0xdf,0xc2,0xc9,0xf8,0xf3,0xee,0xe5 }, + { 0x3c,0x37,0x2a,0x21,0x10,0x1b,0x06,0x0d,0x64,0x6f,0x72,0x79,0x48,0x43,0x5e,0x55 }, + { 0x01,0x0a,0x17,0x1c,0x2d,0x26,0x3b,0x30,0x59,0x52,0x4f,0x44,0x75,0x7e,0x63,0x68 }, + { 0xb1,0xba,0xa7,0xac,0x9d,0x96,0x8b,0x80,0xe9,0xe2,0xff,0xf4,0xc5,0xce,0xd3,0xd8 }, + { 0x7a,0x71,0x6c,0x67,0x56,0x5d,0x40,0x4b,0x22,0x29,0x34,0x3f,0x0e,0x05,0x18,0x13 }, + { 0xca,0xc1,0xdc,0xd7,0xe6,0xed,0xf0,0xfb,0x92,0x99,0x84,0x8f,0xbe,0xb5,0xa8,0xa3 }}; + + +AES::uint8 AES::gf_mul13[16][16] = { + { 0x00,0x0d,0x1a,0x17,0x34,0x39,0x2e,0x23,0x68,0x65,0x72,0x7f,0x5c,0x51,0x46,0x4b }, + { 0xd0,0xdd,0xca,0xc7,0xe4,0xe9,0xfe,0xf3,0xb8,0xb5,0xa2,0xaf,0x8c,0x81,0x96,0x9b }, + { 0xbb,0xb6,0xa1,0xac,0x8f,0x82,0x95,0x98,0xd3,0xde,0xc9,0xc4,0xe7,0xea,0xfd,0xf0 }, + { 0x6b,0x66,0x71,0x7c,0x5f,0x52,0x45,0x48,0x03,0x0e,0x19,0x14,0x37,0x3a,0x2d,0x20 }, + { 0x6d,0x60,0x77,0x7a,0x59,0x54,0x43,0x4e,0x05,0x08,0x1f,0x12,0x31,0x3c,0x2b,0x26 }, + { 0xbd,0xb0,0xa7,0xaa,0x89,0x84,0x93,0x9e,0xd5,0xd8,0xcf,0xc2,0xe1,0xec,0xfb,0xf6 }, + { 0xd6,0xdb,0xcc,0xc1,0xe2,0xef,0xf8,0xf5,0xbe,0xb3,0xa4,0xa9,0x8a,0x87,0x90,0x9d }, + { 0x06,0x0b,0x1c,0x11,0x32,0x3f,0x28,0x25,0x6e,0x63,0x74,0x79,0x5a,0x57,0x40,0x4d }, + { 0xda,0xd7,0xc0,0xcd,0xee,0xe3,0xf4,0xf9,0xb2,0xbf,0xa8,0xa5,0x86,0x8b,0x9c,0x91 }, + { 0x0a,0x07,0x10,0x1d,0x3e,0x33,0x24,0x29,0x62,0x6f,0x78,0x75,0x56,0x5b,0x4c,0x41 }, + { 0x61,0x6c,0x7b,0x76,0x55,0x58,0x4f,0x42,0x09,0x04,0x13,0x1e,0x3d,0x30,0x27,0x2a }, + { 0xb1,0xbc,0xab,0xa6,0x85,0x88,0x9f,0x92,0xd9,0xd4,0xc3,0xce,0xed,0xe0,0xf7,0xfa }, + { 0xb7,0xba,0xad,0xa0,0x83,0x8e,0x99,0x94,0xdf,0xd2,0xc5,0xc8,0xeb,0xe6,0xf1,0xfc }, + { 0x67,0x6a,0x7d,0x70,0x53,0x5e,0x49,0x44,0x0f,0x02,0x15,0x18,0x3b,0x36,0x21,0x2c }, + { 0x0c,0x01,0x16,0x1b,0x38,0x35,0x22,0x2f,0x64,0x69,0x7e,0x73,0x50,0x5d,0x4a,0x47 }, + { 0xdc,0xd1,0xc6,0xcb,0xe8,0xe5,0xf2,0xff,0xb4,0xb9,0xae,0xa3,0x80,0x8d,0x9a,0x97 }}; + + +AES::uint8 AES::gf_mul14[16][16] = { + { 0x00,0x0e,0x1c,0x12,0x38,0x36,0x24,0x2a,0x70,0x7e,0x6c,0x62,0x48,0x46,0x54,0x5a }, + { 0xe0,0xee,0xfc,0xf2,0xd8,0xd6,0xc4,0xca,0x90,0x9e,0x8c,0x82,0xa8,0xa6,0xb4,0xba }, + { 0xdb,0xd5,0xc7,0xc9,0xe3,0xed,0xff,0xf1,0xab,0xa5,0xb7,0xb9,0x93,0x9d,0x8f,0x81 }, + { 0x3b,0x35,0x27,0x29,0x03,0x0d,0x1f,0x11,0x4b,0x45,0x57,0x59,0x73,0x7d,0x6f,0x61 }, + { 0xad,0xa3,0xb1,0xbf,0x95,0x9b,0x89,0x87,0xdd,0xd3,0xc1,0xcf,0xe5,0xeb,0xf9,0xf7 }, + { 0x4d,0x43,0x51,0x5f,0x75,0x7b,0x69,0x67,0x3d,0x33,0x21,0x2f,0x05,0x0b,0x19,0x17 }, + { 0x76,0x78,0x6a,0x64,0x4e,0x40,0x52,0x5c,0x06,0x08,0x1a,0x14,0x3e,0x30,0x22,0x2c }, + { 0x96,0x98,0x8a,0x84,0xae,0xa0,0xb2,0xbc,0xe6,0xe8,0xfa,0xf4,0xde,0xd0,0xc2,0xcc }, + { 0x41,0x4f,0x5d,0x53,0x79,0x77,0x65,0x6b,0x31,0x3f,0x2d,0x23,0x09,0x07,0x15,0x1b }, + { 0xa1,0xaf,0xbd,0xb3,0x99,0x97,0x85,0x8b,0xd1,0xdf,0xcd,0xc3,0xe9,0xe7,0xf5,0xfb }, + { 0x9a,0x94,0x86,0x88,0xa2,0xac,0xbe,0xb0,0xea,0xe4,0xf6,0xf8,0xd2,0xdc,0xce,0xc0 }, + { 0x7a,0x74,0x66,0x68,0x42,0x4c,0x5e,0x50,0x0a,0x04,0x16,0x18,0x32,0x3c,0x2e,0x20 }, + { 0xec,0xe2,0xf0,0xfe,0xd4,0xda,0xc8,0xc6,0x9c,0x92,0x80,0x8e,0xa4,0xaa,0xb8,0xb6 }, + { 0x0c,0x02,0x10,0x1e,0x34,0x3a,0x28,0x26,0x7c,0x72,0x60,0x6e,0x44,0x4a,0x58,0x56 }, + { 0x37,0x39,0x2b,0x25,0x0f,0x01,0x13,0x1d,0x47,0x49,0x5b,0x55,0x7f,0x71,0x63,0x6d }, + { 0xd7,0xd9,0xcb,0xc5,0xef,0xe1,0xf3,0xfd,0xa7,0xa9,0xbb,0xb5,0x9f,0x91,0x83,0x8d }}; + + + + +void AES::CopyToData(const AES::uint8 * state) +{ +int x, y, index = 0; + + for(x=0 ; x<4 ; ++x) + for(y=0 ; y<4 ; ++y) + data[y][x] = state[index++]; +} + + + +void AES::CopyFromData(AES::uint8 * state) +{ +int x, y, index = 0; + + for(x=0 ; x<4 ; ++x) + for(y=0 ; y<4 ; ++y) + state[index++] = data[y][x]; +} + + +void AES::CopyFromData(std::vector & out, bool clear) +{ +int x, y; + + if( clear ) + out.clear(); + + if( out.size() + 16 > out.capacity() ) + out.reserve(out.size() + 16); + + for(x=0 ; x<4 ; ++x) + for(y=0 ; y<4 ; ++y) + out.push_back(data[y][x]); +} + + + +void AES::PrintData() +{ +int x, y; +char buf[20]; + + for(y=0 ; y<4 ; ++y) + { + for(x=0 ; x<4 ; ++x) + { + sprintf(buf, "%02x ", data[y][x]); + std::cout << buf; + } + + std::cout << std::endl; + } +} + + +void AES::PrintKey(int xs) +{ +int x, y; +char buf[20]; + + for(y=0 ; y<4 ; ++y) + { + for(x=xs ; x> 4; + int x = (v & 0x0f); + +return sbox[y][x]; +} + + + +void AES::SubBytes() +{ +int x, y; + + for(y=0 ; y<4 ; ++y) + for(x=0 ; x<4 ; ++x) + data[y][x] = SubBytes(data[y][x]); +} + + + +void AES::ShiftRows1(AES::uint8 tab[4]) +{ + uint8 temp = tab[0]; + + tab[0] = tab[1]; + tab[1] = tab[2]; + tab[2] = tab[3]; + tab[3] = temp; +} + + + +void AES::ShiftRows2(AES::uint8 tab[4]) +{ + uint8 temp1 = tab[0]; + uint8 temp2 = tab[1]; + + tab[0] = tab[2]; + tab[1] = tab[3]; + tab[2] = temp1; + tab[3] = temp2; +} + + + +void AES::ShiftRows3(AES::uint8 tab[4]) +{ + uint8 temp = tab[3]; + + tab[3] = tab[2]; + tab[2] = tab[1]; + tab[1] = tab[0]; + tab[0] = temp; +} + + + +void AES::ShiftRows() +{ + ShiftRows1(data[1]); + ShiftRows2(data[2]); + ShiftRows3(data[3]); +} + + + +AES::uint8 AES::MixColumns2(AES::uint8 v) +{ + bool high_bit = (v & 0x80) != 0; + + v = v << 1; + + if( high_bit ) + v = v ^ 0x1b; + +return v; +} + + + +AES::uint8 AES::MixColumns3(AES::uint8 v) +{ + bool high_bit = (v & 0x80) != 0; + + AES::uint8 vold = v; + + v = (v << 1) ^ vold; + + if( high_bit ) + v = v ^ 0x1b; + +return v; +} + + + +AES::uint8 AES::MixColumns(int type, AES::uint8 value) +{ + switch(type) + { + case 2: + return MixColumns2(value); + + case 3: + return MixColumns3(value); + + case 1: + default: + return value; + } +} + + + +void AES::MixColumns() +{ +int x, y, i; +uint8 v; +uint8 temp[4]; + + for(x=0 ; x<4 ; ++x) + { + for(y=0 ; y<4 ; ++y) + { + v = 0; + + for(i=0 ; i<4 ; ++i) + v ^= MixColumns(mixcolumntab[y][i], data[i][x]); + + temp[y] = v; + } + + for(y=0 ; y<4 ; ++y) + data[y][x] = temp[y]; + + } +} + + + + +bool AES::Key(AES::uint8 * key_src, int key_length) +{ +int x, y, index = 0; + + key_len = key_length; + + if( key_len == 16 ) + { + key_col = 4; + round = 10; + } + else + if( key_len == 24 ) + { + key_col = 6; + round = 12; + } + else + if( key_len == 32 ) + { + key_col = 8; + round = 14; + } + else + { + return false; + } + + for(x=0 ; x 6 && i % key_col == 4 ) + { + SubWordKey(i); + } + + for(y=0 ; y<4 ; ++y) + key[y][i] ^= key[y][i-key_col]; + + + + //PrintKey3(i); + + /* + if( i % key_col == 0 ) + { + std::cout << " ---- " << (rcon_index-1) << std::endl; + PrintKey2(i-key_col); + } + */ + } + + //std::cout << " ---- " << rcon_index << std::endl; + //PrintKey2(i-key_col); +} + + + +void AES::AddRoundKey(int xs) +{ +int x, y; + + for(y=0 ; y<4 ; ++y) + for(x=0 ; x<4 ; ++x) + data[y][x] ^= key[y][xs+x]; +} + + + +void AES::EncodeData() +{ +int i; + +// std::cout << " input data " << std::endl; +// PrintData(); + + AddRoundKey(0); + +// std::cout << " first round key " << std::endl; +// PrintData(); + + for(i=0 ; i=0 ; --i) + { + InvShiftRows(); + +// std::cout << " after invshiftrows, i= " << i << std::endl; +// PrintData(); + + InvSubBytes(); + +// std::cout << " after invsubbutes, i= " << i << std::endl; +// PrintData(); + + AddRoundKey(i*4); + +// std::cout << " after add round key, i= " << i << std::endl; +// PrintData(); + + if( i != 0 ) + { + InvMixColumns(); + +// std::cout << " after inv mix columns, i= " << i << std::endl; +// PrintData(); + } + } +} + + + +/* + + +*/ + +bool AES::Encode(AES::uint8 * block, size_t len) +{ + if( len % 16 != 0 ) + return false; + + while( len > 0 ) + { + CopyToData(block); + EncodeData(); + CopyFromData(block); + + len -= 16; + block += 16; + } + +return true; +} + + +bool AES::Decode(AES::uint8 * block, size_t len) +{ + if( len % 16 != 0 ) + return false; + + while( len > 0 ) + { + CopyToData(block); + DecodeData(); + CopyFromData(block); + + len -= 16; + block += 16; + } + +return true; +} + + + + + +void AES::IntToBuf(AES::uint8 * buf, AES::uint16 value) +{ + buf[0] = value & 0xff; + buf[1] = (value >> 8) & 0xff; +} + +void AES::IntToBuf(AES::uint8 * buf, AES::uint32 value) +{ + buf[0] = value & 0xff; + buf[1] = (value >> 8) & 0xff; + buf[2] = (value >> 16) & 0xff; + buf[3] = (value >> 24) & 0xff; +} + + +void AES::CreateHeader(TiHeader & header, const AES::uint8 * block, size_t len, const std::string & name) +{ + header.signature = int('t') + (int('i') << 8); + + // first padding from 3 to 9 + header.pad1 = (6 * rand()) / RAND_MAX + 3; + header.all_len = 12 + header.pad1 + name.size() + len; + + header.pad2 = 0; + + if( (header.all_len % 16) != 0 ) + header.pad2 = 16 - (header.all_len % 16); + + header.all_len += header.pad2; + header.checksum_before = Checksum(block, len); + header.checksum_after = 0; + header.name_len = name.size(); +} + + +void AES::PutHeader(const TiHeader & header, std::vector & out) +{ +uint8 buf[16]; + + IntToBuf(buf, header.signature); + out.push_back(buf[0]); + out.push_back(buf[1]); + + // space for checksum after encoding + out.push_back(0); + out.push_back(0); + out.push_back(0); + out.push_back(0); + + IntToBuf(buf, header.pad1); + IntToBuf(buf+2, header.pad2); + IntToBuf(buf+4, header.checksum_before); + IntToBuf(buf+8, header.name_len); + + for(int i=12 ; i<16 ; ++i) + buf[i] = 0; + + CopyToData(buf); +} + + +void AES::PutChecksumAfter(std::vector & out) +{ + if( out.size() < 7 ) + return; // something wrong + + // checksum starting from 6th byte + AES::uint32 checksum_after = Checksum(&out[6], out.size()-6); + IntToBuf(&out[2], checksum_after); +} + + +AES::uint32 AES::Checksum(const uint8 * block, size_t len) +{ +uint32 sum = 0; + + for(size_t i=0 ; i & out) +{ +AES::uint16 index = 0; + + while( true ) + { + for( ; x<4 ; ++x) + { + for(; y<4 ; ++y) + { + if( index < pad ) + { + data[y][x] = (rand() * 255) / RAND_MAX; + index += 1; + } + else + { + return; + } + } + + y = 0; + } + + x = 0; + EncodeData(); + CopyFromData(out, false); + } +} + + +void AES::EncodeName(int & y, int & x, const std::string & name, std::vector & out) +{ +size_t index = 0; + + while( true ) + { + for( ; x<4 ; ++x) + { + for(; y<4 ; ++y) + { + if( index < name.size() ) + { + data[y][x] = name[index]; + index += 1; + } + else + { + return; + } + } + + y = 0; + } + + x = 0; + EncodeData(); + CopyFromData(out, false); + } +} + + + +void AES::EncodeData(int & y, int & x, const AES::uint8 * block, size_t len, std::vector & out) +{ +size_t index = 0; + + while( true ) + { + for( ; x<4 ; ++x) + { + for(; y<4 ; ++y) + { + if( index < len ) + { + data[y][x] = block[index]; + index += 1; + } + else + { + return; + } + } + + y = 0; + } + + x = 0; + EncodeData(); + CopyFromData(out, false); + } +} + + + + + +/* + (not encrypted) + 2 bytes: signature "ti" + 4 bytes: data checksum after encoding + --- + 6 bytes + (encrypted) + 2 bytes: first padding length (from 3 to 9) + 2 bytes: last padding length (can be zero) + 4 bytes: data checksum before encoding + 4 bytes: name string length (it can be a name of a file or just zero means an empty string) + --- + 12 bytes (18 bytes alltogether) + + ... bytes: first padding + ... bytes: name string + ... bytes: data + ... bytes: last padding +*/ +bool AES::Encode(const AES::uint8 * block, size_t len, const std::string & name, std::vector & out) +{ +TiHeader header; + + out.clear(); + CreateHeader(header, block, len, name); + PutHeader(header, out); + + if( out.capacity() < header.all_len ) + out.reserve(header.all_len); + + // skipping first 12 bytes from 'data' + int y = 0; + int x = 3; + + EncodePad (y, x, header.pad1, out); + EncodeName(y, x, name, out); + EncodeData(y, x, block, len, out); + EncodePad (y, x, header.pad2, out); + PutChecksumAfter(out); + +return true; +} + + +bool AES::Encode(const std::vector & block, const std::string & name, std::vector & out) +{ + if( block.empty() ) + return Encode(0, 0, name, out); + else + return Encode(&block[0], block.size(), name, out); +} + + +/* +*/ +void AES::ReadHeader(TiHeader & header, const AES::uint8 * block) +{ + header.signature = (uint16(block[1]) << 8) + uint16(block[0]); + header.checksum_after = (uint32(block[5]) << 24) + (uint32(block[4]) << 16) + (uint32(block[3]) << 8) + uint32(block[2]); + + header.pad1 = (uint16(data[1][0]) << 8) + uint16(data[0][0]); + header.pad2 = (uint16(data[3][0]) << 8) + uint16(data[2][0]); + header.checksum_before = (uint32(data[3][1]) << 24) + (uint32(data[2][1]) << 16) + (uint32(data[1][1]) << 8) + uint32(data[0][1]); + header.name_len = (uint32(data[3][2]) << 24) + (uint32(data[2][2]) << 16) + (uint32(data[1][2]) << 8) + uint32(data[0][2]); +} + + + +void AES::DecodePad(int & y, int & x, const AES::uint8 * & block, size_t & len, AES::uint16 pad) +{ +AES::uint16 index = 0; + + while( true ) + { + for( ; x<4 ; ++x) + { + for( ; y<4 ; ++y) + { + if( index < pad ) + { + index += 1; + } + else + { + return; + } + } + + y = 0; + } + + x = 0; + + if( len > 0 ) + { + CopyToData(block); + DecodeData(); + block += 16; + len -= 16; + } + } +} + + +void AES::DecodeName(int & y, int & x, const AES::uint8 * & block, size_t & len, AES::uint32 name_len, std::string & name) +{ +AES::uint32 index = 0; + + while( true ) + { + for( ; x<4 ; ++x) + { + for( ; y<4 ; ++y) + { + if( index < name_len ) + { + index += 1; + name += static_cast(data[y][x]); + } + else + { + return; + } + } + + y = 0; + } + + x = 0; + + if( len > 0 ) + { + CopyToData(block); + DecodeData(); + block += 16; + len -= 16; + } + } +} + + +void AES::DecodeData(int & y, int & x, const AES::uint8 * & block, size_t & len, size_t data_len, std::vector & out) +{ +size_t index = 0; + + while( true ) + { + for( ; x<4 ; ++x) + { + for( ; y<4 ; ++y) + { + if( index < data_len ) + { + index += 1; + out.push_back(data[y][x]); + } + else + { + return; + } + } + + y = 0; + } + + x = 0; + + if( len > 0 ) + { + CopyToData(block); + DecodeData(); + block += 16; + len -= 16; + } + } +} + + + +bool AES::CheckSignatureAndChecksumAfter(const TiHeader & header, const AES::uint8 * block, size_t len) +{ + if( ((header.signature >> 8) & 0xff) != 'i' || (header.signature & 0xff) != 't' ) + return false; + + AES::uint32 ch_after = Checksum(block+6, len-6); + +return ch_after == header.checksum_after; +} + + +bool AES::CheckChecksumBefore(const TiHeader & header, std::vector & out) +{ + AES::uint32 ch_before = 0; + + if( !out.empty() ) + ch_before = Checksum(&out[0], out.size()); + +return ch_before == header.checksum_before; +} + + +bool AES::Decode(const AES::uint8 * block, size_t len, std::string & name, std::vector & out) +{ +TiHeader header; + + name.clear(); + out.clear(); + + // incorrect size + if( len < 18 || (len - 6) % 16 != 0) + return false; + + CopyToData(block+6); + DecodeData(); + ReadHeader(header, block); + + if( !CheckSignatureAndChecksumAfter(header, block, len) ) + return false; + + size_t min_size = 18 + header.pad1 + header.name_len + header.pad2; + + if( len < min_size ) + return false; + + size_t data_len = len - 18 - header.pad1 - header.name_len - header.pad2; + int y = 0; + int x = 3; + + // skipping non encrypted part and first block + block += (6 + 16); + len -= (6 + 16); + + DecodePad (y, x, block, len, header.pad1); + DecodeName(y, x, block, len, header.name_len, name); + DecodeData(y, x, block, len, data_len, out); + +return CheckChecksumBefore(header, out); +} + + +bool AES::Decode(const std::vector & block, std::string & name, std::vector & out) +{ + if( block.empty() ) + return Decode(0, 0, name, out); + else + return Decode(&block[0], block.size(), name, out); +} + + + + + + + + + + + + + + + + + + + + +/* + algorithm description: http://www.samiam.org/galois.html +*/ +AES::uint8 AES::GaloisMultiply(AES::uint8 a, AES::uint8 b) +{ +int i; +uint8 p = 0; + + for(i=0; i<8 ;++i) + { + if(b & 1) + p ^= a; + + bool a_high_bit = (a & 0x80) != 0; + + a = a << 1; + + if( a_high_bit ) + a ^= 0x1b; + + b = b >> 1; + } + +return p; +} + + +bool AES::CheckGFTable(int value, AES::uint8 gf_mul[16][16]) +{ +int x,y; +bool ok = true; + + for(y=0 ; y<16 ; ++y) + { + for(x=0 ; x<16 ; ++x) + { + int v1 = gf_mul[y][x]; + int v2 = GaloisMultiply(value, y*16 + x); + + if( v1 != v2 ) + { + std::cout << "error: y: " << y << ", x: " << x << ", v1: " << v1 << ", v2: " << v2 << std::endl; + ok = false; + } + } + } + +return ok; +} + + +bool AES::CheckGFTables() +{ +bool ok9, ok11, ok13, ok14; + + ok9 = CheckGFTable(9, gf_mul9); + ok11 = CheckGFTable(11, gf_mul11); + ok13 = CheckGFTable(13, gf_mul13); + ok14 = CheckGFTable(14, gf_mul14); + + bool ok = ok9 && ok11 && ok13 && ok14; + + if( ok ) + std::cout << "All GF tables are good" << std::endl; + +return ok; +} + + + + +} // namespace Tito + + diff --git a/aes.h b/aes.h new file mode 100755 index 0000000..c8c8014 --- /dev/null +++ b/aes.h @@ -0,0 +1,239 @@ +/* + * This file is a part of Tito - a cryptography library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 headerfile_tito_aes +#define headerfile_tito_aes + +#include +#include + + +namespace Tito +{ + + +class AES +{ +public: + +typedef unsigned char uint8; +typedef unsigned short int uint16; +typedef unsigned int uint32; + + + + // 'state' + // 128 bits data block (16 bytes) + // this is input/output buffer for encoding/decoding + uint8 data[4][4]; + + // copying 16 bytes (128bits) buffer to/from 'data' table + void CopyToData(const uint8 * state); + void CopyFromData(uint8 * state); + void CopyFromData(std::vector & out, bool clear = true); + + // setting a new key + // key_length should be either: 16, 24 or 32 + // if the key has incorrect length the method does nothing and returns false + bool Key(AES::uint8 * key_src, int key_length); + + // encoding/decoding one 128 bits block + // you can set the value for encoding/decoding either by directly + // setting 'data' table or using CopyToData method + void EncodeData(); + void DecodeData(); + + // encoding/decoding block of data + // the length should be multiplication of 16 (128bits) + // the method returns false if length is incorrect + bool Encode(uint8 * block, size_t len); + bool Decode(uint8 * block, size_t len); + + // encoding/decoding block of data + // there is not any restrictions to the length + // we are using our own header in which we remember the length + // some control sums, how many padding bytes were used + // Encode returns always true + // Decode returns false is the control sums are different from original in the header + bool Encode(const uint8 * block, size_t len, const std::string & name, std::vector & out); + bool Encode(const std::vector & block, const std::string & name, std::vector & out); + bool Decode(const uint8 * block, size_t len, std::string & name, std::vector & out); + bool Decode(const std::vector & block, std::string & name, std::vector & out); + + // printing 'data' tab + // for debug purposes + void PrintData(); + void PrintKey(int xs); + void PrintKey2(int xs); + void PrintKey3(int xs); + bool CheckGFTables(); + + + +private: + + + // key (either 128 or 192 or 256 bits) + // and a space for key expansion + uint8 key[4][60]; + + // key length (in bytes) + // 16 for 128 bits + // 24 for 192 bits + // 32 for 256 bits + int key_len; + + // key columns + // 4 for 128 bits key + // 6 for 192 bits key + // 8 for 256 bits key + int key_col; + + // how many rounds should be performed + // 10 for 128 bits key + // 12 for 192 bits key + // 14 for 256 bits key + int round; + + // sbox and inverse sbox tables (256 bytes each) + static uint8 sbox[16][16]; + static uint8 invsbox[16][16]; + + // a table for mixcolumn state + static int mixcolumntab[4][4]; + + static uint8 Rcon[10]; + + + static int invmixcolumntab[4][4]; + + static uint8 gf_mul9[16][16]; + static uint8 gf_mul11[16][16]; + static uint8 gf_mul13[16][16]; + static uint8 gf_mul14[16][16]; + + // returning a coresponding value from sbox table + uint8 SubBytes(AES::uint8 v); + + // making the SubBytes algorithm on all items in 'data' table + void SubBytes(); + + // performing shift rows by 1 item + void ShiftRows1(AES::uint8 tab[4]); + + // performing shift rows by 2 items + void ShiftRows2(AES::uint8 tab[4]); + + // performing shift rows by 3 item + void ShiftRows3(AES::uint8 tab[4]); + + // performing shift rows on 'data' table + void ShiftRows(); + + + uint8 MixColumns2(uint8 v); + uint8 MixColumns3(uint8 v); + uint8 MixColumns(int type, uint8 value); + void MixColumns(); + + + + void RotKey(int i); + void SubWordKey(int i); + void KeyExpansion(); + + void AddRoundKey(int xs); + + + + /* inverse */ + + void InvShiftRows1(uint8 tab[4]); + void InvShiftRows2(uint8 tab[4]); + void InvShiftRows3(uint8 tab[4]); + void InvShiftRows(); + + uint8 InvSubBytes(uint8 v); + void InvSubBytes(); + void InvMixColumns(); + + uint8 InvMixColumns(uint8 gf_mul[16][16], uint8 v); + uint8 InvMixColumns(int type, uint8 value); + + + /* for debug */ + + uint8 GaloisMultiply(uint8 a, uint8 b); + bool CheckGFTable(int value, uint8 gf_mul[16][16]); + + + struct TiHeader + { + AES::uint16 signature; + AES::uint16 pad1; + AES::uint16 pad2; + AES::uint32 checksum_before; + AES::uint32 checksum_after; + AES::uint32 name_len; + size_t all_len; + }; + + void IntToBuf(uint8 * buf, uint16 value); + void IntToBuf(uint8 * buf, uint32 value); + void CreateHeader(TiHeader & header, const uint8 * block, size_t len, const std::string & name); + void PutHeader(const TiHeader & header, std::vector & out); + void PutChecksumAfter(std::vector & out); + uint32 Checksum(const uint8 * block, size_t len); + void EncodePad(int & y, int & x, uint16 pad, std::vector & out); + void EncodeName(int & y, int & x, const std::string & name, std::vector & out); + void EncodeData(int & y, int & x, const uint8 * block, size_t len, std::vector & out); + + void ReadHeader(TiHeader & header, const uint8 * block); + void DecodePad(int & y, int & x, const uint8 * & block, size_t & len, uint16 pad); + void DecodeName(int & y, int & x, const uint8 * & block, size_t & len, uint32 name_len, std::string & name); + void DecodeData(int & y, int & x, const uint8 * & block, size_t & len, size_t data_len, std::vector & out); + + bool CheckSignatureAndChecksumAfter(const TiHeader & header, const uint8 * block, size_t len); + bool CheckChecksumBefore(const TiHeader & header, std::vector & out); +}; + + + +} // namespace Tito + + +#endif diff --git a/base64.cpp b/base64.cpp new file mode 100755 index 0000000..56ec936 --- /dev/null +++ b/base64.cpp @@ -0,0 +1,281 @@ +/* + * This file is a part of Tito - a cryptography library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 "base64.h" + + +namespace Tito +{ + + +// 64 characters +const char * Base64::tabbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + + +Base64::Base64() +{ + padding = '='; + tabbase64_len = 64; + not_existing = 256; // first 8 bits are zero +} + + + +void Base64::SetPadding(char c) +{ + for(size_t i=0 ; i(s); + + tab4[0] = tab4[1] = tab4[2] = tab4[3] = 64; + + if( len == 0 ) + return; + + tab4[0] = tab3[0] >> 2; + tab4[1] = (tab3[0] & 0x03) << 4; + + if( len == 1 ) + return; + + tab4[1] = tab4[1] | ((tab3[1] & 0xf0) >> 4); + tab4[2] = (tab3[1] & 0x0f) << 2; + + if( len == 2 ) + return; + + tab4[2] = (tab4[2]) | ((tab3[2] & 0xc0) >> 6); + tab4[3] = tab3[2] & 0x3f; +} + + + +void Base64::ConvertFrom4to3Pieces(const unsigned int * tab4, unsigned int * tab3) +{ + /* + tab4[0] and tab4[1] are always different from 'not_existing' + */ + + tab3[0] = ((tab4[0] & 0x3f) << 2) | (( tab4[1] & 0x30 ) >> 4); + tab3[1] = tab3[2] = not_existing; + + if( tab4[2] == not_existing ) + return; + + tab3[1] = ((tab4[1] & 0x0f) << 4) | (( tab4[2] & 0x3c ) >> 2); + + if( tab4[3] == not_existing ) + return; + + tab3[2] = ((tab4[2] & 0x03) << 6) | (tab4[3] & 0x3f); +} + + + + + +bool Base64::CharFromBase64(unsigned int from, unsigned int & to) +{ + if( from>='A' && from<='Z' ) + { + to = from-'A'; + return true; + } + else + if( from>='a' && from<='z' ) + { + to = from - 'a' + 'Z'-'A' + 1; + return true; + } + else + if( from>='0' && from<='9' ) + { + to = from - '0' + 'Z'-'A' + 1 + 'z'-'a' + 1; + return true; + } + else + if( from == '+' ) + { + to = tabbase64_len - 2; + return true; + } + else + if( from == '/' ) + { + to = tabbase64_len - 1; + return true; + } + + /* + such character does not exist in tabbase64 table + */ + return false; +} + + + +bool Base64::Make4pieces(const char * s, unsigned int * tab4) +{ + for(size_t i=0 ; i<4 ; ++i) + { + if( s[i] == padding ) + tab4[i] = not_existing; + else + if( !CharFromBase64(s[i], tab4[i]) ) + return false; + } + +return true; +} + + + + +void Base64::Save4PiecesToString(std::string & s, const unsigned int * tab4) +{ + for(int i=0 ; i<4 ; ++i) + { + if( tab4[i] < tabbase64_len ) + s += tabbase64[tab4[i]]; + else + s += padding; + } +} + + + +void Base64::Save3PiecesToString(std::string & s, const unsigned int * tab3) +{ + for(int i=0 ; i<3 ; ++i) + { + if( tab3[i] != not_existing ) + s += tab3[i]; + } +} + + + + +/* +*/ +void Base64::Encode(const char * in, size_t len, std::string & out) +{ +unsigned int tab4[4]; + + out.clear(); + size_t new_size = len + len/3 + 3; + out.reserve(new_size); + + for(size_t i=0 ; i < len ; i+=3) + { + Convert3to4Pieces(in+i, len-i, tab4); + Save4PiecesToString(out, tab4); + } +} + + +void Base64::Encode(const char * in, std::string & out) +{ + size_t len = strlen(in); + Encode(in, len, out); +} + + +void Base64::Encode(const std::string & in, std::string & out) +{ + Encode(in.c_str(), in.size(), out); +} + + + + + + +bool Base64::Decode(const char * in, size_t len, std::string & out) +{ +unsigned int tab3[3]; +unsigned int tab4[4]; + + out.clear(); + size_t new_size = len - len/3 + 3; + out.reserve(new_size); + + if( len % 4 != 0 ) + return false; + + for(size_t i=0 ; i + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 headerfile_tito_base64 +#define headerfile_tito_base64 + +#include + + +namespace Tito +{ + + +class Base64 +{ +public: + + Base64(); + + // default '='; + void SetPadding(char c); + + void Encode(const char * in, size_t len, std::string & out); + void Encode(const char * in, std::string & out); + void Encode(const std::string & in, std::string & out); + + bool Decode(const char * in, size_t len, std::string & out); + bool Decode(const char * in, std::string & out); + bool Decode(const std::string & in, std::string & out); + + + +private: + + static const char * tabbase64; + size_t tabbase64_len; + char padding; + unsigned int not_existing; + + void Convert3to4Pieces(const char * s, size_t len, unsigned int * tab4); + void ConvertFrom4to3Pieces(const unsigned int * tab4, unsigned int * tab3); + bool CharFromBase64(unsigned int from, unsigned int & to); + bool Make4pieces(const char * s, unsigned int * tab4); + void Save4PiecesToString(std::string & s, const unsigned int * tab4); + void Save3PiecesToString(std::string & s, const unsigned int * tab3); + +}; + + + +} // namespace Tito + + + +#endif + diff --git a/crypto.cpp b/crypto.cpp new file mode 100755 index 0000000..15407c5 --- /dev/null +++ b/crypto.cpp @@ -0,0 +1,163 @@ +/* + * This file is a part of Tito - a cryptography library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 "crypto.h" + +// !! FIX ME +//#include "log.h" + +#include "../ezc/src/utf8.h" +#include "misc.h" + + +namespace Tito +{ + + + +bool Crypto::SetAESKey(unsigned char aes_key[32]) +{ + if( !aes.Key(aes_key, 32) ) + { + //log << log1 << "problem with AES key" << logend; + return false; + } + +return true; +} + + + +void Crypto::Crypt(const std::wstring & in, std::wstring & out) +{ + Ezc::WideToUTF8(in, utf8_str); + aes.Encode((const unsigned char*)utf8_str.c_str(), utf8_str.size(), aes_name, uint8_tab); + + base64_str.clear(); + + if( !uint8_tab.empty() ) + base64.Encode((const char*)&uint8_tab[0], uint8_tab.size(), base64_str); + + AssignString(base64_str, out); + Clear(); +} + + +void Crypto::Crypt(const std::vector & in, std::string & out) +{ + aes.Encode((const unsigned char*)&in[0], in.size(), aes_name, uint8_tab); + base64.Encode((const char*)&uint8_tab[0], uint8_tab.size(), out); + Clear(); +} + + + +bool Crypto::Decrypt(const std::wstring & in, std::wstring & out) +{ + out.clear(); + + if( in.empty() ) + return true; + + AssignString(in, base64_str); + base64.Decode(base64_str, aes_str); + + if( aes.Decode((const unsigned char *)aes_str.c_str(), aes_str.size(), aes_tmp_name, uint8_tab) ) + { + if( !uint8_tab.empty() ) + Ezc::UTF8ToWide((const char*)&uint8_tab[0], uint8_tab.size(), out); + + Clear(); + return true; + } + else + { + //log << "problem with AES decoding (skipping)" << logend; + } + + Clear(); + +return false; +} + + +bool Crypto::Decrypt(const std::string & in, std::vector & out) +{ + out.clear(); + + if( in.empty() ) + return true; + + base64.Decode(in, aes_str); + + if( aes.Decode((const unsigned char *)aes_str.c_str(), aes_str.size(), aes_tmp_name, uint8_tab) ) + { + out.resize(uint8_tab.size()); + + for(size_t i=0 ; i + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 headerfile_tito_crypto +#define headerfile_tito_crypto + +#include "aes.h" +#include "base64.h" + + +namespace Tito +{ + + + +class Crypto +{ +public: + + + /* + setting AES256 key + the table should consists of 32 bytes + */ + bool SetAESKey(unsigned char aes_key[32]); + + + /* + crypting AES256 and base64 then + so the 'out' string is ready to save as a normal text + */ + void Crypt(const std::wstring & in, std::wstring & out); + void Crypt(const std::vector & in, std::string & out); + + + /* + decrypting base64 and AES256 then + decrypt can return false if the control sums are incorrect + in such a case out is empty + if 'in' is empty the 'out' will be empty too + */ + bool Decrypt(const std::wstring & in, std::wstring & out); + bool Decrypt(const std::string & in, std::vector & out); + + + /* + clearing a string or a vector + first it puts some characters and then calls clear() method + */ + template + void Clear(BufferType & str); + + +private: + + // AES cryptography + AES aes; + + // base64 encoding/decoding + Base64 base64; + + // a table used with AES + std::vector uint8_tab; + + // AES name (always empty) + std::string aes_name; + std::string aes_tmp_name; + + std::string utf8_str; + std::string base64_str; + std::string aes_str; + + void Clear(); + +}; + + + +template +void Crypto::Clear(BufferType & str) +{ + for(size_t i=0 ; i + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 "misc.h" + + +namespace Tito +{ + + + +void AssignString(const char * src, size_t len, std::wstring & dst, bool clear) +{ + if( clear ) + dst.clear(); + + if( dst.capacity() < dst.size() + len ) + dst.reserve(dst.size() + len + 128); + + for(size_t i=0 ; i(src[i]); +} + + + +void AssignString(const char * src, std::wstring & dst, bool clear) +{ +size_t len; + + for(len=0 ; src[len] ; ++len){} + + AssignString(src, len, dst, clear); +} + + +void AssignString(const std::string & src, std::wstring & dst, bool clear) +{ + AssignString(src.c_str(), src.size(), dst, clear); +} + + + + + +void AssignString(const wchar_t * src, size_t len, std::string & dst, bool clear) +{ + if( clear ) + dst.clear(); + + if( dst.capacity() < dst.size() + len ) + dst.reserve(dst.size() + len + 128); + + for(size_t i=0 ; i(src[i]); +} + + +void AssignString(const wchar_t * src, std::string & dst, bool clear) +{ +size_t len; + + for(len=0 ; src[len] ; ++len){} + + AssignString(src, len, dst, clear); +} + + +void AssignString(const std::wstring & src, std::string & dst, bool clear) +{ + AssignString(src.c_str(), src.size(), dst, clear); +} + + + +void AssignString(const char * src, size_t len, std::string & dst, bool clear) +{ + if( clear ) + dst.clear(); + + // we suppose that append is smart enough and we don't have to use reserve() + dst.append(src, len); +} + + + +void AssignString(const char * src, std::string & dst, bool clear) +{ +size_t len; + + for(len=0 ; src[len] ; ++len){} + + AssignString(src, len, dst, clear); +} + + + + +void AssignString(const std::string & src, std::string & dst, bool clear) +{ + if( clear ) + dst.clear(); + + dst.append(src); +} + + +void AssignString(const wchar_t * src, size_t len, std::wstring & dst, bool clear) +{ + if( clear ) + dst.clear(); + + // we suppose that append is smart enough and we don't have to use reserve() + dst.append(src, len); +} + + +void AssignString(const wchar_t * src, std::wstring & dst, bool clear) +{ +size_t len; + + for(len=0 ; src[len] ; ++len){} + + AssignString(src, len, dst, clear); +} + + + +void AssignString(const std::wstring & src, std::wstring & dst, bool clear) +{ + if( clear ) + dst.clear(); + + dst.append(src); +} + + + + +} // namespace Tito + + + + + + + diff --git a/misc.h b/misc.h new file mode 100755 index 0000000..6475f61 --- /dev/null +++ b/misc.h @@ -0,0 +1,83 @@ +/* + * This file is a part of Tito - a cryptography library + * and is distributed under the (new) BSD licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * 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. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 headerfile_tito_misc +#define headerfile_tito_misc + + +#include +#include +#include +#include +#include + + +namespace Tito +{ + + + +/* + conversions between ascii text and wide characters + (destination is always std::string or std::wstring) + + characters are copied as they are without any locales checking +*/ + +void AssignString(const char * src, size_t len, std::wstring & dst, bool clear = true); +void AssignString(const char * src, std::wstring & dst, bool clear = true); +void AssignString(const std::string & src, std::wstring & dst, bool clear = true); + +void AssignString(const wchar_t * src, size_t len, std::string & dst, bool clear = true); +void AssignString(const wchar_t * src, std::string & dst, bool clear = true); +void AssignString(const std::wstring & src, std::string & dst, bool clear = true); + +void AssignString(const char * src, size_t len, std::string & dst, bool clear = true); +void AssignString(const char * src, std::string & dst, bool clear = true); +void AssignString(const std::string & src, std::string & dst, bool clear = true); + +void AssignString(const wchar_t * src, size_t len, std::wstring & dst, bool clear = true); +void AssignString(const wchar_t * src, std::wstring & dst, bool clear = true); +void AssignString(const std::wstring & src, std::wstring & dst, bool clear = true); + + + +} // namespace Tito + + + +#endif