makerom v0.1

This commit is contained in:
3DSGuy
2014-02-16 16:55:00 +08:00
commit 0155b2098e
151 changed files with 67007 additions and 0 deletions
+258
View File
@@ -0,0 +1,258 @@
AccessControlInfo:
AffinityMask: 1
AutoGen: true
CoreVersion: 2
DescVersion: 2
Descriptor: |
AP///wAABAACAAAAAAAFGJ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiIAAAAAAAABBUFQ6VQAAACRo
aW9GSU8AJGhvc3RpbzAkaG9zdGlvMWFjOnUAAAAAYm9zczpVAABjYW06dQAA
AGNlY2Q6dQAAY2ZnOnUAAABkbHA6RktDTGRscDpTUlZSZHNwOjpEU1BmcmQ6
dQAAAGZzOlVTRVIAZ3NwOjpHcHVoaWQ6VVNFUmh0dHA6QwAAbWljOnUAAABu
ZG06dQAAAG5ld3M6dQAAbndtOjpVRFNwdG06dQAAAHB4aTpkZXYAc29jOlUA
AABzc2w6QwAAAHkycjp1AAAAbGRyOnJvAABpcjpVU0VSAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAABOn/rw/7//8ec/APIA8JH/APaR/1D/gf9Y/4H/cP+B/3j/gf8B
AQD/AAIA/iECAPz/////////////////////////////////////////////
////////////////////////////////////////AAAAAAAAAAAAAAAAAAAA
AAADAAAAAAAAAAAAAAAAAAI=
DisableDebug: false
EnableInterruptNumbers:
EnableSystemCalls:
ArbitrateAddress: 34
Break: 60
CancelTimer: 28
ClearEvent: 25
ClearTimer: 29
CloseHandle: 35
ConnectToPort: 45
ControlMemory: 1
CreateAddressArbiter: 33
CreateEvent: 23
CreateMemoryBlock: 30
CreateMutex: 19
CreateSemaphore: 21
CreateThread: 8
CreateTimer: 26
DuplicateHandle: 39
ExitProcess: 3
ExitThread: 9
GetCurrentProcessorNumber: 17
GetHandleInfo: 41
GetProcessId: 53
GetProcessIdOfThread: 54
GetProcessIdealProcessor: 6
GetProcessInfo: 43
GetResourceLimit: 56
GetResourceLimitCurrentValues: 58
GetResourceLimitLimitValues: 57
GetSystemInfo: 42
GetSystemTick: 40
GetThreadContext: 59
GetThreadId: 55
GetThreadIdealProcessor: 15
GetThreadInfo: 44
GetThreadPriority: 11
MapMemoryBlock: 31
OutputDebugString: 61
QueryMemory: 2
ReleaseMutex: 20
ReleaseSemaphore: 22
SendSyncRequest1: 46
SendSyncRequest2: 47
SendSyncRequest3: 48
SendSyncRequest4: 49
SendSyncRequest: 50
SetThreadPriority: 12
SetTimer: 27
SignalEvent: 24
SleepThread: 10
UnmapMemoryBlock: 32
WaitSynchronization1: 36
WaitSynchronizationN: 37
FileSystemAccess:
- Debug
- DirectSdmc
- DirectSdmcWrite
HandleTableSize: 512
IORegisterMapping:
- 1ff50000-1ff57fff
- 1ff70000-1ff77fff
IdealProcessor: 1
IoAccessControl:
- UseDirectSdmc
- SdApplication
MemoryMapping:
- 1f000000-1f5fffff:r
MemoryType: Application
Priority: 24
ProgramId: 0x00040000ffffff00L
ReleaseKernelMajor: "02"
ReleaseKernelMinor: "33"
ServiceAccessControl:
- APT:U
- $hioFIO
- $hostio0
- $hostio1
- ac:u
- boss:U
- cam:u
- cecd:u
- cfg:u
- dlp:FKCL
- dlp:SRVR
- dsp::DSP
- frd:u
- fs:USER
- gsp::Gpu
- hid:USER
- http:C
- mic:u
- ndm:u
- news:u
- nwm::UDS
- ptm:u
- pxi:dev
- soc:U
- ssl:C
- y2r:u
- ldr:ro
- ir:USER
Signature: |
3xyLmORvojVswxgXmPPOVH4ULn8e2G3PvClO/jIuwRGtRprGcOruKFUi4TYF
HASKzg8Mg4/I1t4RjurPrZvPgQ3rcROz066DAkwOEFBZPO5gBvuMf8IgJAFi
VYdgD636cy72ZWLS5RBFaXA5A9E57FDB1CU5spARTpXLGevKD7X6x7Di1+Bx
w+VVM55c3E07URENMXiWytcYWO4A6SjyaHbUV/5lsUtJP/amWErH/MS7YbxY
jVVl5gp5OUG4gGH3BcP+1osJgsJfplb57h0OBj6fP/GTmk+i1ZGHiv7Pw/yK
scR46dEa97HTIMuDvgPVyqVeF6aRENS+I9ZLTwOprg==
StorageId:
- 0
CommonHeaderKey:
D: |
jL2yO86eUQnYbXIrzgFVMm7FVze0LglZ2f5g+c42hWoEdnb5BOotaMQPBfqt
aUyAEmzQPaoi/4l4V+hTJRXQfthVRqIEx27B84l8LA6Tl5Fy9PaQaQ+4yRfP
g6ylH2l0EikrIVjy2uMlFgl0QJCrG+QGKHftxhaGCifdAwFNmiZuyJ/TmktZ
0RCb66lYcr2h/p2G7SnpKUliS9h9KnpmG+UEgVYQUK+4SCfByUa9PxYGpT0E
nw1UcRz0gsBmdOqcgzwnAd9vVqgb42hVn6uQZyAl+j1RKiMWywZarazIR/k5
Lmr4+groimSEa+3ajyoIho9WaWTDmFU3mkhA2tUDIQ==
DP: |
pD8c9uymjXDj6oyhx7EmQcrEDizxsj6hTjJ0x3G/PYNv/v2/DA9gp3X30h35
uRZ1O+SgonWCGVnOJ7Wfjr4w2cOcSzxpzT3PQsS6Gs9z0RvcDsUHRL5f2EiT
6A1ZPj6xyzmo9Ts6w9yfxCwaHci0f2hP9bq9FimfFKigCoNcFBE=
DQ: |
y+6Pado7N+SIZJgQ7zEGyQ7/SxGHHEy5uW04HHde9IqHD5HFGG2GegF655mM
iI9ja1eTCh/AFs8xjAg0drQEvB5q80TjPNKtwVUT8ghOlN3xTzpdaLwX0d+c
Twy74VY4KPawcdDeLaGFtXknhFOdGmIbx+BInibz7NZ9eLqGwaE=
Exponent: |
AQAB
InverseQ: |
tc9/lcF837g8AdfyeuCyuLyd36Zm1ZmJ1VSSuH8y3/1ZhBYZkOFXxU7EhMvJ
FyAu4qyCA9otzCXM+cqKxE3ZCkSconsXOu8szZTwuINSkwHlt22FtiTfPt+V
/g5kjtkjoZVOGfSvvfel9Smwy1yrFvKfi/yJsjATeNFjiEquV/w=
Modulus: |
z+yySANtuAnjXGxiLKlJ4fT0DGzD5S+dUKArWgDGcgALowRdlEbnABtIhbVh
LMl0yitDE8F4l1wzLwfHhfDa22CWUA98S3rXF53k5cOrb12leDKtBN2Wbtx1
/8Iv+qLuRonNrmmSpEi8RkfEjIlj4QpNHNxGL1twinzpIpwJC6iXQMoqfYSh
BEou29fQZEOc0HgRQYgz3TFikC0X8sapK5xwq9zTq13a7j1sDoH/9mdaRPms
Bz0jlHVlkyAMxXYdD2UGPSGi8JaAtwpJUzijXcB0PKTZQDaFH4zRLRX57ySp
fp2yHvigcoEXd3OxVn+tBaLSMFr1068PEEpS2AlHlw==
P: |
6SdD3AiAybNamgUgGJduyFWO1/LeakmoJm+23IEJADyU4nz+reGjxQnMrR+x
syuB8VPGuf1z0SInfRIu9PEjIfW9/H/fZ59GwckQuJbneODjW7KU1jM3cTVX
+AWvaxWDwlCUmVSYD2OySUJlo3szGmBYh/o/tKAq7kElaaOt+cc=
Q: |
5EyO8bCyfqgLTfipAG/nNLObQbqMyARdQfudxh4eQqHmzblEM3jareuA8eUZ
K8pIaP+U9UfxwWTeFsOulrpsm04j4gS71WGNx3YwOIRPXXOn7zBkxA3AO9qq
K8lMeV3gNsdt4Fz8Zh2F68HSP4avB+ThO2S18SXMyIkcM7Sbw7E=
DefaultSpec:
AccessControlInfo:
ServiceAccessControl:
- APT:U
- $hioFIO
- $hostio0
- $hostio1
- ac:u
- boss:U
- cam:u
- cecd:u
- cfg:u
- dlp:FKCL
- dlp:SRVR
- dsp::DSP
- frd:u
- fs:USER
- gsp::Gpu
- hid:USER
- http:C
- mic:u
- ndm:u
- news:u
- nwm::UDS
- ptm:u
- pxi:dev
- soc:U
- ssl:C
- y2r:u
- ldr:ro
- ir:USER
AffinityMask: 1
FirmwareVersion: 2
HandleTableSize: 512
IORegisterMapping:
- 1ff50000-1ff57fff
- 1ff70000-1ff77fff
IdealProcessor: 0
MemoryMapping:
- 1f000000-1f5fffff:r
Priority: 16
BasicInfo:
CompanyCode: "00"
Logo: Nintendo
Title: default
ExeFs:
ReadOnly:
- RO
ReadWrite:
- RW
Text:
- STUP_ENTRY
PlainRegion:
- .module_id
Rom:
DefaultReject:
- .*
File:
- "*"
SystemControlInfo:
Dependency:
ac: 0x0004013000002402L
am: 0x0004013000001502L
boss: 0x0004013000003402L
camera: 0x0004013000001602L
cecd: 0x0004013000002602L
cfg: 0x0004013000001702L
codec: 0x0004013000001802L
csnd: 0x0004013000002702L
dlp: 0x0004013000002802L
dsp: 0x0004013000001a02L
friends: 0x0004013000003202L
gpio: 0x0004013000001b02L
gsp: 0x0004013000001c02L
hid: 0x0004013000001d02L
http: 0x0004013000002902L
i2c: 0x0004013000001e02L
ir: 0x0004013000003302L
mcu: 0x0004013000001f02L
mic: 0x0004013000002002L
ndm: 0x0004013000002b02L
news: 0x0004013000003502L
nim: 0x0004013000002c02L
nwm: 0x0004013000002d02L
pdn: 0x0004013000002102L
ps: 0x0004013000003102L
ptm: 0x0004013000002202L
ro: 0x0004013000003702L
socket: 0x0004013000002e02L
spi: 0x0004013000002302L
ssl: 0x0004013000002f02L
StackSize: 262144
+37
View File
@@ -0,0 +1,37 @@
# Default value for application
BasicInfo:
Title : "Homebrew"
CompanyCode : "00"
MediaSize : 128MB # 128MB / 256MB / 512MB / 1GB / 2GB
MediaFootPadding: false
ProductCode : "CTR-P-HAXX"
ContentType : Application # Application / SystemUpdate / Manual / Child / Trial
Logo : Nintendo # Nintendo / Licenced / Distributed
BackupMemoryType: None # None / 128KB / 512KB
Rom:
# Specifies the root path of the file system to include in the ROM.
HostRoot: "$(ROMFS_ROOT)"
SaveDataSize: 512KB
TitleInfo:
UniqueId: 1337
#TargetCategory: Contents
Category: Application
#DemoIndex: 1
Version: 0
CardInfo:
#WritableAddress: 0x200
#CardType : S2 # S1 / S2
#CryptoType : 3 # 0 - 3
CardDevice : NorFlash # NorFlash(0), None(1), BT(2)
#MediaType : CARD1 # Card1 / Card2
Option:
# ??????????????? true
UseOnSD: true # true if App is to be installed to SD
EnableCompress: true # true / false
FreeProductCode: true # true ???????????????????????
EnableCrypt : true # fasle ????????
+59
View File
@@ -0,0 +1,59 @@
# Makerom Sources
UTILS_OBJS = utils.o keyset.o titleid.o
CIA_OBJS = cia.o certs.o tik.o tmd.o
NCCH_OBJS = ncch.o exheader.o exefs.o elf.o romfs.o
NCSD_OBJS = ncsd.o
SETTINGS_OBJS = usersettings.o yamlsettings.o
LIB_API_OBJS = crypto.o yaml_ctr.o blz.o
OBJS = makerom.o $(UTILS_OBJS) $(LIB_API_OBJS) $(SETTINGS_OBJS) $(NCSD_OBJS) $(NCCH_OBJS) $(CIA_OBJS)
# Libraries
POLAR_OBJS = polarssl/aes.o polarssl/bignum.o polarssl/rsa.o polarssl/sha1.o polarssl/sha2.o polarssl/padlock.o polarssl/md.o polarssl/md_wrap.o polarssl/md2.o polarssl/md4.o polarssl/md5.o polarssl/sha4.o polarssl/base64.o polarssl/cipher.o polarssl/cipher_wrap.o polarssl/camellia.o polarssl/des.o polarssl/blowfish.o
YAML_OBJS = libyaml/api.o libyaml/dumper.o libyaml/emitter.o libyaml/loader.o libyaml/parser.o libyaml/reader.o libyaml/scanner.o libyaml/writer.o
# Compiler Settings
LIBS = -static-libgcc -static-libstdc++
CXXFLAGS = -I.
CFLAGS = --std=c99 -Wall -I. -DMAKEROM_VER_MAJOR=$(VER_MAJOR) -DMAKEROM_VER_MINOR=$(VER_MINOR) $(MAKEROM_BUILD_FLAGS)
CC = gcc
# MAKEROM Build Settings
MAKEROM_BUILD_FLAGS = -DPRIVATE_BUILD -DRETAIL_FSIGN -DELF_DEBUG
VER_MAJOR = 0
VER_MINOR = 1
OUTPUT = makerom
#
main: build
rebuild: clean build
build: $(OBJS) $(POLAR_OBJS) $(YAML_OBJS)
g++ -o $(OUTPUT) $(LIBS) $(OBJS) $(POLAR_OBJS) $(YAML_OBJS)
clean:
rm -rf $(OUTPUT) $(OBJS) $(POLAR_OBJS) $(YAML_OBJS) *.cci *.cia *.cxi *.cfa
# Winfail compatibility
rebuildwin: cleanwin build
cleanwin:
del $(OUTPUT).exe *.o polarssl\*.o libyaml\*.o *.cci *.cia *.cxi *.cfa
#Test Functions
ccigen_sdk:
ctr_makerom32 -f card -rsf testdata\Application.rsf -o content_test_sdk.cci -content testdata\app_zeroskey.cxi:0 -content testdata\manual_zeroskey.cfa:1 -content testdata\dlp_zeroskey.cfa:2 -content testdata\update_zeroskey.cfa:7
del content_test_sdk.cci.xml
ccigen:
$(OUTPUT) -f card -rsf testdata\Application.rsf -o content_test.cci -content testdata\app_zeroskey.cxi:0 -content testdata\manual_zeroskey.cfa:1 -content testdata\dlp_zeroskey.cfa:2 -content testdata\update_zeroskey.cfa:7
ciagen_sdk:
ctr_makecia32 -o content_test.cia -i testdata\app_zeroskey.cxi:0 -i testdata\manual_zeroskey.cfa:1 -i testdata\dlp_zeroskey.cfa:2
ciagen:
$(OUTPUT) -f cia -o content_test.cia -content testdata\app_zeroskey.cxi:0 -content testdata\manual_zeroskey.cfa:1 -content testdata\dlp_zeroskey.cfa:2 -encryptcia
pyramids:
$(OUTPUT) -f cxi -accessdesc app -o pyramids.cxi -code pyramids\code.bin -exheader pyramids\exheader.bin -rsf pyramids\app.rsf -desc pyramids\build.desc -icon pyramids\icon.icn -banner pyramids\banner.bnr -romfs pyramids\romfs.bin
+52
View File
File diff suppressed because one or more lines are too long
+336
View File
@@ -0,0 +1,336 @@
/*----------------------------------------------------------------------------*/
/*-- blz.c - Bottom LZ coding for Nintendo GBA/DS --*/
/*-- Copyright (C) 2011 CUE --*/
/*-- --*/
/*-- 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 3 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, see <http://www.gnu.org/licenses/>. --*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
#include "lib.h"
#include "blz.h"
/*----------------------------------------------------------------------------*/
#define CMD_DECODE 0x00 // decode
#define CMD_ENCODE 0x01 // encode
#define BLZ_SHIFT 1 // bits to shift
#define BLZ_MASK 0x80 // bits to check:
// ((((1 << BLZ_SHIFT) - 1) << (8 - BLZ_SHIFT)
#define BLZ_THRESHOLD 2 // max number of bytes to not encode
#define BLZ_N 0x1002 // max offset ((1 << 12) + 2)
#define BLZ_F 0x12 // max coded ((1 << 4) + BLZ_THRESHOLD)
#define RAW_MINIM 0x00000000 // empty file, 0 bytes
#define RAW_MAXIM 0x00FFFFFF // 3-bytes length, 16MB - 1
#define BLZ_MINIM 0x00000004 // header only (empty RAW file)
#define BLZ_MAXIM 0x01400000 // 0x0120000A, padded to 20MB:
// * length, RAW_MAXIM
// * flags, (RAW_MAXIM + 7) / 8
// * header, 11
// 0x00FFFFFF + 0x00200000 + 12 + padding
/*----------------------------------------------------------------------------*/
#define BREAK(text) { printf(text); return; }
#define EXIT(text) { printf(text); exit(-1); }
/*----------------------------------------------------------------------------*/
u8 *Memory(int length, int size);
u8 *BLZ_Code(u8 *raw_buffer, int raw_len, u32 *new_len, int best);
void BLZ_Invert(u8 *buffer, int length);
/*----------------------------------------------------------------------------*/
u8 *Memory(int length, int size) {
u8 *fb;
fb = (u8 *) calloc(length * size, size);
if (fb == NULL) EXIT("\nMemory error\n");
return(fb);
}
/*----------------------------------------------------------------------------*/
void BLZ_Decode(char *filename) {
// u8 *pak_buffer, *raw_buffer, *pak, *raw, *pak_end, *raw_end;
// u32 pak_len, raw_len, len, pos, inc_len, hdr_len, enc_len, dec_len;
// u8 flags, mask;
// printf("- decoding '%s'", filename);
// // pak_buffer = Load(filename, &pak_len, BLZ_MINIM, BLZ_MAXIM);
// inc_len = *(u32 *)(pak_buffer + pak_len - 4);
// if (!inc_len) {
// enc_len = 0;
// dec_len = pak_len - 4;
// pak_len = 0;
// raw_len = dec_len;
// } else {
// if (pak_len < 8) EXIT("File has a bad header\n");
// hdr_len = pak_buffer[pak_len - 5];
// if ((hdr_len < 0x08) || (hdr_len > 0x0B)) EXIT("Bad header length\n");
// if (pak_len <= hdr_len) EXIT("Bad length\n");
// enc_len = *(u32 *)(pak_buffer + pak_len - 8) & 0x00FFFFFF;
// dec_len = pak_len - enc_len;
// pak_len = enc_len - hdr_len;
// raw_len = dec_len + enc_len + inc_len;
// if (raw_len > RAW_MAXIM) EXIT("Bad decoded length\n");
// }
// raw_buffer = (u8 *) Memory(raw_len, sizeof(char));
// pak = pak_buffer;
// raw = raw_buffer;
// pak_end = pak_buffer + dec_len + pak_len;
// raw_end = raw_buffer + raw_len;
// for (len = 0; len < dec_len; len++) *(raw++) = *(pak++);
// BLZ_Invert(pak_buffer + dec_len, pak_len);
// mask = 0;
// while (raw < raw_end) {
// if (!(mask >>= BLZ_SHIFT)) {
// if (pak == pak_end) break;
// flags = *pak++;
// mask = BLZ_MASK;
// }
// if (!(flags & mask)) {
// if (pak == pak_end) break;
// *raw++ = *pak++;
// } else {
// if (pak + 1 >= pak_end) break;
// pos = *pak++ << 8;
// pos |= *pak++;
// len = (pos >> 12) + BLZ_THRESHOLD + 1;
// if (raw + len > raw_end) {
// printf(", WARNING: wrong decoded length!");
// len = raw_end - raw;
// }
// pos = (pos & 0xFFF) + 3;
// while (len--) *(raw++) = *(raw - pos);
// }
// }
// BLZ_Invert(raw_buffer + dec_len, raw_len - dec_len);
// raw_len = raw - raw_buffer;
// if (raw != raw_end) printf(", WARNING: unexpected end of encoded file!");
// // Save(filename, raw_buffer, raw_len);
// free(raw_buffer);
// free(pak_buffer);
// printf("\n");
}
u8 *Load(char *filename, u32 *length, int min, int max) {
FILE *fp;
int fs;
u8 *fb;
if ((fp = fopen(filename, "rb")) == NULL) EXIT("\nFile open error\n");
fseek(fp, 0, SEEK_END);
fs = ftell(fp);
fseek(fp, 0, SEEK_SET);
if ((fs < min) || (fs > max)) EXIT("\nFile size error\n");
fb = Memory(fs + 3, sizeof(char));
if (fread(fb, 1, fs, fp) != fs) EXIT("\nFile read error\n");
if (fclose(fp) == EOF) EXIT("\nFile close error\n");
*length = fs;
return(fb);
}
/*----------------------------------------------------------------------------*/
u8* BLZ_Encode(char *filename, u32* pak_len, int mode) {
u8 *raw_buffer, *pak_buffer, *new_buffer;
u32 raw_len, new_len;
raw_buffer = Load(filename, &raw_len, RAW_MINIM, RAW_MAXIM);
pak_buffer = NULL;
*pak_len = BLZ_MAXIM + 1;
new_buffer = BLZ_Code(raw_buffer, raw_len, &new_len, mode);
if (new_len < *pak_len) {
if (pak_buffer != NULL) free(pak_buffer);
pak_buffer = new_buffer;
*pak_len = new_len;
}
return pak_buffer;
}
/*----------------------------------------------------------------------------*/
u8 *BLZ_Code(u8 *raw_buffer, int raw_len, u32 *new_len, int best) {
u8 *pak_buffer, *pak, *raw, *raw_end, *flg, *tmp;
u32 pak_len, inc_len, hdr_len, enc_len, len, pos, max;
u32 len_best, pos_best, len_next, pos_next, len_post, pos_post;
u32 pak_tmp, raw_tmp;
u8 mask;
#define SEARCH(l,p) { \
l = BLZ_THRESHOLD; \
\
max = raw - raw_buffer >= BLZ_N ? BLZ_N : raw - raw_buffer; \
for (pos = 3; pos <= max; pos++) { \
for (len = 0; len < BLZ_F; len++) { \
if (raw + len == raw_end) break; \
if (len >= pos) break; \
if (*(raw + len) != *(raw + len - pos)) break; \
} \
\
if (len > l) { \
p = pos; \
if ((l = len) == BLZ_F) break; \
} \
} \
}
pak_tmp = 0;
raw_tmp = raw_len;
pak_len = raw_len + ((raw_len + 7) / 8) + 11;
pak_buffer = (u8 *) Memory(pak_len, sizeof(char));
BLZ_Invert(raw_buffer, raw_len);
pak = pak_buffer;
raw = raw_buffer;
raw_end = raw_buffer + raw_len;
mask = 0;
while (raw < raw_end) {
if (!(mask >>= BLZ_SHIFT)) {
*(flg = pak++) = 0;
mask = BLZ_MASK;
}
SEARCH(len_best, pos_best);
// LZ-CUE optimization start
if (best) {
if (len_best > BLZ_THRESHOLD) {
if (raw + len_best < raw_end) {
raw += len_best;
SEARCH(len_next, pos_next);
raw -= len_best - 1;
SEARCH(len_post, pos_post);
raw--;
if (len_next <= BLZ_THRESHOLD) len_next = 1;
if (len_post <= BLZ_THRESHOLD) len_post = 1;
if (len_best + len_next <= 1 + len_post) len_best = 1;
}
}
}
// LZ-CUE optimization end
*flg <<= 1;
if (len_best > BLZ_THRESHOLD) {
raw += len_best;
*flg |= 1;
*pak++ = ((len_best - (BLZ_THRESHOLD+1)) << 4) | ((pos_best - 3) >> 8);
*pak++ = (pos_best - 3) & 0xFF;
} else {
*pak++ = *raw++;
}
if (pak - pak_buffer + raw_len - (raw - raw_buffer) < pak_tmp + raw_tmp) {
pak_tmp = pak - pak_buffer;
raw_tmp = raw_len - (raw - raw_buffer);
}
}
while (mask && (mask != 1)) {
mask >>= BLZ_SHIFT;
*flg <<= 1;
}
pak_len = pak - pak_buffer;
BLZ_Invert(raw_buffer, raw_len);
BLZ_Invert(pak_buffer, pak_len);
if (!pak_tmp || (raw_len + 4 < ((pak_tmp + raw_tmp + 3) & -4) + 8)) {
pak = pak_buffer;
raw = raw_buffer;
raw_end = raw_buffer + raw_len;
while (raw < raw_end) *pak++ = *raw++;
while ((pak - pak_buffer) & 3) *pak++ = 0;
*(u32 *)pak = 0; pak += 4;
} else {
tmp = (u8 *) Memory(raw_tmp + pak_tmp + 11, sizeof(char));
for (len = 0; len < raw_tmp; len++)
tmp[len] = raw_buffer[len];
for (len = 0; len < pak_tmp; len++)
tmp[raw_tmp + len] = pak_buffer[len + pak_len - pak_tmp];
pak = pak_buffer;
pak_buffer = tmp;
free(pak);
pak = pak_buffer + raw_tmp + pak_tmp;
enc_len = pak_tmp;
hdr_len = 8;
inc_len = raw_len - pak_tmp - raw_tmp;
while ((pak - pak_buffer) & 3) {
*pak++ = 0xFF;
hdr_len++;
}
*(u32 *)pak = enc_len + hdr_len; pak += 3;
*pak++ = hdr_len;
*(u32 *)pak = inc_len - hdr_len; pak += 4;
}
*new_len = pak - pak_buffer;
return(pak_buffer);
}
/*----------------------------------------------------------------------------*/
void BLZ_Invert(u8 *buffer, int length) {
u8 *bottom, ch;
bottom = buffer + length - 1;
while (buffer < bottom) {
ch = *buffer;
*buffer++ = *bottom;
*bottom-- = ch;
}
}
/*----------------------------------------------------------------------------*/
/*-- EOF Copyright (C) 2011 CUE --*/
/*----------------------------------------------------------------------------*/
+9
View File
@@ -0,0 +1,9 @@
#ifndef _BLZ_H_
#define _BLZ_H_
#define BLZ_NORMAL 0 // normal mode
#define BLZ_BEST 1 // best mode
u8 *BLZ_Code(u8 *raw_buffer, int raw_len, u32 *new_len, int best);
#endif
+139
View File
@@ -0,0 +1,139 @@
#include "lib.h"
#include "certs.h"
// Cert Sizes
u32 GetCertSize(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
u32 PubKSectionSize = GetCertPubkSectionSize((pubk_types)u8_to_u32(certcore->KeyType,BE));
return (4+SigSize+SigPadding+sizeof(Cert_Struct)+PubKSectionSize);
}
void GetCertSigSectionSizes(u32 *SigSize, u32 *SigPadding, u8 *cert)
{
sig_types sig = (sig_types)u8_to_u32(cert,BE);
switch(sig){
case RSA_4096_SHA1 :
*SigSize = 0x200;
*SigPadding = 0x3C;
break;
case RSA_2048_SHA1 :
*SigSize = 0x100;
*SigPadding = 0x3C;
break;
case ECC_SHA1 :
*SigSize = 0x3C;
*SigPadding = 0x40;
break;
case RSA_4096_SHA256 :
*SigSize = 0x200;
*SigPadding = 0x3C;
break;
case RSA_2048_SHA256 :
*SigSize = 0x100;
*SigPadding = 0x3C;
break;
case ECC_SHA256 :
*SigSize = 0x3C;
*SigPadding = 0x40;
break;
default :
*SigSize = 0;
*SigPadding = 0;
break;
}
return;
}
u32 GetCertPubkSectionSize(pubk_types type)
{
switch(type){
case RSA_4096_PUBK : return sizeof(rsa_4096_pubk_struct);
case RSA_2048_PUBK : return sizeof(rsa_2048_pubk_struct);
case ECC_PUBK : return sizeof(ecc_pubk_struct);
default : return 0;
}
}
// Issuer/Name Functions
u8 *GetCertIssuer(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
return certcore->Issuer;
}
u8 *GetCertName(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
return certcore->Name;
}
int GenCertChildIssuer(u8 *dest, u8 *cert)
{
u8 *Issuer = GetCertIssuer(cert);
u8 *Name = GetCertName(cert);
u32 out_size = strlen((char*)Issuer) + strlen((char*)Name) + 1;
if(out_size > 0x40) return MEM_ERROR;
memcpy(dest,Issuer,strlen((char*)Issuer));
dest[strlen((char*)Issuer)] = '-';
memcpy((dest+strlen((char*)Issuer)+1),Name,strlen((char*)Name));
return 0;
}
// Pubk
pubk_types GetCertPubkType(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
Cert_Struct *certcore = (Cert_Struct*)(cert+4+SigSize+SigPadding);
return (pubk_types)u8_to_u32(certcore->KeyType,BE);
}
u8 *GetCertPubk(u8 *cert)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
return (cert+4+SigSize+SigPadding+sizeof(Cert_Struct));
}
bool VerifyCert(u8 *cert, u8 *pubk)
{
u32 SigSize = 0;
u32 SigPadding = 0;
GetCertSigSectionSizes(&SigSize,&SigPadding,cert);
if(!SigSize || !SigPadding) return 0;
u8 *signature = (cert+4);
u8 *data = (cert+4+SigSize+SigPadding);
u32 datasize = sizeof(Cert_Struct) + GetCertPubkSectionSize(GetCertPubkType(cert));
int result = ctr_sig(data,datasize,signature,pubk,NULL,u8_to_u32(cert,BE),CTR_RSA_VERIFY);
if(result == 0) return true;
else return false;
}
+47
View File
@@ -0,0 +1,47 @@
#ifndef _CERTS_H_
#define _CERTS_H_
typedef struct
{
u8 Issuer[0x40];
u8 KeyType[4];
u8 Name[0x40];
u8 Unknown[4];
} Cert_Struct;
typedef struct
{
u8 Modulus[0x200];
u8 PubExponent[4];
u8 Padding[0x34];
} rsa_4096_pubk_struct;
typedef struct
{
u8 Modulus[0x100];
u8 PubExponent[4];
u8 Padding[0x34];
} rsa_2048_pubk_struct;
typedef struct
{
u8 PubK[0x3C];
u8 Padding[0x3C];
} ecc_pubk_struct;
#endif
// Cert Sizes
u32 GetCertSize(u8 *cert);
void GetCertSigSectionSizes(u32 *SigSize, u32 *SigPadding, u8 *cert);
u32 GetCertPubkSectionSize(pubk_types type);
// Issuer/Name Functions
u8 *GetCertIssuer(u8 *cert);
u8 *GetCertName(u8 *cert);
int GenCertChildIssuer(u8 *dest, u8 *cert);
// Pubk
pubk_types GetCertPubkType(u8 *cert);
u8 *GetCertPubk(u8 *cert);
bool VerifyCert(u8 *cert, u8 *pubk);
+613
View File
@@ -0,0 +1,613 @@
#include "lib.h"
#include "ncch.h"
#include "exheader.h"
#include "exefs.h"
#include "certs.h"
#include "cia.h"
#include "tik.h"
#include "tmd.h"
#include "titleid.h"
#include "srl.h"
#include "ncsd.h"
// Private Prototypes
/* cia_settings tools */
void init_CIASettings(cia_settings *set);
void free_CIASettings(cia_settings *set);
int get_CIASettings(cia_settings *ciaset, user_settings *usrset);
int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset);
int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset);
int GetCIADataFromNcch(cia_settings *ciaset, NCCH_Header *NcchHdr, ExtendedHeader_Struct *ExHeader);
int GetMetaRegion(cia_settings *ciaset, ExtendedHeader_Struct *ExHeader, u8 *ExeFs);
int GetContentFilePtrs(cia_settings *ciaset, user_settings *usrset);
int GetSettingsFromSrl(cia_settings *ciaset);
int GetSettingsFromCci(cia_settings *ciaset);
u16 SetupVersion(u16 Major, u16 Minor, u16 Micro);
int BuildCIA_CertChain(cia_settings *ciaset);
int BuildCIA_Header(cia_settings *ciaset);
int WriteCurrentSectionstoFile(cia_settings *ciaset);
int WriteContentsToFile(cia_settings *ciaset, user_settings *usrset);
int WriteTMDToFile(cia_settings *ciaset);
int CryptContent(u8 *EncBuffer,u8 *DecBuffer,u64 size,u8 *title_key, u16 index, u8 mode);
int build_CIA(user_settings *usrset)
{
int result = 0;
// Init Settings
cia_settings *ciaset = malloc(sizeof(cia_settings));
if(!ciaset) {fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); return MEM_ERROR;}
init_CIASettings(ciaset);
// Get Settings
result = get_CIASettings(ciaset,usrset);
if(result) goto finish;
// Create Output File
ciaset->out = fopen(usrset->outfile,"wb");
if(!ciaset->out){
fprintf(stderr,"[CIA ERROR] Failed to create '%s'\n",usrset->outfile);
result = FAILED_TO_CREATE_OUTFILE;
goto finish;
}
// Create CIA Sections
/* Certificate Chain */
result = BuildCIA_CertChain(ciaset);
if(result) goto finish;
/* Ticket */
result = BuildTicket(ciaset);
if(result) goto finish;
/* CIA Header */
result = BuildCIA_Header(ciaset);
if(result) goto finish;
/* Write To File Current Sections to File */
/* Explanation :
In order to conserve memory, only one Content is in memory at a time.
This however has the limitation of only being able to generate TMD after all content
has been processed (, encrypted) and written to file.
*/
result = WriteCurrentSectionstoFile(ciaset);
if(result) goto finish;
result = WriteContentsToFile(ciaset, usrset);
if(result) goto finish;
result = BuildTMD(ciaset);
if(result) goto finish;
result = WriteTMDToFile(ciaset);
finish:
if(result != FAILED_TO_CREATE_OUTFILE && ciaset->out) fclose(ciaset->out);
free_CIASettings(ciaset);
return result;
}
void init_CIASettings(cia_settings *set)
{
memset(set,0,sizeof(cia_settings));
}
void free_CIASettings(cia_settings *set)
{
if(set->content.ContentFilePtrs){
for(u32 i = 1; i < set->content.ContentCount; i++){
fclose(set->content.ContentFilePtrs[i]);
}
free(set->content.ContentFilePtrs);
}
free(set->CIA_Sections.CertChain.buffer);
free(set->CIA_Sections.Ticket.buffer);
free(set->CIA_Sections.TitleMetaData.buffer);
free(set->CIA_Sections.CXI_MetaData.buffer);
memset(set,0,sizeof(cia_settings));
free(set);
}
int get_CIASettings(cia_settings *ciaset, user_settings *usrset)
{
int result = 0;
// Transfering data from usrset
result = GetSettingsFromUsrset(ciaset,usrset);
if(usrset->Content0IsNcch){
result = GetSettingsFromNcch0(ciaset,0);
if(result) return result;
result = GetContentFilePtrs(ciaset,usrset);
if(result) return result;
}
else if(usrset->Content0IsSrl){
result = GetSettingsFromSrl(ciaset);
if(result) return result;
}
else if(usrset->Content0IsCci){
result = GetSettingsFromCci(ciaset);
if(result) return result;
}
return 0;
}
int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
{
// General Stuff
ciaset->keys = &usrset->keys;
ciaset->content.content0 = usrset->Content0.buffer;
ciaset->content.content0_FileLen = usrset->Content0.size;
u32_to_u8(ciaset->Title_type,TYPE_CTR,BE);
ciaset->content.EncryptContents = usrset->EncryptContents;
ciaset->cert.ca_crl_version = 0;
ciaset->cert.signer_crl_version = 0;
for(int i = 0; i < 3; i++){
ciaset->Version[i] = usrset->Version[i];
}
// Random Number generator
u8 hash[0x20];
ctr_sha(ciaset->content.content0,0x100,hash,CTR_SHA_256);
// Ticket Data
memcpy(ciaset->tik.TicketID,(hash+0x8),8);
if(usrset->RandomTitleKey){
memcpy(ciaset->tik.TitleKey,(hash+0x10),16);
}
else{
memcpy(ciaset->tik.TitleKey,usrset->keys.aes.NormalKey,16);
}
ciaset->tik.ticket_format_ver = 1;
ciaset->tik.UnknownDataType = tik_normal;
int result = GenCertChildIssuer(ciaset->tik.TicketIssuer,usrset->keys.certs.tik_cert);
if(result) return result;
// Tmd Stuff
if(usrset->ContentID[0] > 0xffffffff){
ciaset->content.ContentId[0] = u8_to_u32(hash,BE);
}
else ciaset->content.ContentId[0] = usrset->ContentID[0];
ciaset->tmd.tmd_format_ver = 1;
result = GenCertChildIssuer(ciaset->tmd.TMDIssuer,usrset->keys.certs.tmd_cert);
return 0;
}
int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
{
/* Sanity Checks */
if(!ciaset->content.content0_FileLen)
return CIA_NO_NCCH0;
u8 *ncch0 = (u8*)(ciaset->content.content0+ncch0_offset);
if(!IsNCCH(NULL,ncch0)){
fprintf(stderr,"[CIA ERROR] Content0 is not NCCH\n");
return CIA_INVALID_NCCH0;
}
/* Get Ncch0 Header */
NCCH_Header *hdr = NULL;
hdr = GetNCCH_CommonHDR(hdr,NULL,ncch0);
if(IsCfa(hdr)){
ciaset->content.IsCfa = true;
}
ciaset->content.ContentOffset[0] = 0;
ciaset->content.ContentSize[0] = GetNCCH_MediaSize(hdr)*GetNCCH_MediaUnitSize(hdr);
ciaset->content.TotalContentSize = ciaset->content.ContentSize[0];
/* Get Ncch0 Import Context */
NCCH_STRUCT *ncch_ctx = malloc(sizeof(NCCH_STRUCT));
if(!ncch_ctx){ fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); return MEM_ERROR; }
memset(ncch_ctx,0x0,sizeof(NCCH_STRUCT));
GetCXIStruct(ncch_ctx,hdr);
/* Verify Ncch0 (Sig&Hash Checks) */
int result = VerifyNCCH(ncch0,ciaset->keys,true);
if(result == UNABLE_TO_LOAD_NCCH_KEY){
ciaset->content.KeyNotFound = true;
if(!ciaset->content.IsCfa){
fprintf(stderr,"[CIA WARNING] CXI AES Key could not be loaded\n");
fprintf(stderr," Meta Region, SaveDataSize, Remaster Version cannot be obtained\n");
}
}
else if(result != 0){
fprintf(stderr,"[CIA ERROR] Content 0 Is Corrupt\n");
return CIA_INVALID_NCCH0;
}
/* Gen Settings From Ncch0 */
endian_memcpy(ciaset->TitleID,hdr->title_id,8,LE);
/* Getting ExeFs/ExHeader */
u8 *ExeFs = malloc(ncch_ctx->exefs_size);
if(!ExeFs){ fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); return MEM_ERROR; }
ExtendedHeader_Struct *ExHeader = malloc(ncch_ctx->exheader_size);
if(!ExHeader){ fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); free(ExeFs); return MEM_ERROR; }
GetNCCHSection(ExeFs, ncch_ctx->exefs_size, 0, ncch0, ncch_ctx, ciaset->keys, ncch_exefs);
GetNCCHSection((u8*)ExHeader, ncch_ctx->exheader_size, 0, ncch0, ncch_ctx, ciaset->keys, ncch_ExHeader);
result = GetCIADataFromNcch(ciaset,hdr,ExHeader); // Data For TMD
if(result) goto finish;
result = GetMetaRegion(ciaset,ExHeader,ExeFs); // Meta Region
/* Finish */
finish:
free(ExeFs);
free(ExHeader);
/* Return */
free(ncch_ctx);
return result;
}
int GetCIADataFromNcch(cia_settings *ciaset, NCCH_Header *NcchHdr, ExtendedHeader_Struct *ExHeader)
{
u16 Category = u8_to_u16((ciaset->TitleID+2),BE);
bool IsPatch = (Category == 0x000E);
if(IsPatch||ciaset->content.IsCfa||ciaset->content.KeyNotFound) u32_to_u8(ciaset->tmd.SaveDataSize,0,LE);
else u32_to_u8(ciaset->tmd.SaveDataSize,(u32)GetSaveDataSize_frm_exhdr(ExHeader),LE);
if(ciaset->content.IsCfa||ciaset->content.KeyNotFound){
if(ciaset->Version[0] == 0xffff){ // '-major' wasn't set
if(ciaset->content.IsCfa){ // Is a CFA and can be decrypted
fprintf(stderr,"[CIA ERROR] Invalid major version. Use '-major' option.\n");
return CIA_BAD_VERSION;
}
else // CXI which cannot be decrypted
ciaset->Version[0] = 0;
}
}
else{ // Is a CXI and can be decrypted
if(ciaset->Version[0] != 0xffff){ // '-major' was set
fprintf(stderr,"[CIA ERROR] Option '-major' cannot be applied for cxi.\n");
return CIA_BAD_VERSION;
}
// Setting remaster ver
ciaset->Version[0] = GetRemasterVersion_frm_exhdr(ExHeader);
}
SetupVersion(ciaset->Version[0],ciaset->Version[1],ciaset->Version[2]);
u16 version = SetupVersion(ciaset->Version[0],ciaset->Version[1],ciaset->Version[2]);
u16_to_u8(ciaset->tik.TicketVersion,version,BE);
u16_to_u8(ciaset->tmd.TitleVersion,version,BE);
return 0;
}
int GetMetaRegion(cia_settings *ciaset, ExtendedHeader_Struct *ExHeader, u8 *ExeFs)
{
if(ciaset->content.IsCfa || ciaset->content.KeyNotFound) return 0;
ciaset->CIA_Sections.CXI_MetaData.size = sizeof(MetaData_Struct) + GetExeFsSectionSize("icon",ExeFs);
ciaset->CIA_Sections.CXI_MetaData.buffer = malloc(ciaset->CIA_Sections.CXI_MetaData.size);
if(!ciaset->CIA_Sections.CXI_MetaData.buffer){ fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); return MEM_ERROR; }
MetaData_Struct *hdr = (MetaData_Struct*)ciaset->CIA_Sections.CXI_MetaData.buffer;
memset(hdr,0,sizeof(MetaData_Struct));
GetDependancyList_frm_exhdr(hdr->DependancyList,ExHeader);
GetCoreVersion_frm_exhdr(hdr->CoreVersion,ExHeader);
if(DoesExeFsSectionExist("icon",ExeFs)){
u8 *IconDestPos = (ciaset->CIA_Sections.CXI_MetaData.buffer + sizeof(MetaData_Struct));
memcpy(IconDestPos,GetExeFsSection("icon",ExeFs),GetExeFsSectionSize("icon",ExeFs));
}
return 0;
}
int GetContentFilePtrs(cia_settings *ciaset, user_settings *usrset)
{
ciaset->content.ContentFilePtrs = malloc(sizeof(FILE*)*CIA_MAX_CONTENT);
if(!ciaset->content.ContentFilePtrs){ fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); return MEM_ERROR; }
memset(ciaset->content.ContentFilePtrs,0,sizeof(FILE*)*CIA_MAX_CONTENT);
int j = 1;
NCCH_Header *hdr = malloc(sizeof(NCCH_Header));
for(int i = 1; i < CIA_MAX_CONTENT; i++){
if(usrset->ContentPath[i]){
ciaset->content.ContentFilePtrs[j] = fopen(usrset->ContentPath[i],"rb");
if(!ciaset->content.ContentFilePtrs[j]){ fprintf(stderr,"[CIA ERROR] Failed to open '%s'\n",usrset->ContentPath[i]); return FAILED_TO_OPEN_FILE; }
if(usrset->ContentID[i] == 0x100000000){
u8 hash[0x20];
ctr_sha(usrset->ContentPath[i],strlen(usrset->ContentPath[i]),hash,CTR_SHA_256);
ciaset->content.ContentId[j] = u8_to_u32(hash,BE);
}
else ciaset->content.ContentId[j] = (u32)usrset->ContentID[i];
ciaset->content.ContentIndex[j] = (u16)i;
// Get Data from ncch HDR
GetNCCH_CommonHDR(hdr,ciaset->content.ContentFilePtrs[j],NULL);
// Get TitleID
memcpy(ciaset->content.ContentTitleId[j],hdr->title_id,8);
// Get Size
ciaset->content.ContentSize[j] = GetNCCH_MediaSize(hdr)*GetNCCH_MediaUnitSize(hdr);
ciaset->content.ContentOffset[j] = ciaset->content.TotalContentSize;
ciaset->content.TotalContentSize += ciaset->content.ContentSize[j];
// Finish get next content
j++;
}
}
free(hdr);
ciaset->content.ContentCount = j;
// Check Conflicting IDs
for(int i = 0; i < ciaset->content.ContentCount; i++){
for(j = i+1; j < ciaset->content.ContentCount; j++){
if(ciaset->content.ContentId[j] == ciaset->content.ContentId[i]){
fprintf(stderr,"[CIA ERROR] CIA Content %d and %d, have conflicting IDs\n",ciaset->content.ContentIndex[j],ciaset->content.ContentIndex[i]);
return CIA_CONFILCTING_CONTENT_IDS;
}
}
}
return 0;
}
int GetSettingsFromSrl(cia_settings *ciaset)
{
SRL_Header *hdr = (SRL_Header*)ciaset->content.content0;
if(!hdr || ciaset->content.content0_FileLen < sizeof(SRL_Header)) {
fprintf(stderr,"[CIA ERROR] Invalid TWL SRL File\n");
return FAILED_TO_IMPORT_FILE;
}
// Check if TWL SRL File
if(u8_to_u16(&hdr->title_id[6],LE) != 0x0003){
fprintf(stderr,"[CIA ERROR] Invalid TWL SRL File\n");
return FAILED_TO_IMPORT_FILE;
}
// Generate and store Converted TitleID
u64_to_u8(ciaset->TitleID,ConvertTwlIdToCtrId(u8_to_u64(hdr->title_id,LE)),BE);
//memdump(stdout,"SRL TID: ",ciaset->TitleID,8);
// Get TWL Flag
ciaset->tmd.twl_flag = ((hdr->reserved_flags[3] & 6) >> 1);
// Get Remaster Version
u16 version = SetupVersion(hdr->rom_version,ciaset->Version[1],0);
u16_to_u8(ciaset->tik.TicketVersion,version,BE);
u16_to_u8(ciaset->tmd.TitleVersion,version,BE);
// Get SaveDataSize (Public and Private)
memcpy(ciaset->tmd.SaveDataSize,hdr->pub_save_data_size,4);
memcpy(ciaset->tmd.PrivSaveDataSize,hdr->priv_save_data_size,4);
// Setting CIA Content Settings
ciaset->content.ContentCount = 1;
ciaset->content.ContentOffset[0] = 0;
ciaset->content.ContentSize[0] = ciaset->content.content0_FileLen;
ciaset->content.TotalContentSize = ciaset->content.content0_FileLen;
return 0;
}
int GetSettingsFromCci(cia_settings *ciaset)
{
int result = 0;
if(!IsCci(ciaset->content.content0)){
fprintf(stderr,"[CIA ERROR] Invalid CCI file\n");
return FAILED_TO_IMPORT_FILE;
}
u32 ncch0_offset = GetPartitionOffset(ciaset->content.content0,0);
if(!ncch0_offset){
fprintf(stderr,"[CIA ERROR] Invalid CCI file (invalid ncch0 size)\n");
return FAILED_TO_IMPORT_FILE;
}
result = GetSettingsFromNcch0(ciaset, ncch0_offset);
if(result){
fprintf(stderr,"Import of Ncch 0 failed(%d)\n",result);
return result;
}
ciaset->content.ContentCount = 1;
ciaset->content.CCIContentOffsets[0] = ncch0_offset;
NCCH_Header *hdr = malloc(sizeof(NCCH_Header));
for(int i = 1; i < 8; i++){
if(GetPartitionSize(ciaset->content.content0,i)){
ciaset->content.CCIContentOffsets[ciaset->content.ContentCount] = GetPartitionOffset(ciaset->content.content0,i);
// Get Data from ncch HDR
GetNCCH_CommonHDR(hdr,NULL,GetPartition(ciaset->content.content0,i));
// Get Size
ciaset->content.ContentSize[ciaset->content.ContentCount] = GetPartitionSize(ciaset->content.content0,i);
ciaset->content.ContentOffset[ciaset->content.ContentCount] = ciaset->content.TotalContentSize;
ciaset->content.TotalContentSize += ciaset->content.ContentSize[ciaset->content.ContentCount];
// Get ID
u8 hash[0x20];
ctr_sha((u8*)hdr,0x200,hash,CTR_SHA_256);
ciaset->content.ContentId[ciaset->content.ContentCount] = u8_to_u32(hash,BE);
// Get Index
ciaset->content.ContentIndex[ciaset->content.ContentCount] = i;
// Increment Content Count
ciaset->content.ContentCount++;
}
}
free(hdr);
return 0;
}
u16 SetupVersion(u16 Major, u16 Minor, u16 Micro)
{
return (((Major << 10) & 0xFC00) | ((Minor << 4) & 0x3F0) | (Micro & 0xf));
}
int BuildCIA_CertChain(cia_settings *ciaset)
{
ciaset->CIA_Sections.CertChain.size = GetCertSize(ciaset->keys->certs.ca_cert) + GetCertSize(ciaset->keys->certs.tik_cert) + GetCertSize(ciaset->keys->certs.tmd_cert);
ciaset->CIA_Sections.CertChain.buffer = malloc(ciaset->CIA_Sections.CertChain.size);
if(!ciaset->CIA_Sections.CertChain.buffer) { fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); return MEM_ERROR; }
memcpy(ciaset->CIA_Sections.CertChain.buffer,ciaset->keys->certs.ca_cert,GetCertSize(ciaset->keys->certs.ca_cert));
memcpy((ciaset->CIA_Sections.CertChain.buffer+GetCertSize(ciaset->keys->certs.ca_cert)),ciaset->keys->certs.tik_cert,GetCertSize(ciaset->keys->certs.tik_cert));
memcpy((ciaset->CIA_Sections.CertChain.buffer+GetCertSize(ciaset->keys->certs.ca_cert)+GetCertSize(ciaset->keys->certs.tik_cert)),ciaset->keys->certs.tmd_cert,GetCertSize(ciaset->keys->certs.tmd_cert));
return 0;
}
int BuildCIA_Header(cia_settings *ciaset)
{
// Allocating memory for header
ciaset->CIA_Sections.Header.size = sizeof(CIA_Header);
ciaset->CIA_Sections.Header.buffer = malloc(ciaset->CIA_Sections.Header.size);
if(!ciaset->CIA_Sections.Header.buffer){ fprintf(stderr,"[CIA ERROR] MEM ERROR\n"); return MEM_ERROR; }
CIA_Header *hdr = (CIA_Header*)ciaset->CIA_Sections.Header.buffer;
// Clearing
memset(hdr,0,sizeof(CIA_Header));
// Predict TMD Size
ciaset->CIA_Sections.TitleMetaData.size = PredictTMDSize(ciaset->content.ContentCount);
// Setting Data
u32_to_u8(hdr->HdrSize,sizeof(CIA_Header),LE);
u16_to_u8(hdr->Type,0x0,LE);
u16_to_u8(hdr->Version,0x0,LE);
u32_to_u8(hdr->CertChainSize,ciaset->CIA_Sections.CertChain.size,LE);
u32_to_u8(hdr->TicketSize,ciaset->CIA_Sections.Ticket.size,LE);
u32_to_u8(hdr->TitleMetaDataSize,ciaset->CIA_Sections.TitleMetaData.size,LE);
u32_to_u8(hdr->CXI_MetaSize,ciaset->CIA_Sections.CXI_MetaData.size,LE);
u64_to_u8(hdr->ContentSize,ciaset->content.TotalContentSize,LE);
// Recording Offsets
ciaset->CIA_Sections.CertChainOffset = align_value(sizeof(CIA_Header),0x40);
ciaset->CIA_Sections.TicketOffset = align_value(ciaset->CIA_Sections.CertChainOffset+ciaset->CIA_Sections.CertChain.size,0x40);
ciaset->CIA_Sections.TitleMetaDataOffset = align_value(ciaset->CIA_Sections.TicketOffset+ciaset->CIA_Sections.Ticket.size,0x40);
ciaset->CIA_Sections.ContentOffset = align_value(ciaset->CIA_Sections.TitleMetaDataOffset+ciaset->CIA_Sections.TitleMetaData.size,0x40);
ciaset->CIA_Sections.CXI_MetaDataOffset = align_value(ciaset->CIA_Sections.ContentOffset+ciaset->content.TotalContentSize,0x40);
// SetCIAContentIndex, actually works for all index values now. CIA files generated can now hold, with
// validity, 65536 contents. Or at least have a content with index value of 65535.
for(int i = 0; i < ciaset->content.ContentCount; i++){
// This works by treating the 0x2000 byte index array as an array of 2048 u32 values
// Used for determining which u32 chunk to write the value to
u16 section = ciaset->content.ContentIndex[i]/32;
// Calculating the value added to the u32
u32 value = 0x80000000/(1<<ciaset->content.ContentIndex[i]);
// Retrieving current u32 block
u32 cur_content_index_section = u8_to_u32(hdr->ContentIndex+(sizeof(u32)*section),BE);
// Adding value to block
cur_content_index_section += value;
// Returning block
u32_to_u8(hdr->ContentIndex+(sizeof(u32)*section),cur_content_index_section,BE);
}
return 0;
}
int WriteCurrentSectionstoFile(cia_settings *ciaset)
{
WriteBuffer(ciaset->CIA_Sections.Header.buffer,ciaset->CIA_Sections.Header.size,0,ciaset->out);
WriteBuffer(ciaset->CIA_Sections.CertChain.buffer,ciaset->CIA_Sections.CertChain.size,ciaset->CIA_Sections.CertChainOffset,ciaset->out);
WriteBuffer(ciaset->CIA_Sections.Ticket.buffer,ciaset->CIA_Sections.Ticket.size,ciaset->CIA_Sections.TicketOffset,ciaset->out);
WriteBuffer(ciaset->CIA_Sections.CXI_MetaData.buffer,ciaset->CIA_Sections.CXI_MetaData.size,ciaset->CIA_Sections.CXI_MetaDataOffset,ciaset->out);
return 0;
}
int WriteContentsToFile(cia_settings *ciaset, user_settings *usrset)
{
u8 *Content0 = ciaset->content.content0;
if(usrset->Content0IsCci) Content0 = (u8*)(ciaset->content.content0+ciaset->content.CCIContentOffsets[0]);
ctr_sha(Content0,ciaset->content.ContentSize[0],ciaset->content.ContentHash[0],CTR_SHA_256);
if(ciaset->content.EncryptContents) {
ciaset->content.ContentType[0] |= Encrypted;
CryptContent(Content0,Content0,ciaset->content.ContentSize[0],ciaset->tik.TitleKey,ciaset->content.ContentIndex[0],ENC);
}
WriteBuffer(Content0,ciaset->content.ContentSize[0],ciaset->content.ContentOffset[0]+ciaset->CIA_Sections.ContentOffset,ciaset->out);
// Free Buffer if Not CCI
if(!usrset->Content0IsCci){
free(usrset->Content0.buffer);
usrset->Content0.buffer = NULL;
usrset->Content0.size = 0;
}
// Add additional contents, recreating them with their new TitleID
if(usrset->Content0IsNcch){
u8 TitleId[8];
endian_memcpy(TitleId,ciaset->TitleID,8,LE);
for(int i = 1; i < ciaset->content.ContentCount; i++){
u8 *ContentBuff = RetargetNCCH(ciaset->content.ContentFilePtrs[i],ciaset->content.ContentSize[i],ciaset->content.ContentTitleId[i],TitleId,ciaset->keys);
if(!ContentBuff){
fprintf(stderr,"[CIA ERROR] Could not import content %d to CIA\n",i);
return FAILED_TO_IMPORT_FILE;
}
ctr_sha(ContentBuff,ciaset->content.ContentSize[i],ciaset->content.ContentHash[i],CTR_SHA_256);
if(ciaset->content.EncryptContents) {
ciaset->content.ContentType[i] |= Encrypted;
CryptContent(ContentBuff,ContentBuff,ciaset->content.ContentSize[i],ciaset->tik.TitleKey,ciaset->content.ContentIndex[i],ENC);
}
WriteBuffer(ContentBuff,ciaset->content.ContentSize[i],ciaset->content.ContentOffset[i]+ciaset->CIA_Sections.ContentOffset,ciaset->out);
free(ContentBuff);
}
}
else if(usrset->Content0IsCci){
for(int i = 1; i < ciaset->content.ContentCount; i++){
u8 *ContentBuff = (u8*)(ciaset->content.content0+ciaset->content.CCIContentOffsets[i]);
ctr_sha(ContentBuff,ciaset->content.ContentSize[i],ciaset->content.ContentHash[i],CTR_SHA_256);
if(ciaset->content.EncryptContents) {
ciaset->content.ContentType[i] |= Encrypted;
CryptContent(ContentBuff,ContentBuff,ciaset->content.ContentSize[i],ciaset->tik.TitleKey,ciaset->content.ContentIndex[i],ENC);
}
WriteBuffer(ContentBuff,ciaset->content.ContentSize[i],ciaset->content.ContentOffset[i]+ciaset->CIA_Sections.ContentOffset,ciaset->out);
}
free(usrset->Content0.buffer);
usrset->Content0.buffer = NULL;
usrset->Content0.size = 0;
}
return 0;
}
int WriteTMDToFile(cia_settings *ciaset)
{
WriteBuffer(ciaset->CIA_Sections.TitleMetaData.buffer,ciaset->CIA_Sections.TitleMetaData.size,ciaset->CIA_Sections.TitleMetaDataOffset,ciaset->out);
return 0;
}
int CryptContent(u8 *EncBuffer,u8 *DecBuffer,u64 size,u8 *title_key, u16 index, u8 mode)
{
//generating IV
u8 iv[16];
memset(&iv,0x0,16);
iv[0] = (index >> 8) & 0xff;
iv[1] = index & 0xff;
//Crypting content
ctr_aes_context ctx;
memset(&ctx,0x0,sizeof(ctr_aes_context));
ctr_init_aes_cbc(&ctx,title_key,iv,mode);
if(mode == ENC) ctr_aes_cbc(&ctx,DecBuffer,EncBuffer,size,ENC);
else ctr_aes_cbc(&ctx,EncBuffer,DecBuffer,size,DEC);
return 0;
}
+109
View File
@@ -0,0 +1,109 @@
// Enums
typedef enum
{
CIA_NO_NCCH0 = -1,
CIA_INVALID_NCCH0 = -2,
CIA_CONFILCTING_CONTENT_IDS = -3,
CIA_BAD_VERSION = -4,
} cia_errors;
// Structs
typedef struct
{
u8 HdrSize[4];
u8 Type[2];
u8 Version[2];
u8 CertChainSize[4];
u8 TicketSize[4];
u8 TitleMetaDataSize[4];
u8 CXI_MetaSize[4];
u8 ContentSize[8];
u8 ContentIndex[0x2000];
} CIA_Header;
typedef struct
{
u8 DependancyList[0x30*0x8];
u8 Reserved0[0x180];
u8 CoreVersion[4];
u8 Reserved1[0xfc];
} MetaData_Struct;
typedef struct
{
FILE *out;
u8 TitleID[8];
u8 Title_type[4];
u16 Version[3];
keys_struct *keys;
struct{
u8 ca_crl_version;
u8 signer_crl_version;
} cert;
struct{
u8 TicketIssuer[0x40];
u8 ticket_format_ver;
u8 TicketID[8];
u8 DeviceID[8];
u8 TicketVersion[3];
u8 TitleKey[16];
u8 UnknownDataType;
} tik;
struct{
u8 TMDIssuer[0x40];
u8 tmd_format_ver;
u8 TitleVersion[3];
u8 SaveDataSize[4];
u8 PrivSaveDataSize[4];
u8 twl_flag;
} tmd;
struct{
u8 *content0;
u64 content0_FileLen;
bool IsCfa;
bool KeyNotFound;
bool EncryptContents;
FILE **ContentFilePtrs;
u64 CCIContentOffsets[CCI_MAX_CONTENT];
u16 ContentCount;
u64 ContentSize[CIA_MAX_CONTENT];
u64 ContentOffset[CIA_MAX_CONTENT];
u16 ContentIndex[CIA_MAX_CONTENT];
u16 ContentType[CIA_MAX_CONTENT];
u32 ContentId[CIA_MAX_CONTENT];
u8 ContentHash[CIA_MAX_CONTENT][0x20];
u8 ContentTitleId[CIA_MAX_CONTENT][8];
u64 TotalContentSize;
} content;
struct{
COMPONENT_STRUCT Header;
u32 CertChainOffset;
COMPONENT_STRUCT CertChain;
u32 TicketOffset;
COMPONENT_STRUCT Ticket;
u32 TitleMetaDataOffset;
COMPONENT_STRUCT TitleMetaData;
u32 CXI_MetaDataOffset;
COMPONENT_STRUCT CXI_MetaData;
u64 ContentOffset;
} CIA_Sections;
// Finish CIA data req.
} cia_settings;
// Public Prototypes
int build_CIA(user_settings *usrset);
+423
View File
@@ -0,0 +1,423 @@
#include "lib.h"
#include "crypto.h"
// API for polarssl adapted/copied from CTRTOOL by neimod
void ctr_sha(void *data, u64 size, u8 *hash, int mode)
{
switch(mode){
case(CTR_SHA_1): sha1((u8*)data, size, hash); break;
case(CTR_SHA_256): sha2((u8*)data, size, hash, 0); break;
}
}
void ctr_add_counter(ctr_aes_context* ctx, u32 carry)
{
u32 counter[4];
u32 sum;
int i;
for(i=0; i<4; i++)
counter[i] = (ctx->ctr[i*4+0]<<24) | (ctx->ctr[i*4+1]<<16) | (ctx->ctr[i*4+2]<<8) | (ctx->ctr[i*4+3]<<0);
for(i=3; i>=0; i--)
{
sum = counter[i] + carry;
if (sum < counter[i])
carry = 1;
else
carry = 0;
counter[i] = sum;
}
for(i=0; i<4; i++)
{
ctx->ctr[i*4+0] = counter[i]>>24;
ctx->ctr[i*4+1] = counter[i]>>16;
ctx->ctr[i*4+2] = counter[i]>>8;
ctx->ctr[i*4+3] = counter[i]>>0;
}
}
void ctr_init_counter(ctr_aes_context* ctx, u8 key[16], u8 ctr[16])
{
aes_setkey_enc(&ctx->aes, key, 128);
memcpy(ctx->ctr, ctr, 16);
}
void ctr_crypt_counter_block(ctr_aes_context* ctx, u8 input[16], u8 output[16])
{
int i;
u8 stream[16];
aes_crypt_ecb(&ctx->aes, AES_ENCRYPT, ctx->ctr, stream);
if (input)
{
for(i=0; i<16; i++)
{
output[i] = stream[i] ^ input[i];
}
}
else
{
for(i=0; i<16; i++)
output[i] = stream[i];
}
ctr_add_counter(ctx, 1);
}
void ctr_crypt_counter(ctr_aes_context* ctx, u8* input, u8* output, u32 size)
{
u8 stream[16];
u32 i;
while(size >= 16)
{
ctr_crypt_counter_block(ctx, input, output);
if (input)
input += 16;
if (output)
output += 16;
size -= 16;
}
if (size)
{
memset(stream, 0, 16);
ctr_crypt_counter_block(ctx, stream, stream);
if (input)
{
for(i=0; i<size; i++)
output[i] = input[i] ^ stream[i];
}
else
{
memcpy(output, stream, size);
}
}
}
void ctr_init_aes_cbc(ctr_aes_context* ctx,u8 key[16],u8 iv[16], u8 mode)
{
switch(mode){
case(ENC): aes_setkey_enc(&ctx->aes, key, 128); break;
case(DEC): aes_setkey_dec(&ctx->aes, key, 128); break;
}
memcpy(ctx->iv, iv, 16);
}
void ctr_aes_cbc(ctr_aes_context* ctx,u8* input,u8* output,u32 size,u8 mode)
{
switch(mode){
case(ENC): aes_crypt_cbc(&ctx->aes, AES_ENCRYPT, size, ctx->iv, input, output); break;
case(DEC): aes_crypt_cbc(&ctx->aes, AES_DECRYPT, size, ctx->iv, input, output); break;
}
}
void ctr_rsa_free(ctr_rsa_context* ctx)
{
rsa_free(&ctx->rsa);
}
int ctr_rsa_init(ctr_rsa_context* ctx, u8 *modulus, u8 *private_exp, u8 *exponent, u8 rsa_type, u8 mode)
{
// Sanity Check
if(ctx == NULL || modulus == NULL ||(private_exp == NULL && mode == RSAKEY_PRIV) || (exponent == NULL && mode == RSAKEY_PUB))
return Fail;
rsa_init(&ctx->rsa, RSA_PKCS_V15, 0);
u16 n_size = 0;
u16 d_size = 0;
u16 e_size = 0;
switch(rsa_type){
case RSA_2048:
ctx->rsa.len = 0x100;
n_size = 0x100;
d_size = 0x100;
e_size = 3;
break;
case RSA_4096:
ctx->rsa.len = 0x200;
n_size = 0x200;
d_size = 0x200;
e_size = 3;
break;
default: return Fail;
}
switch(mode){
case(RSAKEY_PUB):
if (mpi_read_binary(&ctx->rsa.N, modulus, n_size))
goto clean;
if (mpi_read_binary(&ctx->rsa.E, exponent, e_size))
goto clean;
break;
case(RSAKEY_PRIV):
if (mpi_read_binary(&ctx->rsa.N, modulus, n_size))
goto clean;
if (mpi_read_binary(&ctx->rsa.D, private_exp, d_size))
goto clean;
break;
default: return Fail;
}
return Good;
clean:
ctr_rsa_free(ctx);
return Fail;
}
int ctr_sig(void *data, u64 size, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode)
{
int result = 0;
int hashtype, hashlen, sigtype;
if(data == NULL || signature == NULL || modulus == NULL ||(private_exp == NULL && mode == CTR_RSA_SIGN))
return Fail;
switch(type){
case RSA_4096_SHA1:
hashtype = CTR_SHA_1;
hashlen = 0x14;
sigtype = RSA_4096;
case RSA_4096_SHA256:
hashtype = CTR_SHA_256;
hashlen = 0x20;
sigtype = RSA_4096;
break;
case RSA_2048_SHA1:
hashtype = CTR_SHA_1;
hashlen = 0x14;
sigtype = RSA_2048;
case RSA_2048_SHA256:
hashtype = CTR_SHA_256;
hashlen = 0x20;
sigtype = RSA_2048;
break;
case ECC_SHA1:
hashtype = CTR_SHA_1;
hashlen = 0x14;
sigtype = ECC;
case ECC_SHA256:
hashtype = CTR_SHA_256;
hashlen = 0x20;
sigtype = ECC;
break;
default: return Fail;
}
u8 hash[hashlen];
memset(hash,0,hashlen);
ctr_sha(data,size,hash,hashtype);
//memdump(stdout,"Data: ",data,size);
//memdump(stdout,"HashFor Sig: ",hash,hashlen);
if(sigtype == RSA_2048 || sigtype == RSA_4096)
result = ctr_rsa(hash,signature,modulus,private_exp,type,mode);
else if(sigtype == ECC){
printf("[!] ECC is not yet implemented\n");
result = Fail;
}
return result;
}
int ctr_rsa(u8 *hash, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode)
{
int result = 0;
// Sanity Check
if(hash == NULL || signature == NULL || modulus == NULL ||(private_exp == NULL && mode == CTR_RSA_SIGN))
return Fail;
// Getting details from sig type
int hashtype;
int hashlen;
int sigtype;
switch(type){
case RSA_4096_SHA1:
hashtype = SIG_RSA_SHA1;
hashlen = 0x14;
sigtype = RSA_4096;
break;
case RSA_4096_SHA256:
hashtype = SIG_RSA_SHA256;
hashlen = 0x14;
sigtype = RSA_4096;
break;
case RSA_2048_SHA1:
hashtype = SIG_RSA_SHA1;
hashlen = 0x20;
sigtype = RSA_2048;
break;
case RSA_2048_SHA256:
hashtype = SIG_RSA_SHA256;
hashlen = 0x20;
sigtype = RSA_2048;
break;
default: return Fail;
}
// Setting up
ctr_rsa_context ctx;
u8 exponent[3] = {0x01,0x00,0x01};
switch(mode){
case CTR_RSA_VERIFY:
result = ctr_rsa_init(&ctx,modulus,NULL,(u8*)exponent,sigtype,RSAKEY_PUB);
break;
case CTR_RSA_SIGN:
result = ctr_rsa_init(&ctx,modulus,private_exp,NULL,sigtype,RSAKEY_PRIV);
break;
}
if(result)return result;
switch(mode){
case CTR_RSA_VERIFY:
return rsa_pkcs1_verify(&ctx.rsa,RSA_PUBLIC,hashtype,hashlen,hash,signature);
case CTR_RSA_SIGN:
return ctr_rsa_rsassa_pkcs1_v15_sign(&ctx.rsa,RSA_PRIVATE,hashtype,hashlen,hash,signature);
}
return Fail;
}
/**
* Hacked from rsa.c, polarssl doesn't like generating signatures when only D and N are present
**/
int ctr_rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
{
size_t nb_pad, olen, ret;
unsigned char *p = sig;
if( ctx->padding != RSA_PKCS_V15 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
olen = ctx->len;
switch( hash_id )
{
case SIG_RSA_RAW:
nb_pad = olen - 3 - hashlen;
break;
case SIG_RSA_MD2:
case SIG_RSA_MD4:
case SIG_RSA_MD5:
nb_pad = olen - 3 - 34;
break;
case SIG_RSA_SHA1:
nb_pad = olen - 3 - 35;
break;
case SIG_RSA_SHA224:
nb_pad = olen - 3 - 47;
break;
case SIG_RSA_SHA256:
nb_pad = olen - 3 - 51;
break;
case SIG_RSA_SHA384:
nb_pad = olen - 3 - 67;
break;
case SIG_RSA_SHA512:
nb_pad = olen - 3 - 83;
break;
default:
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
}
if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
*p++ = 0;
*p++ = RSA_SIGN;
memset( p, 0xFF, nb_pad );
p += nb_pad;
*p++ = 0;
switch( hash_id )
{
case SIG_RSA_RAW:
memcpy( p, hash, hashlen );
break;
case SIG_RSA_MD2:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 2; break;
case SIG_RSA_MD4:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 4; break;
case SIG_RSA_MD5:
memcpy( p, ASN1_HASH_MDX, 18 );
memcpy( p + 18, hash, 16 );
p[13] = 5; break;
case SIG_RSA_SHA1:
memcpy( p, ASN1_HASH_SHA1, 15 );
memcpy( p + 15, hash, 20 );
break;
case SIG_RSA_SHA224:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 28 );
p[1] += 28; p[14] = 4; p[18] += 28; break;
case SIG_RSA_SHA256:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 32 );
p[1] += 32; p[14] = 1; p[18] += 32; break;
case SIG_RSA_SHA384:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 48 );
p[1] += 48; p[14] = 2; p[18] += 48; break;
case SIG_RSA_SHA512:
memcpy( p, ASN1_HASH_SHA2X, 19 );
memcpy( p + 19, hash, 64 );
p[1] += 64; p[14] = 3; p[18] += 64; break;
default:
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
}
mpi T, T1, T2;
mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 );
MPI_CHK( mpi_read_binary( &T, sig, ctx->len ) );
if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
{
mpi_free( &T );
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
}
MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
MPI_CHK( mpi_write_binary( &T, sig, olen ) );
cleanup:
mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );
return( 0 );
}
+101
View File
@@ -0,0 +1,101 @@
#ifndef _CTR_CRYPTO_H_
#define _CTR_CRYPTO_H_
#include "polarssl/config.h"
#include "polarssl/aes.h"
#include "polarssl/rsa.h"
#include "polarssl/sha1.h"
#include "polarssl/sha2.h"
typedef enum
{
RSA_4096_SHA1 = 0x00010000,
RSA_2048_SHA1 = 0x00010001,
ECC_SHA1 = 0x00010002,
RSA_4096_SHA256 = 0x00010003,
RSA_2048_SHA256 = 0x00010004,
ECC_SHA256 = 0x00010005
} sig_types;
typedef enum
{
RSA_2048 = 0,
RSA_4096 = 1,
ECC = 2,
} ctr_sig_types;
typedef enum
{
CTR_RSA_VERIFY = 0,
CTR_RSA_SIGN = 1,
} ctr_rsa_functions;
typedef enum
{
CTR_SHA_1 = 1,
CTR_SHA_256 = 256,
} ctr_sha_modes;
typedef enum
{
RSA_4096_PUBK = 0,
RSA_2048_PUBK,
ECC_PUBK
} pubk_types;
typedef enum
{
ENC,
DEC
} aescbcmode;
typedef enum
{
RSAKEY_INVALID,
RSAKEY_PRIV,
RSAKEY_PUB
} rsakeytype;
typedef struct
{
u8 ctr[16];
u8 iv[16];
aes_context aes;
} ctr_aes_context;
typedef struct
{
rsa_context rsa;
} ctr_rsa_context;
#ifdef __cplusplus
extern "C" {
#endif
// SHA
void ctr_sha(void *data, u64 size, u8 *hash, int mode);
// AES
void ctr_add_counter(ctr_aes_context* ctx, u32 carry);
void ctr_init_counter(ctr_aes_context* ctx, u8 key[16],u8 ctr[16]);
void ctr_crypt_counter_block(ctr_aes_context* ctx, u8 input[16], u8 output[16]);
void ctr_crypt_counter(ctr_aes_context* ctx, u8* input, u8* output, u32 size);
void ctr_init_aes_cbc(ctr_aes_context* ctx,u8 key[16],u8 iv[16], u8 mode);
void ctr_aes_cbc(ctr_aes_context* ctx,u8* input,u8* output,u32 size,u8 mode);
// RSA
void ctr_rsa_free(ctr_rsa_context* ctx);
int ctr_rsa_init(ctr_rsa_context* ctx, u8 *modulus, u8 *private_exp, u8 *exponent, u8 rsa_type, u8 mode);
int ctr_rsa(u8 *hash, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode);
int ctr_rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
int mode,
int hash_id,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig );
// Signature Functions
int ctr_sig(void *data, u64 size, u8 *signature, u8 *modulus, u8 *private_exp, u32 type, u8 mode);
#ifdef __cplusplus
}
#endif
#endif
+954
View File
@@ -0,0 +1,954 @@
#include "lib.h"
#include "ncch.h"
#include "elf_hdr.h"
#include "elf.h"
#include "blz.h"
int ImportPlainRegionFromFile(ncch_settings *ncchset);
int ImportExeFsCodeBinaryFromFile(ncch_settings *ncchset);
u32 GetPageSize(ncch_settings *ncchset);
u32 SizeToPage(u32 memorySize, ElfContext *elf);
int GetBSS_SizeFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset);
int ImportPlainRegionFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset);
int CreateExeFsCode(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset);
int CreateCodeSegmentFromElf(CodeSegment *out, ElfContext *elf, u8 *ElfFile, char **Names, u32 NameNum);
ElfSegment** GetContinuousSegments(u16 *ContinuousSegmentNum, ElfContext *elf, char **Names, u32 NameNum);
ElfSegment** GetSegments(u16 *SegmentNum, ElfContext *elf, char **Names, u32 NameNum);
// ELF Functions
int GetElfContext(ElfContext *elf, u8 *ElfFile);
int GetElfSectionEntries(ElfContext *elf, u8 *ElfFile);
int GetElfProgramEntries(ElfContext *elf, u8 *ElfFile);
void PrintElfContext(ElfContext *elf, u8 *ElfFile);
int ReadElfHdr(ElfContext *elf, u8 *ElfFile);
int CreateElfSegments(ElfContext *elf, u8 *ElfFile);
bool IsIgnoreSection(ElfSectionEntry info);
/* ELF Section Entry Functions */
u8* GetELFSectionHeader(u16 Index, ElfContext *elf, u8 *ElfFile);
u8* GetELFSectionEntry(u16 Index, ElfContext *elf, u8 *ElfFile);
char* GetELFSectionEntryName(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFSectionEntryType(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFSectionEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFSectionEntryAddress(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFSectionEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFSectionEntrySize(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFSectionEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile);
u16 GetElfSectionIndexFromName(char *Name, ElfContext *elf, u8 *ElfFile);
bool IsBss(ElfSectionEntry *Section);
bool IsData(ElfSectionEntry *Section);
bool IsRO(ElfSectionEntry *Section);
bool IsText(ElfSectionEntry *Section);
/* ELF Program Entry Functions */
u8* GetELFProgramHeader(u16 Index, ElfContext *elf, u8 *ElfFile);
u8* GetELFProgramEntry(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryType(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryFileSize(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryMemorySize(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryVAddress(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryPAddress(u16 Index, ElfContext *elf, u8 *ElfFile);
u64 GetELFProgramEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile);
int BuildExeFsCode(ncch_settings *ncchset)
{
int result = 0;
if(ncchset->ComponentFilePtrs.plainregion){ // Import PlainRegion from file
result = ImportPlainRegionFromFile(ncchset);
if(result) return result;
}
if(!ncchset->Options.IsBuildingCodeSection){ // Import ExeFs Code from file and return
result = ImportExeFsCodeBinaryFromFile(ncchset);
return result;
}
/* Import ELF */
u8 *ElfFile = malloc(ncchset->ComponentFilePtrs.elf_size);
if(!ElfFile) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); return MEM_ERROR;}
ReadFile_64(ElfFile,ncchset->ComponentFilePtrs.elf_size,0,ncchset->ComponentFilePtrs.elf);
/* Create ELF Context */
ElfContext *elf = malloc(sizeof(ElfContext));
if(!elf) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); free(ElfFile); return MEM_ERROR;}
memset(elf,0,sizeof(ElfContext));
result = GetElfContext(elf,ElfFile);
if(result) goto finish;
/* Setting Page Size */
elf->PageSize = GetPageSize(ncchset);
if(!ncchset->ComponentFilePtrs.plainregion){
result = ImportPlainRegionFromElf(elf,ElfFile,ncchset);
if(result) goto finish;
}
#ifdef ELF_DEBUG
PrintElfContext(elf,ElfFile);
#endif
result = CreateExeFsCode(elf,ElfFile,ncchset);
if(result) goto finish;
result = GetBSS_SizeFromElf(elf,ElfFile,ncchset);
if(result) goto finish;
finish:
if(result){
if(result == NOT_ELF_FILE) fprintf(stderr,"[ELF ERROR] Not ELF File\n");
else if(result == NOT_ARM_ELF) fprintf(stderr,"[ELF ERROR] Not ARM ELF\n");
else if(result == NON_EXECUTABLE_ELF) fprintf(stderr,"[ELF ERROR] Not Executeable ELF\n");
else if(result == NOT_FIND_BSS_SIZE) fprintf(stderr,"[ELF ERROR] BSS Size Could not be found\n");
else if(result == NOT_FIND_CODE_SECTIONS) fprintf(stderr,"[ELF ERROR] Failed to retrieve code sections from ELF\n");
else fprintf(stderr,"[ELF ERROR] Failed to process ELF file (%d)\n",result);
}
for(int i = 0; i < elf->ActiveSegments; i++){
free(elf->Segments[i].Header);
free(elf->Segments[i].Sections);
}
free(ElfFile);
free(elf->Sections);
free(elf->ProgramHeaders);
free(elf->Segments);
free(elf);
return result;
}
int ImportPlainRegionFromFile(ncch_settings *ncchset)
{
ncchset->Sections.PlainRegion.size = align_value(ncchset->ComponentFilePtrs.plainregion_size,ncchset->Options.MediaSize);
ncchset->Sections.PlainRegion.buffer = malloc(ncchset->Sections.PlainRegion.size);
if(!ncchset->Sections.PlainRegion.buffer) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); return MEM_ERROR;}
ReadFile_64(ncchset->Sections.PlainRegion.buffer,ncchset->ComponentFilePtrs.plainregion_size,0,ncchset->ComponentFilePtrs.plainregion);
return 0;
}
int ImportExeFsCodeBinaryFromFile(ncch_settings *ncchset)
{
u32 size = ncchset->ComponentFilePtrs.code_size;
u8 *buffer = malloc(size);
if(!buffer) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); return MEM_ERROR;}
ReadFile_64(buffer,size,0,ncchset->ComponentFilePtrs.code);
ncchset->ExeFs_Sections.Code.size = ncchset->ComponentFilePtrs.code_size;
ncchset->ExeFs_Sections.Code.buffer = malloc(ncchset->ExeFs_Sections.Code.size);
if(!ncchset->ExeFs_Sections.Code.buffer) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); return MEM_ERROR;}
ReadFile_64(ncchset->ExeFs_Sections.Code.buffer,ncchset->ExeFs_Sections.Code.size,0,ncchset->ComponentFilePtrs.code);
if(ncchset->Options.CompressCode){
u32 new_len;
ncchset->ExeFs_Sections.Code.buffer = BLZ_Code(buffer,size,&new_len,BLZ_NORMAL);
ncchset->ExeFs_Sections.Code.size = new_len;
free(buffer);
}
else{
ncchset->ExeFs_Sections.Code.size = size;
ncchset->ExeFs_Sections.Code.buffer = buffer;
}
return 0;
}
u32 GetPageSize(ncch_settings *ncchset)
{
if(ncchset->yaml_set->DefaultSpec.Option.PageSize)
return strtoul(ncchset->yaml_set->DefaultSpec.Option.PageSize,NULL,10);
return 0x1000;
}
u32 SizeToPage(u32 memorySize, ElfContext *elf)
{
return align_value(memorySize,elf->PageSize)/elf->PageSize;
}
int GetBSS_SizeFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset)
{
for(int i = 0; i < elf->SectionTableEntryCount; i++){
if(IsBss(&elf->Sections[i])) {
ncchset->CodeDetails.BSS_Size = elf->Sections[i].Size;
return 0;
}
}
return NOT_FIND_BSS_SIZE;
}
int ImportPlainRegionFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset) // Doesn't work same as N makerom
{
if(!ncchset->yaml_set->DefaultSpec.PlainRegionNum) return 0;
u16 *Index = malloc(sizeof(u16)*ncchset->yaml_set->DefaultSpec.PlainRegionNum);
/* Getting Index Values for each section */
for(int i = 0; i < ncchset->yaml_set->DefaultSpec.PlainRegionNum; i++){
Index[i] = GetElfSectionIndexFromName(ncchset->yaml_set->DefaultSpec.PlainRegion[i],elf,ElfFile);
}
// Eliminating Duplicated Sections
for(int i = ncchset->yaml_set->DefaultSpec.PlainRegionNum - 1; i >= 0; i--){
for(int j = i-1; j >= 0; j--){
if(Index[i] == Index[j]) Index[i] = 0;
}
}
/* Calculating Total Size of Data */
u64 TotalSize = 0;
for(int i = 0; i < ncchset->yaml_set->DefaultSpec.PlainRegionNum; i++){
TotalSize += elf->Sections[Index[i]].Size;
}
/* Creating Output Buffer */
ncchset->Sections.PlainRegion.size = align_value(TotalSize,ncchset->Options.MediaSize);
ncchset->Sections.PlainRegion.buffer = malloc(ncchset->Sections.PlainRegion.size);
if(!ncchset->Sections.PlainRegion.buffer) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); return MEM_ERROR;}
memset(ncchset->Sections.PlainRegion.buffer,0,ncchset->Sections.PlainRegion.size);
/* Storing Sections */
u64 pos = 0;
for(int i = 0; i < ncchset->yaml_set->DefaultSpec.PlainRegionNum; i++){
memcpy((ncchset->Sections.PlainRegion.buffer+pos),elf->Sections[Index[i]].Ptr,elf->Sections[Index[i]].Size);
pos += elf->Sections[Index[i]].Size;
}
return 0;
}
int CreateExeFsCode(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset)
{
/* Getting Code Segments */
CodeSegment Text;
memset(&Text,0,sizeof(CodeSegment));
CodeSegment RO;
memset(&RO,0,sizeof(CodeSegment));
CodeSegment Data;
memset(&Data,0,sizeof(CodeSegment));
int result = CreateCodeSegmentFromElf(&Text,elf,ElfFile,ncchset->yaml_set->DefaultSpec.ExeFs.Text,ncchset->yaml_set->DefaultSpec.ExeFs.TextNum);
if(result) return result;
result = CreateCodeSegmentFromElf(&RO,elf,ElfFile,ncchset->yaml_set->DefaultSpec.ExeFs.ReadOnly,ncchset->yaml_set->DefaultSpec.ExeFs.ReadOnlyNum);
if(result) return result;
result = CreateCodeSegmentFromElf(&Data,elf,ElfFile,ncchset->yaml_set->DefaultSpec.ExeFs.ReadWrite,ncchset->yaml_set->DefaultSpec.ExeFs.ReadWriteNum);
if(result) return result;
/* Allocating Buffer for ExeFs Code */
u32 size = (Text.MaxPageNum + RO.MaxPageNum + Data.MaxPageNum)*elf->PageSize;
u8 *code = malloc(size);
/* Writing Code into Buffer */
u8 *TextPos = (code + 0);
u8 *ROPos = (code + Text.MaxPageNum*elf->PageSize);
u8 *DataPos = (code + (Text.MaxPageNum + RO.MaxPageNum)*elf->PageSize);
if(Text.Size) memcpy(TextPos,Text.Data,Text.Size);
if(RO.Size) memcpy(ROPos,RO.Data,RO.Size);
if(Data.Size) memcpy(DataPos,Data.Data,Data.Size);
/* Compressing If needed */
if(ncchset->Options.CompressCode){
u32 new_len;
ncchset->ExeFs_Sections.Code.buffer = BLZ_Code(code,size,&new_len,BLZ_NORMAL);
ncchset->ExeFs_Sections.Code.size = new_len;
free(code);
}
else{
ncchset->ExeFs_Sections.Code.size = size;
ncchset->ExeFs_Sections.Code.buffer = code;
}
/* Setting CodeSegment Data and freeing original buffers */
ncchset->CodeDetails.TextAddress = Text.Address;
ncchset->CodeDetails.TextMaxPages = Text.MaxPageNum;
ncchset->CodeDetails.TextSize = Text.Size;
if(Text.Size) free(Text.Data);
ncchset->CodeDetails.ROAddress = RO.Address;
ncchset->CodeDetails.ROMaxPages = RO.MaxPageNum;
ncchset->CodeDetails.ROSize = RO.Size;
if(RO.Size) free(RO.Data);
ncchset->CodeDetails.DataAddress = Data.Address;
ncchset->CodeDetails.DataMaxPages = Data.MaxPageNum;
ncchset->CodeDetails.DataSize = Data.Size;
if(Data.Size) free(Data.Data);
/* Return */
return 0;
}
int CreateCodeSegmentFromElf(CodeSegment *out, ElfContext *elf, u8 *ElfFile, char **Names, u32 NameNum)
{
u16 ContinuousSegmentNum = 0;
memset(out,0,sizeof(CodeSegment));
ElfSegment **ContinuousSegments = GetContinuousSegments(&ContinuousSegmentNum,elf,Names,NameNum);
if (ContinuousSegments == NULL){
if(!ContinuousSegmentNum) // Nothing Was Found
return 0;
else // Error with found segments
return ELF_SEGMENTS_NOT_CONTINUOUS;
}
/* Getting Segment Size/Settings */
u32 vAddr = 0;
u32 memorySize = 0;
for(int i = 0; i < ContinuousSegmentNum; i++){
if (i==0){
vAddr = ContinuousSegments[i]->VAddr;
}
else{ // Add rounded size from previous segment
u32 num = ContinuousSegments[i]->VAddr - (vAddr + memorySize);
memorySize += num;
}
memorySize += ContinuousSegments[i]->Header->SizeInMemory;
for (int j = 0; j < ContinuousSegments[i]->SectionNum; j++){
ElfSectionEntry *Section = &ContinuousSegments[i]->Sections[j];
if (IsBss(Section) && j == (ContinuousSegments[i]->SectionNum-1))
memorySize -= Section->Size;
}
}
// For Check
#ifdef ELF_DEBUG
printf("Address: 0x%x\n",vAddr);
printf("Size: 0x%x\n",memorySize);
#endif
out->Address = vAddr;
out->Size = memorySize;
out->MaxPageNum = SizeToPage(memorySize,elf);
out->Data = malloc(memorySize);
/* Writing Segment to Buffer */
vAddr = 0;
memorySize = 0;
for(int i = 0; i < ContinuousSegmentNum; i++){
if (i==0){
vAddr = ContinuousSegments[i]->VAddr;
}
else{
u32 num = ContinuousSegments[i]->VAddr - (vAddr + memorySize);
memorySize += num;
}
u32 size = 0;
for (int j = 0; j < ContinuousSegments[i]->SectionNum; j++){
ElfSectionEntry *Section = &ContinuousSegments[i]->Sections[j];
if (!IsBss(Section)){
u8 *pos = (out->Data + memorySize + size);
memcpy(pos,Section->Ptr,Section->Size);
size += Section->Size;
}
else if (j == (ContinuousSegments[i]->SectionNum-1))
memorySize -= Section->Size;
else
size += Section->Size;
}
}
free(ContinuousSegments);
return 0;
}
ElfSegment** GetContinuousSegments(u16 *ContinuousSegmentNum, ElfContext *elf, char **Names, u32 NameNum)
{
u16 SegmentNum = 0;
ElfSegment **Segments = GetSegments(&SegmentNum, elf, Names, NameNum);
if (Segments == NULL || SegmentNum == 0){ // No Segments for the names were found
//printf("Not Found Segment\n");
return NULL;
}
if (SegmentNum == 1){ //Return as there is no need to check
*ContinuousSegmentNum = SegmentNum;
return Segments;
}
u32 vAddr = Segments[0]->VAddr + Segments[0]->Header->SizeInMemory;
for (int i = 1; i < SegmentNum; i++){
if (Segments[i]->VAddr != (u32)align_value(vAddr,Segments[i]->Header->Alignment)){ //Each Segment must start after each other
fprintf(stderr,"[ELF ERROR] %s segment and %s segment are not continuous\n", Segments[i]->Name, Segments[i - 1]->Name);
free(Segments);
*ContinuousSegmentNum = 0xffff; // Signify to function that an error occured
return NULL;
}
}
*ContinuousSegmentNum = SegmentNum;
return Segments;
}
ElfSegment** GetSegments(u16 *SegmentNum, ElfContext *elf, char **Names, u32 NameNum)
{
if (Names == NULL)
{
return NULL;
}
ElfSegment **Segments = malloc(sizeof(ElfSegment*)*NameNum);
*SegmentNum = 0; // There can be a max of NameNum Segments, however, they might not all exist
for (int i = 0; i < NameNum; i++){
for(int j = 0; j < elf->ActiveSegments; j++){
if(strcmp(Names[i],elf->Segments[j].Name) == 0){ // If there is a match, store Segment data pointer & increment index
Segments[*SegmentNum] = &elf->Segments[j];
*SegmentNum = *SegmentNum + 1;
}
}
}
return Segments;
}
// ELF Functions
int GetElfContext(ElfContext *elf, u8 *ElfFile)
{
if(u8_to_u32(ElfFile,BE) != ELF_MAGIC) return NOT_ELF_FILE;
elf->Is64bit = (ElfFile[4] == elf_64_bit);
elf->IsLittleEndian = (ElfFile[5] == elf_little_endian);
int result = ReadElfHdr(elf,ElfFile);
if(result) return result;
result = GetElfSectionEntries(elf,ElfFile);
if(result) return result;
result = GetElfProgramEntries(elf,ElfFile);
if(result) return result;
result = CreateElfSegments(elf,ElfFile);
if(result) return result;
return 0;
}
int GetElfSectionEntries(ElfContext *elf, u8 *ElfFile)
{
elf->Sections = malloc(sizeof(ElfSectionEntry)*elf->SectionTableEntryCount);
if(!elf->Sections) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); return MEM_ERROR;}
for(int i = 0; i < elf->SectionTableEntryCount; i++){
elf->Sections[i].Name = GetELFSectionEntryName(i,elf,ElfFile);
elf->Sections[i].Type = GetELFSectionEntryType(i,elf,ElfFile);
elf->Sections[i].Flags = GetELFSectionEntryFlags(i,elf,ElfFile);
elf->Sections[i].Ptr = GetELFSectionEntry(i,elf,ElfFile);
elf->Sections[i].OffsetInFile = GetELFSectionEntryFileOffset(i,elf,ElfFile);
elf->Sections[i].Size = GetELFSectionEntrySize(i,elf,ElfFile);
elf->Sections[i].Address = GetELFSectionEntryAddress(i,elf,ElfFile);
elf->Sections[i].Alignment = GetELFSectionEntryAlignment(i,elf,ElfFile);
}
return 0;
}
int GetElfProgramEntries(ElfContext *elf, u8 *ElfFile)
{
elf->ProgramHeaders = malloc(sizeof(ElfProgramEntry)*elf->ProgramTableEntryCount);
if(!elf->ProgramHeaders) {fprintf(stderr,"[ELF ERROR] MEM ERROR\n"); return MEM_ERROR;}
for(int i = 0; i < elf->ProgramTableEntryCount; i++){
elf->ProgramHeaders[i].Type = GetELFProgramEntryType(i,elf,ElfFile);
elf->ProgramHeaders[i].Flags = GetELFProgramEntryFlags(i,elf,ElfFile);
elf->ProgramHeaders[i].Ptr = GetELFProgramEntry(i,elf,ElfFile);
elf->ProgramHeaders[i].OffsetInFile = GetELFProgramEntryFileOffset(i,elf,ElfFile);
elf->ProgramHeaders[i].SizeInFile = GetELFProgramEntryFileSize(i,elf,ElfFile);
elf->ProgramHeaders[i].PhysicalAddress = GetELFProgramEntryPAddress(i,elf,ElfFile);
elf->ProgramHeaders[i].VirtualAddress = GetELFProgramEntryVAddress(i,elf,ElfFile);
elf->ProgramHeaders[i].SizeInMemory = GetELFProgramEntryMemorySize(i,elf,ElfFile);
elf->ProgramHeaders[i].Alignment = GetELFProgramEntryAlignment(i,elf,ElfFile);
}
return 0;
}
void PrintElfContext(ElfContext *elf, u8 *ElfFile)
{
printf("[+] Basic Details\n");
printf(" Class: %s\n",elf->Is64bit ? "64-bit" : "32-bit");
printf(" Data: %s\n",elf->IsLittleEndian ? "Little Endian" : "Big Endian");
printf("\n[+] Program Table Data\n");
printf(" Offset: 0x%lx\n",elf->ProgramTableOffset);
printf(" Size: 0x%x\n",elf->ProgramTableEntrySize);
printf(" Count: 0x%x\n",elf->ProgramTableEntryCount);
printf("\n[+] Section Table Data\n");
printf(" Offset: 0x%lx\n",elf->SectionTableOffset);
printf(" Size: 0x%x\n",elf->SectionTableEntrySize);
printf(" Count: 0x%x\n",elf->SectionTableEntryCount);
printf(" Lable Index: 0x%x\n",elf->SectionHeaderNameEntryIndex);
for(int i = 0; i < elf->ActiveSegments; i++){
printf(" Segment [%d][%s]\n",i,elf->Segments[i].Name);
printf(" > Size : 0x%x\n",elf->Segments[i].Header->SizeInFile);
printf(" > Address : 0x%x\n",elf->Segments[i].VAddr);
printf(" > Sections : %d\n",elf->Segments[i].SectionNum);
for(int j = 0; j < elf->Segments[i].SectionNum; j++){
printf(" > Section [%d][%s]\n",j,elf->Segments[i].Sections[j].Name);
}
/*
char outpath[100];
memset(&outpath,0,100);
sprintf(outpath,"%s.bin",elf->Sections[i].Name);
chdir("elfsections");
FILE *tmp = fopen(outpath,"wb");
WriteBuffer(elf->Sections[i].Ptr,elf->Sections[i].Size,0,tmp);
fclose(tmp);
chdir("..");
*/
}
}
int ReadElfHdr(ElfContext *elf, u8 *ElfFile)
{
if(elf->Is64bit){
elf_64_hdr *hdr = (elf_64_hdr*)ElfFile;
u16 Architecture = u8_to_u16(hdr->TargetArchitecture,elf->IsLittleEndian);
u16 Type = u8_to_u16(hdr->Type,elf->IsLittleEndian);
if(Architecture != elf_arm) return NOT_ARM_ELF;
if(Type != elf_executeable) return NON_EXECUTABLE_ELF;
elf->ProgramTableOffset = u8_to_u64(hdr->ProgramHeaderTableOffset,elf->IsLittleEndian);
elf->ProgramTableEntrySize = u8_to_u16(hdr->ProgramHeaderEntrySize,elf->IsLittleEndian);
elf->ProgramTableEntryCount = u8_to_u16(hdr->ProgramHeaderEntryCount,elf->IsLittleEndian);
elf->SectionTableOffset = u8_to_u64(hdr->SectionHeaderTableOffset,elf->IsLittleEndian);
elf->SectionTableEntrySize = u8_to_u16(hdr->SectionTableEntrySize,elf->IsLittleEndian);
elf->SectionTableEntryCount = u8_to_u16(hdr->SectionHeaderEntryCount,elf->IsLittleEndian);
elf->SectionHeaderNameEntryIndex = u8_to_u16(hdr->SectionHeaderNameEntryIndex,elf->IsLittleEndian);
}
else{
elf_32_hdr *hdr = (elf_32_hdr*)ElfFile;
u16 Architecture = u8_to_u16(hdr->TargetArchitecture,elf->IsLittleEndian);
u16 Type = u8_to_u16(hdr->Type,elf->IsLittleEndian);
if(Architecture != elf_arm) return NOT_ARM_ELF;
if(Type != elf_executeable) return NON_EXECUTABLE_ELF;
elf->ProgramTableOffset = u8_to_u32(hdr->ProgramHeaderTableOffset,elf->IsLittleEndian);
elf->ProgramTableEntrySize = u8_to_u16(hdr->ProgramHeaderEntrySize,elf->IsLittleEndian);
elf->ProgramTableEntryCount = u8_to_u16(hdr->ProgramHeaderEntryCount,elf->IsLittleEndian);
elf->SectionTableOffset = u8_to_u32(hdr->SectionHeaderTableOffset,elf->IsLittleEndian);
elf->SectionTableEntrySize = u8_to_u16(hdr->SectionTableEntrySize,elf->IsLittleEndian);
elf->SectionTableEntryCount = u8_to_u16(hdr->SectionHeaderEntryCount,elf->IsLittleEndian);
elf->SectionHeaderNameEntryIndex = u8_to_u16(hdr->SectionHeaderNameEntryIndex,elf->IsLittleEndian);
}
return 0;
}
/* Section Hdr Functions */
u8* GetELFSectionHeader(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return NULL;
return (ElfFile + elf->SectionTableOffset + elf->SectionTableEntrySize*Index);
}
u8* GetELFSectionEntry(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return NULL;
return (u8*) (ElfFile + GetELFSectionEntryFileOffset(Index,elf,ElfFile));
}
char* GetELFSectionEntryName(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return 0;
u64 NameIndex = 0;
if(elf->Is64bit){
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
NameIndex = u8_to_u64(shdr->sh_name,elf->IsLittleEndian);
}
else{
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
NameIndex = u8_to_u32(shdr->sh_name,elf->IsLittleEndian);
}
u8 *NameTable = GetELFSectionEntry(elf->SectionHeaderNameEntryIndex,elf,ElfFile);
return (char*)(NameTable+NameIndex);
}
u64 GetELFSectionEntryType(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u64(shdr->sh_type,elf->IsLittleEndian);
}
else{
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u32(shdr->sh_type,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFSectionEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u64(shdr->sh_flags,elf->IsLittleEndian);
}
else{
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u32(shdr->sh_flags,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFSectionEntryAddress(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u64(shdr->sh_addr,elf->IsLittleEndian);
}
else{
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u32(shdr->sh_addr,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFSectionEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u64(shdr->sh_offset,elf->IsLittleEndian);
}
else{
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u32(shdr->sh_offset,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFSectionEntrySize(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u64(shdr->sh_size,elf->IsLittleEndian);
}
else{
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u32(shdr->sh_size,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFSectionEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->SectionTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u64(shdr->sh_addralign,elf->IsLittleEndian);
}
else{
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
return u8_to_u32(shdr->sh_addralign,elf->IsLittleEndian);
}
return 0;
}
u16 GetElfSectionIndexFromName(char *Name, ElfContext *elf, u8 *ElfFile)
{
for(int i = 0; i < elf->SectionTableEntryCount; i++){
if(strcmp(Name,elf->Sections[i].Name) == 0) return i;
}
return 0; // Assuming 0 is always empty
}
bool IsBss(ElfSectionEntry *Section)
{
if(Section->Type == 8 && Section->Flags == 3)
return true;
return false;
}
bool IsData(ElfSectionEntry *Section)
{
if(Section->Type == 1 && Section->Flags == 3)
return true;
return false;
}
bool IsRO(ElfSectionEntry *Section)
{
if(Section->Type == 1 && Section->Flags == 2)
return true;
return false;
}
bool IsText(ElfSectionEntry *Section)
{
if(Section->Type == 1 && Section->Flags == 6)
return true;
return false;
}
/* ProgramHeader Functions */
u8* GetELFProgramHeader(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return NULL;
return (ElfFile + elf->ProgramTableOffset + elf->ProgramTableEntrySize*Index);
}
u8* GetELFProgramEntry(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return NULL;
return (u8*) (ElfFile + GetELFProgramEntryFileOffset(Index,elf,ElfFile));
return NULL;
}
u64 GetELFProgramEntryType(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_type,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_type,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFProgramEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_flags,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_flags,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFProgramEntryFileSize(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_filesz,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_filesz,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFProgramEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_offset,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_offset,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFProgramEntryMemorySize(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_memsz,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_memsz,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFProgramEntryVAddress(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_vaddr,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_vaddr,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFProgramEntryPAddress(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_paddr,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_paddr,elf->IsLittleEndian);
}
return 0;
}
u64 GetELFProgramEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile)
{
if(Index >= elf->ProgramTableEntryCount) return 0;
if(elf->Is64bit){
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u64(phdr->p_align,elf->IsLittleEndian);
}
else{
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
return u8_to_u32(phdr->p_align,elf->IsLittleEndian);
}
return 0;
}
int CreateElfSegments(ElfContext *elf, u8 *ElfFile)
{
int num = 0;
// Interate through Each Program Header
elf->ActiveSegments = 0;
elf->Segments = malloc(sizeof(ElfSegment)*elf->ProgramTableEntryCount);
ElfSegment *segment = malloc(sizeof(ElfSegment)); // Temporary Buffer
for (int i = 0; i < elf->ProgramTableEntryCount; i++){
if (elf->ProgramHeaders[i].SizeInMemory != 0 && elf->ProgramHeaders[i].Type == 1){
memset(segment,0,sizeof(ElfSegment));
bool flag = false;
u32 size = 0;
u32 vAddr = elf->ProgramHeaders[i].VirtualAddress;
u32 memorySize = elf->ProgramHeaders[i].SizeInMemory;
u16 SectionInfoCapacity = 10;
segment->SectionNum = 0;
segment->Sections = malloc(sizeof(ElfSectionEntry)*SectionInfoCapacity);
// Itterate Through Section Headers
for (int j = num; j < elf->SectionTableEntryCount; j++){
if (!flag){
if (elf->Sections[j].Address != vAddr)
goto Skip;
while (j < (int)elf->Sections[j].Size && elf->Sections[j].Address == vAddr && !IsIgnoreSection(elf->Sections[j]))
j++;
j--;
flag = true;
segment->VAddr = elf->Sections[j].Address;
segment->Name = elf->Sections[j].Name;
}
if(segment->SectionNum < SectionInfoCapacity)
memcpy(&segment->Sections[segment->SectionNum],&elf->Sections[j],sizeof(ElfSectionEntry));
else{
SectionInfoCapacity = SectionInfoCapacity*2;
ElfSectionEntry *tmp = malloc(sizeof(ElfSectionEntry)*SectionInfoCapacity);
for(int k = 0; k < segment->SectionNum; k++)
memcpy(&tmp[k],&segment->Sections[k],sizeof(ElfSectionEntry));
free(segment->Sections);
segment->Sections = tmp;
memcpy(&segment->Sections[segment->SectionNum],&elf->Sections[j],sizeof(ElfSectionEntry));
}
segment->SectionNum++;
size += elf->Sections[j].Size;
if (size == memorySize)
break;
if (size > memorySize){
fprintf(stderr,"[ELF ERROR] Too large section size.\n Segment size = 0x%x\n Section Size = 0x%x\n", memorySize, size);
return ELF_SEGMENT_SECTION_SIZE_MISMATCH;
}
Skip: ;
}
if(segment->SectionNum){
segment->Header = &elf->ProgramHeaders[i];
memcpy(&elf->Segments[elf->ActiveSegments],segment,sizeof(ElfSegment));
elf->ActiveSegments++;
}
else{
free(segment->Sections);
free(segment);
fprintf(stderr,"[ELF ERROR] Program Header Has no corresponding Sections, ELF Cannot be proccessed\n");
return ELF_SEGMENTS_NOT_FOUND;
}
}
}
free(segment);
return 0;
}
bool IsIgnoreSection(ElfSectionEntry info)
{
if (info.Address)
return false;
if (info.Type != 1 && info.Type != 0)
return true;
char IgnoreSectionNames[7][20] = { ".debug_abbrev", ".debug_frame", ".debug_info", ".debug_line", ".debug_loc", ".debug_pubnames", ".comment" };
for (int i = 0; i < 7; i++){
if (strcmp(IgnoreSectionNames[i],info.Name) == 0)
return true;
}
return false;
}
+87
View File
@@ -0,0 +1,87 @@
#ifndef _ELF_H_
#define _ELF_H_
typedef enum
{
NOT_ELF_FILE = -10,
NOT_ARM_ELF = -11,
NON_EXECUTABLE_ELF = -12,
ELF_SECTION_NOT_FOUND = -13,
NOT_FIND_BSS_SIZE = -14,
NOT_FIND_CODE_SECTIONS = -15,
ELF_SEGMENT_SECTION_SIZE_MISMATCH = -16,
ELF_SEGMENTS_NOT_CONTINUOUS = -17,
ELF_SEGMENTS_NOT_FOUND = -18,
} elf_errors;
typedef struct
{
char *Name;
u64 Type;
u64 Flags;
u8 *Ptr;
u64 OffsetInFile;
u64 Size;
u64 Address;
u64 Alignment;
} ElfSectionEntry;
typedef struct
{
u64 Type;
u64 Flags;
u8 *Ptr;
u64 OffsetInFile;
u64 SizeInFile;
u64 VirtualAddress;
u64 PhysicalAddress;
u64 SizeInMemory;
u64 Alignment;
} ElfProgramEntry;
typedef struct
{
char *Name;
u64 VAddr;
ElfProgramEntry *Header;
u32 SectionNum;
ElfSectionEntry *Sections;
} ElfSegment;
typedef struct
{
u32 Address;
u32 Size;
u32 MaxPageNum;
u8 *Data;
} CodeSegment;
typedef struct
{
u32 PageSize;
bool IsLittleEndian;
bool Is64bit;
u64 ProgramTableOffset;
u16 ProgramTableEntrySize;
u16 ProgramTableEntryCount;
u64 SectionTableOffset;
u16 SectionTableEntrySize;
u16 SectionTableEntryCount;
u16 SectionHeaderNameEntryIndex;
ElfSectionEntry *Sections;
ElfProgramEntry *ProgramHeaders;
u16 ActiveSegments;
ElfSegment *Segments;
} ElfContext;
#endif
int BuildExeFsCode(ncch_settings *ncchset);
+177
View File
@@ -0,0 +1,177 @@
#ifndef _ELF_HDR_H_
#define _ELF_HDR_H_
static const u32 ELF_MAGIC = 0x7f454c46;
typedef enum
{
elf_32_bit = 1,
elf_64_bit = 2,
} elf_bit_format_types;
typedef enum
{
elf_little_endian = 1,
elf_big_endian = 2,
} elf_endianness;
typedef enum
{
elf_relocatable = 1,
elf_executeable = 2,
elf_shared = 3,
elf_core = 4,
} elf_type;
typedef enum
{
elf_arm = 0x28,
} elf_target_architecture;
typedef struct
{
u8 Magic[4];
u8 BitFormat;
u8 Endianness;
u8 ELF_Version;
u8 OS;
u8 Padding_0[8];
u8 Type[2];
u8 TargetArchitecture[2];
u8 Version[4];
u8 EntryPoint[4];
u8 ProgramHeaderTableOffset[4];
u8 SectionHeaderTableOffset[4];
u8 Flags[4];
u8 HeaderSize[2];
u8 ProgramHeaderEntrySize[2];
u8 ProgramHeaderEntryCount[2];
u8 SectionTableEntrySize[2];
u8 SectionHeaderEntryCount[2];
u8 SectionHeaderNameEntryIndex[2];
} elf_32_hdr;
typedef struct
{
u8 Magic[4];
u8 BitFormat;
u8 Endianness;
u8 ELF_Version;
u8 OS;
u8 Padding_0[8];
u8 Type[2];
u8 TargetArchitecture[2];
u8 Version[4];
u8 EntryPoint[8];
u8 ProgramHeaderTableOffset[8];
u8 SectionHeaderTableOffset[8];
u8 Flags[4];
u8 HeaderSize[2];
u8 ProgramHeaderEntrySize[2];
u8 ProgramHeaderEntryCount[2];
u8 SectionTableEntrySize[2];
u8 SectionHeaderEntryCount[2];
u8 SectionHeaderNameEntryIndex[2];
} elf_64_hdr;
/* Section header. */
/* Legal values for sh_type (section type). */
#define SHT_NULL 0 /* Section header table entry unused */
#define SHT_PROGBITS 1 /* Program data */
#define SHT_SYMTAB 2 /* Symbol table */
#define SHT_STRTAB 3 /* String table */
#define SHT_RELA 4 /* Relocation entries with addends */
#define SHT_HASH 5 /* Symbol hash table */
#define SHT_DYNAMIC 6 /* Dynamic linking information */
#define SHT_NOTE 7 /* Notes */
#define SHT_NOBITS 8 /* Program space with no data (bss) */
#define SHT_REL 9 /* Relocation entries, no addends */
#define SHT_SHLIB 10 /* Reserved */
#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
#define SHT_NUM 12 /* Number of defined types. */
#define SHT_LOOS 0x60000000 /* Start OS-specific */
#define SHT_LOSUNW 0x6ffffffb /* Sun-specific low bound. */
#define SHT_SUNW_COMDAT 0x6ffffffb
#define SHT_SUNW_syminfo 0x6ffffffc
#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
#define SHT_HIOS 0x6fffffff /* End OS-specific type */
#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
#define SHT_LOUSER 0x80000000 /* Start of application-specific */
#define SHT_HIUSER 0x8fffffff /* End of application-specific */
typedef struct
{
u8 sh_name[4]; /* Section name (string tbl index) */
u8 sh_type[4]; /* Section type */
u8 sh_flags[4]; /* Section flags */
u8 sh_addr[4]; /* Section virtual addr at execution */
u8 sh_offset[4]; /* Section file offset */
u8 sh_size[4]; /* Section size in bytes */
u8 sh_link[4]; /* Link to another section */
u8 sh_info[4]; /* Additional section information */
u8 sh_addralign[4]; /* Section alignment */
u8 sh_entsize[4]; /* Entry size if section holds table */
} elf_32_shdr;
typedef struct
{
u8 sh_name[8]; /* Section name (string tbl index) */
u8 sh_type[8]; /* Section type */
u8 sh_flags[8]; /* Section flags */
u8 sh_addr[8]; /* Section virtual addr at execution */
u8 sh_offset[8]; /* Section file offset */
u8 sh_size[8]; /* Section size in bytes */
u8 sh_link[8]; /* Link to another section */
u8 sh_info[8]; /* Additional section information */
u8 sh_addralign[8]; /* Section alignment */
u8 sh_entsize[8]; /* Entry size if section holds table */
} elf_64_shdr;
/* Program segment header. */
/* p_type legal values */
#define PT_NULL 0 /* Program header table entry unused */
#define PT_LOAD 1 /* Loadable program segment */
#define PT_DYNAMIC 2 /* Dynamic linking information */
#define PT_INTERP 3 /* Program interpreter */
#define PT_NOTE 4 /* Auxiliary information */
#define PT_SHLIB 5 /* Reserved */
#define PT_PHDR 6 /* Entry for header table itself */
#define PT_NUM 7 /* Number of defined types. */
#define PT_LOOS 0x60000000 /* Start of OS-specific */
#define PT_HIOS 0x6fffffff /* End of OS-specific */
#define PT_LOPROC 0x70000000 /* Start of processor-specific */
#define PT_HIPROC 0x7fffffff /* End of processor-specific */
typedef struct
{
u8 p_type[4]; /* Segment type */
u8 p_offset[4]; /* Segment file offset */
u8 p_vaddr[4]; /* Segment virtual address */
u8 p_paddr[4]; /* Segment physical address */
u8 p_filesz[4]; /* Segment size in file */
u8 p_memsz[4]; /* Segment size in memory */
u8 p_flags[4]; /* Segment flags */
u8 p_align[4]; /* Segment alignment */
} elf_32_phdr;
typedef struct
{
u8 p_type[8]; /* Segment type */
u8 p_flags[8]; /* Segment flags */
u8 p_offset[8]; /* Segment file offset */
u8 p_vaddr[8]; /* Segment virtual address */
u8 p_paddr[8]; /* Segment physical address */
u8 p_filesz[8]; /* Segment size in file */
u8 p_memsz[8]; /* Segment size in memory */
u8 p_align[8]; /* Segment alignment */
} elf_64_phdr;
#endif
+179
View File
@@ -0,0 +1,179 @@
#include "lib.h"
#include "ncch.h"
#include "exefs.h"
// Private Prototypes
u32 PredictExeFS_Size(ExeFs_BuildContext *ctx);
int GenerateExeFS_Header(ExeFs_BuildContext *ctx, u8 *outbuff);
void InitialiseExeFSContext(ExeFs_BuildContext *ctx);
void FreeExeFSContext(ExeFs_BuildContext *ctx);
int ImportDatatoExeFS(ExeFs_BuildContext *ctx, u8 *outbuff);
int ImportToExeFSContext(ExeFs_BuildContext *ctx, char *lable, u8 *buffer, u32 size);
// ExeFs Build Functions
int BuildExeFs(ncch_settings *ncchset)
{
/* Intialising ExeFs Build Context */
ExeFs_BuildContext *ctx = malloc(sizeof(ExeFs_BuildContext));
if(!ctx) {fprintf(stderr,"[EXEFS ERROR] MEM ERROR\n"); return MEM_ERROR;}
InitialiseExeFSContext(ctx);
ctx->media_unit = ncchset->Options.MediaSize;
/* Importing ExeFs */
if(ncchset->ExeFs_Sections.Code.size)
ImportToExeFSContext(ctx,".code",ncchset->ExeFs_Sections.Code.buffer,ncchset->ExeFs_Sections.Code.size);
if(ncchset->ExeFs_Sections.Banner.size)
ImportToExeFSContext(ctx,"banner",ncchset->ExeFs_Sections.Banner.buffer,ncchset->ExeFs_Sections.Banner.size);
if(ncchset->ExeFs_Sections.Icon.size)
ImportToExeFSContext(ctx,"icon",ncchset->ExeFs_Sections.Icon.buffer,ncchset->ExeFs_Sections.Icon.size);
if(ncchset->Sections.Logo.size && ncchset->Options.IncludeExeFsLogo)
ImportToExeFSContext(ctx,"logo",ncchset->Sections.Logo.buffer,ncchset->Sections.Logo.size);
/* Allocating Memory for ExeFs */
ncchset->Sections.ExeFs.size = PredictExeFS_Size(ctx);
ncchset->Sections.ExeFs.buffer = malloc(ncchset->Sections.ExeFs.size);
if(!ncchset->Sections.ExeFs.buffer){
printf("[EXEFS ERROR] Could Not Allocate Memory for ExeFS\n");
return Fail;
}
memset(ncchset->Sections.ExeFs.buffer,0,ncchset->Sections.ExeFs.size);
/* Generating Header, and writing sections to buffer */
GenerateExeFS_Header(ctx,ncchset->Sections.ExeFs.buffer);
ImportDatatoExeFS(ctx,ncchset->Sections.ExeFs.buffer);
/* Finish */
FreeExeFSContext(ctx);
return 0;
}
u32 PredictExeFS_Size(ExeFs_BuildContext *ctx)
{
u32 exefs_size = 0x200; // Size of header
for(int i = 0; i < ctx->section_count; i++){
exefs_size += align_value(ctx->section_size[i],ctx->media_unit);
}
//exefs_size = align_value(ctx->exefs_size,ctx->media_unit);
return exefs_size;
}
int GenerateExeFS_Header(ExeFs_BuildContext *ctx, u8 *outbuff)
{
for(int i = 0; i < ctx->section_count; i++){
if(i == 0)
ctx->section_offset[i] = 0;
else
ctx->section_offset[i] = align_value((ctx->section_offset[i-1]+ctx->section_size[i-1]),ctx->media_unit);
memcpy(ctx->file_header[i].name,ctx->lable[i],8);
u32_to_u8(ctx->file_header[i].offset,ctx->section_offset[i],LE);
u32_to_u8(ctx->file_header[i].size,ctx->section_size[i],LE);
ctr_sha(ctx->section[i],ctx->section_size[i],ctx->file_hashes[9-i],CTR_SHA_256);
}
memcpy(outbuff,ctx->file_header,sizeof(ExeFs_FileHeader)*10);
memcpy(outbuff+0xc0,ctx->file_hashes,0x20*10);
return 0;
}
void InitialiseExeFSContext(ExeFs_BuildContext *ctx)
{
memset(ctx,0,sizeof(ExeFs_BuildContext));
}
void FreeExeFSContext(ExeFs_BuildContext *ctx)
{
/*
if(ctx->outbuff != NULL)
free(ctx->outbuff);
for(int i = 0; i < 10; i++){
if(ctx->section[i] != NULL)
free(ctx->section[i]);
}
*/
memset(ctx,0,sizeof(ExeFs_BuildContext));
free(ctx);
}
int ImportDatatoExeFS(ExeFs_BuildContext *ctx, u8 *outbuff)
{
for(int i = 0; i < ctx->section_count; i++){
memcpy(outbuff+ctx->section_offset[i]+0x200,ctx->section[i],ctx->section_size[i]);
}
return 0;
}
int ImportToExeFSContext(ExeFs_BuildContext *ctx, char *lable, u8 *buffer, u32 size)
{
if(ctx == NULL || lable == NULL || buffer == NULL){
printf("[!] PTR ERROR\n");
return PTR_ERROR;
}
if(ctx->section_count >= 10){
printf("[!] Maximum ExeFS Capacity Reached\n");
return EXEFS_MAX_REACHED;
}
if(strlen(lable) > 8){
printf("[!] ExeFS Section Name: '%s' is too large\n",lable);
return EXEFS_SECTION_NAME_ERROR;
}
ctx->section_count++;
ctx->section[ctx->section_count - 1] = buffer;
ctx->section_size[ctx->section_count - 1] = size;
strcpy(ctx->lable[ctx->section_count - 1],lable);
return 0;
}
// ExeFs Read Functions
bool DoesExeFsSectionExist(char *section, u8 *ExeFs)
{
ExeFs_Header *hdr = (ExeFs_Header*) ExeFs;
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
if(strncmp(hdr->SectionHdr[i].name,section,8) == 0) return true;
}
return false;
}
u8* GetExeFsSection(char *section, u8 *ExeFs)
{
ExeFs_Header *hdr = (ExeFs_Header*) ExeFs;
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
if(strncmp(hdr->SectionHdr[i].name,section,8) == 0){
u32 offset = u8_to_u32(hdr->SectionHdr[i].offset,LE) + sizeof(ExeFs_Header);
return (u8*)(ExeFs+offset);
}
}
return NULL;
}
u8* GetExeFsSectionHash(char *section, u8 *ExeFs)
{
ExeFs_Header *hdr = (ExeFs_Header*) ExeFs;
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
if(strncmp(hdr->SectionHdr[i].name,section,8) == 0){
return (u8*)(hdr->SectionHashes[MAX_EXEFS_SECTIONS-1-i]);
}
}
return NULL;
}
u32 GetExeFsSectionSize(char *section, u8 *ExeFs)
{
ExeFs_Header *hdr = (ExeFs_Header*) ExeFs;
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
if(strncmp(hdr->SectionHdr[i].name,section,8) == 0){
return u8_to_u32(hdr->SectionHdr[i].size,LE);
}
}
return 0;
}
u32 GetExeFsSectionOffset(char *section, u8 *ExeFs)
{
ExeFs_Header *hdr = (ExeFs_Header*) ExeFs;
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
if(strncmp(hdr->SectionHdr[i].name,section,8) == 0){
return u8_to_u32(hdr->SectionHdr[i].offset,LE) + sizeof(ExeFs_Header);
}
}
return 0;
}
+54
View File
@@ -0,0 +1,54 @@
#ifndef _EXEFS_H_
#define _EXEFS_H_
#define MAX_EXEFS_SECTIONS 10 // DO NOT CHANGE
typedef enum
{
PTR_ERROR = -10,
EXEFS_MAX_REACHED = -11,
EXEFS_SECTION_NAME_ERROR = -12,
} exefs_errors;
typedef struct
{
char name[8];
u8 offset[4];
u8 size[4];
} ExeFs_FileHeader;
typedef struct
{
//Input
int section_count;
u8 *section[10];
u32 section_size[10];
u32 section_offset[10];
char lable[10][8];
u32 media_unit;
//Working Data
ExeFs_FileHeader file_header[10];
u8 file_hashes[10][0x20];
} ExeFs_BuildContext;
typedef struct
{
ExeFs_FileHeader SectionHdr[MAX_EXEFS_SECTIONS];
u8 Reserved[0x20];
u8 SectionHashes[MAX_EXEFS_SECTIONS][0x20];
} ExeFs_Header;
#endif
/* ExeFs Build Functions */
int BuildExeFs(ncch_settings *ncchset);
/* ExeFs Read Functions */
bool DoesExeFsSectionExist(char *section, u8 *ExeFs);
u8* GetExeFsSection(char *section, u8 *ExeFs);
u8* GetExeFsSectionHash(char *section, u8 *ExeFs);
u32 GetExeFsSectionSize(char *section, u8 *ExeFs);
u32 GetExeFsSectionOffset(char *section, u8 *ExeFs);
+488
View File
@@ -0,0 +1,488 @@
#include "lib.h"
#include "ncch.h"
#include "exheader.h"
#include "titleid.h"
#include "polarssl\base64.h"
#ifndef RETAIL_FSIGN
#include "accessdesc_sig.h" // For AccessDesc Presets
#endif
/* Prototypes */
void init_ExHeaderSettings(exheader_settings *exhdrset);
void free_ExHeaderSettings(exheader_settings *exhdrset);
int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings *ncchset);
int get_ExHeaderSettingsFromYaml(exheader_settings *exhdrset);
void AdjustBooleans(desc_settings *yaml);
int get_ExHeaderCodeSetInfo(exhdr_CodeSetInfo *CodeSetInfo, desc_settings *yaml);
int get_ExHeaderDependencyList(u8 *DependencyList, desc_settings *yaml);
int get_ExHeaderSystemInfo(exhdr_SystemInfo *SystemInfo, desc_settings *yaml);
int get_ExHeaderARM11SystemLocalInfo(exhdr_ARM11SystemLocalCapabilities *arm11, desc_settings *yaml);
int get_ExHeaderARM11KernelInfo(exhdr_ARM11KernelCapabilities *arm11, desc_settings *yaml);
int get_ExHeaderARM9AccessControlInfo(exhdr_ARM9AccessControlInfo *arm9, desc_settings *yaml);
int set_AccessDesc(exheader_settings *exhdrset, ncch_settings *ncchset);
/* ExHeader Signature Functions */
int SignAccessDesc(ExtendedHeader_Struct *ExHdr, keys_struct *keys)
{
u8 *AccessDesc = (u8*) &ExHdr->AccessDescriptor.ncchpubkeymodulus;
u8 *Signature = (u8*) &ExHdr->AccessDescriptor.signature;
return ctr_sig(AccessDesc,0x300,Signature,keys->rsa.AccessDesc_Pub,keys->rsa.AccessDesc_Priv,RSA_2048_SHA256,CTR_RSA_SIGN);
}
int CheckAccessDescSignature(ExtendedHeader_Struct *ExHdr, keys_struct *keys)
{
u8 *AccessDesc = (u8*) &ExHdr->AccessDescriptor.ncchpubkeymodulus;
u8 *Signature = (u8*) &ExHdr->AccessDescriptor.signature;
return ctr_sig(AccessDesc,0x300,Signature,keys->rsa.AccessDesc_Pub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
}
/* ExHeader Build Functions */
int BuildExHeader(ncch_settings *ncchset)
{
int result = 0;
exheader_settings *exhdrset = malloc(sizeof(exheader_settings));
if(!exhdrset) {fprintf(stderr,"[EXHEADER ERROR] MEM ERROR\n"); return MEM_ERROR;}
init_ExHeaderSettings(exhdrset);
// Get Settings
result = get_ExHeaderSettingsFromNcchset(exhdrset,ncchset);
if(result) goto finish;
result = get_ExHeaderSettingsFromYaml(exhdrset);
if(result) goto finish;
result = set_AccessDesc(exhdrset,ncchset);
if(result) goto finish;
memcpy(&exhdrset->ExHdr->ARM11SystemLocalCapabilities.Flags,&exhdrset->ExHdr->AccessDescriptor.ARM11SystemLocalCapabilities.Flags,0x1f8);
finish:
if(result) fprintf(stderr,"[EXHEADER ERROR] Failed to create ExHeader\n");
free_ExHeaderSettings(exhdrset);
return result;
}
void init_ExHeaderSettings(exheader_settings *exhdrset)
{
memset(exhdrset,0,sizeof(exheader_settings));
}
void free_ExHeaderSettings(exheader_settings *exhdrset)
{
free(exhdrset);
}
int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings *ncchset)
{
/* Transfer settings */
exhdrset->keys = ncchset->keys;
exhdrset->yaml = ncchset->yaml_set;
/* Creating Output Buffer */
ncchset->Sections.ExHeader.size = 0x800;
ncchset->Sections.ExHeader.buffer = malloc(ncchset->Sections.ExHeader.size);
if(!ncchset->Sections.ExHeader.buffer) {fprintf(stderr,"[EXHEADER ERROR] MEM ERROR\n"); return MEM_ERROR;}
memset(ncchset->Sections.ExHeader.buffer,0,ncchset->Sections.ExHeader.size);
/* Import ExHeader template */
if(ncchset->ComponentFilePtrs.exheader_size){
u32 import_size = min_u64(0x400,ncchset->ComponentFilePtrs.exheader_size);
ReadFile_64(ncchset->Sections.ExHeader.buffer,import_size,0,ncchset->ComponentFilePtrs.exheader);
}
/* Create ExHeader Struct for output */
exhdrset->ExHdr = (ExtendedHeader_Struct*)ncchset->Sections.ExHeader.buffer;
/* Set Code Info if Code Section was built not imported */
if(ncchset->Options.IsBuildingCodeSection){
/* BSS Size */
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.BssSize,ncchset->CodeDetails.BSS_Size,LE);
/* Data */
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.DataSectionInfo.Address,ncchset->CodeDetails.DataAddress,LE);
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.DataSectionInfo.CodeSize,ncchset->CodeDetails.DataSize,LE);
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.DataSectionInfo.NumMaxPages,ncchset->CodeDetails.DataMaxPages,LE);
/* RO */
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.ReadOnlySectionInfo.Address,ncchset->CodeDetails.ROAddress,LE);
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.ReadOnlySectionInfo.CodeSize,ncchset->CodeDetails.ROSize,LE);
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.ReadOnlySectionInfo.NumMaxPages,ncchset->CodeDetails.ROMaxPages,LE);
/* Text */
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.TextSectionInfo.Address,ncchset->CodeDetails.TextAddress,LE);
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.TextSectionInfo.CodeSize,ncchset->CodeDetails.TextSize,LE);
u32_to_u8(exhdrset->ExHdr->CodeSetInfo.TextSectionInfo.NumMaxPages,ncchset->CodeDetails.TextMaxPages,LE);
}
/* Set Simple Flags */
if(ncchset->Options.CompressCode)
exhdrset->ExHdr->CodeSetInfo.Flags.flag |= ExeFsCodeCompress;
if(ncchset->Options.UseOnSD)
exhdrset->ExHdr->CodeSetInfo.Flags.flag |= RetailSDAppFlag;
return 0;
}
int get_ExHeaderSettingsFromYaml(exheader_settings *exhdrset)
{
AdjustBooleans(exhdrset->yaml);
int result = 0;
result = get_ExHeaderCodeSetInfo(&exhdrset->ExHdr->CodeSetInfo, exhdrset->yaml);
if(result) goto finish;
result = get_ExHeaderDependencyList((u8*)&exhdrset->ExHdr->DependencyList[0], exhdrset->yaml);
if(result) goto finish;
result = get_ExHeaderSystemInfo(&exhdrset->ExHdr->SystemInfo, exhdrset->yaml);
if(result) goto finish;
result = get_ExHeaderARM11SystemLocalInfo(&exhdrset->ExHdr->ARM11SystemLocalCapabilities, exhdrset->yaml);
if(result) goto finish;
result = get_ExHeaderARM11KernelInfo(&exhdrset->ExHdr->ARM11KernelCapabilities, exhdrset->yaml);
if(result) goto finish;
result = get_ExHeaderARM9AccessControlInfo(&exhdrset->ExHdr->ARM9AccessControlInfo, exhdrset->yaml);
if(result) goto finish;
finish:
return result;
}
void AdjustBooleans(desc_settings *yaml)
{
if(yaml->DefaultSpec.AccessControlInfo.DisableDebug == -1) yaml->DefaultSpec.AccessControlInfo.DisableDebug = 0;
if(yaml->DefaultSpec.AccessControlInfo.EnableForceDebug == -1) yaml->DefaultSpec.AccessControlInfo.EnableForceDebug = 0;
if(yaml->DefaultSpec.AccessControlInfo.CanWriteSharedPage == -1) yaml->DefaultSpec.AccessControlInfo.CanWriteSharedPage = 0;
if(yaml->DefaultSpec.AccessControlInfo.CanUsePrivilegedPriority == -1) yaml->DefaultSpec.AccessControlInfo.CanUsePrivilegedPriority = 0;
if(yaml->DefaultSpec.AccessControlInfo.CanUseNonAlphabetAndNumber == -1) yaml->DefaultSpec.AccessControlInfo.CanUseNonAlphabetAndNumber = 0;
if(yaml->DefaultSpec.AccessControlInfo.PermitMainFunctionArgument == -1) yaml->DefaultSpec.AccessControlInfo.PermitMainFunctionArgument = 0;
if(yaml->DefaultSpec.AccessControlInfo.CanShareDeviceMemory == -1) yaml->DefaultSpec.AccessControlInfo.CanShareDeviceMemory = 0;
if(yaml->DefaultSpec.AccessControlInfo.UseOtherVariationSaveData == -1) yaml->DefaultSpec.AccessControlInfo.UseOtherVariationSaveData = 0;
if(yaml->DefaultSpec.AccessControlInfo.UseExtSaveData == -1) yaml->DefaultSpec.AccessControlInfo.UseExtSaveData = 0;
if(yaml->DefaultSpec.AccessControlInfo.RunnableOnSleep == -1) yaml->DefaultSpec.AccessControlInfo.RunnableOnSleep = 0;
if(yaml->DefaultSpec.AccessControlInfo.SpecialMemoryArrange == -1) yaml->DefaultSpec.AccessControlInfo.SpecialMemoryArrange = 0;
}
int get_ExHeaderCodeSetInfo(exhdr_CodeSetInfo *CodeSetInfo, desc_settings *yaml)
{
/* Name */
if(yaml->DefaultSpec.BasicInfo.Title){
if(strlen(yaml->DefaultSpec.BasicInfo.Title) > 8){
fprintf(stderr,"[EXHEADER ERROR] Parameter Too Long 'BasicInfo/Title'\n");
return EXHDR_BAD_YAML_OPT;
}
strcpy((char*)CodeSetInfo->Name,yaml->DefaultSpec.BasicInfo.Title);
}
else{
fprintf(stderr,"[EXHEADER ERROR] Parameter Not Found: 'BasicInfo/Title'\n");
}
/* Stack Size */
if(yaml->DefaultSpec.SystemControlInfo.StackSize){
u32 StackSize = strtoul(yaml->DefaultSpec.SystemControlInfo.StackSize,NULL,0);
u32_to_u8(CodeSetInfo->StackSize,StackSize,LE);
}
else{
fprintf(stderr,"[EXHEADER ERROR] Parameter Not Found: 'SystemControlInfo/StackSize'\n");
}
/* Remaster Version */
if(yaml->DefaultSpec.SystemControlInfo.RemasterVersion){
u16 RemasterVersion = strtol(yaml->DefaultSpec.SystemControlInfo.RemasterVersion,NULL,0);
u16_to_u8(CodeSetInfo->Flags.remasterVersion,RemasterVersion,LE);
}
else{
u16_to_u8(CodeSetInfo->Flags.remasterVersion,0,LE);
}
return 0;
}
int get_ExHeaderDependencyList(u8 *DependencyList, desc_settings *yaml)
{
if(yaml->DefaultSpec.SystemControlInfo.DependencyNum > 0x30){
fprintf(stderr,"[EXHEADER ERROR] Too Many Dependency IDs\n");
return EXHDR_BAD_YAML_OPT;
}
for(int i = 0; i < yaml->DefaultSpec.SystemControlInfo.DependencyNum; i++){
u8 *pos = (DependencyList + 0x8*i);
u64 TitleID = strtoull(yaml->DefaultSpec.SystemControlInfo.Dependency[i],NULL,0);
u64_to_u8(pos,TitleID,LE);
}
return 0;
}
int get_ExHeaderSystemInfo(exhdr_SystemInfo *SystemInfo, desc_settings *yaml)
{
/* SaveDataSize */
if(yaml->DefaultSpec.Rom.SaveDataSize){
u64 SaveDataSize = strtoull(yaml->DefaultSpec.Rom.SaveDataSize,NULL,10);
if(strstr(yaml->DefaultSpec.Rom.SaveDataSize,"K")){
char *str = strstr(yaml->DefaultSpec.Rom.SaveDataSize,"K");
if(strcmp(str,"K") == 0 || strcmp(str,"KB") == 0 ){
SaveDataSize = SaveDataSize*KB;
}
}
else if(strstr(yaml->DefaultSpec.Rom.SaveDataSize,"M")){
char *str = strstr(yaml->DefaultSpec.Rom.SaveDataSize,"M");
if(strcmp(str,"M") == 0 || strcmp(str,"MB") == 0 ){
SaveDataSize = SaveDataSize*MB;
}
}
else if(strstr(yaml->DefaultSpec.Rom.SaveDataSize,"G")){
char *str = strstr(yaml->DefaultSpec.Rom.SaveDataSize,"G");
if(strcmp(str,"G") == 0 || strcmp(str,"GB") == 0 ){
SaveDataSize = SaveDataSize*GB;
}
}
else{
fprintf(stderr,"[EXHEADER ERROR] Invalid save data size format.\n");
return EXHDR_BAD_YAML_OPT;
}
if((SaveDataSize & 65536) != 0){
fprintf(stderr,"[EXHEADER ERROR] Save data size must be aligned to 64K.\n");
return EXHDR_BAD_YAML_OPT;
}
u64_to_u8(SystemInfo->SaveDataSize,SaveDataSize,LE);
}
else{
u64_to_u8(SystemInfo->SaveDataSize,0,LE);
}
/* Jump Id */
if(yaml->DefaultSpec.SystemControlInfo.JumpId){
u64 JumpId = strtoull(yaml->DefaultSpec.SystemControlInfo.JumpId,NULL,0);
u64_to_u8(SystemInfo->JumpId,JumpId,LE);
}
else{
u64 JumpId = 0;
int result = GetProgramID(&JumpId,yaml,false);
if(result) return result;
u64_to_u8(SystemInfo->JumpId,JumpId,LE);
}
return 0;
}
int get_ExHeaderARM11SystemLocalInfo(exhdr_ARM11SystemLocalCapabilities *arm11, desc_settings *yaml)
{
/* Program Id */
u64 ProgramId = 0;
int result = GetProgramID(&ProgramId,yaml,true);
if(result) return result;
u64_to_u8(arm11->ProgramId,ProgramId,LE);
return 0;
/* Flags */
//u32_to_u8(
}
int get_ExHeaderARM11KernelInfo(exhdr_ARM11KernelCapabilities *arm11, desc_settings *yaml)
{
return 0;
}
int get_ExHeaderARM9AccessControlInfo(exhdr_ARM9AccessControlInfo *arm9, desc_settings *yaml)
{
return 0;
}
int set_AccessDesc(exheader_settings *exhdrset, ncch_settings *ncchset)
{
switch(ncchset->Options.accessdesc){
case auto_gen :
/* Set RSA Keys */
memcpy(ncchset->CxiRsaKey.PrivK,exhdrset->keys->rsa.CFA_Priv,0x100);
memcpy(ncchset->CxiRsaKey.PubK,exhdrset->keys->rsa.CFA_Pub,0x100);
memcpy(&exhdrset->ExHdr->AccessDescriptor.ncchpubkeymodulus,exhdrset->keys->rsa.CFA_Pub,0x100);
/* Copy Data From ExHeader */
memcpy(&exhdrset->ExHdr->AccessDescriptor.ARM11SystemLocalCapabilities,&exhdrset->ExHdr->ARM11SystemLocalCapabilities,sizeof(exhdr_ARM11SystemLocalCapabilities));
memcpy(&exhdrset->ExHdr->AccessDescriptor.ARM11KernelCapabilities,&exhdrset->ExHdr->ARM11KernelCapabilities,sizeof(exhdr_ARM11KernelCapabilities));
memcpy(&exhdrset->ExHdr->AccessDescriptor.ARM9AccessControlInfo,&exhdrset->ExHdr->ARM9AccessControlInfo,sizeof(exhdr_ARM9AccessControlInfo));
/* Sign AccessDesc */
return SignAccessDesc(exhdrset->ExHdr,exhdrset->keys);
#ifndef RETAIL_FSIGN
case app :
memcpy(ncchset->CxiRsaKey.PrivK,(u8*)App_HdrPrivK,0x100);
memcpy(ncchset->CxiRsaKey.PubK,(u8*)App_HdrPubK,0x100);
memcpy(&exhdrset->ExHdr->AccessDescriptor.signature,(u8*)App_AcexData,0x400);
return 0;
case demo :
memcpy(ncchset->CxiRsaKey.PrivK,(u8*)Demo_HdrPrivK,0x100);
memcpy(ncchset->CxiRsaKey.PubK,(u8*)Demo_HdrPubK,0x100);
memcpy(&exhdrset->ExHdr->AccessDescriptor.signature,(u8*)Demo_AcexData,0x400);
return 0;
case dlp :
memcpy(ncchset->CxiRsaKey.PrivK,(u8*)Dlp_HdrPrivK,0x100);
memcpy(ncchset->CxiRsaKey.PubK,(u8*)Dlp_HdrPubK,0x100);
memcpy(&exhdrset->ExHdr->AccessDescriptor.signature,(u8*)Dlp_AcexData,0x400);
return 0;
case use_desc_file:
/* Yaml Option Sanity Checks */
if(!exhdrset->yaml->CommonHeaderKey.Found){
fprintf(stderr,"[EXHEADER ERROR] Desc Section 'CommonHeaderKey' not found\n");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->yaml->CommonHeaderKey.D){
fprintf(stderr,"[EXHEADER ERROR] 'CommonHeaderKey/D' not found\n");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(strlen(exhdrset->yaml->CommonHeaderKey.D) != 350){
fprintf(stderr,"[EXHEADER ERROR] 'CommonHeaderKey/D' has invalid length (%d)\n",strlen(exhdrset->yaml->CommonHeaderKey.D));
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->yaml->CommonHeaderKey.Modulus){
fprintf(stderr,"[EXHEADER ERROR] 'CommonHeaderKey/Modulus' not found\n");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(strlen(exhdrset->yaml->CommonHeaderKey.Modulus) != 350){
fprintf(stderr,"[EXHEADER ERROR] 'CommonHeaderKey/Modulus' has invalid length (%d)\n",strlen(exhdrset->yaml->CommonHeaderKey.Modulus));
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->yaml->AccessControlDescriptor.AccCtlDescSign){
fprintf(stderr,"[EXHEADER ERROR] 'AccessControlDescriptor/Signature' not found\n");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(strlen(exhdrset->yaml->AccessControlDescriptor.AccCtlDescSign) != 350){
fprintf(stderr,"[EXHEADER ERROR] 'AccessControlDescriptor/Signature' has invalid length (%d)\n",strlen(exhdrset->yaml->AccessControlDescriptor.AccCtlDescSign));
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(!exhdrset->yaml->AccessControlDescriptor.AccCtlDescBin){
fprintf(stderr,"[EXHEADER ERROR] 'AccessControlDescriptor/Descriptor' not found\n");
return COMMON_HEADER_KEY_NOT_FOUND;
}
if(strlen(exhdrset->yaml->AccessControlDescriptor.AccCtlDescBin) != 696){
fprintf(stderr,"[EXHEADER ERROR] 'AccessControlDescriptor/Descriptor' has invalid length (%d)\n",strlen(exhdrset->yaml->AccessControlDescriptor.AccCtlDescBin));
return COMMON_HEADER_KEY_NOT_FOUND;
}
/* Set RSA Keys */
int result = 0;
u32 out = 0x500;
u8 *tmp = malloc(0x500);
result = base64_decode(tmp,&out,(const u8*)exhdrset->yaml->CommonHeaderKey.Modulus,strlen(exhdrset->yaml->CommonHeaderKey.Modulus));
if(result) goto finish;
memcpy(ncchset->CxiRsaKey.PubK,tmp,0x100);
out = 0x500;
result = base64_decode(tmp,&out,(const u8*)exhdrset->yaml->CommonHeaderKey.D,strlen(exhdrset->yaml->CommonHeaderKey.D));
if(result) goto finish;
memcpy(ncchset->CxiRsaKey.PrivK,tmp,0x100);
/* Set AccessDesc */
out = 0x500;
result = base64_decode(tmp,&out,(const u8*)exhdrset->yaml->AccessControlDescriptor.AccCtlDescSign,strlen(exhdrset->yaml->AccessControlDescriptor.AccCtlDescSign));
if(result) goto finish;
memcpy(exhdrset->ExHdr->AccessDescriptor.signature,tmp,0x100);
memcpy(exhdrset->ExHdr->AccessDescriptor.ncchpubkeymodulus,ncchset->CxiRsaKey.PubK,0x100);
out = 0x500;
result = base64_decode(tmp,&out,(const u8*)exhdrset->yaml->AccessControlDescriptor.AccCtlDescBin,strlen(exhdrset->yaml->AccessControlDescriptor.AccCtlDescBin));
if(result) goto finish;
memcpy(&exhdrset->ExHdr->AccessDescriptor.ARM11SystemLocalCapabilities,tmp,0x200);
finish:
free(tmp);
return result;
#endif
}
return 0;
}
/* ExHeader Binary Print Functions */
void exhdr_Print_ServiceAccessControl(ExtendedHeader_Struct *hdr)
{
printf("[+] Service Access Control\n");
for(int i = 0; i < 32; i ++){
char *SVC_Handle = (char*)hdr->ARM11SystemLocalCapabilities.ServiceAccessControl[i];
if(SVC_Handle[0] == 0) break;
printf("%.8s\n",hdr->ARM11SystemLocalCapabilities.ServiceAccessControl[i]);
}
}
/* ExHeader Binary Read Functions */
u8* GetAccessDescSig_frm_exhdr(ExtendedHeader_Struct *hdr)
{
if(!hdr) return NULL;
return hdr->AccessDescriptor.signature ;
}
u8* GetNcchHdrPubKey_frm_exhdr(ExtendedHeader_Struct *hdr)
{
if(!hdr) return NULL;
return hdr->AccessDescriptor.ncchpubkeymodulus;
}
u8* GetAccessDesc_frm_exhdr(ExtendedHeader_Struct *hdr)
{
if(!hdr) return NULL;
return hdr->AccessDescriptor.ncchpubkeymodulus;
}
u16 GetRemasterVersion_frm_exhdr(ExtendedHeader_Struct *hdr)
{
return u8_to_u16(hdr->CodeSetInfo.Flags.remasterVersion,LE);
}
u64 GetSaveDataSize_frm_exhdr(ExtendedHeader_Struct *hdr)
{
return u8_to_u64(hdr->SystemInfo.SaveDataSize,LE);
}
int GetCoreVersion_frm_exhdr(u8 *Dest, ExtendedHeader_Struct *hdr)
{
return (int) memcpy(Dest,hdr->ARM11SystemLocalCapabilities.Flags,4);
}
int GetDependancyList_frm_exhdr(u8 *Dest,ExtendedHeader_Struct *hdr)
{
if(!Dest) return -1;
for(int i = 0; i < 0x30; i++){
memcpy(Dest,hdr->DependencyList,0x30*8);
}
return 0;
}
/* ExHeader Settings Read from Yaml */
int GetSaveDataSize_yaml(u64 *SaveDataSize, user_settings *usrset)
{
if(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize){
*SaveDataSize = strtoull(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize,NULL,10);
if(strstr(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize,"K")){
char *str = strstr(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize,"K");
if(strcmp(str,"K") == 0 || strcmp(str,"KB") == 0 ){
*SaveDataSize = *SaveDataSize*KB;
}
}
else if(strstr(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize,"M")){
char *str = strstr(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize,"M");
if(strcmp(str,"M") == 0 || strcmp(str,"MB") == 0 ){
*SaveDataSize = *SaveDataSize*MB;
}
}
else if(strstr(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize,"G")){
char *str = strstr(usrset->yaml_set.DefaultSpec.Rom.SaveDataSize,"G");
if(strcmp(str,"G") == 0 || strcmp(str,"GB") == 0 ){
*SaveDataSize = *SaveDataSize*GB;
}
}
else{
fprintf(stderr,"[EXHEADER ERROR] Invalid save data size format.\n");
return EXHDR_BAD_YAML_OPT;
}
if((*SaveDataSize & 65536) != 0){
fprintf(stderr,"[EXHEADER ERROR] Save data size must be aligned to 64K.\n");
return EXHDR_BAD_YAML_OPT;
}
}
else{
*SaveDataSize = 0;
}
return 0;
}
int GetRemasterVersion_yaml(u16 *RemasterVersion, user_settings *usrset)
{
char *Str = usrset->yaml_set.DefaultSpec.SystemControlInfo.RemasterVersion;
if(!Str){
*RemasterVersion = 0;
return 0;
}
*RemasterVersion = strtol(Str,NULL,0);
return 0;
}
+188
View File
@@ -0,0 +1,188 @@
#ifndef _EXHEADER_H_
#define _EXHEADER_H_
typedef enum
{
COMMON_HEADER_KEY_NOT_FOUND = -10,
EXHDR_BAD_YAML_OPT = -11,
} exheader_errors;
typedef enum
{
ExeFsCodeCompress = 1,
RetailSDAppFlag = 2,
} SystemInfoFlags_Flagbitmask;
typedef enum
{
APPLICATION = 1,
SYSTEM = 2,
BASE = 3
} MemoryTypeName;
typedef enum
{
PERMIT_DEBUG = 1,
FORCE_DEBUG = 2,
CAN_USE_NON_ALPHABET_AND_NUMBER = 4,
CAN_WRITE_SHARED_PAGE = 8,
CAN_USE_PRIVILEGE_PRIORITY = 16,
PERMIT_MAIN_FUNCTION_ARGUMENT = 32,
CAN_SHARE_DEVICE_MEMORY = 64,
RUNNABLE_ON_SLEEP = 128,
SPECIAL_MEMORY_ARRANGE = 4096
} OtherCapabilities_Flagbitmask;
typedef struct
{
u8 reserved[5];
u8 flag;
u8 remasterVersion[2]; // le u16
} exhdr_SystemInfoFlags;
typedef struct
{
u8 Address[4]; // le u32
u8 NumMaxPages[4]; // le u32
u8 CodeSize[4]; // le u32
} exhdr_CodeSegmentInfo;
typedef struct
{
u8 Name[8];
exhdr_SystemInfoFlags Flags;
exhdr_CodeSegmentInfo TextSectionInfo;
u8 StackSize[4]; // le u32
exhdr_CodeSegmentInfo ReadOnlySectionInfo;
u8 Reserved[4];
exhdr_CodeSegmentInfo DataSectionInfo;
u8 BssSize[4]; // le u32
} exhdr_CodeSetInfo;
typedef struct
{
u8 SaveDataSize[8];
u8 JumpId[8];
u8 Reserved[0x30];
} exhdr_SystemInfo;
typedef struct
{
u8 extsavedataid[8];
u8 systemsavedataid[8];
u8 reserved[8];
u8 accessinfo[7];
u8 otherattributes;
} exhdr_StorageInfo;
typedef struct
{
u8 ProgramId[8];
u8 Flags[8];
u8 MaxCpu;
u8 Reserved0;
u8 ResourceLimitDescriptor[15][2];
exhdr_StorageInfo StorageInfo;
u8 ServiceAccessControl[32][8]; // Those char[8] svc handles
u8 Reserved1[0x1f];
u8 ResourceLimitCategory;
} exhdr_ARM11SystemLocalCapabilities;
typedef struct
{
u8 descriptors[28][4];// Descripters are a collection of u32s, with bitmask idents so they can be identified, no matter the pos
/*
struct
{
u32 data[8];
} SystemCallAccessControl;
struct
{
u32 data[8];
} InterruptNumberList;
struct
{
} AddressMapping;
struct
{
u32 Data; // le u32 : Flags
} OtherCapabilities;
struct
{
u32 Data;
} HandleTableSize;
struct
{
u32 Data;
} ReleaseKernelVersion;
*/
u8 reserved[0x10];
} exhdr_ARM11KernelCapabilities;
typedef struct
{
u8 descriptors[15];
u8 descversion;
} exhdr_ARM9AccessControlInfo;
typedef struct
{
// systemcontrol info {
// coreinfo {
exhdr_CodeSetInfo CodeSetInfo;
u8 DependencyList[0x30][8];
// }
exhdr_SystemInfo SystemInfo;
// }
// accesscontrolinfo {
exhdr_ARM11SystemLocalCapabilities ARM11SystemLocalCapabilities;
exhdr_ARM11KernelCapabilities ARM11KernelCapabilities;
exhdr_ARM9AccessControlInfo ARM9AccessControlInfo;
// }
struct {
u8 signature[0x100];
u8 ncchpubkeymodulus[0x100];
exhdr_ARM11SystemLocalCapabilities ARM11SystemLocalCapabilities;
exhdr_ARM11KernelCapabilities ARM11KernelCapabilities;
exhdr_ARM9AccessControlInfo ARM9AccessControlInfo;
} AccessDescriptor;
} ExtendedHeader_Struct;
typedef struct
{
keys_struct *keys;
desc_settings *yaml;
/* Output */
ExtendedHeader_Struct *ExHdr; // is the exheader output buffer ptr(in ncchset) cast as exheader struct ptr;
} exheader_settings;
#endif
/* ExHeader Signature Functions */
int SignAccessDesc(ExtendedHeader_Struct *ExHdr, keys_struct *keys);
int CheckAccessDescSignature(ExtendedHeader_Struct *ExHdr, keys_struct *keys);
/* ExHeader Build Functions */
int BuildExHeader(ncch_settings *ncchset);
/* ExHeader Binary Print Functions */
void exhdr_Print_ServiceAccessControl(ExtendedHeader_Struct *hdr);
/* ExHeader Binary Read Functions */
u8* GetAccessDescSig_frm_exhdr(ExtendedHeader_Struct *hdr);
u8* GetNcchHdrPubKey_frm_exhdr(ExtendedHeader_Struct *hdr);
u8* GetAccessDesc_frm_exhdr(ExtendedHeader_Struct *hdr);
u16 GetRemasterVersion_frm_exhdr(ExtendedHeader_Struct *hdr);
u64 GetSaveDataSize_frm_exhdr(ExtendedHeader_Struct *hdr);
int GetDependancyList_frm_exhdr(u8 *Dest,ExtendedHeader_Struct *hdr);
int GetCoreVersion_frm_exhdr(u8 *Dest, ExtendedHeader_Struct *hdr);
/* ExHeader Settings Read from Yaml */
int GetSaveDataSize_yaml(u64 *SaveDataSize, user_settings *usrset);
int GetRemasterVersion_yaml(u16 *RemasterVersion, user_settings *usrset);
+884
View File
@@ -0,0 +1,884 @@
#ifndef _KEYS_DEBUG_H_
#define _KEYS_DEBUG_H_
// AES KEYS
static const unsigned char zeros_fixed_aesKey[16] = //zeros_fixed_aesKey
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char system_fixed_aesKey[16] = //system_fixed_aesKey
{
0x52, 0x7C, 0xE6, 0x30, 0xA9, 0xCA, 0x30, 0x5F,
0x36, 0x96, 0xF3, 0xCD, 0xE9, 0x54, 0x19, 0x4B
};
static const unsigned char ctr_aes_common_key_dev0[16] = //ctr_aes_common_key_dev0
{
0x55, 0xA3, 0xF8, 0x72, 0xBD, 0xC8, 0x0C, 0x55,
0x5A, 0x65, 0x43, 0x81, 0x13, 0x9E, 0x15, 0x3B
};
static const unsigned char ctr_aes_common_key_dev1[16] = //ctr_aes_common_key_dev1
{
0x44, 0x34, 0xED, 0x14, 0x82, 0x0C, 0xA1, 0xEB,
0xAB, 0x82, 0xC1, 0x6E, 0x7B, 0xEF, 0x0C, 0x25
};
static const unsigned char common_dpki_aesKey[16] = //common_dpki_aesKey
{
0xA1, 0x60, 0x4A, 0x6A, 0x71, 0x23, 0xB5, 0x29,
0xAE, 0x8B, 0xEC, 0x32, 0xC8, 0x16, 0xFC, 0xAA
};
//ECC Keys
static const unsigned char xs_dpki_eccPubKey[60] = //xs_dpki_eccPubKey
{
0x01, 0xD5, 0xA2, 0x3C, 0xE8, 0xE9, 0xDF, 0x8C,
0x0A, 0xA5, 0xAA, 0xE1, 0x76, 0xE1, 0x24, 0x7C,
0x90, 0x97, 0xA6, 0xFE, 0x2A, 0xD3, 0x8C, 0xB4,
0xDE, 0x74, 0x32, 0xDE, 0x5B, 0x84, 0x01, 0xAC,
0xB2, 0x13, 0x71, 0x9D, 0x4B, 0x9C, 0xEB, 0xD4,
0x13, 0xC2, 0x27, 0x66, 0xC5, 0x5F, 0x83, 0x97,
0xC4, 0x83, 0xA3, 0x9E, 0x3B, 0xFC, 0xE8, 0xA9,
0xB5, 0x10, 0x3A, 0x7B
};
//RSA Keys
static const unsigned char cert_root_rsa_pubk[0x200] =
{
0xD0, 0x1F, 0xE1, 0x00, 0xD4, 0x35, 0x56, 0xB2,
0x4B, 0x56, 0xDA, 0xE9, 0x71, 0xB5, 0xA5, 0xD3,
0x84, 0xB9, 0x30, 0x03, 0xBE, 0x1B, 0xBF, 0x28,
0xA2, 0x30, 0x5B, 0x06, 0x06, 0x45, 0x46, 0x7D,
0x5B, 0x02, 0x51, 0xD2, 0x56, 0x1A, 0x27, 0x4F,
0x9E, 0x9F, 0x9C, 0xEC, 0x64, 0x61, 0x50, 0xAB,
0x3D, 0x2A, 0xE3, 0x36, 0x68, 0x66, 0xAC, 0xA4,
0xBA, 0xE8, 0x1A, 0xE3, 0xD7, 0x9A, 0xA6, 0xB0,
0x4A, 0x8B, 0xCB, 0xA7, 0xE6, 0xFB, 0x64, 0x89,
0x45, 0xEB, 0xDF, 0xDB, 0x85, 0xBA, 0x09, 0x1F,
0xD7, 0xD1, 0x14, 0xB5, 0xA3, 0xA7, 0x80, 0xE3,
0xA2, 0x2E, 0x6E, 0xCD, 0x87, 0xB5, 0xA4, 0xC6,
0xF9, 0x10, 0xE4, 0x03, 0x22, 0x08, 0x81, 0x4B,
0x0C, 0xEE, 0xA1, 0xA1, 0x7D, 0xF7, 0x39, 0x69,
0x5F, 0x61, 0x7E, 0xF6, 0x35, 0x28, 0xDB, 0x94,
0x96, 0x37, 0xA0, 0x56, 0x03, 0x7F, 0x7B, 0x32,
0x41, 0x38, 0x95, 0xC0, 0xA8, 0xF1, 0x98, 0x2E,
0x15, 0x65, 0xE3, 0x8E, 0xED, 0xC2, 0x2E, 0x59,
0x0E, 0xE2, 0x67, 0x7B, 0x86, 0x09, 0xF4, 0x8C,
0x2E, 0x30, 0x3F, 0xBC, 0x40, 0x5C, 0xAC, 0x18,
0x04, 0x2F, 0x82, 0x20, 0x84, 0xE4, 0x93, 0x68,
0x03, 0xDA, 0x7F, 0x41, 0x34, 0x92, 0x48, 0x56,
0x2B, 0x8E, 0xE1, 0x2F, 0x78, 0xF8, 0x03, 0x24,
0x63, 0x30, 0xBC, 0x7B, 0xE7, 0xEE, 0x72, 0x4A,
0xF4, 0x58, 0xA4, 0x72, 0xE7, 0xAB, 0x46, 0xA1,
0xA7, 0xC1, 0x0C, 0x2F, 0x18, 0xFA, 0x07, 0xC3,
0xDD, 0xD8, 0x98, 0x06, 0xA1, 0x1C, 0x9C, 0xC1,
0x30, 0xB2, 0x47, 0xA3, 0x3C, 0x8D, 0x47, 0xDE,
0x67, 0xF2, 0x9E, 0x55, 0x77, 0xB1, 0x1C, 0x43,
0x49, 0x3D, 0x5B, 0xBA, 0x76, 0x34, 0xA7, 0xE4,
0xE7, 0x15, 0x31, 0xB7, 0xDF, 0x59, 0x81, 0xFE,
0x24, 0xA1, 0x14, 0x55, 0x4C, 0xBD, 0x8F, 0x00,
0x5C, 0xE1, 0xDB, 0x35, 0x08, 0x5C, 0xCF, 0xC7,
0x78, 0x06, 0xB6, 0xDE, 0x25, 0x40, 0x68, 0xA2,
0x6C, 0xB5, 0x49, 0x2D, 0x45, 0x80, 0x43, 0x8F,
0xE1, 0xE5, 0xA9, 0xED, 0x75, 0xC5, 0xED, 0x45,
0x1D, 0xCE, 0x78, 0x94, 0x39, 0xCC, 0xC3, 0xBA,
0x28, 0xA2, 0x31, 0x2A, 0x1B, 0x87, 0x19, 0xEF,
0x0F, 0x73, 0xB7, 0x13, 0x95, 0x0C, 0x02, 0x59,
0x1A, 0x74, 0x62, 0xA6, 0x07, 0xF3, 0x7C, 0x0A,
0xA7, 0xA1, 0x8F, 0xA9, 0x43, 0xA3, 0x6D, 0x75,
0x2A, 0x5F, 0x41, 0x92, 0xF0, 0x13, 0x61, 0x00,
0xAA, 0x9C, 0xB4, 0x1B, 0xBE, 0x14, 0xBE, 0xB1,
0xF9, 0xFC, 0x69, 0x2F, 0xDF, 0xA0, 0x94, 0x46,
0xDE, 0x5A, 0x9D, 0xDE, 0x2C, 0xA5, 0xF6, 0x8C,
0x1C, 0x0C, 0x21, 0x42, 0x92, 0x87, 0xCB, 0x2D,
0xAA, 0xA3, 0xD2, 0x63, 0x75, 0x2F, 0x73, 0xE0,
0x9F, 0xAF, 0x44, 0x79, 0xD2, 0x81, 0x74, 0x29,
0xF6, 0x98, 0x00, 0xAF, 0xDE, 0x6B, 0x59, 0x2D,
0xC1, 0x98, 0x82, 0xBD, 0xF5, 0x81, 0xCC, 0xAB,
0xF2, 0xCB, 0x91, 0x02, 0x9E, 0xF3, 0x5C, 0x4C,
0xFD, 0xBB, 0xFF, 0x49, 0xC1, 0xFA, 0x1B, 0x2F,
0xE3, 0x1D, 0xE7, 0xA5, 0x60, 0xEC, 0xB4, 0x7E,
0xBC, 0xFE, 0x32, 0x42, 0x5B, 0x95, 0x6F, 0x81,
0xB6, 0x99, 0x17, 0x48, 0x7E, 0x3B, 0x78, 0x91,
0x51, 0xDB, 0x2E, 0x78, 0xB1, 0xFD, 0x2E, 0xBE,
0x7E, 0x62, 0x6B, 0x3E, 0xA1, 0x65, 0xB4, 0xFB,
0x00, 0xCC, 0xB7, 0x51, 0xAF, 0x50, 0x73, 0x29,
0xC4, 0xA3, 0x93, 0x9E, 0xA6, 0xDD, 0x9C, 0x50,
0xA0, 0xE7, 0x38, 0x6B, 0x01, 0x45, 0x79, 0x6B,
0x41, 0xAF, 0x61, 0xF7, 0x85, 0x55, 0x94, 0x4F,
0x3B, 0xC2, 0x2D, 0xC3, 0xBD, 0x0D, 0x00, 0xF8,
0x79, 0x8A, 0x42, 0xB1, 0xAA, 0xA0, 0x83, 0x20,
0x65, 0x9A, 0xC7, 0x39, 0x5A, 0xB4, 0xF3, 0x29
};
static const unsigned char cpA_dpki_rsa_privExp[256] = //cpA_dpki_rsa_privExp
{
0x28, 0xCE, 0xDC, 0x39, 0x02, 0x7F, 0x3E, 0x8E,
0xAA, 0xB7, 0x59, 0x11, 0xE0, 0x68, 0xBF, 0x80,
0xA6, 0x44, 0x77, 0xDB, 0x1B, 0xA2, 0x50, 0xA3,
0x69, 0xE5, 0x96, 0xB2, 0xC4, 0xCA, 0x7A, 0x35,
0x0D, 0xFC, 0x4A, 0xB2, 0xFB, 0xC0, 0x18, 0xA5,
0x30, 0xB4, 0x9D, 0x10, 0x44, 0xD1, 0xAD, 0x33,
0xFD, 0x15, 0xA7, 0x8D, 0x0F, 0x17, 0xD5, 0xA4,
0xF5, 0x5E, 0x7F, 0x33, 0xF6, 0x80, 0x04, 0x27,
0x6A, 0xEA, 0x9C, 0xEE, 0x68, 0x04, 0x1A, 0xA5,
0xD4, 0x35, 0xA2, 0x25, 0xA2, 0x31, 0xD9, 0xF2,
0xF0, 0xAC, 0xDE, 0x69, 0xB6, 0x64, 0x56, 0x75,
0x2E, 0x9B, 0xEA, 0xDE, 0x2A, 0xBB, 0xD6, 0x00,
0xAA, 0xE6, 0x9B, 0xC2, 0xF6, 0x9F, 0x60, 0xCD,
0x0E, 0xFA, 0xB1, 0x14, 0x4A, 0x47, 0xD6, 0x63,
0x9A, 0xCD, 0x9C, 0x93, 0xB9, 0x09, 0x42, 0xDA,
0x8F, 0xFB, 0xE5, 0x7B, 0xF1, 0x4F, 0x96, 0x33,
0xF9, 0x45, 0x5B, 0xCC, 0x84, 0xAB, 0xC2, 0xD8,
0xC4, 0x0C, 0x85, 0xFA, 0x51, 0x28, 0xB9, 0x97,
0x95, 0x23, 0x8C, 0xB3, 0x1D, 0x4E, 0xB6, 0x1C,
0xCC, 0x60, 0x41, 0xFB, 0x26, 0xC7, 0xD6, 0xCB,
0x77, 0x18, 0xF7, 0xEA, 0xCD, 0x10, 0x3C, 0x5B,
0xA3, 0xC0, 0x77, 0x4C, 0x11, 0xF3, 0x74, 0x50,
0xEE, 0x23, 0x80, 0xC4, 0x5D, 0xDD, 0x57, 0xF5,
0x7D, 0x49, 0x57, 0x4A, 0xBA, 0x62, 0xBF, 0x06,
0xD9, 0xD1, 0x7F, 0x91, 0x10, 0x89, 0x6F, 0x49,
0x09, 0xD7, 0xE9, 0xAF, 0x4C, 0x9F, 0x67, 0x9D,
0x89, 0x82, 0xE4, 0xD5, 0xC1, 0x9A, 0xDC, 0x55,
0x79, 0xE7, 0xE9, 0x2D, 0x81, 0x42, 0x14, 0x55,
0x61, 0x47, 0x9B, 0xED, 0x76, 0x92, 0x1D, 0x2F,
0xB5, 0x7C, 0x28, 0x4B, 0xFF, 0x7B, 0xC2, 0x3B,
0x36, 0x73, 0x99, 0xA6, 0x21, 0x43, 0x0E, 0xA1,
0x1F, 0x82, 0xB8, 0x91, 0x71, 0x11, 0xB2, 0xC1
};
static const unsigned char cpA_dpki_rsa_pubMod[256] = //cpA_dpki_rsa_pubMod
{
0xAA, 0x7F, 0x93, 0x80, 0x28, 0x9B, 0xE8, 0x98,
0x63, 0x10, 0x7A, 0xE1, 0x0C, 0x59, 0x2C, 0x2F,
0x7C, 0xFF, 0xBD, 0xAA, 0xDD, 0x74, 0xF4, 0xA2,
0xFB, 0xAC, 0xD7, 0x6F, 0x00, 0x93, 0x42, 0x06,
0x34, 0x71, 0x56, 0xD8, 0x40, 0x49, 0x72, 0x9F,
0x3E, 0x24, 0xFA, 0x5E, 0x19, 0xD1, 0x5B, 0x63,
0x5C, 0xD2, 0xEF, 0x09, 0xDE, 0x32, 0xEE, 0x6B,
0x6F, 0xC8, 0xFA, 0x32, 0x8E, 0x2E, 0x96, 0xB9,
0x94, 0x41, 0x04, 0x7D, 0x07, 0x62, 0x95, 0xDA,
0x0D, 0x91, 0xD8, 0x09, 0x35, 0xD0, 0xDE, 0x8E,
0x6B, 0xC6, 0xAB, 0x14, 0x27, 0x01, 0x9C, 0xFE,
0x49, 0x96, 0xFC, 0x9B, 0x54, 0x79, 0x4D, 0xEB,
0xD7, 0xC6, 0x66, 0x73, 0xA6, 0xDD, 0x3A, 0x77,
0x65, 0x47, 0x94, 0xEC, 0x1C, 0x87, 0xAA, 0x46,
0xD9, 0x78, 0xA9, 0x7D, 0xDB, 0x11, 0x22, 0x6E,
0xD4, 0x12, 0xC2, 0x78, 0x4B, 0x21, 0x83, 0x92,
0xC7, 0x10, 0xC7, 0x74, 0x19, 0xFF, 0xAA, 0xF6,
0x0B, 0x75, 0xD8, 0x23, 0xDD, 0x33, 0xC3, 0xA1,
0x5B, 0xA7, 0x2D, 0x30, 0xA5, 0xA4, 0xD8, 0xF8,
0x0F, 0xD6, 0x73, 0xFD, 0x26, 0xCB, 0x29, 0xA6,
0xEF, 0x50, 0x39, 0xE2, 0x5F, 0x59, 0x61, 0x84,
0x6B, 0xDA, 0x2E, 0xC7, 0xCB, 0xE4, 0x38, 0x4B,
0x28, 0xFB, 0x0D, 0xD5, 0x8E, 0x7C, 0xAA, 0x7D,
0x4B, 0x37, 0x3A, 0xD7, 0x81, 0xDD, 0x73, 0xE3,
0x09, 0x93, 0xBD, 0xBD, 0x7E, 0x08, 0x55, 0x4A,
0x8C, 0xA5, 0xC9, 0x84, 0x2D, 0x71, 0x01, 0xA2,
0x2A, 0x01, 0xB0, 0x15, 0xFB, 0x30, 0x78, 0xB9,
0x13, 0xF4, 0xC7, 0x3F, 0xB5, 0xA6, 0xF1, 0xA2,
0x5E, 0x22, 0xB0, 0x02, 0xB6, 0xE0, 0x09, 0x54,
0x7F, 0x0F, 0xBD, 0xF0, 0xFE, 0xA5, 0x50, 0x1D,
0x93, 0x15, 0xF9, 0x3D, 0x83, 0x0F, 0x0F, 0x0E,
0x3D, 0xE2, 0x3D, 0x96, 0xE7, 0x09, 0xD9, 0x77
};
static const unsigned char xs9_dpki_rsa_privExp[256] = //xs9_dpki_rsa_privExp
{
0x74, 0xCB, 0xCF, 0x1E, 0xD0, 0x2D, 0xD4, 0xF9,
0xE0, 0x05, 0xCE, 0x9C, 0x66, 0x3D, 0xE3, 0x62,
0x66, 0x62, 0x4E, 0xB5, 0x82, 0xE1, 0x24, 0x1B,
0x5F, 0x73, 0x2A, 0x7F, 0x1D, 0xB3, 0x6E, 0x50,
0x07, 0x83, 0xA0, 0xC0, 0xED, 0xCE, 0xB7, 0xF9,
0x3D, 0xAC, 0x61, 0xC5, 0x7B, 0x99, 0xA0, 0xBC,
0xCE, 0x42, 0x8F, 0xD3, 0xB0, 0xA5, 0xBF, 0x2A,
0x3D, 0x3E, 0x5E, 0xDC, 0x56, 0xC3, 0xA5, 0xDE,
0x35, 0xCD, 0x0A, 0x00, 0xF8, 0x17, 0x6B, 0x20,
0x79, 0xEF, 0xD8, 0x83, 0x23, 0xBF, 0x21, 0x28,
0xFF, 0x38, 0x7D, 0x80, 0x07, 0x15, 0x18, 0x6C,
0xB9, 0x20, 0xF8, 0x85, 0x77, 0xBC, 0xD9, 0x2A,
0x35, 0x1C, 0xFE, 0xE3, 0xF1, 0xE8, 0x98, 0x2E,
0xA0, 0x4A, 0x48, 0x77, 0x35, 0x03, 0xC9, 0x7A,
0xAC, 0xDA, 0xBE, 0x6D, 0x1D, 0xFB, 0xE4, 0xDE,
0xEC, 0x70, 0x65, 0xFA, 0x10, 0x65, 0xA4, 0xB8,
0x6A, 0xDF, 0x32, 0x6B, 0x8E, 0x28, 0x79, 0x25,
0x87, 0x72, 0xC0, 0x7C, 0x5B, 0x81, 0xBC, 0x81,
0x92, 0x44, 0x7D, 0xEA, 0x61, 0xBD, 0x3C, 0x48,
0xF3, 0x0E, 0x18, 0xDC, 0x8D, 0x89, 0xA0, 0x34,
0xC3, 0xAE, 0x9C, 0x57, 0x72, 0xA6, 0xD7, 0x7C,
0x79, 0xF7, 0xE9, 0x14, 0x6E, 0x15, 0xAC, 0x01,
0xFA, 0xFF, 0xC8, 0xA2, 0x2A, 0x3A, 0xAB, 0x24,
0x3C, 0x7E, 0x2E, 0xC5, 0xDA, 0x83, 0xD5, 0x9D,
0x24, 0x10, 0x83, 0x7A, 0xF4, 0xBB, 0xA3, 0x6F,
0x88, 0xCE, 0xEC, 0x24, 0x1B, 0xF4, 0x36, 0x2E,
0x96, 0xC9, 0x6D, 0x19, 0x02, 0xFE, 0xAA, 0x21,
0x3E, 0x95, 0xA7, 0xFE, 0x83, 0xC8, 0x99, 0x7F,
0xD1, 0xCB, 0x7C, 0x1F, 0x91, 0x30, 0xDB, 0xA4,
0xD3, 0xDD, 0xDA, 0x9B, 0x12, 0x4E, 0x24, 0xD1,
0xA5, 0x6F, 0x15, 0xFC, 0x2C, 0x72, 0x98, 0x2C,
0x89, 0xC5, 0x7D, 0x89, 0xDE, 0x2B, 0x4E, 0x01
};
static const unsigned char xs9_dpki_rsa_pubMod[256] = //xs9_dpki_rsa_pubMod
{
0xC0, 0x84, 0x4C, 0xEB, 0x7E, 0xB0, 0xCF, 0xF0,
0xAE, 0xB7, 0x77, 0x69, 0x85, 0x93, 0xE4, 0x99,
0x5A, 0x95, 0x4E, 0x58, 0x17, 0x38, 0xCE, 0xD6,
0x81, 0xB0, 0xBD, 0x77, 0x09, 0xE7, 0xF8, 0x9A,
0xDF, 0xAD, 0x05, 0x48, 0x83, 0xF6, 0xC3, 0xFD,
0xDF, 0x7B, 0x83, 0xE0, 0x0C, 0x26, 0x81, 0x54,
0x43, 0x29, 0xEA, 0x82, 0x6C, 0x89, 0xF0, 0xA6,
0x74, 0x42, 0x86, 0x4D, 0x32, 0x60, 0x32, 0x7D,
0xA7, 0x7A, 0x13, 0x40, 0x66, 0x59, 0xDA, 0x3E,
0x41, 0x6B, 0x27, 0x94, 0x03, 0x4F, 0xAA, 0x22,
0x9D, 0xD5, 0x54, 0x52, 0xDB, 0x27, 0x0A, 0x6A,
0xA2, 0x3D, 0x19, 0xB1, 0x66, 0x1B, 0x19, 0x7D,
0xAB, 0xC7, 0x0E, 0x88, 0x17, 0x91, 0xA1, 0x2A,
0xB4, 0x3C, 0x6C, 0xCB, 0xF5, 0xAA, 0x7C, 0x3A,
0xDD, 0x36, 0xFB, 0x35, 0x71, 0x7B, 0x20, 0x01,
0x59, 0x00, 0xD6, 0xF6, 0x90, 0x39, 0x35, 0x41,
0x31, 0xF8, 0xC1, 0xC0, 0x57, 0x3A, 0x35, 0x18,
0x58, 0x90, 0xB1, 0xAD, 0x9A, 0x0E, 0xEC, 0xE0,
0xF4, 0x7A, 0x7D, 0xA5, 0x27, 0x48, 0xC9, 0x72,
0xAB, 0x0D, 0x08, 0x7B, 0x62, 0x35, 0x40, 0x91,
0x14, 0x2B, 0xB1, 0x1D, 0x1A, 0xFA, 0xF9, 0xCD,
0x5C, 0x17, 0x13, 0x53, 0x52, 0x71, 0xCA, 0xE2,
0x2A, 0x78, 0xB1, 0x7F, 0x4A, 0xCD, 0x59, 0xD8,
0xBA, 0x1D, 0x7D, 0x70, 0x5F, 0x78, 0x1B, 0x9F,
0x9D, 0x37, 0x18, 0x8E, 0xD7, 0xCD, 0x0D, 0x49,
0x57, 0x74, 0x69, 0x88, 0x3A, 0x6B, 0x8E, 0x4E,
0x1B, 0x85, 0xDD, 0xBE, 0x39, 0x45, 0x05, 0x89,
0x56, 0x12, 0x97, 0x59, 0x9A, 0x09, 0xA4, 0xC8,
0x2D, 0x2F, 0xF5, 0xCF, 0xB4, 0x73, 0x70, 0xDB,
0x58, 0x1E, 0xB2, 0x4E, 0x77, 0x6F, 0xA4, 0x7E,
0x62, 0xDF, 0xB7, 0x05, 0xE8, 0x80, 0x42, 0x5C,
0xB8, 0x78, 0x87, 0x97, 0x7F, 0x66, 0x2C, 0x5F
};
static const unsigned char DevNcsdCfa_privExp[256] = //DevNcsdCfa_privExp
{
0x32, 0x36, 0x43, 0xC2, 0xB3, 0x1A, 0x7E, 0x13,
0xAB, 0xA2, 0xB6, 0x8B, 0x4F, 0x05, 0xA7, 0xA6,
0xCD, 0xE7, 0xA6, 0x74, 0x47, 0x49, 0xE6, 0x51,
0xE4, 0x71, 0x74, 0x15, 0x76, 0x91, 0xF7, 0x92,
0xB1, 0x4E, 0xF6, 0x99, 0x73, 0x1E, 0xCF, 0xB5,
0x1D, 0x7C, 0xAF, 0xC5, 0xEA, 0x57, 0x01, 0xE5,
0x5C, 0x10, 0x47, 0xEA, 0x3A, 0x54, 0x86, 0x03,
0x2A, 0x76, 0x05, 0x72, 0x53, 0x16, 0xC2, 0xAE,
0x2D, 0xBE, 0x71, 0xF7, 0x17, 0x6B, 0x23, 0xDD,
0x2C, 0xB8, 0x8D, 0x13, 0x14, 0xE5, 0xDA, 0x3B,
0xC7, 0x33, 0x7A, 0xBA, 0xE5, 0x2A, 0x2B, 0x7D,
0x5A, 0x12, 0x27, 0x38, 0x56, 0xDF, 0xED, 0x70,
0x03, 0x0E, 0xED, 0x64, 0xC7, 0xF6, 0x54, 0xAC,
0xFE, 0x1D, 0x77, 0xA4, 0xE4, 0xBC, 0xEB, 0xB9,
0xA6, 0xC5, 0xFE, 0x3A, 0xAF, 0x58, 0x81, 0xE4,
0x3F, 0xA0, 0xE6, 0x93, 0x13, 0x2D, 0x98, 0x7D,
0xB3, 0xE2, 0xC9, 0xC8, 0xD6, 0x31, 0x91, 0x73,
0x9D, 0xCA, 0xC9, 0x44, 0xEF, 0xD0, 0x39, 0xBF,
0x38, 0xFD, 0x1C, 0x91, 0x72, 0x93, 0x40, 0xA9,
0x8A, 0x0D, 0x3E, 0x32, 0xC4, 0x59, 0x4B, 0x0C,
0xC7, 0xEA, 0x50, 0x41, 0x9F, 0xF5, 0xE2, 0xB7,
0x50, 0x7C, 0xE3, 0xC9, 0xEC, 0x46, 0x18, 0xAC,
0xB4, 0x91, 0x2A, 0x32, 0xE0, 0xD8, 0x10, 0x6F,
0xFC, 0x81, 0xB3, 0x95, 0xF3, 0xFC, 0x78, 0xC0,
0xEF, 0xE5, 0x7B, 0x8D, 0x14, 0xD4, 0x36, 0x26,
0x5F, 0xC6, 0x32, 0xC0, 0x19, 0x87, 0x5C, 0x77,
0x26, 0x37, 0xD8, 0xAE, 0x66, 0xD6, 0x0B, 0x28,
0x26, 0x43, 0x7C, 0x25, 0xDB, 0x6D, 0x5C, 0xE8,
0x94, 0x8F, 0xA9, 0x77, 0x07, 0xB2, 0xC0, 0x85,
0xCD, 0x41, 0xBA, 0x48, 0x88, 0x73, 0x34, 0xD5,
0x20, 0x8A, 0x0F, 0xE3, 0x9E, 0x99, 0xF0, 0xC8,
0xE8, 0xD9, 0x2C, 0x2A, 0x21, 0x69, 0xE4, 0xC1
};
static const unsigned char DevNcsdCfa_pubMod[256] = //DevNcsdCfa_pubMod
{
0xB9, 0x0C, 0xC4, 0xC6, 0x78, 0xF8, 0x6E, 0x30,
0x05, 0x28, 0xC1, 0xCB, 0xD2, 0xCF, 0xA7, 0x80,
0x5C, 0x57, 0x4D, 0x16, 0x9C, 0xAF, 0xA6, 0xCD,
0x01, 0xBB, 0x83, 0x33, 0xAD, 0x03, 0xBB, 0x06,
0x63, 0xD8, 0x17, 0xF5, 0xE3, 0xDF, 0xDA, 0x0D,
0x3B, 0x86, 0x0E, 0xA2, 0x80, 0x47, 0x94, 0x44,
0x6F, 0xD9, 0x97, 0x7E, 0x78, 0x6A, 0xC3, 0x93,
0x93, 0xEF, 0x02, 0xFC, 0x22, 0x9F, 0x80, 0x77,
0x8C, 0x70, 0x92, 0x1C, 0x43, 0xB1, 0x37, 0x4C,
0x76, 0xE0, 0x57, 0x3B, 0xAB, 0x89, 0xFF, 0xEF,
0xE5, 0xBB, 0x3E, 0xAB, 0x91, 0x39, 0xB8, 0xD9,
0x66, 0x0B, 0x64, 0x28, 0x91, 0x92, 0xE9, 0xD0,
0xB3, 0xDF, 0xD1, 0x4B, 0xC1, 0x73, 0xB5, 0x3F,
0x56, 0xA0, 0x40, 0x10, 0xFE, 0x15, 0x2B, 0x1F,
0xA2, 0x7A, 0xDE, 0x31, 0xB0, 0x26, 0x40, 0xC3,
0x57, 0xFD, 0x35, 0xCB, 0xF0, 0xFA, 0xFF, 0xFB,
0x6F, 0xDB, 0xCD, 0x34, 0x1D, 0x51, 0x2D, 0x2D,
0x81, 0x18, 0xFF, 0x0C, 0x08, 0x51, 0xD5, 0xB4,
0x4B, 0x56, 0x16, 0x02, 0x9F, 0x4E, 0x6A, 0xDF,
0x06, 0x6E, 0xCB, 0x72, 0x85, 0xE9, 0x2E, 0x43,
0xA2, 0x08, 0x78, 0x0C, 0x38, 0x9C, 0x19, 0xBD,
0x7B, 0x74, 0x74, 0x68, 0xC4, 0x2D, 0xC1, 0x35,
0x9E, 0x65, 0x3B, 0xD8, 0x99, 0x04, 0x1C, 0x8B,
0x93, 0x8E, 0x7E, 0x92, 0x7C, 0xBB, 0xDD, 0x60,
0xEC, 0xE7, 0xFE, 0x0E, 0x9D, 0x4F, 0x36, 0x46,
0xE6, 0xF1, 0x5C, 0x94, 0x70, 0xEE, 0x67, 0x5F,
0x36, 0x2B, 0x70, 0x44, 0x8D, 0xCA, 0x09, 0xB9,
0x58, 0x67, 0xD2, 0x9F, 0xAD, 0x1F, 0x13, 0x54,
0x74, 0xAD, 0xA6, 0x84, 0x44, 0x28, 0xF3, 0xDE,
0x7E, 0x4C, 0x20, 0x2B, 0xC5, 0xE9, 0x12, 0xE9,
0x5E, 0xFB, 0x8D, 0x77, 0xA9, 0xA4, 0xD2, 0x0D,
0x3C, 0x38, 0x24, 0xBE, 0xF5, 0x8A, 0xB5, 0xF5
};
static const unsigned char AccessDesc_privExp[256] = //AccessDesc_privExp
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char AccessDesc_pubMod[256] = //AccessDesc_pubMod
{
0xF4, 0x3C, 0x45, 0x82, 0xFB, 0xF8, 0x90, 0x5D,
0x07, 0x02, 0x9F, 0x2A, 0x98, 0x8B, 0x63, 0xB7,
0xD3, 0x8F, 0x3C, 0xE2, 0xE0, 0xE0, 0x93, 0xBF,
0xDF, 0x32, 0x43, 0x4D, 0xBE, 0xF4, 0xD1, 0x7A,
0x3A, 0x4E, 0x54, 0x31, 0xD7, 0x73, 0xAE, 0x99,
0x4C, 0xC4, 0x1F, 0x3C, 0x3E, 0xF0, 0x57, 0x05,
0xA3, 0x8A, 0x45, 0x54, 0x60, 0xD8, 0x8F, 0xD9,
0x1D, 0x68, 0x0D, 0x0E, 0x2E, 0xEF, 0xC8, 0xE8,
0x3D, 0xC9, 0x19, 0xF3, 0x73, 0x1E, 0x2D, 0xDA,
0x77, 0x88, 0x3E, 0xCA, 0x5E, 0x25, 0x70, 0x4B,
0xF7, 0x70, 0x95, 0x83, 0x54, 0x24, 0xE0, 0xC3,
0x1A, 0x75, 0xDF, 0x61, 0x3D, 0xD1, 0x42, 0xEC,
0x35, 0x1B, 0x38, 0xD6, 0xC1, 0xF6, 0x7E, 0x18,
0x2A, 0x84, 0x85, 0xDD, 0x57, 0x74, 0x1F, 0x0A,
0x2E, 0xF6, 0xB2, 0x94, 0xA2, 0x3E, 0xE9, 0xA1,
0xD0, 0x09, 0xF7, 0x3A, 0x99, 0x80, 0x05, 0xAF,
0x57, 0x55, 0xEF, 0x52, 0xFA, 0x24, 0x3E, 0x7F,
0xD4, 0x7C, 0x41, 0x44, 0x7B, 0x06, 0x7F, 0xB9,
0x5B, 0x2E, 0x8E, 0x96, 0xAE, 0x46, 0x12, 0x4D,
0x64, 0x21, 0xE5, 0x0F, 0x85, 0xCC, 0xEB, 0x92,
0xE5, 0xF0, 0xF5, 0xA7, 0x42, 0x27, 0x3B, 0xEC,
0xF8, 0xE7, 0x81, 0x75, 0x6F, 0x63, 0x0A, 0x8B,
0x0D, 0x77, 0x38, 0x51, 0xE6, 0x66, 0x33, 0xBA,
0x79, 0xDC, 0x2F, 0x2C, 0x8F, 0xC3, 0x28, 0x06,
0xBB, 0x03, 0x9C, 0xDB, 0xD1, 0x64, 0x0A, 0x66,
0xF0, 0xF8, 0xC1, 0x2A, 0x49, 0x1D, 0x0C, 0x6E,
0x35, 0xBB, 0xEA, 0xB3, 0x5C, 0x0D, 0xE9, 0x95,
0x7C, 0x67, 0xBE, 0x65, 0x77, 0xEC, 0x07, 0xC0,
0x23, 0x05, 0x0A, 0x72, 0x48, 0x86, 0xE9, 0x9E,
0xFC, 0x25, 0x15, 0xE7, 0xC8, 0x21, 0x65, 0xE0,
0x1B, 0xD5, 0xD5, 0x0E, 0xD3, 0x11, 0x54, 0xBB,
0x29, 0x78, 0xBF, 0x2A, 0x3C, 0x3B, 0xB6, 0xB1
};
static const unsigned char CrrDevKey_privExp[256] = //CrrDevKey_privExp
{
0x8D, 0x27, 0x29, 0x6B, 0xC7, 0xA7, 0xED, 0xCD,
0x94, 0x2D, 0x36, 0x5E, 0x86, 0xA8, 0x26, 0xE7,
0x43, 0x9E, 0x64, 0xC8, 0xAA, 0x9A, 0x58, 0x21,
0x07, 0xF7, 0xB3, 0xFB, 0xCF, 0x8D, 0x3E, 0x53,
0xF0, 0x02, 0x25, 0x7B, 0x80, 0x18, 0x2E, 0x0D,
0x84, 0x7D, 0x6C, 0xE0, 0xDA, 0xC0, 0x17, 0xA6,
0xA5, 0x13, 0xE6, 0xFD, 0xBF, 0x98, 0xFC, 0x87,
0x9A, 0x9E, 0x0E, 0x13, 0x87, 0x66, 0x24, 0x8D,
0xA5, 0x6C, 0x58, 0x86, 0x10, 0x80, 0x90, 0x89,
0xEE, 0xFD, 0x40, 0x94, 0xCB, 0x1F, 0x26, 0xAB,
0xD1, 0xD3, 0xFF, 0xE9, 0x7B, 0x76, 0xDC, 0x65,
0xC0, 0x15, 0xD8, 0x9B, 0xF6, 0x29, 0xE1, 0x49,
0xE9, 0xDC, 0xBE, 0x24, 0x17, 0xFF, 0x09, 0x2C,
0xD6, 0xC4, 0x6D, 0x50, 0x33, 0xDC, 0xA0, 0x9D,
0x9D, 0xCC, 0xDD, 0x6E, 0x7B, 0xDF, 0x42, 0x22,
0x4D, 0x80, 0xC7, 0xEB, 0xCB, 0xB1, 0x60, 0x2F,
0x04, 0xEE, 0x04, 0x0E, 0x4C, 0x76, 0x49, 0x55,
0x92, 0xA5, 0xC1, 0x13, 0x60, 0x0A, 0x80, 0x15,
0x3D, 0x1C, 0xC6, 0x46, 0x57, 0x2E, 0x7C, 0xB0,
0x3D, 0x87, 0x06, 0x87, 0xFD, 0x31, 0xF8, 0xE7,
0x14, 0x97, 0x2A, 0x57, 0x40, 0xAC, 0x94, 0x61,
0xCD, 0xCF, 0xDE, 0x8C, 0x40, 0x46, 0x95, 0xA0,
0xD6, 0xF9, 0x2C, 0x08, 0x9B, 0x12, 0xBF, 0xF1,
0x88, 0x9C, 0x5D, 0x40, 0x32, 0x6D, 0x9D, 0x99,
0xA4, 0x80, 0xA6, 0xC2, 0x45, 0x5A, 0xD3, 0x22,
0xFE, 0xFA, 0x17, 0x54, 0x11, 0xEA, 0x41, 0xB4,
0xBD, 0x68, 0x1E, 0xDD, 0x3F, 0xE5, 0x92, 0xCB,
0x9E, 0xF8, 0xC0, 0x0A, 0x8B, 0xF5, 0x89, 0xA4,
0x03, 0x68, 0xF8, 0xF8, 0x99, 0x7C, 0xFE, 0xAD,
0x32, 0xDD, 0x5C, 0xB4, 0x06, 0x29, 0xDA, 0x96,
0x8B, 0xBA, 0xCB, 0x15, 0xDE, 0x38, 0x0D, 0xCA,
0xF7, 0x01, 0x65, 0xF6, 0x2D, 0x36, 0x6E, 0x71
};
static const unsigned char CrrDevKey_pubMod[256] = //CrrDevKey_pubMod
{
0xE2, 0xAD, 0xA6, 0xEA, 0xCA, 0xA3, 0xE8, 0xCC,
0xA9, 0x70, 0x1D, 0x2E, 0x23, 0x4B, 0xC6, 0x55,
0xCE, 0x13, 0xD9, 0xA7, 0x58, 0xB4, 0xC7, 0x73,
0x96, 0x1D, 0xE8, 0xC3, 0x09, 0x4D, 0x9B, 0xC3,
0xEB, 0x69, 0xA2, 0x37, 0x83, 0x5D, 0xD8, 0x37,
0x04, 0x72, 0x7A, 0x4F, 0xEA, 0x53, 0x98, 0x9D,
0x0E, 0x01, 0x34, 0x70, 0x9A, 0x82, 0x06, 0xE7,
0x6A, 0xC9, 0xF8, 0x0E, 0x49, 0x5A, 0xA4, 0xE7,
0x0E, 0xFA, 0xD4, 0xAB, 0x3B, 0xC5, 0xD7, 0xF1,
0xA4, 0xFC, 0x92, 0x7F, 0xD0, 0xF3, 0xCD, 0xD5,
0xB9, 0x2A, 0x1A, 0x41, 0x62, 0xB3, 0x7B, 0x3E,
0x1E, 0x35, 0x46, 0x41, 0x8E, 0xB2, 0x53, 0x1A,
0x60, 0xF8, 0xC2, 0xD1, 0x94, 0xB3, 0x9D, 0x76,
0x9F, 0x1D, 0x98, 0xAC, 0xF0, 0xCF, 0xE3, 0xA9,
0x05, 0x85, 0xF2, 0xBF, 0x55, 0x76, 0x1B, 0x89,
0x1C, 0xC3, 0x19, 0x2E, 0xEE, 0x94, 0xBE, 0x75,
0x0F, 0xA3, 0x76, 0x8B, 0x24, 0x24, 0x97, 0xFA,
0xC0, 0x53, 0x24, 0xF5, 0x85, 0x02, 0x19, 0x9D,
0xC5, 0x11, 0x2E, 0x6B, 0xA3, 0x26, 0xFE, 0xF7,
0x55, 0xD4, 0x23, 0x0A, 0x73, 0x3F, 0x37, 0x53,
0xEA, 0xC2, 0xB7, 0xC1, 0xC9, 0xD8, 0xF3, 0x2F,
0x78, 0x76, 0x4A, 0xA0, 0x69, 0x60, 0x91, 0xC2,
0x7D, 0x11, 0x74, 0xEF, 0x96, 0xD9, 0x74, 0x53,
0xB1, 0x1C, 0xB0, 0xC4, 0x32, 0x16, 0x82, 0x3B,
0xAF, 0x61, 0xB2, 0xDE, 0x38, 0x87, 0x3E, 0x37,
0x4B, 0xA3, 0x95, 0x88, 0x8E, 0xE0, 0x27, 0x9A,
0x1F, 0x7D, 0xB8, 0x23, 0xC3, 0x63, 0xE8, 0x68,
0x51, 0xD9, 0x8C, 0x4C, 0xC2, 0x59, 0x86, 0x49,
0xF7, 0x46, 0x9E, 0x3C, 0xD7, 0x9F, 0x89, 0x23,
0xB4, 0x73, 0x35, 0x2F, 0x18, 0x23, 0x76, 0xA3,
0x9F, 0x40, 0x0B, 0x76, 0x90, 0x85, 0xC8, 0x89,
0xDA, 0x65, 0xE7, 0x6E, 0xEF, 0x2E, 0xF5, 0x67
};
static const unsigned char Dummy_rsa_privExp[256] = //Dummy_rsa_privExp
{
0xE3, 0xC6, 0x76, 0x57, 0x2E, 0xCB, 0xA5, 0xE6,
0x0C, 0x01, 0xBD, 0x5C, 0x32, 0x2D, 0x90, 0xE0,
0xFF, 0x9A, 0x80, 0xE8, 0x66, 0x8D, 0x84, 0xDC,
0xF7, 0x75, 0x5F, 0x3F, 0x98, 0x7C, 0x97, 0x40,
0x20, 0x21, 0xB7, 0x24, 0xC0, 0x61, 0x2D, 0x83,
0xB0, 0x91, 0x8E, 0xE3, 0xC2, 0xD0, 0x2C, 0xA1,
0x2C, 0x99, 0x4F, 0x48, 0xF7, 0x4E, 0x13, 0xD3,
0x01, 0x71, 0x25, 0x9B, 0x3C, 0x75, 0x7C, 0xC4,
0xE5, 0x89, 0x7E, 0xDA, 0xF9, 0x99, 0x5C, 0x83,
0xE4, 0xDD, 0x36, 0x62, 0x5B, 0x0E, 0x12, 0x91,
0xD6, 0x39, 0x45, 0x69, 0x62, 0x20, 0xCA, 0xF4,
0xBA, 0x6B, 0x28, 0x1A, 0x7C, 0xBF, 0xB9, 0x97,
0x37, 0x46, 0xC2, 0x7A, 0xCF, 0x10, 0x68, 0xC2,
0xC9, 0xF1, 0x48, 0xDA, 0x8A, 0x2F, 0x4C, 0xBC,
0x3B, 0x1C, 0xB8, 0x8F, 0x04, 0x7F, 0xFD, 0x9D,
0xE2, 0x0A, 0xD2, 0x09, 0x39, 0xC7, 0xD9, 0x81,
0x59, 0x17, 0x73, 0xB2, 0xEC, 0xEB, 0x36, 0x67,
0xA5, 0xA8, 0xD5, 0x71, 0xD9, 0x38, 0x6A, 0xD1,
0x28, 0xB9, 0x46, 0x85, 0x3A, 0x81, 0x85, 0x4E,
0x55, 0xA7, 0x74, 0x79, 0xBB, 0xC5, 0x97, 0xF7,
0xEF, 0xE0, 0x81, 0x20, 0xE0, 0xEA, 0x45, 0x8F,
0xED, 0x70, 0x8E, 0xD6, 0xFF, 0x49, 0xCF, 0x7F,
0xF2, 0xFF, 0x22, 0x20, 0x3F, 0xE9, 0x92, 0x99,
0xDE, 0x81, 0xD6, 0x27, 0xF7, 0xB8, 0x3A, 0x1D,
0x4F, 0xA2, 0x50, 0xFB, 0xA5, 0xE7, 0x98, 0x08,
0xB5, 0x2B, 0xA2, 0x94, 0xA9, 0x17, 0x1A, 0xA8,
0x34, 0xF6, 0x5E, 0x24, 0x2D, 0x40, 0x2F, 0xCB,
0x3C, 0xB0, 0xF8, 0x7E, 0x84, 0xB4, 0x87, 0x82,
0x19, 0xAF, 0x87, 0xB6, 0xFA, 0xA9, 0x67, 0x27,
0x07, 0x28, 0xBA, 0x2E, 0xA5, 0x8E, 0xDD, 0xE5,
0xD4, 0xFD, 0x06, 0x09, 0xDF, 0xBD, 0x87, 0x95,
0x95, 0x25, 0x05, 0x5E, 0xB2, 0x00, 0x18, 0x41
};
static const unsigned char Dummy_rsa_pubMod[256] = //Dummy_rsa_pubMod
{
0xE6, 0x64, 0x06, 0x6C, 0x49, 0x6B, 0xEC, 0xEE,
0x59, 0xAE, 0x11, 0x92, 0xF1, 0x03, 0x43, 0x87,
0x8E, 0xEB, 0x4D, 0x70, 0xA9, 0x71, 0xB4, 0x6D,
0x25, 0x19, 0x02, 0x4A, 0x9E, 0x4D, 0xA3, 0x10,
0xFD, 0xB2, 0x27, 0x56, 0xA3, 0xFB, 0xDD, 0xE5,
0xE4, 0x4E, 0xE0, 0x62, 0x8F, 0xC3, 0x2E, 0xEE,
0x8F, 0x9D, 0x4D, 0x6E, 0x00, 0xDB, 0x88, 0x49,
0xA2, 0xFC, 0x30, 0xFE, 0x94, 0xF3, 0x06, 0x92,
0x75, 0x61, 0x11, 0x1D, 0x24, 0x07, 0xE9, 0x12,
0xB6, 0xB1, 0x57, 0xF5, 0xDC, 0x01, 0xF7, 0x54,
0xBF, 0xC3, 0xAC, 0x8C, 0x73, 0x2C, 0x73, 0x17,
0x8E, 0xBF, 0x2F, 0x68, 0x3C, 0x61, 0x75, 0x32,
0x15, 0x39, 0x93, 0xDD, 0xBA, 0x12, 0x42, 0xD3,
0x25, 0x85, 0xFA, 0xA6, 0x4B, 0xAF, 0x81, 0x4B,
0xCA, 0xD2, 0x9C, 0xF1, 0x3D, 0x37, 0xAE, 0xB9,
0xFD, 0x77, 0x59, 0x78, 0xB9, 0x32, 0x95, 0x19,
0xD1, 0x47, 0xE1, 0xC6, 0xE1, 0x16, 0x13, 0x5D,
0xCC, 0x99, 0x31, 0x63, 0xAD, 0xBB, 0xA5, 0x4F,
0xE4, 0x41, 0x67, 0xFD, 0x7F, 0x1E, 0xA8, 0x9A,
0x35, 0x65, 0xEB, 0xC4, 0x4D, 0xD4, 0xC4, 0x29,
0x0F, 0x40, 0x95, 0xFD, 0x8A, 0x30, 0x67, 0x79,
0xFB, 0xD4, 0x76, 0x6F, 0xD1, 0xDE, 0x8C, 0x72,
0x32, 0x05, 0x97, 0x5A, 0x26, 0x0D, 0x37, 0xCA,
0x12, 0x2C, 0xDC, 0x14, 0x3F, 0xD3, 0x59, 0x00,
0x66, 0xD2, 0x8E, 0xF5, 0x6E, 0x22, 0x08, 0x63,
0x59, 0xB5, 0x3F, 0xBB, 0x3A, 0x4D, 0xD4, 0xD1,
0xC1, 0x21, 0xA7, 0x4D, 0x02, 0x96, 0x08, 0xF5,
0x2B, 0x11, 0xE5, 0x85, 0xD2, 0x6E, 0x91, 0xD6,
0x8F, 0x77, 0x72, 0xEF, 0x37, 0xE3, 0x79, 0x19,
0xA9, 0xEE, 0x58, 0x5D, 0x52, 0x9B, 0x2D, 0x47,
0x7D, 0x27, 0xB8, 0xC3, 0x76, 0xCA, 0xDA, 0xC2,
0xF4, 0xFC, 0xF4, 0x53, 0x7C, 0xD8, 0x43, 0x87
};
//Certificates
static const unsigned char ca4_dpki_cert[0x400] =
{
0x00, 0x01, 0x00, 0x03, 0x19, 0x49, 0x42, 0x9D,
0x1E, 0x58, 0xA6, 0x2E, 0x7E, 0x8B, 0x56, 0xD1,
0xB7, 0x6A, 0xE3, 0x02, 0xFD, 0x8B, 0x97, 0x49,
0x1F, 0x77, 0x87, 0x45, 0xF7, 0x53, 0x88, 0xC4,
0xDD, 0x0B, 0xEB, 0x1D, 0xF1, 0x22, 0xFB, 0x96,
0x42, 0x15, 0x14, 0x97, 0x76, 0x4A, 0x53, 0xCF,
0x78, 0x15, 0x18, 0x45, 0xE4, 0x2C, 0xA8, 0xFD,
0xE4, 0x86, 0xFD, 0x2A, 0x4F, 0x53, 0xF8, 0xA1,
0xBA, 0x00, 0x8A, 0x74, 0x85, 0xFF, 0x73, 0xB3,
0xBF, 0x7E, 0x3C, 0x98, 0x07, 0x29, 0xD0, 0x65,
0x6B, 0x69, 0x32, 0x19, 0xAD, 0xE8, 0x35, 0xEB,
0x5F, 0xFF, 0xFC, 0xCB, 0x7C, 0xBB, 0x5E, 0x30,
0x7F, 0xE0, 0x68, 0x8B, 0x88, 0x8E, 0xF2, 0xD2,
0x05, 0x3F, 0xB7, 0xE7, 0x91, 0xE9, 0x85, 0xFD,
0x15, 0xEF, 0x10, 0xD7, 0x9C, 0xCA, 0x88, 0xD6,
0xBB, 0x15, 0xE8, 0xE4, 0x71, 0x4A, 0x98, 0xEE,
0x09, 0xBF, 0x7B, 0x8A, 0xF0, 0x53, 0x23, 0x2B,
0x64, 0x50, 0xE6, 0xD5, 0xFD, 0xFF, 0xC2, 0x0A,
0x6D, 0x1E, 0xA6, 0xA2, 0x38, 0x12, 0xE1, 0x01,
0x45, 0x25, 0xD5, 0x6D, 0x40, 0x82, 0x70, 0x3B,
0x86, 0x98, 0x69, 0x59, 0xA7, 0x3C, 0xD1, 0xA1,
0x43, 0x64, 0xD2, 0xC2, 0xDA, 0xEA, 0x96, 0xB0,
0x95, 0xF7, 0x6C, 0x46, 0xE4, 0xFF, 0x41, 0x55,
0x46, 0x5E, 0x70, 0xEF, 0x1E, 0xD3, 0x10, 0x53,
0xD9, 0x70, 0x11, 0xE0, 0x10, 0xCC, 0x93, 0xE7,
0x91, 0x40, 0x13, 0x68, 0x7F, 0xA3, 0xA8, 0x02,
0x99, 0x6D, 0x1E, 0x55, 0x7B, 0x1C, 0xCC, 0x7A,
0x7E, 0x8F, 0x58, 0x65, 0xC1, 0x74, 0x2E, 0x28,
0xE2, 0x6D, 0xEF, 0x38, 0xA9, 0x3A, 0xB5, 0xD8,
0x2D, 0x43, 0xEC, 0xCC, 0xBF, 0x0B, 0xEF, 0x22,
0xE1, 0xFD, 0x57, 0xE2, 0x86, 0x43, 0x33, 0x58,
0x2F, 0xED, 0xEA, 0xBC, 0x01, 0x2F, 0x98, 0x6D,
0xDF, 0xC3, 0xE9, 0x44, 0x79, 0x73, 0x47, 0x03,
0x08, 0x45, 0x5B, 0xDC, 0x57, 0xAA, 0x17, 0x0B,
0x84, 0x42, 0x7F, 0x73, 0xA2, 0x9B, 0x48, 0xF6,
0xDA, 0x13, 0x5F, 0x66, 0xC7, 0x45, 0xC1, 0x42,
0xA8, 0x4A, 0xFB, 0x0E, 0x6A, 0x5E, 0xED, 0x85,
0xD7, 0xB9, 0x71, 0x99, 0x36, 0xF8, 0xCE, 0x2B,
0x62, 0x1F, 0x39, 0x5F, 0x40, 0xDC, 0x03, 0xBE,
0xF8, 0x85, 0x4C, 0x11, 0x17, 0xFF, 0x0C, 0x12,
0x86, 0x41, 0xCC, 0x78, 0x43, 0xB9, 0x7B, 0x43,
0x46, 0xDB, 0x22, 0x6F, 0x60, 0x26, 0xAC, 0xB5,
0x6C, 0x27, 0x8B, 0x8E, 0x0E, 0xA7, 0x9A, 0x2D,
0x65, 0xEF, 0x79, 0x8E, 0x10, 0x78, 0xAD, 0x80,
0xED, 0x4B, 0x96, 0x04, 0xD2, 0xF0, 0x8B, 0x2C,
0xD6, 0x4A, 0x23, 0xA3, 0xDB, 0x27, 0x08, 0x33,
0xB4, 0x02, 0xF8, 0x08, 0x51, 0xF3, 0x5B, 0xED,
0x3E, 0xE4, 0x57, 0x7C, 0x66, 0x60, 0xFB, 0xF1,
0x6D, 0x94, 0x13, 0xE0, 0x9C, 0x91, 0x7A, 0x49,
0xD4, 0x2C, 0x6D, 0xA3, 0x75, 0xBC, 0x27, 0xF0,
0x23, 0x0D, 0xB9, 0x8F, 0x89, 0x73, 0xAB, 0x02,
0x7B, 0x52, 0x2C, 0xD5, 0x7E, 0xC0, 0x3D, 0x25,
0xE8, 0xB3, 0xFC, 0x34, 0x94, 0xC9, 0x7F, 0xB1,
0x08, 0xFE, 0x18, 0xC6, 0x8A, 0x43, 0x36, 0xE4,
0x6C, 0x26, 0xB6, 0xF2, 0x80, 0xD2, 0x7E, 0x34,
0xBE, 0x28, 0x7C, 0x3E, 0x46, 0x87, 0xBC, 0x9D,
0x77, 0x6B, 0x76, 0xD9, 0x28, 0xD1, 0xB6, 0x35,
0x2E, 0xC0, 0x34, 0x7D, 0x72, 0x94, 0xAA, 0x93,
0x60, 0x26, 0x8D, 0x26, 0xF5, 0xF6, 0x52, 0x06,
0x4A, 0xF2, 0x40, 0xD7, 0xD0, 0x0C, 0x7C, 0x5E,
0xA3, 0xC3, 0x2D, 0xE6, 0x2D, 0x9B, 0x5C, 0x4B,
0x4C, 0xAB, 0x6F, 0xD7, 0xBD, 0x37, 0x1D, 0x57,
0xC2, 0x16, 0x60, 0x95, 0x91, 0x0E, 0x4A, 0xD8,
0xE9, 0xED, 0x18, 0x1E, 0xF7, 0x61, 0x93, 0x61,
0x53, 0x89, 0x2D, 0x77, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x6F, 0x6F, 0x74, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x43, 0x41, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x81, 0x12, 0x2A, 0x46,
0xC9, 0xCC, 0x2D, 0xC4, 0xDF, 0x29, 0x30, 0xE4,
0xDF, 0x3F, 0x8C, 0x70, 0xA0, 0x78, 0x94, 0x87,
0x75, 0xAD, 0x5E, 0x9A, 0xA6, 0x04, 0xC5, 0xB4,
0xD8, 0xEA, 0xFF, 0x2A, 0xA1, 0xD2, 0x14, 0x67,
0x65, 0x64, 0xEF, 0xCA, 0x28, 0xCC, 0x00, 0x15,
0x45, 0x54, 0xA1, 0xA3, 0xEA, 0x13, 0x79, 0xE9,
0xE6, 0xCA, 0xAC, 0xED, 0x15, 0x93, 0xFE, 0x88,
0xD8, 0x9A, 0xC6, 0xB8, 0xAC, 0xCC, 0xAB, 0x6E,
0x20, 0x7C, 0xEB, 0x7C, 0xCA, 0x29, 0x80, 0x9E,
0x29, 0x80, 0x44, 0x06, 0x62, 0xB7, 0xD4, 0x38,
0x2A, 0x15, 0xDA, 0x43, 0x08, 0x57, 0x45, 0xA9,
0xAA, 0xE5, 0x9A, 0xA0, 0x5B, 0xDB, 0x32, 0xF6,
0x68, 0x69, 0xA2, 0xDD, 0x42, 0x95, 0x38, 0x6C,
0x87, 0xEC, 0xDD, 0x35, 0x08, 0xA2, 0xCF, 0x60,
0xD0, 0x1E, 0x23, 0xEC, 0x2F, 0xE6, 0x98, 0xF4,
0x70, 0xD6, 0x00, 0x15, 0x49, 0xA2, 0xF0, 0x67,
0x59, 0x13, 0x1E, 0x53, 0x4C, 0x70, 0x06, 0x05,
0x7D, 0xEF, 0x1D, 0x18, 0xA8, 0x3F, 0x0A, 0xC7,
0x9C, 0xFE, 0x80, 0xFF, 0x5A, 0x91, 0xF2, 0xBE,
0xD4, 0xA0, 0x83, 0x70, 0x61, 0x19, 0x0A, 0x03,
0x29, 0x90, 0x21, 0x65, 0x40, 0x3C, 0x9A, 0x90,
0x8F, 0xB6, 0x15, 0x73, 0x9F, 0x3C, 0xE3, 0x3B,
0xF1, 0xBA, 0xEA, 0x16, 0xC2, 0x5B, 0xCE, 0xD7,
0x96, 0x3F, 0xAC, 0xC9, 0xD2, 0x4D, 0x9C, 0x0A,
0xD7, 0x6F, 0xC0, 0x20, 0xB2, 0xC4, 0xB8, 0x4C,
0x10, 0xA7, 0x41, 0xA2, 0xCC, 0x7D, 0x9B, 0xAC,
0x3A, 0xAC, 0xCC, 0xA3, 0x52, 0x9B, 0xAC, 0x31,
0x6A, 0x9A, 0xA7, 0x5D, 0x2A, 0x26, 0xC7, 0xD7,
0xD2, 0x88, 0xCB, 0xA4, 0x66, 0xC5, 0xFE, 0x5F,
0x45, 0x4A, 0xE6, 0x79, 0x74, 0x4A, 0x90, 0xA1,
0x57, 0x72, 0xDB, 0x3B, 0x0E, 0x47, 0xA4, 0x9A,
0xF0, 0x31, 0xD1, 0x6D, 0xBE, 0xAB, 0x33, 0x2B,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char xs9_dpki_cert[0x300] =
{
0x00, 0x01, 0x00, 0x04, 0x63, 0x80, 0x5A, 0x35,
0x1A, 0x43, 0x7B, 0xA2, 0x43, 0x19, 0xBB, 0x3A,
0x77, 0x7B, 0x7A, 0xF3, 0x5E, 0x72, 0x4B, 0x15,
0x0A, 0x06, 0x39, 0x6C, 0x5F, 0xEC, 0x38, 0x45,
0xB1, 0x88, 0x76, 0x26, 0x8D, 0x5E, 0xDA, 0xE6,
0x2F, 0x14, 0xBA, 0x02, 0xFA, 0xD6, 0xFC, 0x3B,
0x2B, 0xBE, 0x87, 0x07, 0x63, 0x8E, 0x55, 0xBF,
0x05, 0x5A, 0xFC, 0xFC, 0xB3, 0x47, 0x69, 0x11,
0x89, 0xDB, 0x1C, 0xAF, 0x4B, 0x43, 0x76, 0x62,
0x3E, 0x30, 0x89, 0x0A, 0x9D, 0x3B, 0xBB, 0x3E,
0x50, 0xBD, 0xF7, 0xA6, 0xC0, 0xF7, 0xF8, 0xBB,
0x0D, 0xB5, 0x6A, 0xBB, 0xC6, 0xC3, 0x50, 0xC8,
0x88, 0xBB, 0x9D, 0xF0, 0x9B, 0xD1, 0x30, 0x64,
0x60, 0x69, 0xDD, 0x34, 0x67, 0xA7, 0x00, 0xEB,
0xDC, 0xF9, 0x8C, 0xB0, 0xF7, 0x93, 0x0E, 0x81,
0xFE, 0x98, 0xD9, 0x72, 0x45, 0x8B, 0x94, 0x7E,
0x59, 0xE2, 0xBE, 0x4E, 0x91, 0x2D, 0x75, 0xCA,
0x1B, 0x8E, 0x2E, 0xF4, 0x6D, 0x73, 0xB1, 0x6B,
0x35, 0xB5, 0x67, 0x0D, 0x63, 0x2D, 0x51, 0x38,
0x53, 0x28, 0x19, 0x1D, 0x9D, 0xAE, 0x8D, 0xC6,
0x61, 0xCC, 0xEF, 0xA4, 0xAB, 0xE2, 0xF3, 0xB0,
0x4C, 0x7B, 0xE2, 0x71, 0xB5, 0xF9, 0x2C, 0xFA,
0x55, 0xCD, 0x88, 0x8B, 0x72, 0xCC, 0xBE, 0x67,
0xFA, 0xDF, 0xEF, 0x6B, 0x53, 0x3C, 0x45, 0xD8,
0xCB, 0xDF, 0xB2, 0x76, 0x41, 0x46, 0xD6, 0xC2,
0x6F, 0x27, 0x16, 0xC5, 0x07, 0xF3, 0xF4, 0x44,
0x66, 0xA3, 0x15, 0xD2, 0x77, 0xF2, 0x89, 0xDA,
0xFD, 0xD5, 0x50, 0xCF, 0xA4, 0x9B, 0xEA, 0xCA,
0xC9, 0x7B, 0xE5, 0x46, 0x0E, 0xED, 0x9B, 0xFB,
0x04, 0xA9, 0xDA, 0x19, 0x58, 0xD9, 0x2A, 0x20,
0x8A, 0xAC, 0xC1, 0xF4, 0x8E, 0xE9, 0x14, 0xD8,
0x8A, 0xD7, 0x41, 0xD5, 0x5B, 0x9B, 0x64, 0x22,
0xD8, 0xAF, 0xAE, 0xC7, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x43, 0x41, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x58, 0x53, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0xA3, 0x47, 0xA4,
0xC0, 0x84, 0x4C, 0xEB, 0x7E, 0xB0, 0xCF, 0xF0,
0xAE, 0xB7, 0x77, 0x69, 0x85, 0x93, 0xE4, 0x99,
0x5A, 0x95, 0x4E, 0x58, 0x17, 0x38, 0xCE, 0xD6,
0x81, 0xB0, 0xBD, 0x77, 0x09, 0xE7, 0xF8, 0x9A,
0xDF, 0xAD, 0x05, 0x48, 0x83, 0xF6, 0xC3, 0xFD,
0xDF, 0x7B, 0x83, 0xE0, 0x0C, 0x26, 0x81, 0x54,
0x43, 0x29, 0xEA, 0x82, 0x6C, 0x89, 0xF0, 0xA6,
0x74, 0x42, 0x86, 0x4D, 0x32, 0x60, 0x32, 0x7D,
0xA7, 0x7A, 0x13, 0x40, 0x66, 0x59, 0xDA, 0x3E,
0x41, 0x6B, 0x27, 0x94, 0x03, 0x4F, 0xAA, 0x22,
0x9D, 0xD5, 0x54, 0x52, 0xDB, 0x27, 0x0A, 0x6A,
0xA2, 0x3D, 0x19, 0xB1, 0x66, 0x1B, 0x19, 0x7D,
0xAB, 0xC7, 0x0E, 0x88, 0x17, 0x91, 0xA1, 0x2A,
0xB4, 0x3C, 0x6C, 0xCB, 0xF5, 0xAA, 0x7C, 0x3A,
0xDD, 0x36, 0xFB, 0x35, 0x71, 0x7B, 0x20, 0x01,
0x59, 0x00, 0xD6, 0xF6, 0x90, 0x39, 0x35, 0x41,
0x31, 0xF8, 0xC1, 0xC0, 0x57, 0x3A, 0x35, 0x18,
0x58, 0x90, 0xB1, 0xAD, 0x9A, 0x0E, 0xEC, 0xE0,
0xF4, 0x7A, 0x7D, 0xA5, 0x27, 0x48, 0xC9, 0x72,
0xAB, 0x0D, 0x08, 0x7B, 0x62, 0x35, 0x40, 0x91,
0x14, 0x2B, 0xB1, 0x1D, 0x1A, 0xFA, 0xF9, 0xCD,
0x5C, 0x17, 0x13, 0x53, 0x52, 0x71, 0xCA, 0xE2,
0x2A, 0x78, 0xB1, 0x7F, 0x4A, 0xCD, 0x59, 0xD8,
0xBA, 0x1D, 0x7D, 0x70, 0x5F, 0x78, 0x1B, 0x9F,
0x9D, 0x37, 0x18, 0x8E, 0xD7, 0xCD, 0x0D, 0x49,
0x57, 0x74, 0x69, 0x88, 0x3A, 0x6B, 0x8E, 0x4E,
0x1B, 0x85, 0xDD, 0xBE, 0x39, 0x45, 0x05, 0x89,
0x56, 0x12, 0x97, 0x59, 0x9A, 0x09, 0xA4, 0xC8,
0x2D, 0x2F, 0xF5, 0xCF, 0xB4, 0x73, 0x70, 0xDB,
0x58, 0x1E, 0xB2, 0x4E, 0x77, 0x6F, 0xA4, 0x7E,
0x62, 0xDF, 0xB7, 0x05, 0xE8, 0x80, 0x42, 0x5C,
0xB8, 0x78, 0x87, 0x97, 0x7F, 0x66, 0x2C, 0x5F,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char cpA_dpki_cert[0x300] =
{
0x00, 0x01, 0x00, 0x04, 0x50, 0x05, 0xD7, 0x5E,
0x6D, 0xDE, 0xB8, 0x78, 0x3C, 0x81, 0xE9, 0xEF,
0x0D, 0x17, 0xCD, 0x58, 0xF5, 0x94, 0x26, 0xA3,
0xFD, 0x6F, 0x69, 0x90, 0xE8, 0xF8, 0x32, 0x87,
0x12, 0x2E, 0xC2, 0x5C, 0xA1, 0x4B, 0x99, 0x24,
0x23, 0x37, 0xBA, 0x91, 0xA7, 0x5B, 0x0F, 0x7C,
0x59, 0xFB, 0xF7, 0xD1, 0x89, 0x27, 0x22, 0xC4,
0xE6, 0xAF, 0xC7, 0xDE, 0xC7, 0x4A, 0x6E, 0x00,
0x7F, 0x43, 0x4A, 0x88, 0x8A, 0x82, 0x15, 0xE8,
0xDF, 0x2B, 0x52, 0xED, 0x42, 0x00, 0xBC, 0x69,
0xB4, 0xDA, 0x7F, 0xEB, 0x74, 0x6C, 0x7A, 0x2D,
0x96, 0x56, 0x5B, 0x45, 0x59, 0x7B, 0x8F, 0xAE,
0xB1, 0x6B, 0xDC, 0x76, 0xC1, 0xC8, 0x0C, 0x47,
0xF5, 0x0D, 0xA9, 0xC3, 0xE1, 0xFE, 0x28, 0x50,
0x1C, 0x26, 0xA2, 0xD1, 0x54, 0x4B, 0xD1, 0x60,
0x4A, 0x9E, 0x8F, 0x32, 0x2A, 0xEF, 0x31, 0x5F,
0xEA, 0x48, 0x22, 0x67, 0x22, 0xB7, 0xCB, 0x37,
0x2F, 0xF3, 0x5F, 0x5E, 0x61, 0x6A, 0x53, 0x44,
0xA5, 0x85, 0xE5, 0xA0, 0x8A, 0x2E, 0x17, 0x77,
0x57, 0x2B, 0x7A, 0x9A, 0xF7, 0xD2, 0xD8, 0xC4,
0x9C, 0xD0, 0xA0, 0x54, 0xBF, 0x8A, 0x9D, 0xB4,
0x9F, 0xC6, 0x60, 0x61, 0x7C, 0xB8, 0x35, 0x4E,
0x25, 0x7F, 0x68, 0x68, 0x2F, 0x94, 0xB3, 0xCC,
0x53, 0x8C, 0x42, 0x6F, 0x88, 0xC5, 0x48, 0x5C,
0xBE, 0xC1, 0xD0, 0x48, 0x04, 0x74, 0x96, 0x5A,
0x7E, 0x82, 0x59, 0xAA, 0x9F, 0xB6, 0x61, 0x46,
0xCE, 0x59, 0x21, 0xC6, 0xF0, 0xC1, 0x75, 0x1F,
0x21, 0x91, 0x7F, 0x24, 0x96, 0xCB, 0x0C, 0x70,
0x15, 0x7A, 0xB7, 0xBB, 0x3A, 0x9F, 0x57, 0x56,
0x56, 0x5C, 0x38, 0x92, 0x2E, 0xFD, 0xC8, 0xF1,
0x70, 0xB9, 0xAE, 0xA1, 0xAE, 0x36, 0xF5, 0x5E,
0x35, 0x26, 0x63, 0x0A, 0xBA, 0xB2, 0x05, 0x0F,
0xF0, 0x0C, 0xDC, 0xBB, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x43, 0x41, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x61, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0xA3, 0x4D, 0x5B,
0xAA, 0x7F, 0x93, 0x80, 0x28, 0x9B, 0xE8, 0x98,
0x63, 0x10, 0x7A, 0xE1, 0x0C, 0x59, 0x2C, 0x2F,
0x7C, 0xFF, 0xBD, 0xAA, 0xDD, 0x74, 0xF4, 0xA2,
0xFB, 0xAC, 0xD7, 0x6F, 0x00, 0x93, 0x42, 0x06,
0x34, 0x71, 0x56, 0xD8, 0x40, 0x49, 0x72, 0x9F,
0x3E, 0x24, 0xFA, 0x5E, 0x19, 0xD1, 0x5B, 0x63,
0x5C, 0xD2, 0xEF, 0x09, 0xDE, 0x32, 0xEE, 0x6B,
0x6F, 0xC8, 0xFA, 0x32, 0x8E, 0x2E, 0x96, 0xB9,
0x94, 0x41, 0x04, 0x7D, 0x07, 0x62, 0x95, 0xDA,
0x0D, 0x91, 0xD8, 0x09, 0x35, 0xD0, 0xDE, 0x8E,
0x6B, 0xC6, 0xAB, 0x14, 0x27, 0x01, 0x9C, 0xFE,
0x49, 0x96, 0xFC, 0x9B, 0x54, 0x79, 0x4D, 0xEB,
0xD7, 0xC6, 0x66, 0x73, 0xA6, 0xDD, 0x3A, 0x77,
0x65, 0x47, 0x94, 0xEC, 0x1C, 0x87, 0xAA, 0x46,
0xD9, 0x78, 0xA9, 0x7D, 0xDB, 0x11, 0x22, 0x6E,
0xD4, 0x12, 0xC2, 0x78, 0x4B, 0x21, 0x83, 0x92,
0xC7, 0x10, 0xC7, 0x74, 0x19, 0xFF, 0xAA, 0xF6,
0x0B, 0x75, 0xD8, 0x23, 0xDD, 0x33, 0xC3, 0xA1,
0x5B, 0xA7, 0x2D, 0x30, 0xA5, 0xA4, 0xD8, 0xF8,
0x0F, 0xD6, 0x73, 0xFD, 0x26, 0xCB, 0x29, 0xA6,
0xEF, 0x50, 0x39, 0xE2, 0x5F, 0x59, 0x61, 0x84,
0x6B, 0xDA, 0x2E, 0xC7, 0xCB, 0xE4, 0x38, 0x4B,
0x28, 0xFB, 0x0D, 0xD5, 0x8E, 0x7C, 0xAA, 0x7D,
0x4B, 0x37, 0x3A, 0xD7, 0x81, 0xDD, 0x73, 0xE3,
0x09, 0x93, 0xBD, 0xBD, 0x7E, 0x08, 0x55, 0x4A,
0x8C, 0xA5, 0xC9, 0x84, 0x2D, 0x71, 0x01, 0xA2,
0x2A, 0x01, 0xB0, 0x15, 0xFB, 0x30, 0x78, 0xB9,
0x13, 0xF4, 0xC7, 0x3F, 0xB5, 0xA6, 0xF1, 0xA2,
0x5E, 0x22, 0xB0, 0x02, 0xB6, 0xE0, 0x09, 0x54,
0x7F, 0x0F, 0xBD, 0xF0, 0xFE, 0xA5, 0x50, 0x1D,
0x93, 0x15, 0xF9, 0x3D, 0x83, 0x0F, 0x0F, 0x0E,
0x3D, 0xE2, 0x3D, 0x96, 0xE7, 0x09, 0xD9, 0x77,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif
+557
View File
@@ -0,0 +1,557 @@
#ifndef _KEYS_RETAIL_H_
#define _KEYS_RETAIL_H_
// AES KEYS
static const unsigned char zeros_fixed_aesKey[16] = //zeros_fixed_aesKey
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// RSA KEYS
static const unsigned char cert_root_rsa_pubk[0x200] =
{
0xF8, 0x24, 0x6C, 0x58, 0xBA, 0xE7, 0x50, 0x03,
0x01, 0xFB, 0xB7, 0xC2, 0xEB, 0xE0, 0x01, 0x05,
0x71, 0xDA, 0x92, 0x23, 0x78, 0xF0, 0x51, 0x4E,
0xC0, 0x03, 0x1D, 0xD0, 0xD2, 0x1E, 0xD3, 0xD0,
0x7E, 0xFC, 0x85, 0x20, 0x69, 0xB5, 0xDE, 0x9B,
0xB9, 0x51, 0xA8, 0xBC, 0x90, 0xA2, 0x44, 0x92,
0x6D, 0x37, 0x92, 0x95, 0xAE, 0x94, 0x36, 0xAA,
0xA6, 0xA3, 0x02, 0x51, 0x0C, 0x7B, 0x1D, 0xED,
0xD5, 0xFB, 0x20, 0x86, 0x9D, 0x7F, 0x30, 0x16,
0xF6, 0xBE, 0x65, 0xD3, 0x83, 0xA1, 0x6D, 0xB3,
0x32, 0x1B, 0x95, 0x35, 0x18, 0x90, 0xB1, 0x70,
0x02, 0x93, 0x7E, 0xE1, 0x93, 0xF5, 0x7E, 0x99,
0xA2, 0x47, 0x4E, 0x9D, 0x38, 0x24, 0xC7, 0xAE,
0xE3, 0x85, 0x41, 0xF5, 0x67, 0xE7, 0x51, 0x8C,
0x7A, 0x0E, 0x38, 0xE7, 0xEB, 0xAF, 0x41, 0x19,
0x1B, 0xCF, 0xF1, 0x7B, 0x42, 0xA6, 0xB4, 0xED,
0xE6, 0xCE, 0x8D, 0xE7, 0x31, 0x8F, 0x7F, 0x52,
0x04, 0xB3, 0x99, 0x0E, 0x22, 0x67, 0x45, 0xAF,
0xD4, 0x85, 0xB2, 0x44, 0x93, 0x00, 0x8B, 0x08,
0xC7, 0xF6, 0xB7, 0xE5, 0x6B, 0x02, 0xB3, 0xE8,
0xFE, 0x0C, 0x9D, 0x85, 0x9C, 0xB8, 0xB6, 0x82,
0x23, 0xB8, 0xAB, 0x27, 0xEE, 0x5F, 0x65, 0x38,
0x07, 0x8B, 0x2D, 0xB9, 0x1E, 0x2A, 0x15, 0x3E,
0x85, 0x81, 0x80, 0x72, 0xA2, 0x3B, 0x6D, 0xD9,
0x32, 0x81, 0x05, 0x4F, 0x6F, 0xB0, 0xF6, 0xF5,
0xAD, 0x28, 0x3E, 0xCA, 0x0B, 0x7A, 0xF3, 0x54,
0x55, 0xE0, 0x3D, 0xA7, 0xB6, 0x83, 0x26, 0xF3,
0xEC, 0x83, 0x4A, 0xF3, 0x14, 0x04, 0x8A, 0xC6,
0xDF, 0x20, 0xD2, 0x85, 0x08, 0x67, 0x3C, 0xAB,
0x62, 0xA2, 0xC7, 0xBC, 0x13, 0x1A, 0x53, 0x3E,
0x0B, 0x66, 0x80, 0x6B, 0x1C, 0x30, 0x66, 0x4B,
0x37, 0x23, 0x31, 0xBD, 0xC4, 0xB0, 0xCA, 0xD8,
0xD1, 0x1E, 0xE7, 0xBB, 0xD9, 0x28, 0x55, 0x48,
0xAA, 0xEC, 0x1F, 0x66, 0xE8, 0x21, 0xB3, 0xC8,
0xA0, 0x47, 0x69, 0x00, 0xC5, 0xE6, 0x88, 0xE8,
0x0C, 0xCE, 0x3C, 0x61, 0xD6, 0x9C, 0xBB, 0xA1,
0x37, 0xC6, 0x60, 0x4F, 0x7A, 0x72, 0xDD, 0x8C,
0x7B, 0x3E, 0x3D, 0x51, 0x29, 0x0D, 0xAA, 0x6A,
0x59, 0x7B, 0x08, 0x1F, 0x9D, 0x36, 0x33, 0xA3,
0x46, 0x7A, 0x35, 0x61, 0x09, 0xAC, 0xA7, 0xDD,
0x7D, 0x2E, 0x2F, 0xB2, 0xC1, 0xAE, 0xB8, 0xE2,
0x0F, 0x48, 0x92, 0xD8, 0xB9, 0xF8, 0xB4, 0x6F,
0x4E, 0x3C, 0x11, 0xF4, 0xF4, 0x7D, 0x8B, 0x75,
0x7D, 0xFE, 0xFE, 0xA3, 0x89, 0x9C, 0x33, 0x59,
0x5C, 0x5E, 0xFD, 0xEB, 0xCB, 0xAB, 0xE8, 0x41,
0x3E, 0x3A, 0x9A, 0x80, 0x3C, 0x69, 0x35, 0x6E,
0xB2, 0xB2, 0xAD, 0x5C, 0xC4, 0xC8, 0x58, 0x45,
0x5E, 0xF5, 0xF7, 0xB3, 0x06, 0x44, 0xB4, 0x7C,
0x64, 0x06, 0x8C, 0xDF, 0x80, 0x9F, 0x76, 0x02,
0x5A, 0x2D, 0xB4, 0x46, 0xE0, 0x3D, 0x7C, 0xF6,
0x2F, 0x34, 0xE7, 0x02, 0x45, 0x7B, 0x02, 0xA4,
0xCF, 0x5D, 0x9D, 0xD5, 0x3C, 0xA5, 0x3A, 0x7C,
0xA6, 0x29, 0x78, 0x8C, 0x67, 0xCA, 0x08, 0xBF,
0xEC, 0xCA, 0x43, 0xA9, 0x57, 0xAD, 0x16, 0xC9,
0x4E, 0x1C, 0xD8, 0x75, 0xCA, 0x10, 0x7D, 0xCE,
0x7E, 0x01, 0x18, 0xF0, 0xDF, 0x6B, 0xFE, 0xE5,
0x1D, 0xDB, 0xD9, 0x91, 0xC2, 0x6E, 0x60, 0xCD,
0x48, 0x58, 0xAA, 0x59, 0x2C, 0x82, 0x00, 0x75,
0xF2, 0x9F, 0x52, 0x6C, 0x91, 0x7C, 0x6F, 0xE5,
0x40, 0x3E, 0xA7, 0xD4, 0xA5, 0x0C, 0xEC, 0x3B,
0x73, 0x84, 0xDE, 0x88, 0x6E, 0x82, 0xD2, 0xEB,
0x4D, 0x4E, 0x42, 0xB5, 0xF2, 0xB1, 0x49, 0xA8,
0x1E, 0xA7, 0xCE, 0x71, 0x44, 0xDC, 0x29, 0x94,
0xCF, 0xC4, 0x4E, 0x1F, 0x91, 0xCB, 0xD4, 0x95
};
static const unsigned char AccessDesc_pubMod[0x100] =
{
0xB1, 0xE3, 0xE3, 0x5F, 0x01, 0x39, 0x80, 0xD1,
0x56, 0x78, 0x9D, 0xB7, 0x06, 0xF7, 0x1D, 0xBF,
0x3E, 0x22, 0x76, 0xED, 0xF9, 0x5D, 0xA2, 0x36,
0xB6, 0x30, 0x61, 0x05, 0x96, 0xD3, 0x00, 0xB9,
0xED, 0xF1, 0xD7, 0xE0, 0x1D, 0xA0, 0x4F, 0xB7,
0xCF, 0x5A, 0x19, 0x87, 0x75, 0x49, 0x88, 0x40,
0xED, 0xE3, 0x6F, 0x7C, 0x90, 0x4A, 0x64, 0x45,
0x98, 0xD7, 0x04, 0xB9, 0x5A, 0x6B, 0x45, 0xAA,
0x7E, 0x94, 0xC0, 0xB3, 0xB7, 0xDB, 0x7B, 0x66,
0x59, 0x20, 0xB7, 0x08, 0xE2, 0xF3, 0x83, 0xA3,
0x7F, 0xE3, 0x20, 0x21, 0xA0, 0xEB, 0xB7, 0x28,
0x0F, 0xF3, 0x2B, 0x15, 0xA4, 0xC9, 0xD0, 0xAB,
0x89, 0x39, 0x99, 0x7E, 0x76, 0x5F, 0x9E, 0x4D,
0x1E, 0x01, 0x22, 0x8D, 0x74, 0xA6, 0xEB, 0x9A,
0xA3, 0x9D, 0x45, 0xE5, 0x10, 0x61, 0x6E, 0x20,
0xFD, 0x23, 0x75, 0xC0, 0xC5, 0x05, 0x03, 0xC5,
0x4C, 0x02, 0x4F, 0x54, 0x4B, 0x57, 0x08, 0xB4,
0x46, 0xC3, 0x2C, 0xF1, 0xF9, 0x52, 0x6C, 0xCD,
0x14, 0x55, 0xA8, 0x55, 0x92, 0x6D, 0xE2, 0x4A,
0x41, 0x46, 0xEB, 0x08, 0xC5, 0xF3, 0xB4, 0x8D,
0x0D, 0x5E, 0x21, 0xEA, 0xAF, 0x4D, 0x27, 0x4D,
0xDE, 0x77, 0x93, 0x97, 0xE2, 0xC7, 0x6B, 0x66,
0x1F, 0xDB, 0x2D, 0x6E, 0xA9, 0x5F, 0x61, 0x14,
0x17, 0x7B, 0x2B, 0x66, 0x5A, 0xB5, 0x01, 0x89,
0xF2, 0x23, 0x75, 0x25, 0x25, 0x9C, 0x86, 0x9A,
0x89, 0xFF, 0x64, 0x1D, 0x5B, 0xCE, 0xD7, 0x7E,
0x3F, 0x2D, 0xA8, 0xDA, 0xB5, 0x5A, 0xC5, 0x5F,
0x59, 0x20, 0xB0, 0xED, 0x1C, 0x91, 0xFF, 0xA3,
0x27, 0xB8, 0x8E, 0xCF, 0x82, 0x15, 0xE5, 0x49,
0xEF, 0xE4, 0x58, 0xE1, 0x5F, 0x8F, 0x53, 0xB9,
0x33, 0x2A, 0x56, 0x24, 0xAA, 0xA1, 0xD3, 0x6E,
0x47, 0x1A, 0x63, 0x44, 0x19, 0xB3, 0x8E, 0xA5
};
static const unsigned char RetailNcsdCfa_pubMod[0x100] =
{
0xFB, 0xDE, 0xB8, 0x2B, 0x40, 0x93, 0x0F, 0xF6,
0xB1, 0x9A, 0x08, 0x06, 0x1B, 0x86, 0xFE, 0xD0,
0xDF, 0x10, 0x79, 0x17, 0x3D, 0x8C, 0xE2, 0x7A,
0xCE, 0x8F, 0x23, 0x45, 0xB9, 0x0A, 0x6D, 0xED,
0x30, 0x0E, 0xC1, 0xA8, 0x92, 0xC4, 0xBD, 0x1A,
0xCE, 0xA7, 0xAC, 0x77, 0xAA, 0x47, 0xE5, 0x20,
0x4A, 0x44, 0x91, 0xDF, 0x1C, 0xFE, 0x86, 0x28,
0x12, 0x2D, 0x66, 0xDF, 0xBE, 0xAD, 0x96, 0x61,
0xED, 0xF2, 0xF7, 0x41, 0x7B, 0x57, 0x88, 0x6B,
0x24, 0x1E, 0x7D, 0xEC, 0xBE, 0x98, 0x65, 0x65,
0x36, 0x65, 0x99, 0xA9, 0xFE, 0x24, 0x67, 0x85,
0x99, 0xEE, 0x2A, 0xAE, 0xEE, 0xB1, 0x81, 0x1A,
0x22, 0xE3, 0x6D, 0x75, 0x6E, 0x21, 0xBC, 0xEF,
0x11, 0x5C, 0x61, 0xAF, 0x0C, 0x30, 0x00, 0xB6,
0xA2, 0x23, 0xED, 0xFE, 0x70, 0x15, 0xDA, 0x52,
0xE1, 0xE6, 0x2D, 0xCE, 0x34, 0xE8, 0xAA, 0x4C,
0xF1, 0xD6, 0x67, 0x56, 0x57, 0xD3, 0xDB, 0xC0,
0x90, 0x49, 0x6F, 0x45, 0x73, 0x93, 0x4E, 0x30,
0x30, 0x70, 0xF5, 0xC9, 0x8F, 0x31, 0x25, 0xF2,
0xC2, 0xE7, 0x33, 0x7F, 0x4E, 0xB6, 0xF5, 0x2A,
0xDF, 0x20, 0x00, 0xE5, 0x79, 0xB2, 0xD0, 0xF9,
0x17, 0xF7, 0x7E, 0x16, 0x90, 0x40, 0x00, 0x57,
0x91, 0x44, 0x78, 0xEF, 0x1C, 0xE0, 0x85, 0x09,
0xDA, 0xF4, 0x14, 0x7E, 0x4B, 0xD7, 0x35, 0xD6,
0x87, 0x54, 0x8F, 0x2A, 0xB5, 0xA7, 0x6F, 0x50,
0xD0, 0xF7, 0xD1, 0xF1, 0x19, 0xC9, 0xAC, 0x22,
0x7E, 0x05, 0x11, 0xF5, 0xF2, 0x6D, 0xEE, 0x92,
0x27, 0x57, 0x5F, 0xE5, 0x15, 0x0D, 0x27, 0x68,
0xBF, 0x52, 0x65, 0x74, 0x73, 0xA6, 0x58, 0x6D,
0x79, 0x18, 0xAC, 0x31, 0xDD, 0xDD, 0x80, 0x8B,
0x75, 0x24, 0xE1, 0x17, 0xE1, 0x95, 0x25, 0x16,
0x29, 0xAB, 0x69, 0x69, 0xC8, 0x28, 0xEE, 0x5D
};
static const unsigned char Dummy_rsa_privExp[256] = //Dummy_rsa_privExp
{
0xE3, 0xC6, 0x76, 0x57, 0x2E, 0xCB, 0xA5, 0xE6,
0x0C, 0x01, 0xBD, 0x5C, 0x32, 0x2D, 0x90, 0xE0,
0xFF, 0x9A, 0x80, 0xE8, 0x66, 0x8D, 0x84, 0xDC,
0xF7, 0x75, 0x5F, 0x3F, 0x98, 0x7C, 0x97, 0x40,
0x20, 0x21, 0xB7, 0x24, 0xC0, 0x61, 0x2D, 0x83,
0xB0, 0x91, 0x8E, 0xE3, 0xC2, 0xD0, 0x2C, 0xA1,
0x2C, 0x99, 0x4F, 0x48, 0xF7, 0x4E, 0x13, 0xD3,
0x01, 0x71, 0x25, 0x9B, 0x3C, 0x75, 0x7C, 0xC4,
0xE5, 0x89, 0x7E, 0xDA, 0xF9, 0x99, 0x5C, 0x83,
0xE4, 0xDD, 0x36, 0x62, 0x5B, 0x0E, 0x12, 0x91,
0xD6, 0x39, 0x45, 0x69, 0x62, 0x20, 0xCA, 0xF4,
0xBA, 0x6B, 0x28, 0x1A, 0x7C, 0xBF, 0xB9, 0x97,
0x37, 0x46, 0xC2, 0x7A, 0xCF, 0x10, 0x68, 0xC2,
0xC9, 0xF1, 0x48, 0xDA, 0x8A, 0x2F, 0x4C, 0xBC,
0x3B, 0x1C, 0xB8, 0x8F, 0x04, 0x7F, 0xFD, 0x9D,
0xE2, 0x0A, 0xD2, 0x09, 0x39, 0xC7, 0xD9, 0x81,
0x59, 0x17, 0x73, 0xB2, 0xEC, 0xEB, 0x36, 0x67,
0xA5, 0xA8, 0xD5, 0x71, 0xD9, 0x38, 0x6A, 0xD1,
0x28, 0xB9, 0x46, 0x85, 0x3A, 0x81, 0x85, 0x4E,
0x55, 0xA7, 0x74, 0x79, 0xBB, 0xC5, 0x97, 0xF7,
0xEF, 0xE0, 0x81, 0x20, 0xE0, 0xEA, 0x45, 0x8F,
0xED, 0x70, 0x8E, 0xD6, 0xFF, 0x49, 0xCF, 0x7F,
0xF2, 0xFF, 0x22, 0x20, 0x3F, 0xE9, 0x92, 0x99,
0xDE, 0x81, 0xD6, 0x27, 0xF7, 0xB8, 0x3A, 0x1D,
0x4F, 0xA2, 0x50, 0xFB, 0xA5, 0xE7, 0x98, 0x08,
0xB5, 0x2B, 0xA2, 0x94, 0xA9, 0x17, 0x1A, 0xA8,
0x34, 0xF6, 0x5E, 0x24, 0x2D, 0x40, 0x2F, 0xCB,
0x3C, 0xB0, 0xF8, 0x7E, 0x84, 0xB4, 0x87, 0x82,
0x19, 0xAF, 0x87, 0xB6, 0xFA, 0xA9, 0x67, 0x27,
0x07, 0x28, 0xBA, 0x2E, 0xA5, 0x8E, 0xDD, 0xE5,
0xD4, 0xFD, 0x06, 0x09, 0xDF, 0xBD, 0x87, 0x95,
0x95, 0x25, 0x05, 0x5E, 0xB2, 0x00, 0x18, 0x41
};
static const unsigned char Dummy_rsa_pubMod[256] = //Dummy_rsa_pubMod
{
0xE6, 0x64, 0x06, 0x6C, 0x49, 0x6B, 0xEC, 0xEE,
0x59, 0xAE, 0x11, 0x92, 0xF1, 0x03, 0x43, 0x87,
0x8E, 0xEB, 0x4D, 0x70, 0xA9, 0x71, 0xB4, 0x6D,
0x25, 0x19, 0x02, 0x4A, 0x9E, 0x4D, 0xA3, 0x10,
0xFD, 0xB2, 0x27, 0x56, 0xA3, 0xFB, 0xDD, 0xE5,
0xE4, 0x4E, 0xE0, 0x62, 0x8F, 0xC3, 0x2E, 0xEE,
0x8F, 0x9D, 0x4D, 0x6E, 0x00, 0xDB, 0x88, 0x49,
0xA2, 0xFC, 0x30, 0xFE, 0x94, 0xF3, 0x06, 0x92,
0x75, 0x61, 0x11, 0x1D, 0x24, 0x07, 0xE9, 0x12,
0xB6, 0xB1, 0x57, 0xF5, 0xDC, 0x01, 0xF7, 0x54,
0xBF, 0xC3, 0xAC, 0x8C, 0x73, 0x2C, 0x73, 0x17,
0x8E, 0xBF, 0x2F, 0x68, 0x3C, 0x61, 0x75, 0x32,
0x15, 0x39, 0x93, 0xDD, 0xBA, 0x12, 0x42, 0xD3,
0x25, 0x85, 0xFA, 0xA6, 0x4B, 0xAF, 0x81, 0x4B,
0xCA, 0xD2, 0x9C, 0xF1, 0x3D, 0x37, 0xAE, 0xB9,
0xFD, 0x77, 0x59, 0x78, 0xB9, 0x32, 0x95, 0x19,
0xD1, 0x47, 0xE1, 0xC6, 0xE1, 0x16, 0x13, 0x5D,
0xCC, 0x99, 0x31, 0x63, 0xAD, 0xBB, 0xA5, 0x4F,
0xE4, 0x41, 0x67, 0xFD, 0x7F, 0x1E, 0xA8, 0x9A,
0x35, 0x65, 0xEB, 0xC4, 0x4D, 0xD4, 0xC4, 0x29,
0x0F, 0x40, 0x95, 0xFD, 0x8A, 0x30, 0x67, 0x79,
0xFB, 0xD4, 0x76, 0x6F, 0xD1, 0xDE, 0x8C, 0x72,
0x32, 0x05, 0x97, 0x5A, 0x26, 0x0D, 0x37, 0xCA,
0x12, 0x2C, 0xDC, 0x14, 0x3F, 0xD3, 0x59, 0x00,
0x66, 0xD2, 0x8E, 0xF5, 0x6E, 0x22, 0x08, 0x63,
0x59, 0xB5, 0x3F, 0xBB, 0x3A, 0x4D, 0xD4, 0xD1,
0xC1, 0x21, 0xA7, 0x4D, 0x02, 0x96, 0x08, 0xF5,
0x2B, 0x11, 0xE5, 0x85, 0xD2, 0x6E, 0x91, 0xD6,
0x8F, 0x77, 0x72, 0xEF, 0x37, 0xE3, 0x79, 0x19,
0xA9, 0xEE, 0x58, 0x5D, 0x52, 0x9B, 0x2D, 0x47,
0x7D, 0x27, 0xB8, 0xC3, 0x76, 0xCA, 0xDA, 0xC2,
0xF4, 0xFC, 0xF4, 0x53, 0x7C, 0xD8, 0x43, 0x87
};
//Certificates
static const unsigned char ca3_dpki_cert[0x400] =
{
0x00, 0x01, 0x00, 0x03, 0x70, 0x41, 0x38, 0xEF,
0xBB, 0xBD, 0xA1, 0x6A, 0x98, 0x7D, 0xD9, 0x01,
0x32, 0x6D, 0x1C, 0x94, 0x59, 0x48, 0x4C, 0x88,
0xA2, 0x86, 0x1B, 0x91, 0xA3, 0x12, 0x58, 0x7A,
0xE7, 0x0E, 0xF6, 0x23, 0x7E, 0xC5, 0x0E, 0x10,
0x32, 0xDC, 0x39, 0xDD, 0xE8, 0x9A, 0x96, 0xA8,
0xE8, 0x59, 0xD7, 0x6A, 0x98, 0xA6, 0xE7, 0xE3,
0x6A, 0x0C, 0xFE, 0x35, 0x2C, 0xA8, 0x93, 0x05,
0x82, 0x34, 0xFF, 0x83, 0x3F, 0xCB, 0x3B, 0x03,
0x81, 0x1E, 0x9F, 0x0D, 0xC0, 0xD9, 0xA5, 0x2F,
0x80, 0x45, 0xB4, 0xB2, 0xF9, 0x41, 0x1B, 0x67,
0xA5, 0x1C, 0x44, 0xB5, 0xEF, 0x8C, 0xE7, 0x7B,
0xD6, 0xD5, 0x6B, 0xA7, 0x57, 0x34, 0xA1, 0x85,
0x6D, 0xE6, 0xD4, 0xBE, 0xD6, 0xD3, 0xA2, 0x42,
0xC7, 0xC8, 0x79, 0x1B, 0x34, 0x22, 0x37, 0x5E,
0x5C, 0x77, 0x9A, 0xBF, 0x07, 0x2F, 0x76, 0x95,
0xEF, 0xA0, 0xF7, 0x5B, 0xCB, 0x83, 0x78, 0x9F,
0xC3, 0x0E, 0x3F, 0xE4, 0xCC, 0x83, 0x92, 0x20,
0x78, 0x40, 0x63, 0x89, 0x49, 0xC7, 0xF6, 0x88,
0x56, 0x5F, 0x64, 0x9B, 0x74, 0xD6, 0x3D, 0x8D,
0x58, 0xFF, 0xAD, 0xDA, 0x57, 0x1E, 0x95, 0x54,
0x42, 0x6B, 0x13, 0x18, 0xFC, 0x46, 0x89, 0x83,
0xD4, 0xC8, 0xA5, 0x62, 0x8B, 0x06, 0xB6, 0xFC,
0x5D, 0x50, 0x7C, 0x13, 0xE7, 0xA1, 0x8A, 0xC1,
0x51, 0x1E, 0xB6, 0xD6, 0x2E, 0xA5, 0x44, 0x8F,
0x83, 0x50, 0x14, 0x47, 0xA9, 0xAF, 0xB3, 0xEC,
0xC2, 0x90, 0x3C, 0x9D, 0xD5, 0x2F, 0x92, 0x2A,
0xC9, 0xAC, 0xDB, 0xEF, 0x58, 0xC6, 0x02, 0x18,
0x48, 0xD9, 0x6E, 0x20, 0x87, 0x32, 0xD3, 0xD1,
0xD9, 0xD9, 0xEA, 0x44, 0x0D, 0x91, 0x62, 0x1C,
0x7A, 0x99, 0xDB, 0x88, 0x43, 0xC5, 0x9C, 0x1F,
0x2E, 0x2C, 0x7D, 0x9B, 0x57, 0x7D, 0x51, 0x2C,
0x16, 0x6D, 0x6F, 0x7E, 0x1A, 0xAD, 0x4A, 0x77,
0x4A, 0x37, 0x44, 0x7E, 0x78, 0xFE, 0x20, 0x21,
0xE1, 0x4A, 0x95, 0xD1, 0x12, 0xA0, 0x68, 0xAD,
0xA0, 0x19, 0xF4, 0x63, 0xC7, 0xA5, 0x56, 0x85,
0xAA, 0xBB, 0x68, 0x88, 0xB9, 0x24, 0x64, 0x83,
0xD1, 0x8B, 0x9C, 0x80, 0x6F, 0x47, 0x49, 0x18,
0x33, 0x17, 0x82, 0x34, 0x4A, 0x4B, 0x85, 0x31,
0x33, 0x4B, 0x26, 0x30, 0x32, 0x63, 0xD9, 0xD2,
0xEB, 0x4F, 0x4B, 0xB9, 0x96, 0x02, 0xB3, 0x52,
0xF6, 0xAE, 0x40, 0x46, 0xC6, 0x9A, 0x5E, 0x7E,
0x8E, 0x4A, 0x18, 0xEF, 0x9B, 0xC0, 0xA2, 0xDE,
0xD6, 0x13, 0x10, 0x41, 0x70, 0x12, 0xFD, 0x82,
0x4C, 0xC1, 0x16, 0xCF, 0xB7, 0xC4, 0xC1, 0xF7,
0xEC, 0x71, 0x77, 0xA1, 0x74, 0x46, 0xCB, 0xDE,
0x96, 0xF3, 0xED, 0xD8, 0x8F, 0xCD, 0x05, 0x2F,
0x0B, 0x88, 0x8A, 0x45, 0xFD, 0xAF, 0x2B, 0x63,
0x13, 0x54, 0xF4, 0x0D, 0x16, 0xE5, 0xFA, 0x9C,
0x2C, 0x4E, 0xDA, 0x98, 0xE7, 0x98, 0xD1, 0x5E,
0x60, 0x46, 0xDC, 0x53, 0x63, 0xF3, 0x09, 0x6B,
0x2C, 0x60, 0x7A, 0x9D, 0x8D, 0xD5, 0x5B, 0x15,
0x02, 0xA6, 0xAC, 0x7D, 0x3C, 0xC8, 0xD8, 0xC5,
0x75, 0x99, 0x8E, 0x7D, 0x79, 0x69, 0x10, 0xC8,
0x04, 0xC4, 0x95, 0x23, 0x50, 0x57, 0xE9, 0x1E,
0xCD, 0x26, 0x37, 0xC9, 0xC1, 0x84, 0x51, 0x51,
0xAC, 0x6B, 0x9A, 0x04, 0x90, 0xAE, 0x3E, 0xC6,
0xF4, 0x77, 0x40, 0xA0, 0xDB, 0x0B, 0xA3, 0x6D,
0x07, 0x59, 0x56, 0xCE, 0xE7, 0x35, 0x4E, 0xA3,
0xE9, 0xA4, 0xF2, 0x72, 0x0B, 0x26, 0x55, 0x0C,
0x7D, 0x39, 0x43, 0x24, 0xBC, 0x0C, 0xB7, 0xE9,
0x31, 0x7D, 0x8A, 0x86, 0x61, 0xF4, 0x21, 0x91,
0xFF, 0x10, 0xB0, 0x82, 0x56, 0xCE, 0x3F, 0xD2,
0x5B, 0x74, 0x5E, 0x51, 0x94, 0x90, 0x6B, 0x4D,
0x61, 0xCB, 0x4C, 0x2E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x6F, 0x6F, 0x74, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x43, 0x41, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7B, 0xE8, 0xEF, 0x6C,
0xB2, 0x79, 0xC9, 0xE2, 0xEE, 0xE1, 0x21, 0xC6,
0xEA, 0xF4, 0x4F, 0xF6, 0x39, 0xF8, 0x8F, 0x07,
0x8B, 0x4B, 0x77, 0xED, 0x9F, 0x95, 0x60, 0xB0,
0x35, 0x82, 0x81, 0xB5, 0x0E, 0x55, 0xAB, 0x72,
0x11, 0x15, 0xA1, 0x77, 0x70, 0x3C, 0x7A, 0x30,
0xFE, 0x3A, 0xE9, 0xEF, 0x1C, 0x60, 0xBC, 0x1D,
0x97, 0x46, 0x76, 0xB2, 0x3A, 0x68, 0xCC, 0x04,
0xB1, 0x98, 0x52, 0x5B, 0xC9, 0x68, 0xF1, 0x1D,
0xE2, 0xDB, 0x50, 0xE4, 0xD9, 0xE7, 0xF0, 0x71,
0xE5, 0x62, 0xDA, 0xE2, 0x09, 0x22, 0x33, 0xE9,
0xD3, 0x63, 0xF6, 0x1D, 0xD7, 0xC1, 0x9F, 0xF3,
0xA4, 0xA9, 0x1E, 0x8F, 0x65, 0x53, 0xD4, 0x71,
0xDD, 0x7B, 0x84, 0xB9, 0xF1, 0xB8, 0xCE, 0x73,
0x35, 0xF0, 0xF5, 0x54, 0x05, 0x63, 0xA1, 0xEA,
0xB8, 0x39, 0x63, 0xE0, 0x9B, 0xE9, 0x01, 0x01,
0x1F, 0x99, 0x54, 0x63, 0x61, 0x28, 0x70, 0x20,
0xE9, 0xCC, 0x0D, 0xAB, 0x48, 0x7F, 0x14, 0x0D,
0x66, 0x26, 0xA1, 0x83, 0x6D, 0x27, 0x11, 0x1F,
0x20, 0x68, 0xDE, 0x47, 0x72, 0x14, 0x91, 0x51,
0xCF, 0x69, 0xC6, 0x1B, 0xA6, 0x0E, 0xF9, 0xD9,
0x49, 0xA0, 0xF7, 0x1F, 0x54, 0x99, 0xF2, 0xD3,
0x9A, 0xD2, 0x8C, 0x70, 0x05, 0x34, 0x82, 0x93,
0xC4, 0x31, 0xFF, 0xBD, 0x33, 0xF6, 0xBC, 0xA6,
0x0D, 0xC7, 0x19, 0x5E, 0xA2, 0xBC, 0xC5, 0x6D,
0x20, 0x0B, 0xAF, 0x6D, 0x06, 0xD0, 0x9C, 0x41,
0xDB, 0x8D, 0xE9, 0xC7, 0x20, 0x15, 0x4C, 0xA4,
0x83, 0x2B, 0x69, 0xC0, 0x8C, 0x69, 0xCD, 0x3B,
0x07, 0x3A, 0x00, 0x63, 0x60, 0x2F, 0x46, 0x2D,
0x33, 0x80, 0x61, 0xA5, 0xEA, 0x6C, 0x91, 0x5C,
0xD5, 0x62, 0x35, 0x79, 0xC3, 0xEB, 0x64, 0xCE,
0x44, 0xEF, 0x58, 0x6D, 0x14, 0xBA, 0xAA, 0x88,
0x34, 0x01, 0x9B, 0x3E, 0xEB, 0xEE, 0xD3, 0x79,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char xsC_dpki_cert[0x300] =
{
0x00, 0x01, 0x00, 0x04, 0x91, 0x9E, 0xBE, 0x46,
0x4A, 0xD0, 0xF5, 0x52, 0xCD, 0x1B, 0x72, 0xE7,
0x88, 0x49, 0x10, 0xCF, 0x55, 0xA9, 0xF0, 0x2E,
0x50, 0x78, 0x96, 0x41, 0xD8, 0x96, 0x68, 0x3D,
0xC0, 0x05, 0xBD, 0x0A, 0xEA, 0x87, 0x07, 0x9D,
0x8A, 0xC2, 0x84, 0xC6, 0x75, 0x06, 0x5F, 0x74,
0xC8, 0xBF, 0x37, 0xC8, 0x80, 0x44, 0x40, 0x95,
0x02, 0xA0, 0x22, 0x98, 0x0B, 0xB8, 0xAD, 0x48,
0x38, 0x3F, 0x6D, 0x28, 0xA7, 0x9D, 0xE3, 0x96,
0x26, 0xCC, 0xB2, 0xB2, 0x2A, 0x0F, 0x19, 0xE4,
0x10, 0x32, 0xF0, 0x94, 0xB3, 0x9F, 0xF0, 0x13,
0x31, 0x46, 0xDE, 0xC8, 0xF6, 0xC1, 0xA9, 0xD5,
0x5C, 0xD2, 0x8D, 0x9E, 0x1C, 0x47, 0xB3, 0xD1,
0x1F, 0x4F, 0x54, 0x26, 0xC2, 0xC7, 0x80, 0x13,
0x5A, 0x27, 0x75, 0xD3, 0xCA, 0x67, 0x9B, 0xC7,
0xE8, 0x34, 0xF0, 0xE0, 0xFB, 0x58, 0xE6, 0x88,
0x60, 0xA7, 0x13, 0x30, 0xFC, 0x95, 0x79, 0x17,
0x93, 0xC8, 0xFB, 0xA9, 0x35, 0xA7, 0xA6, 0x90,
0x8F, 0x22, 0x9D, 0xEE, 0x2A, 0x0C, 0xA6, 0xB9,
0xB2, 0x3B, 0x12, 0xD4, 0x95, 0xA6, 0xFE, 0x19,
0xD0, 0xD7, 0x26, 0x48, 0x21, 0x68, 0x78, 0x60,
0x5A, 0x66, 0x53, 0x8D, 0xBF, 0x37, 0x68, 0x99,
0x90, 0x5D, 0x34, 0x45, 0xFC, 0x5C, 0x72, 0x7A,
0x0E, 0x13, 0xE0, 0xE2, 0xC8, 0x97, 0x1C, 0x9C,
0xFA, 0x6C, 0x60, 0x67, 0x88, 0x75, 0x73, 0x2A,
0x4E, 0x75, 0x52, 0x3D, 0x2F, 0x56, 0x2F, 0x12,
0xAA, 0xBD, 0x15, 0x73, 0xBF, 0x06, 0xC9, 0x40,
0x54, 0xAE, 0xFA, 0x81, 0xA7, 0x14, 0x17, 0xAF,
0x9A, 0x4A, 0x06, 0x6D, 0x0F, 0xFC, 0x5A, 0xD6,
0x4B, 0xAB, 0x28, 0xB1, 0xFF, 0x60, 0x66, 0x1F,
0x44, 0x37, 0xD4, 0x9E, 0x1E, 0x0D, 0x94, 0x12,
0xEB, 0x4B, 0xCA, 0xCF, 0x4C, 0xFD, 0x6A, 0x34,
0x08, 0x84, 0x79, 0x82, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x43, 0x41, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x58, 0x53, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x63, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x7A, 0x08, 0x94,
0xAD, 0x50, 0x5B, 0xB6, 0xC6, 0x7E, 0x2E, 0x5B,
0xDD, 0x6A, 0x3B, 0xEC, 0x43, 0xD9, 0x10, 0xC7,
0x72, 0xE9, 0xCC, 0x29, 0x0D, 0xA5, 0x85, 0x88,
0xB7, 0x7D, 0xCC, 0x11, 0x68, 0x0B, 0xB3, 0xE2,
0x9F, 0x4E, 0xAB, 0xBB, 0x26, 0xE9, 0x8C, 0x26,
0x01, 0x98, 0x5C, 0x04, 0x1B, 0xB1, 0x43, 0x78,
0xE6, 0x89, 0x18, 0x1A, 0xAD, 0x77, 0x05, 0x68,
0xE9, 0x28, 0xA2, 0xB9, 0x81, 0x67, 0xEE, 0x3E,
0x10, 0xD0, 0x72, 0xBE, 0xEF, 0x1F, 0xA2, 0x2F,
0xA2, 0xAA, 0x3E, 0x13, 0xF1, 0x1E, 0x18, 0x36,
0xA9, 0x2A, 0x42, 0x81, 0xEF, 0x70, 0xAA, 0xF4,
0xE4, 0x62, 0x99, 0x82, 0x21, 0xC6, 0xFB, 0xB9,
0xBD, 0xD0, 0x17, 0xE6, 0xAC, 0x59, 0x04, 0x94,
0xE9, 0xCE, 0xA9, 0x85, 0x9C, 0xEB, 0x2D, 0x2A,
0x4C, 0x17, 0x66, 0xF2, 0xC3, 0x39, 0x12, 0xC5,
0x8F, 0x14, 0xA8, 0x03, 0xE3, 0x6F, 0xCC, 0xDC,
0xCC, 0xDC, 0x13, 0xFD, 0x7A, 0xE7, 0x7C, 0x7A,
0x78, 0xD9, 0x97, 0xE6, 0xAC, 0xC3, 0x55, 0x57,
0xE0, 0xD3, 0xE9, 0xEB, 0x64, 0xB4, 0x3C, 0x92,
0xF4, 0xC5, 0x0D, 0x67, 0xA6, 0x02, 0xDE, 0xB3,
0x91, 0xB0, 0x66, 0x61, 0xCD, 0x32, 0x88, 0x0B,
0xD6, 0x49, 0x12, 0xAF, 0x1C, 0xBC, 0xB7, 0x16,
0x2A, 0x06, 0xF0, 0x25, 0x65, 0xD3, 0xB0, 0xEC,
0xE4, 0xFC, 0xEC, 0xDD, 0xAE, 0x8A, 0x49, 0x34,
0xDB, 0x8E, 0xE6, 0x7F, 0x30, 0x17, 0x98, 0x62,
0x21, 0x15, 0x5D, 0x13, 0x1C, 0x6C, 0x3F, 0x09,
0xAB, 0x19, 0x45, 0xC2, 0x06, 0xAC, 0x70, 0xC9,
0x42, 0xB3, 0x6F, 0x49, 0xA1, 0x18, 0x3B, 0xCD,
0x78, 0xB6, 0xE4, 0xB4, 0x7C, 0x6C, 0x5C, 0xAC,
0x0F, 0x8D, 0x62, 0xF8, 0x97, 0xC6, 0x95, 0x3D,
0xD1, 0x2F, 0x28, 0xB7, 0x0C, 0x5B, 0x7D, 0xF7,
0x51, 0x81, 0x9A, 0x98, 0x34, 0x65, 0x26, 0x25,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char cpB_dpki_cert[0x300] =
{
0x00, 0x01, 0x00, 0x04, 0x2E, 0xA6, 0x6C, 0x66,
0xCF, 0xF3, 0x35, 0x79, 0x7D, 0x04, 0x97, 0xB7,
0x7A, 0x19, 0x7F, 0x9F, 0xE5, 0x1A, 0xB5, 0xA4,
0x13, 0x75, 0xDC, 0x73, 0xFD, 0x9E, 0x0B, 0x10,
0x66, 0x9B, 0x1B, 0x9A, 0x5B, 0x7E, 0x8A, 0xB2,
0x8F, 0x01, 0xB6, 0x7B, 0x62, 0x54, 0xC1, 0x4A,
0xA1, 0x33, 0x14, 0x18, 0xF2, 0x5B, 0xA5, 0x49,
0x00, 0x4C, 0x37, 0x8D, 0xD7, 0x2F, 0x0C, 0xE6,
0x3B, 0x1F, 0x70, 0x91, 0xAA, 0xFE, 0x38, 0x09,
0xB7, 0xAC, 0x6C, 0x28, 0x76, 0xA6, 0x1D, 0x60,
0x51, 0x6C, 0x43, 0xA6, 0x37, 0x29, 0x16, 0x2D,
0x28, 0x0B, 0xE2, 0x1B, 0xE8, 0xE2, 0xFE, 0x05,
0x7D, 0x8E, 0xB6, 0xE2, 0x04, 0x24, 0x22, 0x45,
0x73, 0x1A, 0xB6, 0xFE, 0xE3, 0x0E, 0x53, 0x35,
0x37, 0x3E, 0xEB, 0xA9, 0x70, 0xD5, 0x31, 0xBB,
0xA2, 0xCB, 0x22, 0x2D, 0x96, 0x84, 0x38, 0x7D,
0x5F, 0x2A, 0x1B, 0xF7, 0x52, 0x00, 0xCE, 0x06,
0x56, 0xE3, 0x90, 0xCE, 0x19, 0x13, 0x5B, 0x59,
0xE1, 0x4F, 0x0F, 0xA5, 0xC1, 0x28, 0x1A, 0x73,
0x86, 0xCC, 0xD1, 0xC8, 0xEC, 0x3F, 0xAD, 0x70,
0xFB, 0xCE, 0x74, 0xDE, 0xEE, 0x1F, 0xD0, 0x5F,
0x46, 0x33, 0x0B, 0x51, 0xF9, 0xB7, 0x9E, 0x1D,
0xDB, 0xF4, 0xE3, 0x3F, 0x14, 0x88, 0x9D, 0x05,
0x28, 0x29, 0x24, 0xC5, 0xF5, 0xDC, 0x27, 0x66,
0xEF, 0x06, 0x27, 0xD7, 0xEE, 0xDC, 0x73, 0x6E,
0x67, 0xC2, 0xE5, 0xB9, 0x38, 0x34, 0x66, 0x80,
0x72, 0x21, 0x6D, 0x1C, 0x78, 0xB8, 0x23, 0xA0,
0x72, 0xD3, 0x4F, 0xF3, 0xEC, 0xF9, 0xBD, 0x11,
0xA2, 0x9A, 0xF1, 0x6C, 0x33, 0xBD, 0x09, 0xAF,
0xB2, 0xD7, 0x4D, 0x53, 0x4E, 0x02, 0x7C, 0x19,
0x24, 0x0D, 0x59, 0x5A, 0x68, 0xEB, 0xB3, 0x05,
0xAC, 0xC4, 0x4A, 0xB3, 0x8A, 0xB8, 0x20, 0xC6,
0xD4, 0x26, 0x56, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x6F, 0x6F, 0x74, 0x2D, 0x43, 0x41, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x62, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x7A, 0x08, 0x0B,
0xA6, 0x89, 0xC5, 0x90, 0xFD, 0x0B, 0x2F, 0x0D,
0x4F, 0x56, 0xB6, 0x32, 0xFB, 0x93, 0x4E, 0xD0,
0x73, 0x95, 0x17, 0xB3, 0x3A, 0x79, 0xDE, 0x04,
0x0E, 0xE9, 0x2D, 0xC3, 0x1D, 0x37, 0xC7, 0xF7,
0x3B, 0xF0, 0x4B, 0xD3, 0xE4, 0x4E, 0x20, 0xAB,
0x5A, 0x6F, 0xEA, 0xF5, 0x98, 0x4C, 0xC1, 0xF6,
0x06, 0x2E, 0x9A, 0x9F, 0xE5, 0x6C, 0x32, 0x85,
0xDC, 0x6F, 0x25, 0xDD, 0xD5, 0xD0, 0xBF, 0x9F,
0xE2, 0xEF, 0xE8, 0x35, 0xDF, 0x26, 0x34, 0xED,
0x93, 0x7F, 0xAB, 0x02, 0x14, 0xD1, 0x04, 0x80,
0x9C, 0xF7, 0x4B, 0x86, 0x0E, 0x6B, 0x04, 0x83,
0xF4, 0xCD, 0x2D, 0xAB, 0x2A, 0x96, 0x02, 0xBC,
0x56, 0xF0, 0xD6, 0xBD, 0x94, 0x6A, 0xED, 0x6E,
0x0B, 0xE4, 0xF0, 0x8F, 0x26, 0x68, 0x6B, 0xD0,
0x9E, 0xF7, 0xDB, 0x32, 0x5F, 0x82, 0xB1, 0x8F,
0x6A, 0xF2, 0xED, 0x52, 0x5B, 0xFD, 0x82, 0x8B,
0x65, 0x3F, 0xEE, 0x6E, 0xCE, 0x40, 0x0D, 0x5A,
0x48, 0xFF, 0xE2, 0x2D, 0x53, 0x8B, 0xB5, 0x33,
0x5B, 0x41, 0x53, 0x34, 0x2D, 0x43, 0x35, 0xAC,
0xF5, 0x90, 0xD0, 0xD3, 0x0A, 0xE2, 0x04, 0x3C,
0x7F, 0x5A, 0xD2, 0x14, 0xFC, 0x9C, 0x0F, 0xE6,
0xFA, 0x40, 0xA5, 0xC8, 0x65, 0x06, 0xCA, 0x63,
0x69, 0xBC, 0xEE, 0x44, 0xA3, 0x2D, 0x9E, 0x69,
0x5C, 0xF0, 0x0B, 0x4F, 0xD7, 0x9A, 0xDB, 0x56,
0x8D, 0x14, 0x9C, 0x20, 0x28, 0xA1, 0x4C, 0x9D,
0x71, 0xB8, 0x50, 0xCA, 0x36, 0x5B, 0x37, 0xF7,
0x0B, 0x65, 0x77, 0x91, 0xFC, 0x5D, 0x72, 0x8C,
0x4E, 0x18, 0xFD, 0x22, 0x55, 0x7C, 0x40, 0x62,
0xD7, 0x47, 0x71, 0x53, 0x3C, 0x70, 0x17, 0x9D,
0x3D, 0xAE, 0x8F, 0x92, 0xB1, 0x17, 0xE4, 0x5C,
0xB3, 0x32, 0xF3, 0xB3, 0xC2, 0xA2, 0x2E, 0x70,
0x5C, 0xFE, 0xC6, 0x6F, 0x6D, 0xA3, 0x77, 0x2B,
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif
+200
View File
@@ -0,0 +1,200 @@
#include "lib.h"
// Private Prototypes
int SetRsaKeySet(u8 **PrivDest, u8 *PrivSource, u8 **PubDest, u8 *PubSource);
int SetUnFixedKey(keys_struct *keys, u8 *UnFixedKey);
int SetTIK_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod);
int SetTMD_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod);
int SetCFA_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod);
int SetCCI_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod);
int SetAccessDesc_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod);
int SetCXI_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod);
int SetCaCert(keys_struct *keys, u8 *Cert);
int SetTikCert(keys_struct *keys, u8 *Cert);
int SetTmdCert(keys_struct *keys, u8 *Cert);
// Code
void InitKeys(keys_struct *keys)
{
memset(keys,0,sizeof(keys_struct));
#ifdef RETAIL_FSIGN
/* AES Keys */
// CIA
SetCommonKey(keys,(u8*)zeros_fixed_aesKey,1);
SetCurrentCommonKey(keys,1);
// NCCH
keys->aes.NormalKey = (u8*)zeros_fixed_aesKey;
SetSystemFixedKey(keys,(u8*)zeros_fixed_aesKey);
/* RSA Keys */
// CIA
SetTIK_RsaKey(keys,(u8*)Dummy_rsa_privExp,(u8*)Dummy_rsa_pubMod);
SetTMD_RsaKey(keys,(u8*)Dummy_rsa_privExp,(u8*)Dummy_rsa_pubMod);
// CFA
SetCFA_RsaKey(keys,(u8*)Dummy_rsa_privExp,(u8*)Dummy_rsa_pubMod);
// CCI
SetCCI_RsaKey(keys,(u8*)Dummy_rsa_privExp,(u8*)Dummy_rsa_pubMod);
// CXI
SetAccessDesc_RsaKey(keys,(u8*)Dummy_rsa_privExp,(u8*)Dummy_rsa_pubMod);
/* Certs */
SetCaCert(keys,(u8*)ca3_dpki_cert);
SetTikCert(keys,(u8*)xsC_dpki_cert);
SetTmdCert(keys,(u8*)cpB_dpki_cert);
#else // DEBUG KEYS
/* AES Keys */
// CIA
SetCommonKey(keys,(u8*)ctr_aes_common_key_dev0,0);
SetCommonKey(keys,(u8*)ctr_aes_common_key_dev1,1);
SetCurrentCommonKey(keys,0);
// NCCH
keys->aes.NormalKey = (u8*)zeros_fixed_aesKey;
SetSystemFixedKey(keys,(u8*)system_fixed_aesKey);
/* RSA Keys */
// CIA
SetTIK_RsaKey(keys,(u8*)xs9_dpki_rsa_privExp,(u8*)xs9_dpki_rsa_pubMod);
SetTMD_RsaKey(keys,(u8*)cpA_dpki_rsa_privExp,(u8*)cpA_dpki_rsa_pubMod);
// CFA
SetCFA_RsaKey(keys,(u8*)DevNcsdCfa_privExp,(u8*)DevNcsdCfa_pubMod);
// CCI
SetCCI_RsaKey(keys,(u8*)DevNcsdCfa_privExp,(u8*)DevNcsdCfa_pubMod);
// CXI
SetAccessDesc_RsaKey(keys,(u8*)AccessDesc_privExp,(u8*)AccessDesc_pubMod);
/* Certs */
SetCaCert(keys,(u8*)ca4_dpki_cert);
SetTikCert(keys,(u8*)xs9_dpki_cert);
SetTmdCert(keys,(u8*)cpA_dpki_cert);
#endif
}
void FreeKeys(keys_struct *keys)
{
// AES
if(keys->aes.CommonKey){
for(int i = 0; i < 256; i++){
free(keys->aes.CommonKey[i]);
}
}
free(keys->aes.CommonKey);
free(keys->aes.SystemFixedKey);
free(keys->aes.UnFixedKey);
// RSA
free(keys->rsa.TIK_Priv);
free(keys->rsa.TIK_Pub);
free(keys->rsa.TMD_Priv);
free(keys->rsa.TMD_Pub);
free(keys->rsa.CFA_Priv);
free(keys->rsa.CFA_Pub);
free(keys->rsa.CCI_Priv);
free(keys->rsa.CCI_Pub);
free(keys->rsa.AccessDesc_Priv);
free(keys->rsa.AccessDesc_Pub);
// Certs
free(keys->certs.ca_cert);
free(keys->certs.tik_cert);
free(keys->certs.tmd_cert);
memset(keys,0,sizeof(keys_struct));
}
int SetRsaKeySet(u8 **PrivDest, u8 *PrivSource, u8 **PubDest, u8 *PubSource)
{
int result = 0;
if(PrivSource){
result = CopyData(PrivDest,PrivSource,0x100);
if(result) return result;
}
if(PubSource){
result = CopyData(PubDest,PubSource,0x100);
if(result) return result;
}
return 0;
}
int SetCommonKey(keys_struct *keys, u8 *CommonKey, u8 Index)
{
if(!keys) return -1;
if(!keys->aes.CommonKey){
keys->aes.CommonKey = malloc(sizeof(u8*)*256);
memset(keys->aes.CommonKey,0,sizeof(u8*)*256);
}
return CopyData(&keys->aes.CommonKey[Index],CommonKey,16);
}
int SetCurrentCommonKey(keys_struct *keys, u8 Index)
{
if(!keys) return -1;
keys->aes.CurrentCommonKey = Index;
return 0;
}
int SetSystemFixedKey(keys_struct *keys, u8 *SystemFixedKey)
{
if(!keys) return -1;
return CopyData(&keys->aes.SystemFixedKey,SystemFixedKey,16);
}
int SetUnFixedKey(keys_struct *keys, u8 *UnFixedKey)
{
if(!keys) return -1;
return CopyData(&keys->aes.UnFixedKey,UnFixedKey,16);
}
int SetTIK_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod)
{
if(!keys) return -1;
return SetRsaKeySet(&keys->rsa.TIK_Priv,PrivateExp,&keys->rsa.TIK_Pub,PublicMod);
}
int SetTMD_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod)
{
if(!keys) return -1;
return SetRsaKeySet(&keys->rsa.TMD_Priv,PrivateExp,&keys->rsa.TMD_Pub,PublicMod);
}
int SetCFA_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod)
{
if(!keys) return -1;
return SetRsaKeySet(&keys->rsa.CFA_Priv,PrivateExp,&keys->rsa.CFA_Pub,PublicMod);
}
int SetCCI_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod)
{
if(!keys) return -1;
return SetRsaKeySet(&keys->rsa.CCI_Priv,PrivateExp,&keys->rsa.CCI_Pub,PublicMod);
}
int SetAccessDesc_RsaKey(keys_struct *keys, u8 *PrivateExp, u8 *PublicMod)
{
if(!keys) return -1;
return SetRsaKeySet(&keys->rsa.AccessDesc_Priv,PrivateExp,&keys->rsa.AccessDesc_Pub,PublicMod);
}
int SetCaCert(keys_struct *keys, u8 *Cert)
{
if(!keys) return -1;
return CopyData(&keys->certs.ca_cert,Cert,0x400);
}
int SetTikCert(keys_struct *keys, u8 *Cert)
{
if(!keys) return -1;
return CopyData(&keys->certs.tik_cert,Cert,0x300);
}
int SetTmdCert(keys_struct *keys, u8 *Cert)
{
if(!keys) return -1;
return CopyData(&keys->certs.tmd_cert,Cert,0x400);
}
+58
View File
@@ -0,0 +1,58 @@
#ifndef _KEYSET_H_
#define _KEYSET_H_
// Structs
typedef struct
{
struct
{
// CIA
u8 **CommonKey;
u8 CurrentCommonKey;
// NCCH Keys
u8 *NormalKey;
u8 *SystemFixedKey;
u8 *UnFixedKey;
} aes;
struct
{
// CIA RSA
u8 *TMD_Priv;
u8 *TMD_Pub;
u8 *TIK_Priv;
u8 *TIK_Pub;
// CFA
u8 *CFA_Priv;
u8 *CFA_Pub;
// CCI
u8 *CCI_Priv;
u8 *CCI_Pub;
// CXI
u8 *AccessDesc_Priv;
u8 *AccessDesc_Pub;
} rsa;
struct
{
// CIA
u8 *ca_cert;
u8 *tik_cert;
u8 *tmd_cert;
} certs;
} keys_struct;
#endif
// Public Prototypes
void InitKeys(keys_struct *keys);
void FreeKeys(keys_struct *keys);
int SetCommonKey(keys_struct *keys, u8 *CommonKey, u8 Index);
int SetCurrentCommonKey(keys_struct *keys, u8 Index);
int SetSystemFixedKey(keys_struct *keys, u8 *SystemFixedKey);
+40
View File
@@ -0,0 +1,40 @@
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef _WIN32
#include <io.h>
#include <direct.h>
#include <windows.h>
//#include <wchar.h>
#else
#include <sys/stat.h>
#include <sys/types.h>
#endif
#include "types.h"
#include "utils.h"
#include "crypto.h"
#ifdef RETAIL_FSIGN
#include "keys_retail.h"
#else
#include "keys_debug.h"
#include "accessdesc_sig.h"
#endif
#include "keyset.h"
#include "usersettings.h"
#include "libyaml/yaml.h"
#include "yaml_ctr.h"
+19
View File
@@ -0,0 +1,19 @@
Copyright (c) 2006 Kirill Simonov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1391
View File
File diff suppressed because it is too large Load Diff
+394
View File
@@ -0,0 +1,394 @@
#include "libyaml/yaml_private.h"
/*
* API functions.
*/
YAML_DECLARE(int)
yaml_emitter_open(yaml_emitter_t *emitter);
YAML_DECLARE(int)
yaml_emitter_close(yaml_emitter_t *emitter);
YAML_DECLARE(int)
yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
/*
* Clean up functions.
*/
static void
yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter);
/*
* Anchor functions.
*/
static void
yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index);
static yaml_char_t *
yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id);
/*
* Serialize functions.
*/
static int
yaml_emitter_dump_node(yaml_emitter_t *emitter, int index);
static int
yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor);
static int
yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor);
static int
yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor);
static int
yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor);
/*
* Issue a STREAM-START event.
*/
YAML_DECLARE(int)
yaml_emitter_open(yaml_emitter_t *emitter)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
assert(emitter); /* Non-NULL emitter object is required. */
assert(!emitter->opened); /* Emitter should not be opened yet. */
STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) {
return 0;
}
emitter->opened = 1;
return 1;
}
/*
* Issue a STREAM-END event.
*/
YAML_DECLARE(int)
yaml_emitter_close(yaml_emitter_t *emitter)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
assert(emitter); /* Non-NULL emitter object is required. */
assert(emitter->opened); /* Emitter should be opened. */
if (emitter->closed) return 1;
STREAM_END_EVENT_INIT(event, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) {
return 0;
}
emitter->closed = 1;
return 1;
}
/*
* Dump a YAML document.
*/
YAML_DECLARE(int)
yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
assert(emitter); /* Non-NULL emitter object is required. */
assert(document); /* Non-NULL emitter object is expected. */
emitter->document = document;
if (!emitter->opened) {
if (!yaml_emitter_open(emitter)) goto error;
}
if (STACK_EMPTY(emitter, document->nodes)) {
if (!yaml_emitter_close(emitter)) goto error;
yaml_emitter_delete_document_and_anchors(emitter);
return 1;
}
assert(emitter->opened); /* Emitter should be opened. */
emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors))
* (document->nodes.top - document->nodes.start));
if (!emitter->anchors) goto error;
memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
* (document->nodes.top - document->nodes.start));
DOCUMENT_START_EVENT_INIT(event, document->titleVersion_directive,
document->tag_directives.start, document->tag_directives.end,
document->start_implicit, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) goto error;
yaml_emitter_anchor_node(emitter, 1);
if (!yaml_emitter_dump_node(emitter, 1)) goto error;
DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) goto error;
yaml_emitter_delete_document_and_anchors(emitter);
return 1;
error:
yaml_emitter_delete_document_and_anchors(emitter);
return 0;
}
/*
* Clean up the emitter object after a document is dumped.
*/
static void
yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter)
{
int index;
if (!emitter->anchors) {
yaml_document_delete(emitter->document);
emitter->document = NULL;
return;
}
for (index = 0; emitter->document->nodes.start + index
< emitter->document->nodes.top; index ++) {
yaml_node_t node = emitter->document->nodes.start[index];
if (!emitter->anchors[index].serialized) {
yaml_free(node.tag);
if (node.type == YAML_SCALAR_NODE) {
yaml_free(node.data.scalar.value);
}
}
if (node.type == YAML_SEQUENCE_NODE) {
STACK_DEL(emitter, node.data.sequence.items);
}
if (node.type == YAML_MAPPING_NODE) {
STACK_DEL(emitter, node.data.mapping.pairs);
}
}
STACK_DEL(emitter, emitter->document->nodes);
yaml_free(emitter->anchors);
emitter->anchors = NULL;
emitter->last_anchor_id = 0;
emitter->document = NULL;
}
/*
* Check the references of a node and assign the anchor id if needed.
*/
static void
yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
{
yaml_node_t *node = emitter->document->nodes.start + index - 1;
yaml_node_item_t *item;
yaml_node_pair_t *pair;
emitter->anchors[index-1].references ++;
if (emitter->anchors[index-1].references == 1) {
switch (node->type) {
case YAML_SEQUENCE_NODE:
for (item = node->data.sequence.items.start;
item < node->data.sequence.items.top; item ++) {
yaml_emitter_anchor_node(emitter, *item);
}
break;
case YAML_MAPPING_NODE:
for (pair = node->data.mapping.pairs.start;
pair < node->data.mapping.pairs.top; pair ++) {
yaml_emitter_anchor_node(emitter, pair->key);
yaml_emitter_anchor_node(emitter, pair->value);
}
break;
default:
break;
}
}
else if (emitter->anchors[index-1].references == 2) {
emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id);
}
}
/*
* Generate a textual representation for an anchor.
*/
#define ANCHOR_TEMPLATE "id%03d"
#define ANCHOR_TEMPLATE_LENGTH 16
static yaml_char_t *
yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id)
{
yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH);
if (!anchor) return NULL;
sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id);
return anchor;
}
/*
* Serialize a node.
*/
static int
yaml_emitter_dump_node(yaml_emitter_t *emitter, int index)
{
yaml_node_t *node = emitter->document->nodes.start + index - 1;
int anchor_id = emitter->anchors[index-1].anchor;
yaml_char_t *anchor = NULL;
if (anchor_id) {
anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
if (!anchor) return 0;
}
if (emitter->anchors[index-1].serialized) {
return yaml_emitter_dump_alias(emitter, anchor);
}
emitter->anchors[index-1].serialized = 1;
switch (node->type) {
case YAML_SCALAR_NODE:
return yaml_emitter_dump_scalar(emitter, node, anchor);
case YAML_SEQUENCE_NODE:
return yaml_emitter_dump_sequence(emitter, node, anchor);
case YAML_MAPPING_NODE:
return yaml_emitter_dump_mapping(emitter, node, anchor);
default:
assert(0); /* Could not happen. */
break;
}
return 0; /* Could not happen. */
}
/*
* Serialize an alias.
*/
static int
yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
ALIAS_EVENT_INIT(event, anchor, mark, mark);
return yaml_emitter_emit(emitter, &event);
}
/*
* Serialize a scalar.
*/
static int
yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
int plain_implicit = (strcmp((char *)node->tag,
YAML_DEFAULT_SCALAR_TAG) == 0);
int quoted_implicit = (strcmp((char *)node->tag,
YAML_DEFAULT_SCALAR_TAG) == 0);
SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value,
node->data.scalar.length, plain_implicit, quoted_implicit,
node->data.scalar.style, mark, mark);
return yaml_emitter_emit(emitter, &event);
}
/*
* Serialize a sequence.
*/
static int
yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0);
yaml_node_item_t *item;
SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit,
node->data.sequence.style, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
for (item = node->data.sequence.items.start;
item < node->data.sequence.items.top; item ++) {
if (!yaml_emitter_dump_node(emitter, *item)) return 0;
}
SEQUENCE_END_EVENT_INIT(event, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
return 1;
}
/*
* Serialize a mapping.
*/
static int
yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0);
yaml_node_pair_t *pair;
MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit,
node->data.mapping.style, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
for (pair = node->data.mapping.pairs.start;
pair < node->data.mapping.pairs.top; pair ++) {
if (!yaml_emitter_dump_node(emitter, pair->key)) return 0;
if (!yaml_emitter_dump_node(emitter, pair->value)) return 0;
}
MAPPING_END_EVENT_INIT(event, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
return 1;
}
+2329
View File
File diff suppressed because it is too large Load Diff
+432
View File
@@ -0,0 +1,432 @@
#include "libyaml/yaml_private.h"
/*
* API functions.
*/
YAML_DECLARE(int)
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
/*
* Error handling.
*/
static int
yaml_parser_set_composer_error(yaml_parser_t *parser,
const char *problem, yaml_mark_t problem_mark);
static int
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
const char *context, yaml_mark_t context_mark,
const char *problem, yaml_mark_t problem_mark);
/*
* Alias handling.
*/
static int
yaml_parser_register_anchor(yaml_parser_t *parser,
int index, yaml_char_t *anchor);
/*
* Clean up functions.
*/
static void
yaml_parser_delete_aliases(yaml_parser_t *parser);
/*
* Composer functions.
*/
static int
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
/*
* Load the next document of the stream.
*/
YAML_DECLARE(int)
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
{
yaml_event_t event;
assert(parser); /* Non-NULL parser object is expected. */
assert(document); /* Non-NULL document object is expected. */
memset(document, 0, sizeof(yaml_document_t));
if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
goto error;
if (!parser->stream_start_produced) {
if (!yaml_parser_parse(parser, &event)) goto error;
assert(event.type == YAML_STREAM_START_EVENT);
/* STREAM-START is expected. */
}
if (parser->stream_end_produced) {
return 1;
}
if (!yaml_parser_parse(parser, &event)) goto error;
if (event.type == YAML_STREAM_END_EVENT) {
return 1;
}
if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
goto error;
parser->document = document;
if (!yaml_parser_load_document(parser, &event)) goto error;
yaml_parser_delete_aliases(parser);
parser->document = NULL;
return 1;
error:
yaml_parser_delete_aliases(parser);
yaml_document_delete(document);
parser->document = NULL;
return 0;
}
/*
* Set composer error.
*/
static int
yaml_parser_set_composer_error(yaml_parser_t *parser,
const char *problem, yaml_mark_t problem_mark)
{
parser->error = YAML_COMPOSER_ERROR;
parser->problem = problem;
parser->problem_mark = problem_mark;
return 0;
}
/*
* Set composer error with context.
*/
static int
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
const char *context, yaml_mark_t context_mark,
const char *problem, yaml_mark_t problem_mark)
{
parser->error = YAML_COMPOSER_ERROR;
parser->context = context;
parser->context_mark = context_mark;
parser->problem = problem;
parser->problem_mark = problem_mark;
return 0;
}
/*
* Delete the stack of aliases.
*/
static void
yaml_parser_delete_aliases(yaml_parser_t *parser)
{
while (!STACK_EMPTY(parser, parser->aliases)) {
yaml_free(POP(parser, parser->aliases).anchor);
}
STACK_DEL(parser, parser->aliases);
}
/*
* Compose a document object.
*/
static int
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_event_t event;
assert(first_event->type == YAML_DOCUMENT_START_EVENT);
/* DOCUMENT-START is expected. */
parser->document->titleVersion_directive
= first_event->data.document_start.titleVersion_directive;
parser->document->tag_directives.start
= first_event->data.document_start.tag_directives.start;
parser->document->tag_directives.end
= first_event->data.document_start.tag_directives.end;
parser->document->start_implicit
= first_event->data.document_start.implicit;
parser->document->start_mark = first_event->start_mark;
if (!yaml_parser_parse(parser, &event)) return 0;
if (!yaml_parser_load_node(parser, &event)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
assert(event.type == YAML_DOCUMENT_END_EVENT);
/* DOCUMENT-END is expected. */
parser->document->end_implicit = event.data.document_end.implicit;
parser->document->end_mark = event.end_mark;
return 1;
}
/*
* Compose a node.
*/
static int
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
{
switch (first_event->type) {
case YAML_ALIAS_EVENT:
return yaml_parser_load_alias(parser, first_event);
case YAML_SCALAR_EVENT:
return yaml_parser_load_scalar(parser, first_event);
case YAML_SEQUENCE_START_EVENT:
return yaml_parser_load_sequence(parser, first_event);
case YAML_MAPPING_START_EVENT:
return yaml_parser_load_mapping(parser, first_event);
default:
assert(0); /* Could not happen. */
return 0;
}
return 0;
}
/*
* Add an anchor.
*/
static int
yaml_parser_register_anchor(yaml_parser_t *parser,
int index, yaml_char_t *anchor)
{
yaml_alias_data_t data;
yaml_alias_data_t *alias_data;
if (!anchor) return 1;
data.anchor = anchor;
data.index = index;
data.mark = parser->document->nodes.start[index-1].start_mark;
for (alias_data = parser->aliases.start;
alias_data != parser->aliases.top; alias_data ++) {
if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
yaml_free(anchor);
return yaml_parser_set_composer_error_context(parser,
"found duplicate anchor; first occurence",
alias_data->mark, "second occurence", data.mark);
}
}
if (!PUSH(parser, parser->aliases, data)) {
yaml_free(anchor);
return 0;
}
return 1;
}
/*
* Compose a node corresponding to an alias.
*/
static int
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_char_t *anchor = first_event->data.alias.anchor;
yaml_alias_data_t *alias_data;
for (alias_data = parser->aliases.start;
alias_data != parser->aliases.top; alias_data ++) {
if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
yaml_free(anchor);
return alias_data->index;
}
}
yaml_free(anchor);
return yaml_parser_set_composer_error(parser, "found undefined alias",
first_event->start_mark);
}
/*
* Compose a scalar node.
*/
static int
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_node_t node;
int index;
yaml_char_t *tag = first_event->data.scalar.tag;
if (!tag || strcmp((char *)tag, "!") == 0) {
yaml_free(tag);
tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
if (!tag) goto error;
}
SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
first_event->data.scalar.length, first_event->data.scalar.style,
first_event->start_mark, first_event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
first_event->data.scalar.anchor)) return 0;
return index;
error:
yaml_free(tag);
yaml_free(first_event->data.scalar.anchor);
yaml_free(first_event->data.scalar.value);
return 0;
}
/*
* Compose a sequence node.
*/
static int
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_event_t event;
yaml_node_t node;
struct {
yaml_node_item_t *start;
yaml_node_item_t *end;
yaml_node_item_t *top;
} items = { NULL, NULL, NULL };
int index, item_index;
yaml_char_t *tag = first_event->data.sequence_start.tag;
if (!tag || strcmp((char *)tag, "!") == 0) {
yaml_free(tag);
tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
if (!tag) goto error;
}
if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
first_event->data.sequence_start.style,
first_event->start_mark, first_event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
first_event->data.sequence_start.anchor)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
while (event.type != YAML_SEQUENCE_END_EVENT) {
item_index = yaml_parser_load_node(parser, &event);
if (!item_index) return 0;
if (!PUSH(parser,
parser->document->nodes.start[index-1].data.sequence.items,
item_index)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
}
parser->document->nodes.start[index-1].end_mark = event.end_mark;
return index;
error:
yaml_free(tag);
yaml_free(first_event->data.sequence_start.anchor);
return 0;
}
/*
* Compose a mapping node.
*/
static int
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_event_t event;
yaml_node_t node;
struct {
yaml_node_pair_t *start;
yaml_node_pair_t *end;
yaml_node_pair_t *top;
} pairs = { NULL, NULL, NULL };
int index;
yaml_node_pair_t pair;
yaml_char_t *tag = first_event->data.mapping_start.tag;
if (!tag || strcmp((char *)tag, "!") == 0) {
yaml_free(tag);
tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
if (!tag) goto error;
}
if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
first_event->data.mapping_start.style,
first_event->start_mark, first_event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
first_event->data.mapping_start.anchor)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
while (event.type != YAML_MAPPING_END_EVENT) {
pair.key = yaml_parser_load_node(parser, &event);
if (!pair.key) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
pair.value = yaml_parser_load_node(parser, &event);
if (!pair.value) return 0;
if (!PUSH(parser,
parser->document->nodes.start[index-1].data.mapping.pairs,
pair)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
}
parser->document->nodes.start[index-1].end_mark = event.end_mark;
return index;
error:
yaml_free(tag);
yaml_free(first_event->data.mapping_start.anchor);
return 0;
}
+1374
View File
File diff suppressed because it is too large Load Diff
+465
View File
@@ -0,0 +1,465 @@
#include "libyaml/yaml_private.h"
/*
* Declarations.
*/
static int
yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
size_t offset, int value);
static int
yaml_parser_update_raw_buffer(yaml_parser_t *parser);
static int
yaml_parser_determine_encoding(yaml_parser_t *parser);
YAML_DECLARE(int)
yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
/*
* Set the reader error and return 0.
*/
static int
yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
size_t offset, int value)
{
parser->error = YAML_READER_ERROR;
parser->problem = problem;
parser->problem_offset = offset;
parser->problem_value = value;
return 0;
}
/*
* Byte order marks.
*/
#define BOM_UTF8 "\xef\xbb\xbf"
#define BOM_UTF16LE "\xff\xfe"
#define BOM_UTF16BE "\xfe\xff"
/*
* Determine the input stream encoding by checking the BOM symbol. If no BOM is
* found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
*/
static int
yaml_parser_determine_encoding(yaml_parser_t *parser)
{
/* Ensure that we had enough bytes in the raw buffer. */
while (!parser->eof
&& parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
if (!yaml_parser_update_raw_buffer(parser)) {
return 0;
}
}
/* Determine the encoding. */
if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
&& !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) {
parser->encoding = YAML_UTF16LE_ENCODING;
parser->raw_buffer.pointer += 2;
parser->offset += 2;
}
else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
&& !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) {
parser->encoding = YAML_UTF16BE_ENCODING;
parser->raw_buffer.pointer += 2;
parser->offset += 2;
}
else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3
&& !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) {
parser->encoding = YAML_UTF8_ENCODING;
parser->raw_buffer.pointer += 3;
parser->offset += 3;
}
else {
parser->encoding = YAML_UTF8_ENCODING;
}
return 1;
}
/*
* Update the raw buffer.
*/
static int
yaml_parser_update_raw_buffer(yaml_parser_t *parser)
{
size_t size_read = 0;
/* Return if the raw buffer is full. */
if (parser->raw_buffer.start == parser->raw_buffer.pointer
&& parser->raw_buffer.last == parser->raw_buffer.end)
return 1;
/* Return on EOF. */
if (parser->eof) return 1;
/* Move the remaining bytes in the raw buffer to the beginning. */
if (parser->raw_buffer.start < parser->raw_buffer.pointer
&& parser->raw_buffer.pointer < parser->raw_buffer.last) {
memmove(parser->raw_buffer.start, parser->raw_buffer.pointer,
parser->raw_buffer.last - parser->raw_buffer.pointer);
}
parser->raw_buffer.last -=
parser->raw_buffer.pointer - parser->raw_buffer.start;
parser->raw_buffer.pointer = parser->raw_buffer.start;
/* Call the read handler to fill the buffer. */
if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last,
parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) {
return yaml_parser_set_reader_error(parser, "input error",
parser->offset, -1);
}
parser->raw_buffer.last += size_read;
if (!size_read) {
parser->eof = 1;
}
return 1;
}
/*
* Ensure that the buffer contains at least `length` characters.
* Return 1 on success, 0 on failure.
*
* The length is supposed to be significantly less that the buffer size.
*/
YAML_DECLARE(int)
yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
{
int first = 1;
assert(parser->read_handler); /* Read handler must be set. */
/* If the EOF flag is set and the raw buffer is empty, do nothing. */
if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last)
return 1;
/* Return if the buffer contains enough characters. */
if (parser->unread >= length)
return 1;
/* Determine the input encoding if it is not known yet. */
if (!parser->encoding) {
if (!yaml_parser_determine_encoding(parser))
return 0;
}
/* Move the unread characters to the beginning of the buffer. */
if (parser->buffer.start < parser->buffer.pointer
&& parser->buffer.pointer < parser->buffer.last) {
size_t size = parser->buffer.last - parser->buffer.pointer;
memmove(parser->buffer.start, parser->buffer.pointer, size);
parser->buffer.pointer = parser->buffer.start;
parser->buffer.last = parser->buffer.start + size;
}
else if (parser->buffer.pointer == parser->buffer.last) {
parser->buffer.pointer = parser->buffer.start;
parser->buffer.last = parser->buffer.start;
}
/* Fill the buffer until it has enough characters. */
while (parser->unread < length)
{
/* Fill the raw buffer if necessary. */
if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) {
if (!yaml_parser_update_raw_buffer(parser)) return 0;
}
first = 0;
/* Decode the raw buffer. */
while (parser->raw_buffer.pointer != parser->raw_buffer.last)
{
unsigned int value = 0, value2 = 0;
int incomplete = 0;
unsigned char octet;
unsigned int width = 0;
int low, high;
size_t k;
size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer;
/* Decode the next character. */
switch (parser->encoding)
{
case YAML_UTF8_ENCODING:
/*
* Decode a UTF-8 character. Check RFC 3629
* (http://www.ietf.org/rfc/rfc3629.txt) for more details.
*
* The following table (taken from the RFC) is used for
* decoding.
*
* Char. number range | UTF-8 octet sequence
* (hexadecimal) | (binary)
* --------------------+------------------------------------
* 0000 0000-0000 007F | 0xxxxxxx
* 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
* 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*
* Additionally, the characters in the range 0xD800-0xDFFF
* are prohibited as they are reserved for use with UTF-16
* surrogate pairs.
*/
/* Determine the length of the UTF-8 sequence. */
octet = parser->raw_buffer.pointer[0];
width = (octet & 0x80) == 0x00 ? 1 :
(octet & 0xE0) == 0xC0 ? 2 :
(octet & 0xF0) == 0xE0 ? 3 :
(octet & 0xF8) == 0xF0 ? 4 : 0;
/* Check if the leading octet is valid. */
if (!width)
return yaml_parser_set_reader_error(parser,
"invalid leading UTF-8 octet",
parser->offset, octet);
/* Check if the raw buffer contains an incomplete character. */
if (width > raw_unread) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"incomplete UTF-8 octet sequence",
parser->offset, -1);
}
incomplete = 1;
break;
}
/* Decode the leading octet. */
value = (octet & 0x80) == 0x00 ? octet & 0x7F :
(octet & 0xE0) == 0xC0 ? octet & 0x1F :
(octet & 0xF0) == 0xE0 ? octet & 0x0F :
(octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
/* Check and decode the trailing octets. */
for (k = 1; k < width; k ++)
{
octet = parser->raw_buffer.pointer[k];
/* Check if the octet is valid. */
if ((octet & 0xC0) != 0x80)
return yaml_parser_set_reader_error(parser,
"invalid trailing UTF-8 octet",
parser->offset+k, octet);
/* Decode the octet. */
value = (value << 6) + (octet & 0x3F);
}
/* Check the length of the sequence against the value. */
if (!((width == 1) ||
(width == 2 && value >= 0x80) ||
(width == 3 && value >= 0x800) ||
(width == 4 && value >= 0x10000)))
return yaml_parser_set_reader_error(parser,
"invalid length of a UTF-8 sequence",
parser->offset, -1);
/* Check the range of the value. */
if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF)
return yaml_parser_set_reader_error(parser,
"invalid Unicode character",
parser->offset, value);
break;
case YAML_UTF16LE_ENCODING:
case YAML_UTF16BE_ENCODING:
low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
/*
* The UTF-16 encoding is not as simple as one might
* naively think. Check RFC 2781
* (http://www.ietf.org/rfc/rfc2781.txt).
*
* Normally, two subsequent bytes describe a Unicode
* character. However a special technique (called a
* surrogate pair) is used for specifying character
* values larger than 0xFFFF.
*
* A surrogate pair consists of two pseudo-characters:
* high surrogate area (0xD800-0xDBFF)
* low surrogate area (0xDC00-0xDFFF)
*
* The following formulas are used for decoding
* and encoding characters using surrogate pairs:
*
* U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
* U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
* W1 = 110110yyyyyyyyyy
* W2 = 110111xxxxxxxxxx
*
* where U is the character value, W1 is the high surrogate
* area, W2 is the low surrogate area.
*/
/* Check for incomplete UTF-16 character. */
if (raw_unread < 2) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"incomplete UTF-16 character",
parser->offset, -1);
}
incomplete = 1;
break;
}
/* Get the character. */
value = parser->raw_buffer.pointer[low]
+ (parser->raw_buffer.pointer[high] << 8);
/* Check for unexpected low surrogate area. */
if ((value & 0xFC00) == 0xDC00)
return yaml_parser_set_reader_error(parser,
"unexpected low surrogate area",
parser->offset, value);
/* Check for a high surrogate area. */
if ((value & 0xFC00) == 0xD800) {
width = 4;
/* Check for incomplete surrogate pair. */
if (raw_unread < 4) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"incomplete UTF-16 surrogate pair",
parser->offset, -1);
}
incomplete = 1;
break;
}
/* Get the next character. */
value2 = parser->raw_buffer.pointer[low+2]
+ (parser->raw_buffer.pointer[high+2] << 8);
/* Check for a low surrogate area. */
if ((value2 & 0xFC00) != 0xDC00)
return yaml_parser_set_reader_error(parser,
"expected low surrogate area",
parser->offset+2, value2);
/* Generate the value of the surrogate pair. */
value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF);
}
else {
width = 2;
}
break;
default:
assert(1); /* Impossible. */
}
/* Check if the raw buffer contains enough bytes to form a character. */
if (incomplete) break;
/*
* Check if the character is in the allowed range:
* #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
* | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
* | [#x10000-#x10FFFF] (32 bit)
*/
if (! (value == 0x09 || value == 0x0A || value == 0x0D
|| (value >= 0x20 && value <= 0x7E)
|| (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF)
|| (value >= 0xE000 && value <= 0xFFFD)
|| (value >= 0x10000 && value <= 0x10FFFF)))
return yaml_parser_set_reader_error(parser,
"control characters are not allowed",
parser->offset, value);
/* Move the raw pointers. */
parser->raw_buffer.pointer += width;
parser->offset += width;
/* Finally put the character into the buffer. */
/* 0000 0000-0000 007F -> 0xxxxxxx */
if (value <= 0x7F) {
*(parser->buffer.last++) = value;
}
/* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
else if (value <= 0x7FF) {
*(parser->buffer.last++) = 0xC0 + (value >> 6);
*(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
/* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
else if (value <= 0xFFFF) {
*(parser->buffer.last++) = 0xE0 + (value >> 12);
*(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
*(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
/* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
else {
*(parser->buffer.last++) = 0xF0 + (value >> 18);
*(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F);
*(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
*(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
parser->unread ++;
}
/* On EOF, put NUL into the buffer and return. */
if (parser->eof) {
*(parser->buffer.last++) = '\0';
parser->unread ++;
return 1;
}
}
return 1;
}
+3570
View File
File diff suppressed because it is too large Load Diff
+141
View File
@@ -0,0 +1,141 @@
#include "libyaml/yaml_private.h"
/*
* Declarations.
*/
static int
yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem);
YAML_DECLARE(int)
yaml_emitter_flush(yaml_emitter_t *emitter);
/*
* Set the writer error and return 0.
*/
static int
yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem)
{
emitter->error = YAML_WRITER_ERROR;
emitter->problem = problem;
return 0;
}
/*
* Flush the output buffer.
*/
YAML_DECLARE(int)
yaml_emitter_flush(yaml_emitter_t *emitter)
{
int low, high;
assert(emitter); /* Non-NULL emitter object is expected. */
assert(emitter->write_handler); /* Write handler must be set. */
assert(emitter->encoding); /* Output encoding must be set. */
emitter->buffer.last = emitter->buffer.pointer;
emitter->buffer.pointer = emitter->buffer.start;
/* Check if the buffer is empty. */
if (emitter->buffer.start == emitter->buffer.last) {
return 1;
}
/* If the output encoding is UTF-8, we don't need to recode the buffer. */
if (emitter->encoding == YAML_UTF8_ENCODING)
{
if (emitter->write_handler(emitter->write_handler_data,
emitter->buffer.start,
emitter->buffer.last - emitter->buffer.start)) {
emitter->buffer.last = emitter->buffer.start;
emitter->buffer.pointer = emitter->buffer.start;
return 1;
}
else {
return yaml_emitter_set_writer_error(emitter, "write error");
}
}
/* Recode the buffer into the raw buffer. */
low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
while (emitter->buffer.pointer != emitter->buffer.last)
{
unsigned char octet;
unsigned int width;
unsigned int value;
size_t k;
/*
* See the "reader.c" code for more details on UTF-8 encoding. Note
* that we assume that the buffer contains a valid UTF-8 sequence.
*/
/* Read the next UTF-8 character. */
octet = emitter->buffer.pointer[0];
width = (octet & 0x80) == 0x00 ? 1 :
(octet & 0xE0) == 0xC0 ? 2 :
(octet & 0xF0) == 0xE0 ? 3 :
(octet & 0xF8) == 0xF0 ? 4 : 0;
value = (octet & 0x80) == 0x00 ? octet & 0x7F :
(octet & 0xE0) == 0xC0 ? octet & 0x1F :
(octet & 0xF0) == 0xE0 ? octet & 0x0F :
(octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
for (k = 1; k < width; k ++) {
octet = emitter->buffer.pointer[k];
value = (value << 6) + (octet & 0x3F);
}
emitter->buffer.pointer += width;
/* Write the character. */
if (value < 0x10000)
{
emitter->raw_buffer.last[high] = value >> 8;
emitter->raw_buffer.last[low] = value & 0xFF;
emitter->raw_buffer.last += 2;
}
else
{
/* Write the character using a surrogate pair (check "reader.c"). */
value -= 0x10000;
emitter->raw_buffer.last[high] = 0xD8 + (value >> 18);
emitter->raw_buffer.last[low] = (value >> 10) & 0xFF;
emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF);
emitter->raw_buffer.last[low+2] = value & 0xFF;
emitter->raw_buffer.last += 4;
}
}
/* Write the raw buffer. */
if (emitter->write_handler(emitter->write_handler_data,
emitter->raw_buffer.start,
emitter->raw_buffer.last - emitter->raw_buffer.start)) {
emitter->buffer.last = emitter->buffer.start;
emitter->buffer.pointer = emitter->buffer.start;
emitter->raw_buffer.last = emitter->raw_buffer.start;
emitter->raw_buffer.pointer = emitter->raw_buffer.start;
return 1;
}
else {
return yaml_emitter_set_writer_error(emitter, "write error");
}
}
+1962
View File
File diff suppressed because it is too large Load Diff
+646
View File
@@ -0,0 +1,646 @@
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "libyaml/yaml.h"
#include <assert.h>
#include <limits.h>
#define YAML_titleVersion_STRING "0.1.4"
#define YAML_titleVersion_MAJOR 0
#define YAML_titleVersion_MINOR 1
#define YAML_titleVersion_PATCH 4
/*
* Memory management.
*/
YAML_DECLARE(void *)
yaml_malloc(size_t size);
YAML_DECLARE(void *)
yaml_realloc(void *ptr, size_t size);
YAML_DECLARE(void)
yaml_free(void *ptr);
YAML_DECLARE(yaml_char_t *)
yaml_strdup(const yaml_char_t *);
/*
* Reader: Ensure that the buffer contains at least `length` characters.
*/
YAML_DECLARE(int)
yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
/*
* Scanner: Ensure that the token stack contains at least one token ready.
*/
YAML_DECLARE(int)
yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
/*
* The size of the input raw buffer.
*/
#define INPUT_RAW_BUFFER_SIZE 16384
/*
* The size of the input buffer.
*
* It should be possible to decode the whole raw buffer.
*/
#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3)
/*
* The size of the output buffer.
*/
#define OUTPUT_BUFFER_SIZE 16384
/*
* The size of the output raw buffer.
*
* It should be possible to encode the whole output buffer.
*/
#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
/*
* The size of other stacks and queues.
*/
#define INITIAL_STACK_SIZE 16
#define INITIAL_QUEUE_SIZE 16
#define INITIAL_STRING_SIZE 16
/*
* Buffer management.
*/
#define BUFFER_INIT(context,buffer,size) \
(((buffer).start = yaml_malloc(size)) ? \
((buffer).last = (buffer).pointer = (buffer).start, \
(buffer).end = (buffer).start+(size), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define BUFFER_DEL(context,buffer) \
(yaml_free((buffer).start), \
(buffer).start = (buffer).pointer = (buffer).end = 0)
/*
* String management.
*/
typedef struct {
yaml_char_t *start;
yaml_char_t *end;
yaml_char_t *pointer;
} yaml_string_t;
YAML_DECLARE(int)
yaml_string_extend(yaml_char_t **start,
yaml_char_t **pointer, yaml_char_t **end);
YAML_DECLARE(int)
yaml_string_join(
yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end);
#define NULL_STRING { NULL, NULL, NULL }
#define STRING(string,length) { (string), (string)+(length), (string) }
#define STRING_ASSIGN(value,string,length) \
((value).start = (string), \
(value).end = (string)+(length), \
(value).pointer = (string))
#define STRING_INIT(context,string,size) \
(((string).start = yaml_malloc(size)) ? \
((string).pointer = (string).start, \
(string).end = (string).start+(size), \
memset((string).start, 0, (size)), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define STRING_DEL(context,string) \
(yaml_free((string).start), \
(string).start = (string).pointer = (string).end = 0)
#define STRING_EXTEND(context,string) \
(((string).pointer+5 < (string).end) \
|| yaml_string_extend(&(string).start, \
&(string).pointer, &(string).end))
#define CLEAR(context,string) \
((string).pointer = (string).start, \
memset((string).start, 0, (string).end-(string).start))
#define JOIN(context,string_a,string_b) \
((yaml_string_join(&(string_a).start, &(string_a).pointer, \
&(string_a).end, &(string_b).start, \
&(string_b).pointer, &(string_b).end)) ? \
((string_b).pointer = (string_b).start, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
/*
* String check operations.
*/
/*
* Check the octet at the specified position.
*/
#define CHECK_AT(string,octet,offset) \
((string).pointer[offset] == (yaml_char_t)(octet))
/*
* Check the current octet in the buffer.
*/
#define CHECK(string,octet) CHECK_AT((string),(octet),0)
/*
* Check if the character at the specified position is an alphabetical
* character, a digit, '_', or '-'.
*/
#define IS_ALPHA_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) '0' && \
(string).pointer[offset] <= (yaml_char_t) '9') || \
((string).pointer[offset] >= (yaml_char_t) 'A' && \
(string).pointer[offset] <= (yaml_char_t) 'Z') || \
((string).pointer[offset] >= (yaml_char_t) 'a' && \
(string).pointer[offset] <= (yaml_char_t) 'z') || \
(string).pointer[offset] == '_' || \
(string).pointer[offset] == '-')
#define IS_ALPHA(string) IS_ALPHA_AT((string),0)
/*
* Check if the character at the specified position is a digit.
*/
#define IS_DIGIT_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) '0' && \
(string).pointer[offset] <= (yaml_char_t) '9'))
#define IS_DIGIT(string) IS_DIGIT_AT((string),0)
/*
* Get the value of a digit.
*/
#define AS_DIGIT_AT(string,offset) \
((string).pointer[offset] - (yaml_char_t) '0')
#define AS_DIGIT(string) AS_DIGIT_AT((string),0)
/*
* Check if the character at the specified position is a hex-digit.
*/
#define IS_HEX_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) '0' && \
(string).pointer[offset] <= (yaml_char_t) '9') || \
((string).pointer[offset] >= (yaml_char_t) 'A' && \
(string).pointer[offset] <= (yaml_char_t) 'F') || \
((string).pointer[offset] >= (yaml_char_t) 'a' && \
(string).pointer[offset] <= (yaml_char_t) 'f'))
#define IS_HEX(string) IS_HEX_AT((string),0)
/*
* Get the value of a hex-digit.
*/
#define AS_HEX_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) 'A' && \
(string).pointer[offset] <= (yaml_char_t) 'F') ? \
((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \
((string).pointer[offset] >= (yaml_char_t) 'a' && \
(string).pointer[offset] <= (yaml_char_t) 'f') ? \
((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \
((string).pointer[offset] - (yaml_char_t) '0'))
#define AS_HEX(string) AS_HEX_AT((string),0)
/*
* Check if the character is ASCII.
*/
#define IS_ASCII_AT(string,offset) \
((string).pointer[offset] <= (yaml_char_t) '\x7F')
#define IS_ASCII(string) IS_ASCII_AT((string),0)
/*
* Check if the character can be printed unescaped.
*/
#define IS_PRINTABLE_AT(string,offset) \
(((string).pointer[offset] == 0x0A) /* . == #x0A */ \
|| ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \
&& (string).pointer[offset] <= 0x7E) \
|| ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \
&& (string).pointer[offset+1] >= 0xA0) \
|| ((string).pointer[offset] > 0xC2 \
&& (string).pointer[offset] < 0xED) \
|| ((string).pointer[offset] == 0xED \
&& (string).pointer[offset+1] < 0xA0) \
|| ((string).pointer[offset] == 0xEE) \
|| ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \
&& !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \
&& (string).pointer[offset+2] == 0xBF) \
&& !((string).pointer[offset+1] == 0xBF \
&& ((string).pointer[offset+2] == 0xBE \
|| (string).pointer[offset+2] == 0xBF))))
#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0)
/*
* Check if the character at the specified position is NUL.
*/
#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset))
#define IS_Z(string) IS_Z_AT((string),0)
/*
* Check if the character at the specified position is BOM.
*/
#define IS_BOM_AT(string,offset) \
(CHECK_AT((string),'\xEF',(offset)) \
&& CHECK_AT((string),'\xBB',(offset)+1) \
&& CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */
#define IS_BOM(string) IS_BOM_AT(string,0)
/*
* Check if the character at the specified position is space.
*/
#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset))
#define IS_SPACE(string) IS_SPACE_AT((string),0)
/*
* Check if the character at the specified position is tab.
*/
#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset))
#define IS_TAB(string) IS_TAB_AT((string),0)
/*
* Check if the character at the specified position is blank (space or tab).
*/
#define IS_BLANK_AT(string,offset) \
(IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset)))
#define IS_BLANK(string) IS_BLANK_AT((string),0)
/*
* Check if the character at the specified position is a line break.
*/
#define IS_BREAK_AT(string,offset) \
(CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \
|| CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \
|| (CHECK_AT((string),'\xC2',(offset)) \
&& CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \
|| (CHECK_AT((string),'\xE2',(offset)) \
&& CHECK_AT((string),'\x80',(offset)+1) \
&& CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \
|| (CHECK_AT((string),'\xE2',(offset)) \
&& CHECK_AT((string),'\x80',(offset)+1) \
&& CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */
#define IS_BREAK(string) IS_BREAK_AT((string),0)
#define IS_CRLF_AT(string,offset) \
(CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1))
#define IS_CRLF(string) IS_CRLF_AT((string),0)
/*
* Check if the character is a line break or NUL.
*/
#define IS_BREAKZ_AT(string,offset) \
(IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset)))
#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0)
/*
* Check if the character is a line break, space, or NUL.
*/
#define IS_SPACEZ_AT(string,offset) \
(IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0)
/*
* Check if the character is a line break, space, tab, or NUL.
*/
#define IS_BLANKZ_AT(string,offset) \
(IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0)
/*
* Determine the width of the character.
*/
#define WIDTH_AT(string,offset) \
(((string).pointer[offset] & 0x80) == 0x00 ? 1 : \
((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \
((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \
((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0)
#define WIDTH(string) WIDTH_AT((string),0)
/*
* Move the string pointer to the next character.
*/
#define MOVE(string) ((string).pointer += WIDTH((string)))
/*
* Copy a character and move the pointers of both strings.
*/
#define COPY(string_a,string_b) \
((*(string_b).pointer & 0x80) == 0x00 ? \
(*((string_a).pointer++) = *((string_b).pointer++)) : \
(*(string_b).pointer & 0xE0) == 0xC0 ? \
(*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++)) : \
(*(string_b).pointer & 0xF0) == 0xE0 ? \
(*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++)) : \
(*(string_b).pointer & 0xF8) == 0xF0 ? \
(*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++)) : 0)
/*
* Stack and queue management.
*/
YAML_DECLARE(int)
yaml_stack_extend(void **start, void **top, void **end);
YAML_DECLARE(int)
yaml_queue_extend(void **start, void **head, void **tail, void **end);
#define STACK_INIT(context,stack,size) \
(((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \
((stack).top = (stack).start, \
(stack).end = (stack).start+(size), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define STACK_DEL(context,stack) \
(yaml_free((stack).start), \
(stack).start = (stack).top = (stack).end = 0)
#define STACK_EMPTY(context,stack) \
((stack).start == (stack).top)
#define PUSH(context,stack,value) \
(((stack).top != (stack).end \
|| yaml_stack_extend((void **)&(stack).start, \
(void **)&(stack).top, (void **)&(stack).end)) ? \
(*((stack).top++) = value, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define POP(context,stack) \
(*(--(stack).top))
#define QUEUE_INIT(context,queue,size) \
(((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \
((queue).head = (queue).tail = (queue).start, \
(queue).end = (queue).start+(size), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define QUEUE_DEL(context,queue) \
(yaml_free((queue).start), \
(queue).start = (queue).head = (queue).tail = (queue).end = 0)
#define QUEUE_EMPTY(context,queue) \
((queue).head == (queue).tail)
#define ENQUEUE(context,queue,value) \
(((queue).tail != (queue).end \
|| yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
(void **)&(queue).tail, (void **)&(queue).end)) ? \
(*((queue).tail++) = value, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define DEQUEUE(context,queue) \
(*((queue).head++))
#define QUEUE_INSERT(context,queue,index,value) \
(((queue).tail != (queue).end \
|| yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
(void **)&(queue).tail, (void **)&(queue).end)) ? \
(memmove((queue).head+(index)+1,(queue).head+(index), \
((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \
*((queue).head+(index)) = value, \
(queue).tail++, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
/*
* Token initializers.
*/
#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \
(memset(&(token), 0, sizeof(yaml_token_t)), \
(token).type = (token_type), \
(token).start_mark = (token_start_mark), \
(token).end_mark = (token_end_mark))
#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \
(token).data.stream_start.encoding = (token_encoding))
#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark)))
#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \
(token).data.alias.value = (token_value))
#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \
(token).data.anchor.value = (token_value))
#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \
(token).data.tag.handle = (token_handle), \
(token).data.tag.suffix = (token_suffix))
#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \
(token).data.scalar.value = (token_value), \
(token).data.scalar.length = (token_length), \
(token).data.scalar.style = (token_style))
#define titleVersion_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_titleVersion_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
(token).data.titleVersion_directive.major = (token_major), \
(token).data.titleVersion_directive.minor = (token_minor))
#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
(token).data.tag_directive.handle = (token_handle), \
(token).data.tag_directive.prefix = (token_prefix))
/*
* Event initializers.
*/
#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \
(memset(&(event), 0, sizeof(yaml_event_t)), \
(event).type = (event_type), \
(event).start_mark = (event_start_mark), \
(event).end_mark = (event_end_mark))
#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \
(EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \
(event).data.stream_start.encoding = (event_encoding))
#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \
(EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark)))
#define DOCUMENT_START_EVENT_INIT(event,event_titleVersion_directive, \
event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \
(EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \
(event).data.document_start.titleVersion_directive = (event_titleVersion_directive), \
(event).data.document_start.tag_directives.start = (event_tag_directives_start), \
(event).data.document_start.tag_directives.end = (event_tag_directives_end), \
(event).data.document_start.implicit = (event_implicit))
#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \
(EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \
(event).data.document_end.implicit = (event_implicit))
#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \
(EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \
(event).data.alias.anchor = (event_anchor))
#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \
event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \
(EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \
(event).data.scalar.anchor = (event_anchor), \
(event).data.scalar.tag = (event_tag), \
(event).data.scalar.value = (event_value), \
(event).data.scalar.length = (event_length), \
(event).data.scalar.plain_implicit = (event_plain_implicit), \
(event).data.scalar.quoted_implicit = (event_quoted_implicit), \
(event).data.scalar.style = (event_style))
#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \
event_implicit,event_style,start_mark,end_mark) \
(EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \
(event).data.sequence_start.anchor = (event_anchor), \
(event).data.sequence_start.tag = (event_tag), \
(event).data.sequence_start.implicit = (event_implicit), \
(event).data.sequence_start.style = (event_style))
#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \
(EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark)))
#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \
event_implicit,event_style,start_mark,end_mark) \
(EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \
(event).data.mapping_start.anchor = (event_anchor), \
(event).data.mapping_start.tag = (event_tag), \
(event).data.mapping_start.implicit = (event_implicit), \
(event).data.mapping_start.style = (event_style))
#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \
(EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark)))
/*
* Document initializer.
*/
#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \
document_titleVersion_directive,document_tag_directives_start, \
document_tag_directives_end,document_start_implicit, \
document_end_implicit,document_start_mark,document_end_mark) \
(memset(&(document), 0, sizeof(yaml_document_t)), \
(document).nodes.start = (document_nodes_start), \
(document).nodes.end = (document_nodes_end), \
(document).nodes.top = (document_nodes_start), \
(document).titleVersion_directive = (document_titleVersion_directive), \
(document).tag_directives.start = (document_tag_directives_start), \
(document).tag_directives.end = (document_tag_directives_end), \
(document).start_implicit = (document_start_implicit), \
(document).end_implicit = (document_end_implicit), \
(document).start_mark = (document_start_mark), \
(document).end_mark = (document_end_mark))
/*
* Node initializers.
*/
#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \
(memset(&(node), 0, sizeof(yaml_node_t)), \
(node).type = (node_type), \
(node).tag = (node_tag), \
(node).start_mark = (node_start_mark), \
(node).end_mark = (node_end_mark))
#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \
node_style,start_mark,end_mark) \
(NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \
(node).data.scalar.value = (node_value), \
(node).data.scalar.length = (node_length), \
(node).data.scalar.style = (node_style))
#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \
node_style,start_mark,end_mark) \
(NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \
(node).data.sequence.items.start = (node_items_start), \
(node).data.sequence.items.end = (node_items_end), \
(node).data.sequence.items.top = (node_items_start), \
(node).data.sequence.style = (node_style))
#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \
node_style,start_mark,end_mark) \
(NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \
(node).data.mapping.pairs.start = (node_pairs_start), \
(node).data.mapping.pairs.end = (node_pairs_end), \
(node).data.mapping.pairs.top = (node_pairs_start), \
(node).data.mapping.style = (node_style))
+29
View File
File diff suppressed because one or more lines are too long
+93
View File
@@ -0,0 +1,93 @@
#include "lib.h"
#include "ncch.h"
#include "ncsd.h"
#include "cia.h"
int main(int argc, char *argv[])
{
// Setting up user settings
user_settings *usrset = malloc(sizeof(user_settings));
if(usrset == NULL) {fprintf(stderr,"[!] MEM ERROR\n"); return -1;}
init_UserSettings(usrset);
int result;
// Parsing command args
result = ParseArgs(argc,argv,usrset);
if(result < 0) goto fail_finalise;
// Import RSF/DESC Settings if present
result = GetYamlSettings(usrset);
if(result < 0) goto fail_finalise;
// Setup Content 0
if(!usrset->IsBuildingNCCH0){ // Import Content 0
if(usrset->Content0IsNcch){
FILE *ncch0 = fopen(usrset->ContentPath[0],"rb");
if(!ncch0) {fprintf(stderr,"[MAKEROM ERROR] Failed to open Content 0: %s\n",usrset->ContentPath[0]); goto fail_finalise;}
fclose(ncch0);
usrset->Content0.size = GetFileSize_u64(usrset->ContentPath[0]);
usrset->Content0.buffer = malloc(usrset->Content0.size);
ncch0 = fopen(usrset->ContentPath[0],"rb");
ReadFile_64(usrset->Content0.buffer, usrset->Content0.size,0,ncch0);
fclose(ncch0);
}
else if(usrset->Content0IsSrl){
FILE *srl = fopen(usrset->SrlPath,"rb");
if(!srl) {fprintf(stderr,"[MAKEROM ERROR] Failed to open SRL: %s\n",usrset->SrlPath); goto fail_finalise;}
fclose(srl);
u64 size = GetFileSize_u64(usrset->SrlPath);
usrset->Content0.size = align_value(size,0x10);
usrset->Content0.buffer = malloc(usrset->Content0.size);
srl = fopen(usrset->SrlPath,"rb");
ReadFile_64(usrset->Content0.buffer,size,0,srl);
fclose(srl);
}
else if(usrset->Content0IsCci){
FILE *cci = fopen(usrset->CciPath,"rb");
if(!cci) {fprintf(stderr,"[MAKEROM ERROR] Failed to open CCI: %s\n",usrset->CciPath); goto fail_finalise;}
fclose(cci);
usrset->Content0.size = GetFileSize_u64(usrset->CciPath);
usrset->Content0.buffer = malloc(usrset->Content0.size);
cci = fopen(usrset->CciPath,"rb");
ReadFile_64(usrset->Content0.buffer, usrset->Content0.size,0,cci);
fclose(cci);
}
}
else{// Build Content 0
result = build_NCCH(usrset);
if(result < 0) {
fprintf(stderr,"[ERROR] %s generation failed\n",usrset->build_ncch_type == CXI? "CXI" : "CFA");
fprintf(stderr,"[RESULT] Failed to build outfile\n");
goto fail_finalise;
}
}
// Make CCI
if(usrset->out_format == CCI){
result = build_CCI(usrset);
if(result < 0) { fprintf(stderr,"[RESULT] Failed to build CCI\n"); goto fail_finalise; }
}
// Make CIA
else if(usrset->out_format == CIA){
result = build_CIA(usrset);
if(result < 0) { fprintf(stderr,"[RESULT] Failed to build CIA\n"); goto fail_finalise; }
}
// No Container Raw CXI/CFA
else if(usrset->out_format == CXI || usrset->out_format == CFA){
FILE *ncch_out = fopen(usrset->outfile,"wb");
if(!ncch_out) {
fprintf(stderr,"[ERROR] Failed to create '%s'\n",usrset->outfile);
fprintf(stderr,"[RESULT] Failed to build '%s'\n",usrset->out_format == CXI? "CXI" : "CFA");
result = FAILED_TO_CREATE_OUTFILE;
goto fail_finalise;
}
WriteBuffer(usrset->Content0.buffer,usrset->Content0.size,0,ncch_out);
fclose(ncch_out);
}
free_UserSettings(usrset);
return 0;
fail_finalise:
free_UserSettings(usrset);
return result;
}
View File
+1045
View File
File diff suppressed because it is too large Load Diff
+238
View File
@@ -0,0 +1,238 @@
#ifndef _NCCH_H_
#define _NCCH_H_
typedef enum
{
NCCH_MEMERROR = -1,
SAVE_DATA_TOO_LARGE = -2,
NCCH_SECTION_NOT_EXIST = -3,
UNABLE_TO_LOAD_NCCH_KEY = -4,
NCCH_EXPORT_BUFFER_TOO_SMALL = -5,
NO_ROMFS_IN_CFA = -6,
NO_EXHEADER_IN_CXI = -7,
NO_EXEFS_IN_CXI = -8,
// SigCheck Errors
CXI_CORRUPT = -9,
ACCESSDESC_SIG_BAD = -10,
NCCH_HDR_SIG_BAD = -11,
// HashCheck Errors
ExHeader_Hashfail = -12,
Logo_Hashfail = -13,
ExeFs_Hashfail = -14,
RomFs_Hashfail = -15,
// Others
NCCH_BAD_YAML_SET = -16,
DATA_POS_DNE = -17,
} ncch_errors;
typedef enum
{
ncch_ExHeader = 1,
ncch_exefs,
ncch_romfs,
ncch_Logo,
ncch_PlainRegion,
} ncch_section;
typedef enum
{
NoKey,
KeyIsNormalFixed,
KeyIsSystemFixed,
KeyIsUnFixed,
KeyIsUnFixed2,
} ncch_key_type;
typedef enum
{
SecureCrypto2 = 3,
ContentPlatform = 4,
ContentType = 5,
ContentUnitSize = 6,
OtherFlag = 7
} ncch_flags;
typedef enum
{
FixedCryptoKey = 0x1,
NoMountRomFs = 0x2,
NoCrypto = 0x4,
} ncch_otherflag_bitmask;
typedef enum
{
RomFS = 0x1,
ExeFS = 0x2,
SystemUpdate = 0x4,
Manual = 0x8,
Child = (0x4|0x8),
Trial = 0x10
} ncch_content_bitmask;
typedef struct
{
u16 version;
u32 exheader_offset;
u32 exheader_size;
u64 logo_offset;
u64 logo_size;
u64 plain_region_offset;
u64 plain_region_size;
u64 exefs_offset;
u64 exefs_size;
u64 exefs_hash_src_size;
u64 romfs_offset;
u64 romfs_size;
u64 romfs_hash_src_size;
u8 titleID[8];
u8 programID[8];
}NCCH_STRUCT;
typedef struct
{
u8 magic[4];
u8 content_size[4];
u8 title_id[8];
u8 maker_code[2];
u8 version[2];
u8 reserved_0[4];
u8 program_id[8];
u8 reserved_1[0x10];
u8 logo_sha_256_hash[0x20];
u8 product_code[0x10];
u8 extended_header_sha_256_hash[0x20];
u8 extended_header_size[4];
u8 reserved_2[4];
u8 flags[8];
u8 plain_region_offset[4];
u8 plain_region_size[4];
u8 logo_region_offset[4];
u8 logo_region_size[4];
u8 exefs_offset[4];
u8 exefs_size[4];
u8 exefs_hash_size[4];
u8 reserved_4[4];
u8 romfs_offset[4];
u8 romfs_size[4];
u8 romfs_hash_size[4];
u8 reserved_5[4];
u8 exefs_sha_256_hash[0x20];
u8 romfs_sha_256_hash[0x20];
} NCCH_Header;
typedef struct
{
keys_struct *keys;
desc_settings *yaml_set;
COMPONENT_STRUCT *out;
struct{
u8 *PubK;
u8 *PrivK;
} CxiRsaKey;
struct
{
u32 MediaSize;
fixed_accessdesc_type accessdesc;
bool IncludeExeFsLogo;
bool CompressCode;
bool UseOnSD;
bool Encrypt;
bool FreeProductCode;
bool IsCfa;
bool IsBuildingCodeSection;
} Options;
struct
{
FILE *elf;
u64 elf_size;
FILE *banner;
u64 banner_size;
FILE *icon;
u64 icon_size;
FILE *logo;
u64 logo_size;
FILE *code;
u64 code_size;
FILE *exheader;
u64 exheader_size;
FILE *romfs;
u64 romfs_size;
FILE *plainregion;
u64 plainregion_size;
} ComponentFilePtrs;
struct
{
COMPONENT_STRUCT Code;
COMPONENT_STRUCT Banner;
COMPONENT_STRUCT Icon;
} ExeFs_Sections;
struct
{
u32 TextAddress;
u32 TextSize;
u32 TextMaxPages;
u32 ROAddress;
u32 ROSize;
u32 ROMaxPages;
u32 DataAddress;
u32 DataSize;
u32 DataMaxPages;
u32 BSS_Size;
} CodeDetails;
struct
{
u64 TotalContentSize;
COMPONENT_STRUCT CommonHeader;
COMPONENT_STRUCT ExHeader;
u64 LogoOffset;
COMPONENT_STRUCT Logo;
u64 PlainRegionOffset;
COMPONENT_STRUCT PlainRegion;
u64 ExeFsOffset;
COMPONENT_STRUCT ExeFs;
u64 RomFsOffset;
COMPONENT_STRUCT RomFs;
} Sections;
} ncch_settings;
#endif
// NCCH Build Functions
int build_NCCH(user_settings *usrset);
// NCCH Read Functions
int VerifyNCCH(u8 *ncch, keys_struct *keys, bool SuppressOutput);
u8* RetargetNCCH(FILE *fp, u64 size, u8 *TitleId, u8 *ProgramId, keys_struct *keys);
NCCH_Header* GetNCCH_CommonHDR(void *out, FILE *fp, u8 *buf);
bool IsNCCH(FILE *fp, u8 *buf);
bool IsCfa(NCCH_Header* hdr);
u32 GetNCCH_MediaUnitSize(NCCH_Header* hdr);
u32 GetNCCH_MediaSize(NCCH_Header* hdr);
ncch_key_type GetNCCHKeyType(NCCH_Header* hdr);
int GetNCCHSection(u8 *dest, u64 dest_max_size, u64 src_pos, u8 *ncch, NCCH_STRUCT *ncch_ctx, keys_struct *keys, ncch_section section);
u8* GetNCCHKey(NCCH_Header* hdr, keys_struct *keys);
int GetCXIStruct(NCCH_STRUCT *ctx, NCCH_Header *header);
void ncch_get_counter(NCCH_STRUCT *ctx, u8 counter[16], u8 type);
void CryptNCCHSection(u8 *buffer, u64 size, u64 src_pos, NCCH_STRUCT *ctx, u8 key[16], u8 type);
+554
View File
@@ -0,0 +1,554 @@
#include "lib.h"
#include "ncch.h"
#include "exheader.h"
#include "ncsd.h"
// Private Prototypes
/* RSA Crypto */
int SignCCI(u8 *Signature, u8 *NCSD_HDR);
int CheckCCISignature(u8 *Signature, u8 *NCSD_HDR);
/* cci_settings tools */
void init_CCISettings(cci_settings *set);
int get_CCISettings(cci_settings *cciset, user_settings *usrset);
void free_CCISettings(cci_settings *set);
/* CCI Data Gen/Write */
int GenNCSDHeader(cci_settings *cciset, user_settings *usrset);
int GenCardInfoHeader(cci_settings *cciset, user_settings *usrset);
int WriteCCI_HDR_ToFile(cci_settings *cciset);
int WriteCCI_Content_ToFile(cci_settings *cciset,user_settings *usrset);
int WriteCCI_DummyBytes(cci_settings *cciset);
/* Get Data from Content Files */
int CheckContent0(cci_settings *cciset, user_settings *usrset);
int GetDataFromContent0(cci_settings *cciset, user_settings *usrset);
int GetContentFP(cci_settings *cciset, user_settings *usrset);
/* Get Data from YAML Settings */
int GetMediaSize(cci_settings *cciset, user_settings *usrset);
u64 GetUnusedSize(u64 MediaSize, u8 CardType);
int GetMediaType(cci_settings *cciset, user_settings *usrset);
int GetPlatform(cci_settings *cciset, user_settings *usrset);
int GetCardDevice(cci_settings *cciset, user_settings *usrset);
int GetWriteableAddress(cci_settings *cciset, user_settings *usrset);
int GetCardInfoBitmask(cci_settings *cciset, user_settings *usrset);
int CheckMediaSize(cci_settings *cciset);
static InternalCCI_Context ctx;
// Code
int build_CCI(user_settings *usrset)
{
int result = 0;
// Init Settings
cci_settings *cciset = malloc(sizeof(cci_settings));
if(!cciset) {fprintf(stderr,"[CCI ERROR] MEM ERROR\n"); return MEM_ERROR;}
init_CCISettings(cciset);
// Get Settings
result = get_CCISettings(cciset,usrset);
if(result) goto finish;
// Create Output File
cciset->out = fopen(usrset->outfile,"wb");
if(!cciset->out){
fprintf(stderr,"[CCI ERROR] Failed to create '%s'\n",usrset->outfile);
result = FAILED_TO_CREATE_OUTFILE;
goto finish;
}
// Generate NCSD Header and Additional Header
result = GenNCSDHeader(cciset,usrset);
if(result) goto finish;
GenCardInfoHeader(cciset,usrset);
// Write to File
WriteCCI_HDR_ToFile(cciset);
result = WriteCCI_Content_ToFile(cciset,usrset);
if(result) goto finish;
// Fill out file if necessary
if(cciset->MediaFootPadding) WriteCCI_DummyBytes(cciset);
// Close output file
finish:
if(result != FAILED_TO_CREATE_OUTFILE && cciset->out) fclose(cciset->out);
free_CCISettings(cciset);
return result;
}
int SignCCI(u8 *Signature, u8 *NCSD_HDR)
{
return ctr_sig(NCSD_HDR,sizeof(NCSD_Header),Signature,ctx.keys->rsa.CCI_Pub,ctx.keys->rsa.CCI_Priv,RSA_2048_SHA256,CTR_RSA_SIGN);
}
int CheckCCISignature(u8 *Signature, u8 *NCSD_HDR)
{
return ctr_sig(NCSD_HDR,sizeof(NCSD_Header),Signature,ctx.keys->rsa.CCI_Pub,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
}
void init_CCISettings(cci_settings *set)
{
memset(set,0,sizeof(cci_settings));
memset(&ctx,0,sizeof(InternalCCI_Context));
}
int get_CCISettings(cci_settings *cciset, user_settings *usrset)
{
ctx.keys = &usrset->keys;
int result = 0;
/* Importing Data from Content0 */
result = CheckContent0(cciset,usrset);
if(result) return result;
result = GetDataFromContent0(cciset,usrset);
if(result) return result;
result = GetMediaSize(cciset,usrset);
if(result) return result;
/* Getting Data from YAML */
result = GetMediaType(cciset,usrset);
if(result) return result;
result = GetPlatform(cciset,usrset);
if(result) return result;
result = GetCardDevice(cciset,usrset);
if(result) return result;
result = GetContentFP(cciset,usrset);
if(result) return result;
result = CheckMediaSize(cciset);
if(result) return result;
/** Card Info Header Data **/
result = GetWriteableAddress(cciset,usrset);
if(result) return result;
result = GetCardInfoBitmask(cciset,usrset);
if(result) return result;
/* All Done */
return 0;
}
void free_CCISettings(cci_settings *set)
{
if(set->content){
for(int i = 1; i < 8; i++) {
if(set->content[i]) fclose(set->content[i]);
}
free(set->content);
}
free(set);
}
int GenNCSDHeader(cci_settings *cciset, user_settings *usrset)
{
memcpy((u8*)ctx.commonHDR.magic,"NCSD",4);
u32_to_u8((u8*)ctx.commonHDR.media_size,(cciset->MediaSize/cciset->MediaUnitSize),LE);
memcpy((u8*)ctx.commonHDR.title_id,cciset->MediaID,8);
for(int i = 0; i < 8; i++){
u32_to_u8((u8*)ctx.commonHDR.offsetsize_table[i].offset,(cciset->ContentOffset[i]/cciset->MediaUnitSize),LE);
u32_to_u8((u8*)ctx.commonHDR.offsetsize_table[i].size,(cciset->ContentSize[i]/cciset->MediaUnitSize),LE);
memcpy((u8*)ctx.commonHDR.partition_id_table[i],cciset->ContentTitleID[i],8);
}
memcpy((u8*)ctx.commonHDR.partition_flags,cciset->NCSD_Flags,8);
if(SignCCI(ctx.Signature,(u8*)&ctx.commonHDR) != Good){
fprintf(stderr,"[CCI ERROR] Failed to sign CCI\n");
return CCI_SIG_FAIL;
}
return 0;
}
int GenCardInfoHeader(cci_settings *cciset, user_settings *usrset)
{
u32_to_u8((u8*)ctx.CardInfoHDR.writable_address,(cciset->WritableAddress/cciset->MediaUnitSize),LE);
u32_to_u8((u8*)ctx.CardInfoHDR.card_info_bitmask,cciset->CardInfoBitmask,BE);
u32_to_u8((u8*)ctx.CardInfoHDR.media_size_used,cciset->TotalContentSize,LE);
memcpy((u8*)ctx.CardInfoHDR.ncch_0_title_id,cciset->ContentTitleID[0],8);
memcpy((u8*)ctx.CardInfoHDR.initial_data,cciset->InitialData,0x30);
if(!(usrset->OmitImportedNcchHdr && !usrset->IsBuildingNCCH0)) memcpy((u8*)ctx.CardInfoHDR.ncch_0_header,cciset->NCCH_HDR,0x100);
memcpy((u8*)ctx.DevCardInfoHDR.TitleKey,cciset->TitleKey,0x10);
return 0;
}
int WriteCCI_HDR_ToFile(cci_settings *cciset)
{
WriteBuffer(ctx.Signature,0x100,0,cciset->out);
WriteBuffer((u8*)&ctx.commonHDR,sizeof(NCSD_Header),0x100,cciset->out);
WriteBuffer((u8*)&ctx.CardInfoHDR,sizeof(CardInfo_Header),0x200,cciset->out);
WriteBuffer((u8*)&ctx.DevCardInfoHDR,sizeof(Dev_CardInfo_Header),0x1200,cciset->out);
return 0;
}
int WriteCCI_Content_ToFile(cci_settings *cciset,user_settings *usrset)
{
// Write Content 0
WriteBuffer(cciset->ncch0,cciset->ContentSize[0],cciset->ContentOffset[0],cciset->out);
free(usrset->Content0.buffer);
usrset->Content0.buffer = NULL;
usrset->Content0.size = 0;
// Add additional contents, recreating them with their new TitleID
for(int i = 1; i < 8; i++){
if(cciset->content[i]){
u8 *ContentBuff = RetargetNCCH(cciset->content[i],cciset->ContentSize[i],cciset->ContentTitleID[i],cciset->MediaID,ctx.keys);
if(!ContentBuff){
fprintf(stderr,"[CCI ERROR] Could not import content %d to CCI\n",i);
return FAILED_TO_IMPORT_FILE;
}
WriteBuffer(ContentBuff,cciset->ContentSize[i],cciset->ContentOffset[i],cciset->out);
free(ContentBuff);
}
}
return 0;
}
int WriteCCI_DummyBytes(cci_settings *cciset)
{
// Seeking end of CCI Data
fseek_64(cciset->out,cciset->TotalContentSize,SEEK_SET);
// Determining Size of Dummy Bytes
u64 len = cciset->MediaSize - cciset->TotalContentSize;
// Creating Buffer of Dummy Bytes
u8 dummy_bytes[cciset->MediaUnitSize];
memset(&dummy_bytes,0xff,cciset->MediaUnitSize);
// Writing Dummy Bytes to file
for(u64 i = 0; i < len; i += cciset->MediaUnitSize){
fwrite(&dummy_bytes,cciset->MediaUnitSize,1,cciset->out);
}
return 0;
}
int GetContentFP(cci_settings *cciset, user_settings *usrset)
{
cciset->content = malloc(sizeof(FILE*)*8);
if(!cciset->content){
fprintf(stderr,"[CCI ERROR] MEM ERROR\n");
return MEM_ERROR;
}
memset(cciset->content,0,sizeof(FILE*)*8);
for(int i = 1; i < 8; i++){
if(usrset->ContentPath[i]){
cciset->content[i] = fopen(usrset->ContentPath[i],"rb");
if(!cciset->content[i]){ // Checking if file could be opened
fprintf(stderr,"[CCI ERROR] Failed to create '%s'\n",usrset->outfile);
return FAILED_TO_OPEN_FILE;
}
if(!IsNCCH(cciset->content[i],NULL)){ // Checking if NCCH
fprintf(stderr,"[CCI ERROR] Content '%s' is invalid\n",usrset->ContentPath[i]);
return NCSD_INVALID_NCCH0;
}
// Getting NCCH Header
NCCH_Header *hdr = malloc(sizeof(NCCH_Header));;
GetNCCH_CommonHDR(hdr,cciset->content[i],NULL);
if(GetNCCH_MediaUnitSize(hdr) != cciset->MediaUnitSize){ // Checking if Media Unit Size matches CCI
fprintf(stderr,"[CCI ERROR] Content '%s' is invalid\n",usrset->ContentPath[i]);
return NCSD_INVALID_NCCH0;
}
memcpy(&cciset->ContentTitleID[i],cciset->MediaID,8); // Set TitleID
// Modify TitleID Accordingly
u16 tmp = u8_to_u16(&hdr->title_id[6],LE);
tmp |= (i+4);
u16_to_u8(&cciset->ContentTitleID[i][6],tmp,LE);
cciset->ContentSize[i] = GetNCCH_MediaSize(hdr)*cciset->MediaUnitSize;
cciset->ContentOffset[i] = cciset->TotalContentSize;
cciset->TotalContentSize += cciset->ContentSize[i];
free(hdr);
}
}
return 0;
}
int CheckContent0(cci_settings *cciset, user_settings *usrset)
{
if(!usrset->Content0.size)
return NCSD_NO_NCCH0;
cciset->ncch0 = usrset->Content0.buffer;
cciset->ncch0_FileLen = usrset->Content0.size;
if(!IsNCCH(NULL,cciset->ncch0))
return NCSD_INVALID_NCCH0;
return 0;
}
int GetDataFromContent0(cci_settings *cciset, user_settings *usrset)
{
cciset->TotalContentSize = 0x4000;
NCCH_Header *hdr;
hdr = GetNCCH_CommonHDR(NULL,NULL,cciset->ncch0);
cciset->NCCH_HDR = hdr;
//memdump(stdout,"ncch0 head: ",(cciset->ncch0+0x100),0x100);
//memdump(stdout,"ncch0 head: ",(u8*)(hdr),0x100);
memcpy(cciset->MediaID,hdr->title_id,8);
memcpy(&cciset->ContentTitleID[0],hdr->title_id,8);
if(usrset->GenSDKCardInfoHeader){
memcpy(cciset->InitialData,Stock_InitialData,0x30);
memcpy(cciset->TitleKey,Stock_TitleKey,0x10);
}
else{
u8 Hash[0x40];
ctr_sha(cciset->ncch0,0x80,Hash,CTR_SHA_256);
ctr_sha((cciset->ncch0+0x80),0x80,(Hash+0x20),CTR_SHA_256);
memcpy(cciset->InitialData,Hash,0x2C);
//memcpy(cciset->TitleKey,(Hash+0x30),0x10); // Might Remove
}
cciset->NCSD_Flags[MediaUnitSize] = hdr->flags[ContentUnitSize];
cciset->MediaUnitSize = GetNCCH_MediaUnitSize(hdr);
cciset->ContentSize[0] = (u64)(GetNCCH_MediaSize(hdr) * cciset->MediaUnitSize);
cciset->ContentOffset[0] = cciset->TotalContentSize;
cciset->TotalContentSize += cciset->ContentSize[0];
return 0;
}
int GetMediaSize(cci_settings *cciset, user_settings *usrset)
{
char *MediaSizeStr = usrset->yaml_set.DefaultSpec.BasicInfo.MediaSize;
if(!MediaSizeStr) cciset->MediaSize = (u64)GB*2;
else{
if(strcasecmp(MediaSizeStr,"128MB") == 0) cciset->MediaSize = (u64)MB*128;
else if(strcasecmp(MediaSizeStr,"256MB") == 0) cciset->MediaSize = (u64)MB*256;
else if(strcasecmp(MediaSizeStr,"512MB") == 0) cciset->MediaSize = (u64)MB*512;
else if(strcasecmp(MediaSizeStr,"1GB") == 0) cciset->MediaSize = (u64)GB*1;
else if(strcasecmp(MediaSizeStr,"2GB") == 0) cciset->MediaSize = (u64)GB*2;
else if(strcasecmp(MediaSizeStr,"4GB") == 0) cciset->MediaSize = (u64)GB*4;
else if(strcasecmp(MediaSizeStr,"8GB") == 0) cciset->MediaSize = (u64)GB*8;
else if(strcasecmp(MediaSizeStr,"16GB") == 0) cciset->MediaSize = (u64)GB*16;
else if(strcasecmp(MediaSizeStr,"32GB") == 0) cciset->MediaSize = (u64)GB*32;
else {
fprintf(stderr,"[CCI ERROR] Invalid MediaSize: %s\n",MediaSizeStr);
return INVALID_YAML_OPT;
}
}
if(usrset->yaml_set.DefaultSpec.BasicInfo.MediaFootPadding != -1) cciset->MediaFootPadding = usrset->yaml_set.DefaultSpec.BasicInfo.MediaFootPadding;
return 0;
}
u64 GetUnusedSize(u64 MediaSize, u8 CardType)
{
if(CardType == CARD1){
switch(MediaSize){
case (u64)MB*128: return (u64)2621440;
case (u64)MB*256: return (u64)5242880;
case (u64)MB*512: return (u64)10485760;
case (u64)GB*1: return (u64)73924608;
case (u64)GB*2: return (u64)147324928;
case (u64)GB*4: return (u64)294649856;
case (u64)GB*8: return (u64)587202560;
default: return (u64)((MediaSize/MB)*0x11800); // Aprox
}
}
else if(CardType == CARD2){
switch(MediaSize){
case (u64)MB*512: return (u64)37224448;
case (u64)GB*1: return (u64)73924608;
case (u64)GB*2: return (u64)147324928;
case (u64)GB*4: return (u64)294649856;
case (u64)GB*8: return (u64)587202560;
default: return (u64)((MediaSize/MB)*0x11800); // Aprox
}
}
return 0;
}
int GetMediaType(cci_settings *cciset, user_settings *usrset)
{
char *MediaTypeStr = usrset->yaml_set.DefaultSpec.CardInfo.MediaType;
if(!MediaTypeStr) cciset->NCSD_Flags[MediaTypeIndex] = CARD1;
else{
if(strcasecmp(MediaTypeStr,"Card1") == 0) cciset->NCSD_Flags[MediaTypeIndex] = CARD1;
else if(strcasecmp(MediaTypeStr,"Card2") == 0) cciset->NCSD_Flags[MediaTypeIndex] = CARD2;
else {
fprintf(stderr,"[CCI ERROR] Invalid MediaType: %s\n",MediaTypeStr);
return INVALID_YAML_OPT;
}
}
return 0;
}
int GetPlatform(cci_settings *cciset, user_settings *usrset)
{
char *PlatformStr = usrset->yaml_set.DefaultSpec.TitleInfo.Platform;
if(!PlatformStr) cciset->NCSD_Flags[MediaPlatformIndex] = CTR;
else{
if(strcasecmp(PlatformStr,"ctr") == 0) cciset->NCSD_Flags[MediaPlatformIndex] = CTR;
else {
fprintf(stderr,"[CCI ERROR] Invalid Platform: %s\n",PlatformStr);
return INVALID_YAML_OPT;
}
}
return 0;
}
int GetCardDevice(cci_settings *cciset, user_settings *usrset)
{
char *CardDeviceStr = usrset->yaml_set.DefaultSpec.CardInfo.CardDevice;
if(!CardDeviceStr) cciset->NCSD_Flags[CardDeviceFlag] = CARD_DEVICE_NONE;
else{
if(strcmp(CardDeviceStr,"NorFlash") == 0) {
cciset->NCSD_Flags[CardDeviceFlag] = CARD_DEVICE_NOR_FLASH;
if(cciset->NCSD_Flags[MediaTypeIndex] == CARD2){
fprintf(stderr,"[CCI WARNING] 'CardDevice: NorFlash' is invalid on Card2\n");
cciset->NCSD_Flags[CardDeviceFlag] = CARD_DEVICE_NONE;
}
}
else if(strcmp(CardDeviceStr,"None") == 0) cciset->NCSD_Flags[CardDeviceFlag] = CARD_DEVICE_NONE;
else if(strcmp(CardDeviceStr,"BT") == 0) cciset->NCSD_Flags[CardDeviceFlag] = CARD_DEVICE_BT;
else {
fprintf(stderr,"[CCI ERROR] Invalid CardDevice: %s\n",CardDeviceStr);
return INVALID_YAML_OPT;
}
}
return 0;
}
int GetWriteableAddress(cci_settings *cciset, user_settings *usrset)
{
int result = GetSaveDataSize_yaml(&cciset->SaveDataSize,usrset);
if(result) return result;
char *WriteableAddressStr = usrset->yaml_set.DefaultSpec.CardInfo.WritableAddress;;
cciset->WritableAddress = -1;
if(cciset->NCSD_Flags[MediaTypeIndex] != CARD2) return 0; // Can only be set for Card2 Media
if(WriteableAddressStr){
if(strncmp(WriteableAddressStr,"0x",2) != 0){
fprintf(stderr,"[CCI ERROR] WritableAddress requires a Hexadecimal value\n");
return INVALID_YAML_OPT;
}
cciset->WritableAddress = strtoul((WriteableAddressStr+2),NULL,16);
}
if(cciset->WritableAddress == -1){ // If not set manually or is max size
if ((cciset->MediaSize / 2) < cciset->SaveDataSize){ // If SaveData size is greater than half the MediaSize
u64 saveDataSize = cciset->SaveDataSize / KB;
fprintf(stderr,"[CCI ERROR] Too large SaveDataSize %luK\n",saveDataSize);
return SAVE_DATA_TOO_LARGE;
}
if (cciset->SaveDataSize > (u64)(2047*MB)){ // Limit set by Nintendo
u64 saveDataSize = cciset->SaveDataSize / KB;
fprintf(stderr,"[CCI ERROR] Too large SaveDataSize %luK\n",saveDataSize);
return SAVE_DATA_TOO_LARGE;
}
u64 UnusedSize = GetUnusedSize(cciset->MediaSize,cciset->NCSD_Flags[MediaTypeIndex]); // Need to look into this
cciset->WritableAddress = cciset->MediaSize - UnusedSize - cciset->SaveDataSize;
}
return 0;
}
int GetCardInfoBitmask(cci_settings *cciset, user_settings *usrset)
{
char *str = usrset->yaml_set.DefaultSpec.CardInfo.CardType;
if(!str) cciset->CardInfoBitmask |= 0;
else{
if(strcasecmp(str,"s1") == 0) cciset->CardInfoBitmask |= 0;
else if(strcasecmp(str,"s2") == 0) cciset->CardInfoBitmask |= 0x20;
else {
fprintf(stderr,"[CCI ERROR] Invalid CardType: %s\n",str);
return INVALID_YAML_OPT;
}
}
str = usrset->yaml_set.DefaultSpec.CardInfo.CryptoType;
if(!str) cciset->CardInfoBitmask |= (3*0x40);
else{
int Value = strtol(str,NULL,10);
if(Value < 0 || Value > 3) {
fprintf(stderr,"[CCI ERROR] Invalid CryptoType: %s\n",str);
return INVALID_YAML_OPT;
}
if(Value != 3){
fprintf(stderr,"[CCI WARNING] Card crypto type = '%d'\n",Value);
}
cciset->CardInfoBitmask |= (Value*0x40);
}
return 0;
}
int CheckMediaSize(cci_settings *cciset)
{
if(cciset->TotalContentSize > cciset->MediaSize){
char *MediaSizeStr = NULL;
switch(cciset->MediaSize){
case (u64)128*MB: MediaSizeStr = " '128MB'"; break;
case (u64)256*MB: MediaSizeStr = " '256MB'"; break;
case (u64)512*MB: MediaSizeStr = " '512MB'"; break;
case (u64)1*GB: MediaSizeStr = " '1GB'"; break;
case (u64)2*GB: MediaSizeStr = " '2GB'"; break;
case (u64)4*GB: MediaSizeStr = " '4GB'"; break;
case (u64)8*GB: MediaSizeStr = " '8GB'"; break;
case (u64)16*GB: MediaSizeStr = " '16GB'"; break;
case (u64)32*GB: MediaSizeStr = " '32GB'"; break;
default: MediaSizeStr = ""; break;
}
fprintf(stderr,"[CCI ERROR] MediaSize%s is too Small\n",MediaSizeStr);
return INVALID_YAML_OPT;
}
return 0;
}
bool IsCci(u8 *ncsd)
{
NCSD_Header *hdr = (NCSD_Header*)(ncsd+0x100);
if(!hdr) return false;
if(memcmp(hdr->magic,"NCSD",4)!=0) return false;
if(hdr->partition_flags[MediaPlatformIndex] != CTR) return false;
if(hdr->partition_flags[MediaTypeIndex] != CARD1 && hdr->partition_flags[MediaTypeIndex] != CARD2) return false;
return true;
}
u8* GetPartition(u8 *ncsd, u8 index)
{
return (u8*)(ncsd+GetPartitionOffset(ncsd,index));
}
u64 GetPartitionOffset(u8 *ncsd, u8 index)
{
NCSD_Header *hdr = (NCSD_Header*)(ncsd+0x100);
u32 media_size = 0x200*pow(2,hdr->partition_flags[MediaUnitSize]);
u32 offset = u8_to_u64(hdr->offsetsize_table[index].offset,LE);
return offset*media_size;
}
u64 GetPartitionSize(u8 *ncsd, u8 index)
{
NCSD_Header *hdr = (NCSD_Header*)(ncsd+0x100);
u32 media_size = 0x200*pow(2,hdr->partition_flags[MediaUnitSize]);
u32 size = u8_to_u64(hdr->offsetsize_table[index].size,LE);
return size*media_size;
}
+162
View File
@@ -0,0 +1,162 @@
#ifndef _NCSD_H_
#define _NCSD_H_
// Enums
typedef enum
{
NCSD_NO_NCCH0 = -1,
NCSD_INVALID_NCCH0 = -2,
INVALID_YAML_OPT = -3,
CCI_SIG_FAIL = -4,
} ncsd_errors;
typedef enum
{
FW6x_SaveCryptoFlag = 1,
CardDeviceFlag = 3,
MediaPlatformIndex = 4,
MediaTypeIndex = 5,
MediaUnitSize = 6,
OldCardDeviceFlag = 7
} FlagIndex;
typedef enum
{
CARD_DEVICE_NOR_FLASH = 1,
CARD_DEVICE_NONE = 2,
CARD_DEVICE_BT = 3
} _CardDevice;
typedef enum
{
CTR = 1,
} _PlatformIndex;
typedef enum
{
INNER_DEVICE,
CARD1,
CARD2,
EXTENDED_DEVICE
} _TypeIndex;
// Structs
typedef struct
{
u8 offset[4];
u8 size[4];
} partition_offsetsize;
typedef struct
{
u8 magic[4];
u8 media_size[4];
u8 title_id[8];
u8 partitions_fs_type[8];
u8 partitions_crypto_type[8];
partition_offsetsize offsetsize_table[8];
u8 exheader_hash[0x20];
u8 additional_header_size[0x4];
u8 sector_zero_offset[0x4];
u8 partition_flags[8];
u8 partition_id_table[8][8];
u8 reserved[0x30];
} NCSD_Header;
typedef struct
{
u8 writable_address[4];
u8 card_info_bitmask[4];
// Notes
u8 reserved_0[0xf8];
u8 media_size_used[8];
u8 reserved_1[0x18];
u8 cver_title_id[8];
u8 cver_title_version[2];
u8 reserved_2[0xcd6];
//
u8 ncch_0_title_id[8];
u8 reserved_3[8];
u8 initial_data[0x30];
u8 reserved_4[0xc0];
u8 ncch_0_header[0x100];
} CardInfo_Header;
typedef struct
{
u8 CardDeviceReserved1[0x200];
u8 TitleKey[0x10];
u8 CardDeviceReserved2[0xf0];
} Dev_CardInfo_Header;
typedef struct
{
u8 Signature[0x100];
NCSD_Header commonHDR;
CardInfo_Header CardInfoHDR;
Dev_CardInfo_Header DevCardInfoHDR;
u8 *ContentImportBuffer;
keys_struct *keys;
} InternalCCI_Context;
typedef struct
{
u64 MediaSize;
u8 MediaID[8];
u8 NCSD_Flags[8];
u64 SaveDataSize;
u64 WritableAddress;
u32 CardInfoBitmask;
u8 InitialData[0x30];
NCCH_Header *NCCH_HDR;
u8 TitleKey[0x10];
u8 *ncch0;
u64 ncch0_FileLen;
FILE **content;
u64 ContentSize[CCI_MAX_CONTENT];
u64 ContentOffset[CCI_MAX_CONTENT];
u8 ContentTitleID[CCI_MAX_CONTENT][8];
u64 TotalContentSize;
bool MediaFootPadding;
u32 MediaUnitSize;
FILE *out;
} cci_settings;
static const u8 Stock_InitialData[0x30] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xAD, 0x88,
0xAC, 0x41, 0xA2, 0xB1, 0x5E, 0x8F,
0x66, 0x9C, 0x97, 0xE5, 0xE1, 0x5E,
0xA3, 0xEB, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const u8 Stock_TitleKey[0x10] =
{
0x6E, 0xC7, 0x5F, 0xB2, 0xE2, 0xB4,
0x87, 0x46, 0x1E, 0xDD, 0xCB, 0xB8,
0x97, 0x11, 0x92, 0xBA
};
#endif
// Public Prototypes
// Build Functions
int build_CCI(user_settings *usrset);
// Read Functions
bool IsCci(u8 *ncsd);
u8* GetPartition(u8 *ncsd, u8 index);
u64 GetPartitionOffset(u8 *ncsd, u8 index);
u64 GetPartitionSize(u8 *ncsd, u8 index);
+1352
View File
File diff suppressed because it is too large Load Diff
+202
View File
@@ -0,0 +1,202 @@
/**
* \file aes.h
*
* \brief AES block cipher
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_AES_H
#define POLARSSL_AES_H
#include "polarssl/config.h"
#include <string.h>
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
#if !defined(POLARSSL_AES_ALT)
// Regular implementation
//
/**
* \brief AES context structure
*/
typedef struct
{
int nr; /*!< number of rounds */
uint32_t *rk; /*!< AES round keys */
uint32_t buf[68]; /*!< unaligned data */
}
aes_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize );
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize );
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int aes_crypt_ecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
*/
int aes_crypt_cbc( aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CFB128 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* both
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int aes_crypt_cfb128( aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int aes_crypt_ctr( aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_AES_ALT */
#include "polarssl/aes_alt.h"
#endif /* POLARSSL_AES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int aes_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* aes.h */
+173
View File
@@ -0,0 +1,173 @@
/*
* An implementation of the ARCFOUR algorithm
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The ARCFOUR algorithm was publicly disclosed on 94/09.
*
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
*/
#include "polarssl/config.h"
#if defined(POLARSSL_ARC4_C)
#include "polarssl/arc4.h"
#if !defined(POLARSSL_ARC4_ALT)
/*
* ARC4 key schedule
*/
void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen )
{
int i, j, a;
unsigned int k;
unsigned char *m;
ctx->x = 0;
ctx->y = 0;
m = ctx->m;
for( i = 0; i < 256; i++ )
m[i] = (unsigned char) i;
j = k = 0;
for( i = 0; i < 256; i++, k++ )
{
if( k >= keylen ) k = 0;
a = m[i];
j = ( j + a + key[k] ) & 0xFF;
m[i] = m[j];
m[j] = (unsigned char) a;
}
}
/*
* ARC4 cipher function
*/
int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input,
unsigned char *output )
{
int x, y, a, b;
size_t i;
unsigned char *m;
x = ctx->x;
y = ctx->y;
m = ctx->m;
for( i = 0; i < length; i++ )
{
x = ( x + 1 ) & 0xFF; a = m[x];
y = ( y + a ) & 0xFF; b = m[y];
m[x] = (unsigned char) b;
m[y] = (unsigned char) a;
output[i] = (unsigned char)
( input[i] ^ m[(unsigned char)( a + b )] );
}
ctx->x = x;
ctx->y = y;
return( 0 );
}
#endif /* !POLARSSL_ARC4_ALT */
#if defined(POLARSSL_SELF_TEST)
#include <string.h>
#include <stdio.h>
/*
* ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
*
* http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
*/
static const unsigned char arc4_test_key[3][8] =
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char arc4_test_pt[3][8] =
{
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
static const unsigned char arc4_test_ct[3][8] =
{
{ 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
{ 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
{ 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
};
/*
* Checkup routine
*/
int arc4_self_test( int verbose )
{
int i;
unsigned char ibuf[8];
unsigned char obuf[8];
arc4_context ctx;
for( i = 0; i < 3; i++ )
{
if( verbose != 0 )
printf( " ARC4 test #%d: ", i + 1 );
memcpy( ibuf, arc4_test_pt[i], 8 );
arc4_setup( &ctx, arc4_test_key[i], 8 );
arc4_crypt( &ctx, 8, ibuf, obuf );
if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif
+98
View File
@@ -0,0 +1,98 @@
/**
* \file arc4.h
*
* \brief The ARCFOUR stream cipher
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_ARC4_H
#define POLARSSL_ARC4_H
#include "polarssl/config.h"
#include <string.h>
#if !defined(POLARSSL_ARC4_ALT)
// Regular implementation
//
/**
* \brief ARC4 context structure
*/
typedef struct
{
int x; /*!< permutation index */
int y; /*!< permutation index */
unsigned char m[256]; /*!< permutation table */
}
arc4_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief ARC4 key schedule
*
* \param ctx ARC4 context to be initialized
* \param key the secret key
* \param keylen length of the key
*/
void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen );
/**
* \brief ARC4 cipher function
*
* \param ctx ARC4 context
* \param length length of the input data
* \param input buffer holding the input data
* \param output buffer for the output data
*
* \return 0 if successful
*/
int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_ARC4_ALT */
#include "polarssl/arc4_alt.h"
#endif /* POLARSSL_ARC4_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int arc4_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* arc4.h */
+246
View File
@@ -0,0 +1,246 @@
/**
* \file asn1.h
*
* \brief Generic ASN.1 parsing
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_ASN1_H
#define POLARSSL_ASN1_H
#include "polarssl/config.h"
#if defined(POLARSSL_BIGNUM_C)
#include "polarssl/bignum.h"
#endif
#include <string.h>
/**
* \addtogroup asn1_module
* \{
*/
/**
* \name ASN1 Error codes
* These error codes are OR'ed to X509 error codes for
* higher error granularity.
* ASN1 is a standard to specify data structures.
* \{
*/
#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
#define POLARSSL_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
#define POLARSSL_ERR_ASN1_MALLOC_FAILED -0x006A /**< Memory allocation failed */
#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
/* \} name */
/**
* \name DER constants
* These constants comply with DER encoded the ANS1 type tags.
* DER encoding uses hexadecimal representation.
* An example DER sequence is:\n
* - 0x02 -- tag indicating INTEGER
* - 0x01 -- length in octets
* - 0x05 -- value
* Such sequences are typically read into \c ::x509_buf.
* \{
*/
#define ASN1_BOOLEAN 0x01
#define ASN1_INTEGER 0x02
#define ASN1_BIT_STRING 0x03
#define ASN1_OCTET_STRING 0x04
#define ASN1_NULL 0x05
#define ASN1_OID 0x06
#define ASN1_UTF8_STRING 0x0C
#define ASN1_SEQUENCE 0x10
#define ASN1_SET 0x11
#define ASN1_PRINTABLE_STRING 0x13
#define ASN1_T61_STRING 0x14
#define ASN1_IA5_STRING 0x16
#define ASN1_UTC_TIME 0x17
#define ASN1_GENERALIZED_TIME 0x18
#define ASN1_UNIVERSAL_STRING 0x1C
#define ASN1_BMP_STRING 0x1E
#define ASN1_PRIMITIVE 0x00
#define ASN1_CONSTRUCTED 0x20
#define ASN1_CONTEXT_SPECIFIC 0x80
/* \} name */
/* \} addtogroup asn1_module */
/** Returns the size of the binary string, without the trailing \\0 */
#define OID_SIZE(x) (sizeof(x) - 1)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name Functions to parse ASN.1 data structures
* \{
*/
/**
* Type-length-value structure that allows for ASN1 using DER.
*/
typedef struct _asn1_buf
{
int tag; /**< ASN1 type, e.g. ASN1_UTF8_STRING. */
size_t len; /**< ASN1 length, e.g. in octets. */
unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
}
asn1_buf;
/**
* Container for ASN1 bit strings.
*/
typedef struct _asn1_bitstring
{
size_t len; /**< ASN1 length, e.g. in octets. */
unsigned char unused_bits; /**< Number of unused bits at the end of the string */
unsigned char *p; /**< Raw ASN1 data for the bit string */
}
asn1_bitstring;
/**
* Container for a sequence of ASN.1 items
*/
typedef struct _asn1_sequence
{
asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
struct _asn1_sequence *next; /**< The next entry in the sequence. */
}
asn1_sequence;
/**
* Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the value
*
* \return 0 if successful, POLARSSL_ERR_ASN1_OUT_OF_DATA on reaching
* end of data, POLARSSL_ERR_ASN1_INVALID_LENGTH if length is
* unparseable.
*/
int asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len );
/**
* Get the tag and length of the tag. Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param len The variable that will receive the length
* \param tag The expected tag
*
* \return 0 if successful, POLARSSL_ERR_ASN1_UNEXPECTED_TAG if tag did
* not match requested tag, or another specific ASN.1 error code.
*/
int asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag );
/**
* Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val );
/**
* Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param val The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val );
/**
* Retrieve a bitstring ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param bs The variable that will receive the value
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
asn1_bitstring *bs);
/**
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
* Updated the pointer to immediately behind the full sequence tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param cur First variable in the chain to fill
* \param tag Type of sequence
*
* \return 0 if successful or a specific ASN.1 error code.
*/
int asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
asn1_sequence *cur,
int tag);
#if defined(POLARSSL_BIGNUM_C)
/**
* Retrieve a MPI value from an integer ASN.1 tag.
* Updates the pointer to immediately behind the full tag.
*
* \param p The position in the ASN.1 data
* \param end End of data
* \param X The MPI that will receive the value
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
int asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mpi *X );
#endif
#ifdef __cplusplus
}
#endif
#endif /* asn1.h */
+260
View File
@@ -0,0 +1,260 @@
/*
* Generic ASN.1 parsing
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_ASN1_PARSE_C)
#include "polarssl/asn1.h"
#if defined(POLARSSL_BIGNUM_C)
#include "polarssl/bignum.h"
#endif
#include <string.h>
#include <stdlib.h>
#include <time.h>
/*
* ASN.1 DER decoding routines
*/
int asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len )
{
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
if( ( **p & 0x80 ) == 0 )
*len = *(*p)++;
else
{
switch( **p & 0x7F )
{
case 1:
if( ( end - *p ) < 2 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = (*p)[1];
(*p) += 2;
break;
case 2:
if( ( end - *p ) < 3 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 8 ) | (*p)[2];
(*p) += 3;
break;
case 3:
if( ( end - *p ) < 4 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
(*p) += 4;
break;
case 4:
if( ( end - *p ) < 5 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4];
(*p) += 5;
break;
default:
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
}
}
if( *len > (size_t) ( end - *p ) )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
return( 0 );
}
int asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag )
{
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
if( **p != tag )
return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
(*p)++;
return( asn1_get_len( p, end, len ) );
}
int asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
return( ret );
if( len != 1 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
*val = ( **p != 0 ) ? 1 : 0;
(*p)++;
return( 0 );
}
int asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
return( ret );
if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
*val = 0;
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
(*p)++;
}
return( 0 );
}
#if defined(POLARSSL_BIGNUM_C)
int asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mpi *X )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
return( ret );
ret = mpi_read_binary( X, *p, len );
*p += len;
return( ret );
}
#endif /* POLARSSL_BIGNUM_C */
int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
asn1_bitstring *bs)
{
int ret;
/* Certificate type is a single byte bitstring */
if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
return( ret );
/* Check length, subtract one for actual bit string length */
if ( bs->len < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
bs->len -= 1;
/* Get number of unused bits, ensure unused bits <= 7 */
bs->unused_bits = **p;
if( bs->unused_bits > 7 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
(*p)++;
/* Get actual bitstring */
bs->p = *p;
*p += bs->len;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return 0;
}
/*
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
*/
int asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
asn1_sequence *cur,
int tag)
{
int ret;
size_t len;
asn1_buf *buf;
/* Get main sequence tag */
if( ( ret = asn1_get_tag( p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( ret );
if( *p + len != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
while( *p < end )
{
buf = &(cur->buf);
buf->tag = **p;
if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
return( ret );
buf->p = *p;
*p += buf->len;
/* Allocate and assign next pointer */
if (*p < end)
{
cur->next = (asn1_sequence *) malloc(
sizeof( asn1_sequence ) );
if( cur->next == NULL )
return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
cur = cur->next;
}
}
/* Set final sequence entry's next pointer to NULL */
cur->next = NULL;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
#endif
+241
View File
@@ -0,0 +1,241 @@
/*
* ASN.1 buffer writing functionality
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_ASN1_WRITE_C)
#include "polarssl/asn1write.h"
int asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
{
if( len < 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = len;
return( 1 );
}
if( len <= 0xFF )
{
if( *p - start < 2 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = len;
*--(*p) = 0x81;
return( 2 );
}
if( *p - start < 3 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
// We assume we never have lengths larger than 65535 bytes
//
*--(*p) = len % 256;
*--(*p) = ( len / 256 ) % 256;
*--(*p) = 0x82;
return( 3 );
}
int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = tag;
return( 1 );
}
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
{
int ret;
size_t len = 0;
// Write the MPI
//
len = mpi_size( X );
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
(*p) -= len;
mpi_write_binary( X, *p, len );
// DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers.
//
if ( X->s ==1 && **p & 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
return( len );
}
int asn1_write_null( unsigned char **p, unsigned char *start )
{
int ret;
size_t len = 0;
// Write NULL
//
ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
return( len );
}
int asn1_write_oid( unsigned char **p, unsigned char *start, char *oid )
{
int ret;
size_t len = 0;
// Write OID
//
len = strlen( oid );
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
(*p) -= len;
memcpy( *p, oid, len );
ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
return( len );
}
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
char *algorithm_oid )
{
int ret;
size_t null_len = 0;
size_t oid_len = 0;
size_t len = 0;
// Write NULL
//
ASN1_CHK_ADD( null_len, asn1_write_null( p, start ) );
// Write OID
//
ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, algorithm_oid ) );
len = oid_len + null_len;
ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + null_len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
return( len );
}
int asn1_write_int( unsigned char **p, unsigned char *start, int val )
{
int ret;
size_t len = 0;
// TODO negative values and values larger than 128
// DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers.
//
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
len += 1;
*--(*p) = val;
if ( val > 0 && **p & 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
return( len );
}
int asn1_write_printable_string( unsigned char **p, unsigned char *start,
char *text )
{
int ret;
size_t len = 0;
// Write string
//
len = strlen( text );
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
(*p) -= len;
memcpy( *p, text, len );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
return( len );
}
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
char *text )
{
int ret;
size_t len = 0;
// Write string
//
len = strlen( text );
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
(*p) -= len;
memcpy( *p, text, len );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
return( len );
}
#endif
+46
View File
@@ -0,0 +1,46 @@
/**
* \file asn1write.h
*
* \brief ASN.1 buffer writing functionality
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_ASN1_WRITE_H
#define POLARSSL_ASN1_WRITE_H
#include "polarssl/asn1.h"
#define ASN1_CHK_ADD(g, f) if( ( ret = f ) < 0 ) return( ret ); else g += ret
int asn1_write_len( unsigned char **p, unsigned char *start, size_t len );
int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag );
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X );
int asn1_write_null( unsigned char **p, unsigned char *start );
int asn1_write_oid( unsigned char **p, unsigned char *start, char *oid );
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, char *algorithm_oid );
int asn1_write_int( unsigned char **p, unsigned char *start, int val );
int asn1_write_printable_string( unsigned char **p, unsigned char *start,
char *text );
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
char *text );
#endif /* POLARSSL_ASN1_WRITE_H */
+269
View File
@@ -0,0 +1,269 @@
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_BASE64_C)
#include "polarssl/base64.h"
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
static const unsigned char base64_enc_map[64] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/'
};
static const unsigned char base64_dec_map[128] =
{
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 127, 127, 127, 127, 127
};
/*
* Encode a buffer into base64 format
*/
int base64_encode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen )
{
size_t i, n;
int C1, C2, C3;
unsigned char *p;
if( slen == 0 )
return( 0 );
n = (slen << 3) / 6;
switch( (slen << 3) - (n * 6) )
{
case 2: n += 3; break;
case 4: n += 2; break;
default: break;
}
if( *dlen < n + 1 )
{
*dlen = n + 1;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
n = (slen / 3) * 3;
for( i = 0, p = dst; i < n; i += 3 )
{
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}
if( i < slen )
{
C1 = *src++;
C2 = ((i + 1) < slen) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
if( (i + 1) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
else *p++ = '=';
*p++ = '=';
}
*dlen = p - dst;
*p = 0;
return( 0 );
}
/*
* Decode a base64-formatted buffer
*/
int base64_decode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen )
{
size_t i, n;
uint32_t j, x;
unsigned char *p;
for( i = j = n = 0; i < slen; i++ )
{
if( ( slen - i ) >= 2 &&
src[i] == '\r' && src[i + 1] == '\n' )
continue;
if( src[i] == '\n' )
continue;
if( src[i] == '=' && ++j > 2 ){
printf("err 0 char[%d] = '%c' (0x%x)\n",i,src[i],src[i]);
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
}
if( src[i] > 127 || base64_dec_map[src[i]] == 127 ){
printf("err 1 char[%d] = '%c' (0x%x)\n",i,src[i],src[i]);
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
}
if( base64_dec_map[src[i]] < 64 && j != 0 ){
printf("err 2 char[%d] = '%c' (0x%x)\n",i,src[i],src[i]);
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
}
n++;
}
if( n == 0 )
return( 0 );
n = ((n * 6) + 7) >> 3;
if( (*dlen+4) < n )
{
*dlen = n;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
if( *src == '\r' || *src == '\n' )
continue;
j -= ( base64_dec_map[*src] == 64 );
x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
if( ++n == 4 )
{
n = 0;
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
if( j > 2 ) *p++ = (unsigned char)( x );
}
}
*dlen = p - dst;
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <string.h>
#include <stdio.h>
static const unsigned char base64_test_dec[64] =
{
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
};
static const unsigned char base64_test_enc[] =
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
/*
* Checkup routine
*/
int base64_self_test( int verbose )
{
size_t len;
const unsigned char *src;
unsigned char buffer[128];
if( verbose != 0 )
printf( " Base64 encoding test: " );
len = sizeof( buffer );
src = base64_test_dec;
if( base64_encode( buffer, &len, src, 64 ) != 0 ||
memcmp( base64_test_enc, buffer, 88 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n Base64 decoding test: " );
len = sizeof( buffer );
src = base64_test_enc;
if( base64_decode( buffer, &len, src, 88 ) != 0 ||
memcmp( base64_test_dec, buffer, 64 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n\n" );
return( 0 );
}
#endif
#endif
+87
View File
@@ -0,0 +1,87 @@
/**
* \file base64.h
*
* \brief RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_BASE64_H
#define POLARSSL_BASE64_H
#include <string.h>
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Encode a buffer into base64 format
*
* \param dst destination buffer
* \param dlen size of the buffer
* \param src source buffer
* \param slen amount of data to be encoded
*
* \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
* *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_encode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen );
/**
* \brief Decode a base64-formatted buffer
*
* \param dst destination buffer
* \param dlen size of the buffer
* \param src source buffer
* \param slen amount of data to be decoded
*
* \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
* POLARSSL_ERR_BASE64_INVALID_CHARACTER if the input data is
* not correct. *dlen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen
*/
int base64_decode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int base64_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* base64.h */
+2135
View File
File diff suppressed because it is too large Load Diff
+685
View File
@@ -0,0 +1,685 @@
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_BIGNUM_H
#define POLARSSL_BIGNUM_H
#include <stdio.h>
#include <string.h>
#include "polarssl/config.h"
#ifdef _MSC_VER
#include <basetsd.h>
#if (_MSC_VER <= 1200)
typedef signed short int16_t;
typedef unsigned short uint16_t;
#else
typedef INT16 int16_t;
typedef UINT16 uint16_t;
#endif
typedef INT32 int32_t;
typedef INT64 int64_t;
typedef UINT32 uint32_t;
typedef UINT64 uint64_t;
#else
#include <inttypes.h>
#endif
#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */
#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
/*
* Maximum size MPIs are allowed to grow to in number of limbs.
*/
#define POLARSSL_MPI_MAX_LIMBS 10000
#if !defined(POLARSSL_CONFIG_OPTIONS)
/*
* Maximum window size used for modular exponentiation. Default: 6
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
*
* Reduction in size, reduces speed.
*/
#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
/*
* Maximum size of MPIs allowed in bits and bytes for user-MPIs.
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
*
* Note: Calculations can results temporarily in larger MPIs. So the number
* of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher.
*/
#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */
#endif /* !POLARSSL_CONFIG_OPTIONS */
#define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
/*
* When reading from files with mpi_read_file() and writing to files with
* mpi_write_file() the buffer should have space
* for a (short) label, the MPI (in the provided radix), the newline
* characters and the '\0'.
*
* By default we assume at least a 10 char label, a minimum radix of 10
* (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
* Autosized at compile time for at least a 10 char label, a minimum radix
* of 10 (decimal) for a number of POLARSSL_MPI_MAX_BITS size.
*
* This used to be statically sized to 1250 for a maximum of 4096 bit
* numbers (1234 decimal chars).
*
* Calculate using the formula:
* POLARSSL_MPI_RW_BUFFER_SIZE = ceil(POLARSSL_MPI_MAX_BITS / ln(10) * ln(2)) +
* LabelSize + 6
*/
#define POLARSSL_MPI_MAX_BITS_SCALE100 ( 100 * POLARSSL_MPI_MAX_BITS )
#define LN_2_DIV_LN_10_SCALE100 332
#define POLARSSL_MPI_RW_BUFFER_SIZE ( ((POLARSSL_MPI_MAX_BITS_SCALE100 + LN_2_DIV_LN_10_SCALE100 - 1) / LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
/*
* Define the base integer type, architecture-wise
*/
#if defined(POLARSSL_HAVE_INT8)
typedef signed char t_sint;
typedef unsigned char t_uint;
typedef uint16_t t_udbl;
#define POLARSSL_HAVE_UDBL
#else
#if defined(POLARSSL_HAVE_INT16)
typedef int16_t t_sint;
typedef uint16_t t_uint;
typedef uint32_t t_udbl;
#define POLARSSL_HAVE_UDBL
#else
#if ( defined(_MSC_VER) && defined(_M_AMD64) )
typedef int64_t t_sint;
typedef uint64_t t_uint;
#else
#if ( defined(__GNUC__) && ( \
defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__) || \
(defined(__sparc__) && defined(__arch64__)) || \
defined(__s390x__) ) )
typedef int64_t t_sint;
typedef uint64_t t_uint;
typedef unsigned int t_udbl __attribute__((mode(TI)));
#define POLARSSL_HAVE_UDBL
#else
typedef int32_t t_sint;
typedef uint32_t t_uint;
#if ( defined(_MSC_VER) && defined(_M_IX86) )
typedef uint64_t t_udbl;
#define POLARSSL_HAVE_UDBL
#else
#if defined( POLARSSL_HAVE_LONGLONG )
typedef unsigned long long t_udbl;
#define POLARSSL_HAVE_UDBL
#endif
#endif
#endif
#endif
#endif /* POLARSSL_HAVE_INT16 */
#endif /* POLARSSL_HAVE_INT8 */
/**
* \brief MPI structure
*/
typedef struct
{
int s; /*!< integer sign */
size_t n; /*!< total # of limbs */
t_uint *p; /*!< pointer to limbs */
}
mpi;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initialize one MPI
*
* \param X One MPI to initialize.
*/
void mpi_init( mpi *X );
/**
* \brief Unallocate one MPI
*
* \param X One MPI to unallocate.
*/
void mpi_free( mpi *X );
/**
* \brief Enlarge to the specified number of limbs
*
* \param X MPI to grow
* \param nblimbs The target number of limbs
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_grow( mpi *X, size_t nblimbs );
/**
* \brief Copy the contents of Y into X
*
* \param X Destination MPI
* \param Y Source MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_copy( mpi *X, const mpi *Y );
/**
* \brief Swap the contents of X and Y
*
* \param X First MPI value
* \param Y Second MPI value
*/
void mpi_swap( mpi *X, mpi *Y );
/**
* \brief Set value from integer
*
* \param X MPI to set
* \param z Value to use
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_lset( mpi *X, t_sint z );
/**
* \brief Get a specific bit from X
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
*
* \return Either a 0 or a 1
*/
int mpi_get_bit( const mpi *X, size_t pos );
/**
* \brief Set a bit of X to a specific value of 0 or 1
*
* \note Will grow X if necessary to set a bit to 1 in a not yet
* existing limb. Will not grow if bit should be set to 0
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
* \param val The value to set the bit to (0 or 1)
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
*/
int mpi_set_bit( mpi *X, size_t pos, unsigned char val );
/**
* \brief Return the number of zero-bits before the least significant
* '1' bit
*
* Note: Thus also the zero-based index of the least significant '1' bit
*
* \param X MPI to use
*/
size_t mpi_lsb( const mpi *X );
/**
* \brief Return the number of bits up to and including the most
* significant '1' bit'
*
* Note: Thus also the one-based index of the most significant '1' bit
*
* \param X MPI to use
*/
size_t mpi_msb( const mpi *X );
/**
* \brief Return the total size in bytes
*
* \param X MPI to use
*/
size_t mpi_size( const mpi *X );
/**
* \brief Import from an ASCII string
*
* \param X Destination MPI
* \param radix Input numeric base
* \param s Null-terminated string buffer
*
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
*/
int mpi_read_string( mpi *X, int radix, const char *s );
/**
* \brief Export into an ASCII string
*
* \param X Source MPI
* \param radix Output numeric base
* \param s String buffer
* \param slen String buffer size
*
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code.
* *slen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with *slen = 0 to obtain the
* minimum required buffer size in *slen.
*/
int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
#if defined(POLARSSL_FS_IO)
/**
* \brief Read X from an opened file
*
* \param X Destination MPI
* \param radix Input numeric base
* \param fin Input file handle
*
* \return 0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if
* the file read buffer is too small or a
* POLARSSL_ERR_MPI_XXX error code
*/
int mpi_read_file( mpi *X, int radix, FILE *fin );
/**
* \brief Write X into an opened file, or stdout if fout is NULL
*
* \param p Prefix, can be NULL
* \param X Source MPI
* \param radix Output numeric base
* \param fout Output file handle (can be NULL)
*
* \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
*
* \note Set fout == NULL to print X on the console.
*/
int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
#endif /* POLARSSL_FS_IO */
/**
* \brief Import X from unsigned binary data, big endian
*
* \param X Destination MPI
* \param buf Input buffer
* \param buflen Input buffer size
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
/**
* \brief Export X into unsigned binary data, big endian
*
* \param X Source MPI
* \param buf Output buffer
* \param buflen Output buffer size
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
*/
int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen );
/**
* \brief Left-shift: X <<= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_shift_l( mpi *X, size_t count );
/**
* \brief Right-shift: X >>= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_shift_r( mpi *X, size_t count );
/**
* \brief Compare unsigned values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if |X| is greater than |Y|,
* -1 if |X| is lesser than |Y| or
* 0 if |X| is equal to |Y|
*/
int mpi_cmp_abs( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if X is greater than Y,
* -1 if X is lesser than Y or
* 0 if X is equal to Y
*/
int mpi_cmp_mpi( const mpi *X, const mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param z The integer value to compare to
*
* \return 1 if X is greater than z,
* -1 if X is lesser than z or
* 0 if X is equal to z
*/
int mpi_cmp_int( const mpi *X, t_sint z );
/**
* \brief Unsigned addition: X = |A| + |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Unsigned substraction: X = |A| - |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
*/
int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed addition: X = A + B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed substraction: X = A - B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Signed addition: X = A + b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to add
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_add_int( mpi *X, const mpi *A, t_sint b );
/**
* \brief Signed substraction: X = A - b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to subtract
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
/**
* \brief Baseline multiplication: X = A * B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
/**
* \brief Baseline multiplication: X = A * b
* Note: b is an unsigned integer type, thus
* Negative values of b are ignored.
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to multiply with
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
/**
* \brief Division by mpi: A = Q * B + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
*
* \note Either Q or R can be NULL.
*/
int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
/**
* \brief Division by int: A = Q * b + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
*
* \note Either Q or R can be NULL.
*/
int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b );
/**
* \brief Modulo: R = A mod B
*
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
*/
int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
/**
* \brief Modulo: r = A mod b
*
* \param r Destination t_uint
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
* POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
*/
int mpi_mod_int( t_uint *r, const mpi *A, t_sint b );
/**
* \brief Sliding-window exponentiation: X = A^E mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param E Exponent MPI
* \param N Modular MPI
* \param _RR Speed-up MPI used for recalculations
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or if
* E is negative
*
* \note _RR is used to avoid re-computing R*R mod N across
* multiple calls, which speeds up things a bit. It can
* be set to NULL if the extra performance is unneeded.
*/
int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
/**
* \brief Fill an MPI X with size bytes of random
*
* \param X Destination MPI
* \param size Size in bytes
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_fill_random( mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Greatest common divisor: G = gcd(A, B)
*
* \param G Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
*/
int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
/**
* \brief Modular inverse: X = A^-1 mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param N Right-hand MPI
*
* \return 0 if successful,
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
*/
int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
/**
* \brief Miller-Rabin primality test
*
* \param X MPI to check
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
*/
int mpi_is_prime( mpi *X,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Prime number generation
*
* \param X Destination MPI
* \param nbits Required size of X in bits ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS )
* \param dh_flag If 1, then (X-1)/2 will be prime too
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
* POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
*/
int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mpi_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* bignum.h */
+632
View File
@@ -0,0 +1,632 @@
/*
* Blowfish implementation
*
* Copyright (C) 2012-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
* http://www.schneier.com/blowfish.html
* http://en.wikipedia.org/wiki/Blowfish_%28cipher%29
*
*/
#include "polarssl/config.h"
#if defined(POLARSSL_BLOWFISH_C)
#include "polarssl/blowfish.h"
#if !defined(POLARSSL_BLOWFISH_ALT)
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
static const uint32_t P[BLOWFISH_ROUNDS + 2] = {
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
0x9216D5D9L, 0x8979FB1BL
};
/* declarations of data at the end of this file */
static const uint32_t S[4][256];
static uint32_t F(blowfish_context *ctx, uint32_t x)
{
unsigned short a, b, c, d;
uint32_t y;
d = (unsigned short)(x & 0xFF);
x >>= 8;
c = (unsigned short)(x & 0xFF);
x >>= 8;
b = (unsigned short)(x & 0xFF);
x >>= 8;
a = (unsigned short)(x & 0xFF);
y = ctx->S[0][a] + ctx->S[1][b];
y = y ^ ctx->S[2][c];
y = y + ctx->S[3][d];
return y;
}
static void blowfish_enc(blowfish_context *ctx, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl, Xr, temp;
short i;
Xl = *xl;
Xr = *xr;
for (i = 0; i < BLOWFISH_ROUNDS; ++i)
{
Xl = Xl ^ ctx->P[i];
Xr = F(ctx, Xl) ^ Xr;
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[BLOWFISH_ROUNDS];
Xl = Xl ^ ctx->P[BLOWFISH_ROUNDS + 1];
*xl = Xl;
*xr = Xr;
}
static void blowfish_dec(blowfish_context *ctx, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl, Xr, temp;
short i;
Xl = *xl;
Xr = *xr;
for (i = BLOWFISH_ROUNDS + 1; i > 1; --i)
{
Xl = Xl ^ ctx->P[i];
Xr = F(ctx, Xl) ^ Xr;
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ ctx->P[1];
Xl = Xl ^ ctx->P[0];
*xl = Xl;
*xr = Xr;
}
/*
* Blowfish key schedule
*/
int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, unsigned int keysize )
{
unsigned int i, j, k;
uint32_t data, datal, datar;
if( keysize < BLOWFISH_MIN_KEY || keysize > BLOWFISH_MAX_KEY ||
( keysize % 8 ) )
{
return POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH;
}
keysize >>= 3;
for( i = 0; i < 4; i++ )
{
for( j = 0; j < 256; j++ )
ctx->S[i][j] = S[i][j];
}
j = 0;
for( i = 0; i < BLOWFISH_ROUNDS + 2; ++i )
{
data = 0x00000000;
for( k = 0; k < 4; ++k )
{
data = ( data << 8 ) | key[j++];
if( j >= keysize )
j = 0;
}
ctx->P[i] = P[i] ^ data;
}
datal = 0x00000000;
datar = 0x00000000;
for( i = 0; i < BLOWFISH_ROUNDS + 2; i += 2 )
{
blowfish_enc( ctx, &datal, &datar );
ctx->P[i] = datal;
ctx->P[i + 1] = datar;
}
for( i = 0; i < 4; i++ )
{
for( j = 0; j < 256; j += 2 )
{
blowfish_enc( ctx, &datal, &datar );
ctx->S[i][j] = datal;
ctx->S[i][j + 1] = datar;
}
}
return( 0 );
}
/*
* Blowfish-ECB block encryption/decryption
*/
int blowfish_crypt_ecb( blowfish_context *ctx,
int mode,
const unsigned char input[BLOWFISH_BLOCKSIZE],
unsigned char output[BLOWFISH_BLOCKSIZE] )
{
uint32_t X0, X1;
GET_UINT32_BE( X0, input, 0 );
GET_UINT32_BE( X1, input, 4 );
if( mode == BLOWFISH_DECRYPT )
{
blowfish_dec(ctx, &X0, &X1);
}
else /* BLOWFISH_ENCRYPT */
{
blowfish_enc(ctx, &X0, &X1);
}
PUT_UINT32_BE( X0, output, 0 );
PUT_UINT32_BE( X1, output, 4 );
return( 0 );
}
/*
* Blowfish-CBC buffer encryption/decryption
*/
int blowfish_crypt_cbc( blowfish_context *ctx,
int mode,
size_t length,
unsigned char iv[BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[BLOWFISH_BLOCKSIZE];
if( length % BLOWFISH_BLOCKSIZE )
return( POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
if( mode == BLOWFISH_DECRYPT )
{
while( length > 0 )
{
memcpy( temp, input, BLOWFISH_BLOCKSIZE );
blowfish_crypt_ecb( ctx, mode, input, output );
for( i = 0; i < BLOWFISH_BLOCKSIZE;i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, BLOWFISH_BLOCKSIZE );
input += BLOWFISH_BLOCKSIZE;
output += BLOWFISH_BLOCKSIZE;
length -= BLOWFISH_BLOCKSIZE;
}
}
else
{
while( length > 0 )
{
for( i = 0; i < BLOWFISH_BLOCKSIZE; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
blowfish_crypt_ecb( ctx, mode, output, output );
memcpy( iv, output, BLOWFISH_BLOCKSIZE );
input += BLOWFISH_BLOCKSIZE;
output += BLOWFISH_BLOCKSIZE;
length -= BLOWFISH_BLOCKSIZE;
}
}
return( 0 );
}
#if defined(POLARSSL_CIPHER_MODE_CFB)
/*
* Blowfish CFB buffer encryption/decryption
*/
int blowfish_crypt_cfb64( blowfish_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output )
{
int c;
size_t n = *iv_off;
if( mode == BLOWFISH_DECRYPT )
{
while( length-- )
{
if( n == 0 )
blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv );
c = *input++;
*output++ = (unsigned char)( c ^ iv[n] );
iv[n] = (unsigned char) c;
n = (n + 1) % BLOWFISH_BLOCKSIZE;
}
}
else
{
while( length-- )
{
if( n == 0 )
blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv );
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
n = (n + 1) % BLOWFISH_BLOCKSIZE;
}
}
*iv_off = n;
return( 0 );
}
#endif /*POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
/*
* Blowfish CTR buffer encryption/decryption
*/
int blowfish_crypt_ctr( blowfish_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[BLOWFISH_BLOCKSIZE],
unsigned char stream_block[BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output )
{
int c, i;
size_t n = *nc_off;
while( length-- )
{
if( n == 0 ) {
blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, nonce_counter, stream_block );
for( i = BLOWFISH_BLOCKSIZE; i > 0; i-- )
if( ++nonce_counter[i - 1] != 0 )
break;
}
c = *input++;
*output++ = (unsigned char)( c ^ stream_block[n] );
n = (n + 1) % BLOWFISH_BLOCKSIZE;
}
*nc_off = n;
return( 0 );
}
#endif /* POLARSSL_CIPHER_MODE_CTR */
static const uint32_t S[4][256] = {
{ 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL },
{ 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L },
{ 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L },
{ 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L }
};
#endif /* !POLARSSL_BLOWFISH_ALT */
#endif /* POLARSSL_BLOWFISH_C */
+171
View File
@@ -0,0 +1,171 @@
/**
* \file blowfish.h
*
* \brief Blowfish block cipher
*
* Copyright (C) 2012-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_BLOWFISH_H
#define POLARSSL_BLOWFISH_H
#include "polarssl/config.h"
#include <string.h>
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define BLOWFISH_ENCRYPT 1
#define BLOWFISH_DECRYPT 0
#define BLOWFISH_MAX_KEY 448
#define BLOWFISH_MIN_KEY 32
#define BLOWFISH_ROUNDS 16 /* when increasing this value, make sure to extend the initialisation vectors */
#define BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */
#define POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */
#define POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
#if !defined(POLARSSL_BLOWFISH_ALT)
// Regular implementation
//
/**
* \brief Blowfish context structure
*/
typedef struct
{
uint32_t P[BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */
uint32_t S[4][256]; /*!< key dependent S-boxes */
}
blowfish_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Blowfish key schedule
*
* \param ctx Blowfish context to be initialized
* \param key encryption key
* \param keysize must be between 32 and 448 bits
*
* \return 0 if successful, or POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH
*/
int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, unsigned int keysize );
/**
* \brief Blowfish-ECB block encryption/decryption
*
* \param ctx Blowfish context
* \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT
* \param input 8-byte input block
* \param output 8-byte output block
*
* \return 0 if successful
*/
int blowfish_crypt_ecb( blowfish_context *ctx,
int mode,
const unsigned char input[BLOWFISH_BLOCKSIZE],
unsigned char output[BLOWFISH_BLOCKSIZE] );
/**
* \brief Blowfish-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (8 bytes)
*
* \param ctx Blowfish context
* \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH
*/
int blowfish_crypt_cbc( blowfish_context *ctx,
int mode,
size_t length,
unsigned char iv[BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
/**
* \brief Blowfish CFB buffer encryption/decryption.
*
* both
* \param ctx Blowfish context
* \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int blowfish_crypt_cfb64( blowfish_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
/**
* \brief Blowfish-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 64-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int blowfish_crypt_ctr( blowfish_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[BLOWFISH_BLOCKSIZE],
unsigned char stream_block[BLOWFISH_BLOCKSIZE],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_BLOWFISH_ALT */
#include "polarssl/blowfish_alt.h"
#endif /* POLARSSL_BLOWFISH_ALT */
#endif /* blowfish.h */
+864
View File
@@ -0,0 +1,864 @@
/**
* \file bn_mul.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Multiply source vector [s] with b, add result
* to destination vector [d] and set carry c.
*
* Currently supports:
*
* . IA-32 (386+) . AMD64 / EM64T
* . IA-32 (SSE2) . Motorola 68000
* . PowerPC, 32-bit . MicroBlaze
* . PowerPC, 64-bit . TriCore
* . SPARC v8 . ARM v3+
* . Alpha . MIPS32
* . C, longlong . C, generic
*/
#ifndef POLARSSL_BN_MUL_H
#define POLARSSL_BN_MUL_H
#include "polarssl/bignum.h"
#if defined(POLARSSL_HAVE_ASM)
#if defined(__GNUC__)
#if defined(__i386__)
#define MULADDC_INIT \
__asm__( " \
movl %%ebx, %0; \
movl %5, %%esi; \
movl %6, %%edi; \
movl %7, %%ecx; \
movl %8, %%ebx; \
"
#define MULADDC_CORE \
" \
lodsl; \
mull %%ebx; \
addl %%ecx, %%eax; \
adcl $0, %%edx; \
addl (%%edi), %%eax; \
adcl $0, %%edx; \
movl %%edx, %%ecx; \
stosl; \
"
#if defined(POLARSSL_HAVE_SSE2)
#define MULADDC_HUIT \
" \
movd %%ecx, %%mm1; \
movd %%ebx, %%mm0; \
movd (%%edi), %%mm3; \
paddq %%mm3, %%mm1; \
movd (%%esi), %%mm2; \
pmuludq %%mm0, %%mm2; \
movd 4(%%esi), %%mm4; \
pmuludq %%mm0, %%mm4; \
movd 8(%%esi), %%mm6; \
pmuludq %%mm0, %%mm6; \
movd 12(%%esi), %%mm7; \
pmuludq %%mm0, %%mm7; \
paddq %%mm2, %%mm1; \
movd 4(%%edi), %%mm3; \
paddq %%mm4, %%mm3; \
movd 8(%%edi), %%mm5; \
paddq %%mm6, %%mm5; \
movd 12(%%edi), %%mm4; \
paddq %%mm4, %%mm7; \
movd %%mm1, (%%edi); \
movd 16(%%esi), %%mm2; \
pmuludq %%mm0, %%mm2; \
psrlq $32, %%mm1; \
movd 20(%%esi), %%mm4; \
pmuludq %%mm0, %%mm4; \
paddq %%mm3, %%mm1; \
movd 24(%%esi), %%mm6; \
pmuludq %%mm0, %%mm6; \
movd %%mm1, 4(%%edi); \
psrlq $32, %%mm1; \
movd 28(%%esi), %%mm3; \
pmuludq %%mm0, %%mm3; \
paddq %%mm5, %%mm1; \
movd 16(%%edi), %%mm5; \
paddq %%mm5, %%mm2; \
movd %%mm1, 8(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm7, %%mm1; \
movd 20(%%edi), %%mm5; \
paddq %%mm5, %%mm4; \
movd %%mm1, 12(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm2, %%mm1; \
movd 24(%%edi), %%mm5; \
paddq %%mm5, %%mm6; \
movd %%mm1, 16(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm4, %%mm1; \
movd 28(%%edi), %%mm5; \
paddq %%mm5, %%mm3; \
movd %%mm1, 20(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm6, %%mm1; \
movd %%mm1, 24(%%edi); \
psrlq $32, %%mm1; \
paddq %%mm3, %%mm1; \
movd %%mm1, 28(%%edi); \
addl $32, %%edi; \
addl $32, %%esi; \
psrlq $32, %%mm1; \
movd %%mm1, %%ecx; \
"
#define MULADDC_STOP \
" \
emms; \
movl %4, %%ebx; \
movl %%ecx, %1; \
movl %%edi, %2; \
movl %%esi, %3; \
" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#else
#define MULADDC_STOP \
" \
movl %4, %%ebx; \
movl %%ecx, %1; \
movl %%edi, %2; \
movl %%esi, %3; \
" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
#if defined(__amd64__) || defined (__x86_64__)
#define MULADDC_INIT \
__asm__( "movq %0, %%rsi " :: "m" (s)); \
__asm__( "movq %0, %%rdi " :: "m" (d)); \
__asm__( "movq %0, %%rcx " :: "m" (c)); \
__asm__( "movq %0, %%rbx " :: "m" (b)); \
__asm__( "xorq %r8, %r8 " );
#define MULADDC_CORE \
__asm__( "movq (%rsi),%rax " ); \
__asm__( "mulq %rbx " ); \
__asm__( "addq $8, %rsi " ); \
__asm__( "addq %rcx, %rax " ); \
__asm__( "movq %r8, %rcx " ); \
__asm__( "adcq $0, %rdx " ); \
__asm__( "nop " ); \
__asm__( "addq %rax, (%rdi) " ); \
__asm__( "adcq %rdx, %rcx " ); \
__asm__( "addq $8, %rdi " );
#define MULADDC_STOP \
__asm__( "movq %%rcx, %0 " : "=m" (c)); \
__asm__( "movq %%rdi, %0 " : "=m" (d)); \
__asm__( "movq %%rsi, %0 " : "=m" (s) :: \
"rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
#endif /* AMD64 */
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
__asm__( "movl %0, %%a2 " :: "m" (s)); \
__asm__( "movl %0, %%a3 " :: "m" (d)); \
__asm__( "movl %0, %%d3 " :: "m" (c)); \
__asm__( "movl %0, %%d2 " :: "m" (b)); \
__asm__( "moveq #0, %d0 " );
#define MULADDC_CORE \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d4:%d1 " ); \
__asm__( "addl %d3, %d1 " ); \
__asm__( "addxl %d0, %d4 " ); \
__asm__( "moveq #0, %d3 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "addxl %d4, %d3 " );
#define MULADDC_STOP \
__asm__( "movl %%d3, %0 " : "=m" (c)); \
__asm__( "movl %%a3, %0 " : "=m" (d)); \
__asm__( "movl %%a2, %0 " : "=m" (s) :: \
"d0", "d1", "d2", "d3", "d4", "a2", "a3" );
#define MULADDC_HUIT \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d4:%d1 " ); \
__asm__( "addxl %d3, %d1 " ); \
__asm__( "addxl %d0, %d4 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d3:%d1 " ); \
__asm__( "addxl %d4, %d1 " ); \
__asm__( "addxl %d0, %d3 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d4:%d1 " ); \
__asm__( "addxl %d3, %d1 " ); \
__asm__( "addxl %d0, %d4 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d3:%d1 " ); \
__asm__( "addxl %d4, %d1 " ); \
__asm__( "addxl %d0, %d3 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d4:%d1 " ); \
__asm__( "addxl %d3, %d1 " ); \
__asm__( "addxl %d0, %d4 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d3:%d1 " ); \
__asm__( "addxl %d4, %d1 " ); \
__asm__( "addxl %d0, %d3 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d4:%d1 " ); \
__asm__( "addxl %d3, %d1 " ); \
__asm__( "addxl %d0, %d4 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "movel %a2@+, %d1 " ); \
__asm__( "mulul %d2, %d3:%d1 " ); \
__asm__( "addxl %d4, %d1 " ); \
__asm__( "addxl %d0, %d3 " ); \
__asm__( "addl %d1, %a3@+ " ); \
__asm__( "addxl %d0, %d3 " );
#endif /* MC68000 */
#if defined(__powerpc__) || defined(__ppc__)
#if defined(__powerpc64__) || defined(__ppc64__)
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
__asm__( "ld r3, %0 " :: "m" (s)); \
__asm__( "ld r4, %0 " :: "m" (d)); \
__asm__( "ld r5, %0 " :: "m" (c)); \
__asm__( "ld r6, %0 " :: "m" (b)); \
__asm__( "addi r3, r3, -8 " ); \
__asm__( "addi r4, r4, -8 " ); \
__asm__( "addic r5, r5, 0 " );
#define MULADDC_CORE \
__asm__( "ldu r7, 8(r3) " ); \
__asm__( "mulld r8, r7, r6 " ); \
__asm__( "mulhdu r9, r7, r6 " ); \
__asm__( "adde r8, r8, r5 " ); \
__asm__( "ld r7, 8(r4) " ); \
__asm__( "addze r5, r9 " ); \
__asm__( "addc r8, r8, r7 " ); \
__asm__( "stdu r8, 8(r4) " );
#define MULADDC_STOP \
__asm__( "addze r5, r5 " ); \
__asm__( "addi r4, r4, 8 " ); \
__asm__( "addi r3, r3, 8 " ); \
__asm__( "std r5, %0 " : "=m" (c)); \
__asm__( "std r4, %0 " : "=m" (d)); \
__asm__( "std r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#else
#define MULADDC_INIT \
__asm__( "ld %%r3, %0 " :: "m" (s)); \
__asm__( "ld %%r4, %0 " :: "m" (d)); \
__asm__( "ld %%r5, %0 " :: "m" (c)); \
__asm__( "ld %%r6, %0 " :: "m" (b)); \
__asm__( "addi %r3, %r3, -8 " ); \
__asm__( "addi %r4, %r4, -8 " ); \
__asm__( "addic %r5, %r5, 0 " );
#define MULADDC_CORE \
__asm__( "ldu %r7, 8(%r3) " ); \
__asm__( "mulld %r8, %r7, %r6 " ); \
__asm__( "mulhdu %r9, %r7, %r6 " ); \
__asm__( "adde %r8, %r8, %r5 " ); \
__asm__( "ld %r7, 8(%r4) " ); \
__asm__( "addze %r5, %r9 " ); \
__asm__( "addc %r8, %r8, %r7 " ); \
__asm__( "stdu %r8, 8(%r4) " );
#define MULADDC_STOP \
__asm__( "addze %r5, %r5 " ); \
__asm__( "addi %r4, %r4, 8 " ); \
__asm__( "addi %r3, %r3, 8 " ); \
__asm__( "std %%r5, %0 " : "=m" (c)); \
__asm__( "std %%r4, %0 " : "=m" (d)); \
__asm__( "std %%r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#endif
#else /* PPC32 */
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
__asm__( "lwz r3, %0 " :: "m" (s)); \
__asm__( "lwz r4, %0 " :: "m" (d)); \
__asm__( "lwz r5, %0 " :: "m" (c)); \
__asm__( "lwz r6, %0 " :: "m" (b)); \
__asm__( "addi r3, r3, -4 " ); \
__asm__( "addi r4, r4, -4 " ); \
__asm__( "addic r5, r5, 0 " );
#define MULADDC_CORE \
__asm__( "lwzu r7, 4(r3) " ); \
__asm__( "mullw r8, r7, r6 " ); \
__asm__( "mulhwu r9, r7, r6 " ); \
__asm__( "adde r8, r8, r5 " ); \
__asm__( "lwz r7, 4(r4) " ); \
__asm__( "addze r5, r9 " ); \
__asm__( "addc r8, r8, r7 " ); \
__asm__( "stwu r8, 4(r4) " );
#define MULADDC_STOP \
__asm__( "addze r5, r5 " ); \
__asm__( "addi r4, r4, 4 " ); \
__asm__( "addi r3, r3, 4 " ); \
__asm__( "stw r5, %0 " : "=m" (c)); \
__asm__( "stw r4, %0 " : "=m" (d)); \
__asm__( "stw r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#else
#define MULADDC_INIT \
__asm__( "lwz %%r3, %0 " :: "m" (s)); \
__asm__( "lwz %%r4, %0 " :: "m" (d)); \
__asm__( "lwz %%r5, %0 " :: "m" (c)); \
__asm__( "lwz %%r6, %0 " :: "m" (b)); \
__asm__( "addi %r3, %r3, -4 " ); \
__asm__( "addi %r4, %r4, -4 " ); \
__asm__( "addic %r5, %r5, 0 " );
#define MULADDC_CORE \
__asm__( "lwzu %r7, 4(%r3) " ); \
__asm__( "mullw %r8, %r7, %r6 " ); \
__asm__( "mulhwu %r9, %r7, %r6 " ); \
__asm__( "adde %r8, %r8, %r5 " ); \
__asm__( "lwz %r7, 4(%r4) " ); \
__asm__( "addze %r5, %r9 " ); \
__asm__( "addc %r8, %r8, %r7 " ); \
__asm__( "stwu %r8, 4(%r4) " );
#define MULADDC_STOP \
__asm__( "addze %r5, %r5 " ); \
__asm__( "addi %r4, %r4, 4 " ); \
__asm__( "addi %r3, %r3, 4 " ); \
__asm__( "stw %%r5, %0 " : "=m" (c)); \
__asm__( "stw %%r4, %0 " : "=m" (d)); \
__asm__( "stw %%r3, %0 " : "=m" (s) :: \
"r3", "r4", "r5", "r6", "r7", "r8", "r9" );
#endif
#endif /* PPC32 */
#endif /* PPC64 */
#if defined(__sparc__) && defined(__sparc64__)
#define MULADDC_INIT \
__asm__( \
" \
ldx %3, %%o0; \
ldx %4, %%o1; \
ld %5, %%o2; \
ld %6, %%o3; \
"
#define MULADDC_CORE \
" \
ld [%%o0], %%o4; \
inc 4, %%o0; \
ld [%%o1], %%o5; \
umul %%o3, %%o4, %%o4; \
addcc %%o4, %%o2, %%o4; \
rd %%y, %%g1; \
addx %%g1, 0, %%g1; \
addcc %%o4, %%o5, %%o4; \
st %%o4, [%%o1]; \
addx %%g1, 0, %%o2; \
inc 4, %%o1; \
"
#define MULADDC_STOP \
" \
st %%o2, %0; \
stx %%o1, %1; \
stx %%o0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#endif /* SPARCv9 */
#if defined(__sparc__) && !defined(__sparc64__)
#define MULADDC_INIT \
__asm__( \
" \
ld %3, %%o0; \
ld %4, %%o1; \
ld %5, %%o2; \
ld %6, %%o3; \
"
#define MULADDC_CORE \
" \
ld [%%o0], %%o4; \
inc 4, %%o0; \
ld [%%o1], %%o5; \
umul %%o3, %%o4, %%o4; \
addcc %%o4, %%o2, %%o4; \
rd %%y, %%g1; \
addx %%g1, 0, %%g1; \
addcc %%o4, %%o5, %%o4; \
st %%o4, [%%o1]; \
addx %%g1, 0, %%o2; \
inc 4, %%o1; \
"
#define MULADDC_STOP \
" \
st %%o2, %0; \
st %%o1, %1; \
st %%o0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#endif /* SPARCv8 */
#if defined(__microblaze__) || defined(microblaze)
#define MULADDC_INIT \
__asm__( "lwi r3, %0 " :: "m" (s)); \
__asm__( "lwi r4, %0 " :: "m" (d)); \
__asm__( "lwi r5, %0 " :: "m" (c)); \
__asm__( "lwi r6, %0 " :: "m" (b)); \
__asm__( "andi r7, r6, 0xffff" ); \
__asm__( "bsrli r6, r6, 16 " );
#define MULADDC_CORE \
__asm__( "lhui r8, r3, 0 " ); \
__asm__( "addi r3, r3, 2 " ); \
__asm__( "lhui r9, r3, 0 " ); \
__asm__( "addi r3, r3, 2 " ); \
__asm__( "mul r10, r9, r6 " ); \
__asm__( "mul r11, r8, r7 " ); \
__asm__( "mul r12, r9, r7 " ); \
__asm__( "mul r13, r8, r6 " ); \
__asm__( "bsrli r8, r10, 16 " ); \
__asm__( "bsrli r9, r11, 16 " ); \
__asm__( "add r13, r13, r8 " ); \
__asm__( "add r13, r13, r9 " ); \
__asm__( "bslli r10, r10, 16 " ); \
__asm__( "bslli r11, r11, 16 " ); \
__asm__( "add r12, r12, r10 " ); \
__asm__( "addc r13, r13, r0 " ); \
__asm__( "add r12, r12, r11 " ); \
__asm__( "addc r13, r13, r0 " ); \
__asm__( "lwi r10, r4, 0 " ); \
__asm__( "add r12, r12, r10 " ); \
__asm__( "addc r13, r13, r0 " ); \
__asm__( "add r12, r12, r5 " ); \
__asm__( "addc r5, r13, r0 " ); \
__asm__( "swi r12, r4, 0 " ); \
__asm__( "addi r4, r4, 4 " );
#define MULADDC_STOP \
__asm__( "swi r5, %0 " : "=m" (c)); \
__asm__( "swi r4, %0 " : "=m" (d)); \
__asm__( "swi r3, %0 " : "=m" (s) :: \
"r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
"r9", "r10", "r11", "r12", "r13" );
#endif /* MicroBlaze */
#if defined(__tricore__)
#define MULADDC_INIT \
__asm__( "ld.a %%a2, %0 " :: "m" (s)); \
__asm__( "ld.a %%a3, %0 " :: "m" (d)); \
__asm__( "ld.w %%d4, %0 " :: "m" (c)); \
__asm__( "ld.w %%d1, %0 " :: "m" (b)); \
__asm__( "xor %d5, %d5 " );
#define MULADDC_CORE \
__asm__( "ld.w %d0, [%a2+] " ); \
__asm__( "madd.u %e2, %e4, %d0, %d1 " ); \
__asm__( "ld.w %d0, [%a3] " ); \
__asm__( "addx %d2, %d2, %d0 " ); \
__asm__( "addc %d3, %d3, 0 " ); \
__asm__( "mov %d4, %d3 " ); \
__asm__( "st.w [%a3+], %d2 " );
#define MULADDC_STOP \
__asm__( "st.w %0, %%d4 " : "=m" (c)); \
__asm__( "st.a %0, %%a3 " : "=m" (d)); \
__asm__( "st.a %0, %%a2 " : "=m" (s) :: \
"d0", "d1", "e2", "d4", "a2", "a3" );
#endif /* TriCore */
#if defined(__arm__)
#if defined(__thumb__) && !defined(__thumb2__)
#define MULADDC_INIT \
__asm__( \
" \
ldr r0, %3; \
ldr r1, %4; \
ldr r2, %5; \
ldr r3, %6; \
lsr r7, r3, #16; \
mov r9, r7; \
lsl r7, r3, #16; \
lsr r7, r7, #16; \
mov r8, r7; \
"
#define MULADDC_CORE \
" \
ldmia r0!, {r6}; \
lsr r7, r6, #16; \
lsl r6, r6, #16; \
lsr r6, r6, #16; \
mov r4, r8; \
mul r4, r6; \
mov r3, r9; \
mul r6, r3; \
mov r5, r9; \
mul r5, r7; \
mov r3, r8; \
mul r7, r3; \
lsr r3, r6, #16; \
add r5, r5, r3; \
lsr r3, r7, #16; \
add r5, r5, r3; \
add r4, r4, r2; \
mov r2, #0; \
adc r5, r2; \
lsl r3, r6, #16; \
add r4, r4, r3; \
adc r5, r2; \
lsl r3, r7, #16; \
add r4, r4, r3; \
adc r5, r2; \
ldr r3, [r1]; \
add r4, r4, r3; \
adc r2, r5; \
stmia r1!, {r4}; \
"
#define MULADDC_STOP \
" \
str r2, %0; \
str r1, %1; \
str r0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "r8", "r9", "cc" \
);
#else
#define MULADDC_INIT \
__asm__( \
" \
ldr r0, %3; \
ldr r1, %4; \
ldr r2, %5; \
ldr r3, %6; \
"
#define MULADDC_CORE \
" \
ldr r4, [r0], #4; \
mov r5, #0; \
ldr r6, [r1]; \
umlal r2, r5, r3, r4; \
adds r7, r6, r2; \
adc r2, r5, #0; \
str r7, [r1], #4; \
"
#define MULADDC_STOP \
" \
str r2, %0; \
str r1, %1; \
str r0, %2; \
" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "cc" \
);
#endif /* Thumb */
#endif /* ARMv3 */
#if defined(__alpha__)
#define MULADDC_INIT \
__asm__( "ldq $1, %0 " :: "m" (s)); \
__asm__( "ldq $2, %0 " :: "m" (d)); \
__asm__( "ldq $3, %0 " :: "m" (c)); \
__asm__( "ldq $4, %0 " :: "m" (b));
#define MULADDC_CORE \
__asm__( "ldq $6, 0($1) " ); \
__asm__( "addq $1, 8, $1 " ); \
__asm__( "mulq $6, $4, $7 " ); \
__asm__( "umulh $6, $4, $6 " ); \
__asm__( "addq $7, $3, $7 " ); \
__asm__( "cmpult $7, $3, $3 " ); \
__asm__( "ldq $5, 0($2) " ); \
__asm__( "addq $7, $5, $7 " ); \
__asm__( "cmpult $7, $5, $5 " ); \
__asm__( "stq $7, 0($2) " ); \
__asm__( "addq $2, 8, $2 " ); \
__asm__( "addq $6, $3, $3 " ); \
__asm__( "addq $5, $3, $3 " );
#define MULADDC_STOP \
__asm__( "stq $3, %0 " : "=m" (c)); \
__asm__( "stq $2, %0 " : "=m" (d)); \
__asm__( "stq $1, %0 " : "=m" (s) :: \
"$1", "$2", "$3", "$4", "$5", "$6", "$7" );
#endif /* Alpha */
#if defined(__mips__)
#define MULADDC_INIT \
__asm__( "lw $10, %0 " :: "m" (s)); \
__asm__( "lw $11, %0 " :: "m" (d)); \
__asm__( "lw $12, %0 " :: "m" (c)); \
__asm__( "lw $13, %0 " :: "m" (b));
#define MULADDC_CORE \
__asm__( "lw $14, 0($10) " ); \
__asm__( "multu $13, $14 " ); \
__asm__( "addi $10, $10, 4 " ); \
__asm__( "mflo $14 " ); \
__asm__( "mfhi $9 " ); \
__asm__( "addu $14, $12, $14 " ); \
__asm__( "lw $15, 0($11) " ); \
__asm__( "sltu $12, $14, $12 " ); \
__asm__( "addu $15, $14, $15 " ); \
__asm__( "sltu $14, $15, $14 " ); \
__asm__( "addu $12, $12, $9 " ); \
__asm__( "sw $15, 0($11) " ); \
__asm__( "addu $12, $12, $14 " ); \
__asm__( "addi $11, $11, 4 " );
#define MULADDC_STOP \
__asm__( "sw $12, %0 " : "=m" (c)); \
__asm__( "sw $11, %0 " : "=m" (d)); \
__asm__( "sw $10, %0 " : "=m" (s) :: \
"$9", "$10", "$11", "$12", "$13", "$14", "$15" );
#endif /* MIPS */
#endif /* GNUC */
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
#define MULADDC_INIT \
____asm__ mov esi, s \
____asm__ mov edi, d \
____asm__ mov ecx, c \
____asm__ mov ebx, b
#define MULADDC_CORE \
____asm__ lodsd \
____asm__ mul ebx \
____asm__ add eax, ecx \
____asm__ adc edx, 0 \
____asm__ add eax, [edi] \
____asm__ adc edx, 0 \
____asm__ mov ecx, edx \
____asm__ stosd
#if defined(POLARSSL_HAVE_SSE2)
#define EMIT ____asm__ _emit
#define MULADDC_HUIT \
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x7E EMIT 0xC9
#define MULADDC_STOP \
EMIT 0x0F EMIT 0x77 \
____asm__ mov c, ecx \
____asm__ mov d, edi \
____asm__ mov s, esi \
#else
#define MULADDC_STOP \
____asm__ mov c, ecx \
____asm__ mov d, edi \
____asm__ mov s, esi \
#endif /* SSE2 */
#endif /* MSVC */
#endif /* POLARSSL_HAVE_ASM */
#if !defined(MULADDC_CORE)
#if defined(POLARSSL_HAVE_UDBL)
#define MULADDC_INIT \
{ \
t_udbl r; \
t_uint r0, r1;
#define MULADDC_CORE \
r = *(s++) * (t_udbl) b; \
r0 = r; \
r1 = r >> biL; \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#else
#define MULADDC_INIT \
{ \
t_uint s0, s1, b0, b1; \
t_uint r0, r1, rx, ry; \
b0 = ( b << biH ) >> biH; \
b1 = ( b >> biH );
#define MULADDC_CORE \
s0 = ( *s << biH ) >> biH; \
s1 = ( *s >> biH ); s++; \
rx = s0 * b1; r0 = s0 * b0; \
ry = s1 * b0; r1 = s1 * b1; \
r1 += ( rx >> biH ); \
r1 += ( ry >> biH ); \
rx <<= biH; ry <<= biH; \
r0 += rx; r1 += (r0 < rx); \
r0 += ry; r1 += (r0 < ry); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#endif /* C (generic) */
#endif /* C (longlong) */
#endif /* bn_mul.h */
+1035
View File
File diff suppressed because it is too large Load Diff
+200
View File
@@ -0,0 +1,200 @@
/**
* \file camellia.h
*
* \brief Camellia block cipher
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_CAMELLIA_H
#define POLARSSL_CAMELLIA_H
#include "polarssl/config.h"
#include <string.h>
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define CAMELLIA_ENCRYPT 1
#define CAMELLIA_DECRYPT 0
#define POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */
#define POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
#if !defined(POLARSSL_CAMELLIA_ALT)
// Regular implementation
//
/**
* \brief CAMELLIA context structure
*/
typedef struct
{
int nr; /*!< number of rounds */
uint32_t rk[68]; /*!< CAMELLIA round keys */
}
camellia_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief CAMELLIA key schedule (encryption)
*
* \param ctx CAMELLIA context to be initialized
* \param key encryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, unsigned int keysize );
/**
* \brief CAMELLIA key schedule (decryption)
*
* \param ctx CAMELLIA context to be initialized
* \param key decryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH
*/
int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, unsigned int keysize );
/**
* \brief CAMELLIA-ECB block encryption/decryption
*
* \param ctx CAMELLIA context
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int camellia_crypt_ecb( camellia_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief CAMELLIA-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \param ctx CAMELLIA context
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int camellia_crypt_cbc( camellia_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief CAMELLIA-CFB128 buffer encryption/decryption
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* camellia_setkey_enc() for both CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT.
*
* \param ctx CAMELLIA context
* \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH
*/
int camellia_crypt_cfb128( camellia_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief CAMELLIA-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* camellia_setkey_enc() for both CAMELLIA_ENCRYPT and CAMELLIA_DECRYPT.
*
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int camellia_crypt_ctr( camellia_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_CAMELLIA_ALT */
#include "polarssl/camellia_alt.h"
#endif /* POLARSSL_CAMELLIA_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int camellia_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* camellia.h */
+196
View File
@@ -0,0 +1,196 @@
/*
* X.509 test certificates
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_CERTS_C)
const char test_ca_crt[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n"
"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n"
"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n"
"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n"
"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n"
"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n"
"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n"
"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n"
"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n"
"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n"
"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n"
"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n"
"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n"
"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n"
"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n"
"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n"
"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n"
"-----END CERTIFICATE-----\r\n";
const char test_ca_key[] =
"-----BEGIN RSA PRIVATE KEY-----\r\n"
"Proc-Type: 4,ENCRYPTED\r\n"
"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n"
"\r\n"
"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n"
"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n"
"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n"
"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n"
"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n"
"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n"
"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n"
"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n"
"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n"
"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n"
"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n"
"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n"
"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n"
"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n"
"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n"
"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n"
"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n"
"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n"
"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n"
"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n"
"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n"
"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n"
"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n"
"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n"
"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n"
"-----END RSA PRIVATE KEY-----\r\n";
const char test_ca_pwd[] = "PolarSSLTest";
const char test_srv_crt[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDPzCCAiegAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN\r\n"
"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/\r\n"
"uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD\r\n"
"d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf\r\n"
"CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr\r\n"
"lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w\r\n"
"bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB\r\n"
"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAf\r\n"
"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n"
"AQEAvc+WwZUemsJu2IiI2Cp6liA+UAvIx98dQe3kZs2zAoF9VwQbXcYzWQ/BILkj\r\n"
"NImKbPL9x0g2jIDn4ZvGYFywMwIO/d++YbwYiQw42/v7RiMy94zBPnzeHi86dy/0\r\n"
"jpOOJUx3IXRsGLdyjb/1T11klcFqGnARiK+8VYolMPP6afKvLXX7K4kiUpsFQhUp\r\n"
"E5VeM5pV1Mci2ETOJau2cO40FJvI/C9W/wR+GAArMaw2fxG77E3laaa0LAOlexM6\r\n"
"A4KOb5f5cGTM5Ih6tEF5FVq3/9vzNIYMa1FqzacBLZF8zSHYLEimXBdzjBoN4qDU\r\n"
"/WzRyYRBRjAI49mzHX6raleqnw==\r\n"
"-----END CERTIFICATE-----\r\n";
const char test_srv_key[] =
"-----BEGIN RSA PRIVATE KEY-----\r\n"
"MIIEogIBAAKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/uOhFkNvuiBZS0/FDUEeW\r\n"
"Ellkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFDd185fAkER4KwVzlw7aPs\r\n"
"FRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVfCrFTxjB+FTms+Vruf5Ke\r\n"
"pgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTrlZvc/kFeF6babFtpzAK6\r\n"
"FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9wbp7OvViJ4lNZnm5akmXi\r\n"
"iD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQABAoIBABaJ9eiRQq4Ypv+w\r\n"
"UTcVpLC0oTueWzcpor1i1zjG4Vzqe/Ok2FqyGToGKMlFK7Hwwa+LEyeJ3xyV5yd4\r\n"
"v1Mw9bDZFdJC1eCBjoUAHtX6k9HOE0Vd6woVQ4Vi6OPI1g7B5Mnr/58rNrnN6TMs\r\n"
"x58NF6euecwTU811QJrZtLbX7j2Cr28yB2Vs8qyYlHwVw5jbDOv43D7vU5gmlIDN\r\n"
"0JQRuWAnOuPzZNoJr4SfJKqHNGxYYY6pHZ1s0dOTLIDb/B8KQWapA2kRmZyid2EH\r\n"
"nwzgLbAsHJCf+bQnhXjXuxtUsrcIL8noZLazlOMxwNEammglVWW23Ud/QRnFgJg5\r\n"
"UgcAcRECgYEA19uYetht5qmwdJ+12oC6zeO+vXLcyD9gon23T5J6w2YThld7/OW0\r\n"
"oArQJGgkAdaq0pcTyOIjtTQVMFygdVmCEJmxh/3RutPcTeydqW9fphKDMej32J8e\r\n"
"GniGmNGiclbcfNOS8E5TGp445yZb9P1+7AHng16bGg3Ykj5EA4G+HCcCgYEAyHAl\r\n"
"//ekk8YjQElm+8izLtFkymIK0aCtEe9C/RIRhFYBeFaotC5dStNhBOncn4ovMAPD\r\n"
"lX/92yDi9OP8PPLN3a4B9XpW3k/SS5GrbT5cwOivBHNllZSmu/2qz5WPGcjVCOrB\r\n"
"LYl3YWr2h3EGKICT03kEoTkiDBvCeOpW7cCGl2cCgYBD5whoXHz1+ptPlI4YVjZt\r\n"
"Xh86aU+ajpVPiEyJ84I6xXmO4SZXv8q6LaycR0ZMbcL+zBelMb4Z2nBv7jNrtuR7\r\n"
"ZF28cdPv+YVr3esaybZE/73VjXup4SQPH6r3l7qKTVi+y6+FeJ4b2Xn8/MwgnT23\r\n"
"8EFrye7wmzpthrjOgZnUMQKBgE9Lhsz/5J0Nis6Y+2Pqn3CLKEukg9Ewtqdct2y0\r\n"
"5Dcta0F3TyCRIxlCDKTL/BslqMtfAdY4H268UO0+8IAQMn9boqzBrHIgs/pvc5kx\r\n"
"TbKHmw2wtWR6vYersBKVgVpbCGSRssDYHGFu1n74qM4HJ/RGcR1zI9QUe1gopSFD\r\n"
"xDtLAoGAVAdWvrqDwgoL2hHW3scGpxdE/ygJDOwHnf+1B9goKAOP5lf2FJaiAxf3\r\n"
"ectoPOgZbCmm/iiDmigu703ld3O+VoCLDD4qx3R+KyALL78gtVJYzSRiKhzgCZ3g\r\n"
"mKsIVRBq4IfwiwyMNG2BYZQAwbSDjjPtn/kPBduPzPj7eriByhI=\r\n"
"-----END RSA PRIVATE KEY-----\r\n";
const char test_cli_crt[] =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
"MTEwMjEyMTQ0NDA3WhcNMjEwMjEyMTQ0NDA3WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n"
"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n"
"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n"
"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n"
"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n"
"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n"
"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n"
"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n"
"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n"
"AQEAAn86isAM8X+mVwJqeItt6E9slhEQbAofyk+diH1Lh8Y9iLlWQSKbw/UXYjx5\r\n"
"LLPZcniovxIcARC/BjyZR9g3UwTHNGNm+rwrqa15viuNOFBchykX/Orsk02EH7NR\r\n"
"Alw5WLPorYjED6cdVQgBl9ot93HdJogRiXCxErM7NC8/eP511mjq+uLDjLKH8ZPQ\r\n"
"8I4ekHJnroLsDkIwXKGIsvIBHQy2ac/NwHLCQOK6mfum1pRx52V4Utu5dLLjD5bM\r\n"
"xOBC7KU4xZKuMXXZM6/93Yb51K/J4ahf1TxJlTWXtnzDr9saEYdNy2SKY/6ZiDNH\r\n"
"D+stpAKiQLAWaAusIWKYEyw9MQ==\r\n"
"-----END CERTIFICATE-----\r\n";
const char test_cli_key[] =
"-----BEGIN RSA PRIVATE KEY-----\r\n"
"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n"
"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n"
"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n"
"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n"
"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n"
"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n"
"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n"
"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n"
"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n"
"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n"
"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n"
"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n"
"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n"
"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n"
"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n"
"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n"
"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n"
"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n"
"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n"
"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n"
"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n"
"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n"
"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n"
"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n"
"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n"
"-----END RSA PRIVATE KEY-----\r\n";
const char test_dhm_params[] =
"-----BEGIN DH PARAMETERS-----\r\n"
"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
"-----END DH PARAMETERS-----\r\n";
#endif
+47
View File
@@ -0,0 +1,47 @@
/**
* \file certs.h
*
* \brief Sample certificates and DHM parameters for testing
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_CERTS_H
#define POLARSSL_CERTS_H
#ifdef __cplusplus
extern "C" {
#endif
extern const char test_ca_crt[];
extern const char test_ca_key[];
extern const char test_ca_pwd[];
extern const char test_srv_crt[];
extern const char test_srv_key[];
extern const char test_cli_crt[];
extern const char test_cli_key[];
extern const char test_dhm_params[];
#ifdef __cplusplus
}
#endif
#endif /* certs.h */
+601
View File
@@ -0,0 +1,601 @@
/**
* \file cipher.c
*
* \brief Generic cipher wrapper for PolarSSL
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_CIPHER_C)
#include "polarssl/cipher.h"
#include "polarssl/cipher_wrap.h"
#include <stdlib.h>
#if defined _MSC_VER && !defined strcasecmp
#define strcasecmp _stricmp
#endif
static const int supported_ciphers[] = {
#if defined(POLARSSL_AES_C)
POLARSSL_CIPHER_AES_128_CBC,
POLARSSL_CIPHER_AES_192_CBC,
POLARSSL_CIPHER_AES_256_CBC,
#if defined(POLARSSL_CIPHER_MODE_CFB)
POLARSSL_CIPHER_AES_128_CFB128,
POLARSSL_CIPHER_AES_192_CFB128,
POLARSSL_CIPHER_AES_256_CFB128,
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
POLARSSL_CIPHER_AES_128_CTR,
POLARSSL_CIPHER_AES_192_CTR,
POLARSSL_CIPHER_AES_256_CTR,
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif /* defined(POLARSSL_AES_C) */
#if defined(POLARSSL_CAMELLIA_C)
POLARSSL_CIPHER_CAMELLIA_128_CBC,
POLARSSL_CIPHER_CAMELLIA_192_CBC,
POLARSSL_CIPHER_CAMELLIA_256_CBC,
#if defined(POLARSSL_CIPHER_MODE_CFB)
POLARSSL_CIPHER_CAMELLIA_128_CFB128,
POLARSSL_CIPHER_CAMELLIA_192_CFB128,
POLARSSL_CIPHER_CAMELLIA_256_CFB128,
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
POLARSSL_CIPHER_CAMELLIA_128_CTR,
POLARSSL_CIPHER_CAMELLIA_192_CTR,
POLARSSL_CIPHER_CAMELLIA_256_CTR,
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif /* defined(POLARSSL_CAMELLIA_C) */
#if defined(POLARSSL_DES_C)
POLARSSL_CIPHER_DES_CBC,
POLARSSL_CIPHER_DES_EDE_CBC,
POLARSSL_CIPHER_DES_EDE3_CBC,
#endif /* defined(POLARSSL_DES_C) */
#if defined(POLARSSL_BLOWFISH_C)
POLARSSL_CIPHER_BLOWFISH_CBC,
#if defined(POLARSSL_CIPHER_MODE_CFB)
POLARSSL_CIPHER_BLOWFISH_CFB64,
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
POLARSSL_CIPHER_BLOWFISH_CTR,
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif /* defined(POLARSSL_BLOWFISH_C) */
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
POLARSSL_CIPHER_NULL,
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
0
};
const int *cipher_list( void )
{
return supported_ciphers;
}
const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type )
{
/* Find static cipher information */
switch ( cipher_type )
{
#if defined(POLARSSL_AES_C)
case POLARSSL_CIPHER_AES_128_CBC:
return &aes_128_cbc_info;
case POLARSSL_CIPHER_AES_192_CBC:
return &aes_192_cbc_info;
case POLARSSL_CIPHER_AES_256_CBC:
return &aes_256_cbc_info;
#if defined(POLARSSL_CIPHER_MODE_CFB)
case POLARSSL_CIPHER_AES_128_CFB128:
return &aes_128_cfb128_info;
case POLARSSL_CIPHER_AES_192_CFB128:
return &aes_192_cfb128_info;
case POLARSSL_CIPHER_AES_256_CFB128:
return &aes_256_cfb128_info;
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
case POLARSSL_CIPHER_AES_128_CTR:
return &aes_128_ctr_info;
case POLARSSL_CIPHER_AES_192_CTR:
return &aes_192_ctr_info;
case POLARSSL_CIPHER_AES_256_CTR:
return &aes_256_ctr_info;
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif
#if defined(POLARSSL_CAMELLIA_C)
case POLARSSL_CIPHER_CAMELLIA_128_CBC:
return &camellia_128_cbc_info;
case POLARSSL_CIPHER_CAMELLIA_192_CBC:
return &camellia_192_cbc_info;
case POLARSSL_CIPHER_CAMELLIA_256_CBC:
return &camellia_256_cbc_info;
#if defined(POLARSSL_CIPHER_MODE_CFB)
case POLARSSL_CIPHER_CAMELLIA_128_CFB128:
return &camellia_128_cfb128_info;
case POLARSSL_CIPHER_CAMELLIA_192_CFB128:
return &camellia_192_cfb128_info;
case POLARSSL_CIPHER_CAMELLIA_256_CFB128:
return &camellia_256_cfb128_info;
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
case POLARSSL_CIPHER_CAMELLIA_128_CTR:
return &camellia_128_ctr_info;
case POLARSSL_CIPHER_CAMELLIA_192_CTR:
return &camellia_192_ctr_info;
case POLARSSL_CIPHER_CAMELLIA_256_CTR:
return &camellia_256_ctr_info;
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif
#if defined(POLARSSL_DES_C)
case POLARSSL_CIPHER_DES_CBC:
return &des_cbc_info;
case POLARSSL_CIPHER_DES_EDE_CBC:
return &des_ede_cbc_info;
case POLARSSL_CIPHER_DES_EDE3_CBC:
return &des_ede3_cbc_info;
#endif
#if defined(POLARSSL_BLOWFISH_C)
case POLARSSL_CIPHER_BLOWFISH_CBC:
return &blowfish_cbc_info;
#if defined(POLARSSL_CIPHER_MODE_CFB)
case POLARSSL_CIPHER_BLOWFISH_CFB64:
return &blowfish_cfb64_info;
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
case POLARSSL_CIPHER_BLOWFISH_CTR:
return &blowfish_ctr_info;
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
case POLARSSL_CIPHER_NULL:
return &null_cipher_info;
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
default:
return NULL;
}
}
const cipher_info_t *cipher_info_from_string( const char *cipher_name )
{
if( NULL == cipher_name )
return NULL;
/* Get the appropriate cipher information */
#if defined(POLARSSL_CAMELLIA_C)
if( !strcasecmp( "CAMELLIA-128-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CBC );
if( !strcasecmp( "CAMELLIA-192-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CBC );
if( !strcasecmp( "CAMELLIA-256-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CBC );
#if defined(POLARSSL_CIPHER_MODE_CFB)
if( !strcasecmp( "CAMELLIA-128-CFB128", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CFB128 );
if( !strcasecmp( "CAMELLIA-192-CFB128", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CFB128 );
if( !strcasecmp( "CAMELLIA-256-CFB128", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CFB128 );
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
if( !strcasecmp( "CAMELLIA-128-CTR", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_128_CTR );
if( !strcasecmp( "CAMELLIA-192-CTR", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_192_CTR );
if( !strcasecmp( "CAMELLIA-256-CTR", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_CAMELLIA_256_CTR );
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif
#if defined(POLARSSL_AES_C)
if( !strcasecmp( "AES-128-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CBC );
if( !strcasecmp( "AES-192-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CBC );
if( !strcasecmp( "AES-256-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CBC );
#if defined(POLARSSL_CIPHER_MODE_CFB)
if( !strcasecmp( "AES-128-CFB128", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CFB128 );
if( !strcasecmp( "AES-192-CFB128", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CFB128 );
if( !strcasecmp( "AES-256-CFB128", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CFB128 );
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
if( !strcasecmp( "AES-128-CTR", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_128_CTR );
if( !strcasecmp( "AES-192-CTR", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_192_CTR );
if( !strcasecmp( "AES-256-CTR", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_AES_256_CTR );
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif
#if defined(POLARSSL_DES_C)
if( !strcasecmp( "DES-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_DES_CBC );
if( !strcasecmp( "DES-EDE-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE_CBC );
if( !strcasecmp( "DES-EDE3-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE3_CBC );
#endif
#if defined(POLARSSL_BLOWFISH_C)
if( !strcasecmp( "BLOWFISH-CBC", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_BLOWFISH_CBC );
#if defined(POLARSSL_CIPHER_MODE_CFB)
if( !strcasecmp( "BLOWFISH-CFB64", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_BLOWFISH_CFB64 );
#endif /* defined(POLARSSL_CIPHER_MODE_CFB) */
#if defined(POLARSSL_CIPHER_MODE_CTR)
if( !strcasecmp( "BLOWFISH-CTR", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_BLOWFISH_CTR );
#endif /* defined(POLARSSL_CIPHER_MODE_CTR) */
#endif
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
if( !strcasecmp( "NULL", cipher_name ) )
return cipher_info_from_type( POLARSSL_CIPHER_NULL );
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
return NULL;
}
int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info )
{
if( NULL == cipher_info || NULL == ctx )
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
memset( ctx, 0, sizeof( cipher_context_t ) );
if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
return POLARSSL_ERR_CIPHER_ALLOC_FAILED;
ctx->cipher_info = cipher_info;
return 0;
}
int cipher_free_ctx( cipher_context_t *ctx )
{
if( ctx == NULL || ctx->cipher_info == NULL )
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
return 0;
}
int cipher_setkey( cipher_context_t *ctx, const unsigned char *key,
int key_length, const operation_t operation )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
ctx->key_length = key_length;
ctx->operation = operation;
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
return 0;
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
/*
* For CFB and CTR mode always use the encryption key schedule
*/
if( POLARSSL_ENCRYPT == operation ||
POLARSSL_MODE_CFB == ctx->cipher_info->mode ||
POLARSSL_MODE_CTR == ctx->cipher_info->mode )
{
return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
ctx->key_length );
}
if( POLARSSL_DECRYPT == operation )
return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
ctx->key_length );
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
}
int cipher_reset( cipher_context_t *ctx, const unsigned char *iv )
{
if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv )
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
ctx->unprocessed_len = 0;
memcpy( ctx->iv, iv, cipher_get_iv_size( ctx ) );
return 0;
}
int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen )
{
int ret;
size_t copy_len = 0;
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ||
input == output )
{
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
}
*olen = 0;
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
{
memcpy( output, input, ilen );
*olen = ilen;
return 0;
}
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
{
/*
* If there is not enough data for a full block, cache it.
*/
if( ( ctx->operation == POLARSSL_DECRYPT &&
ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) ||
( ctx->operation == POLARSSL_ENCRYPT &&
ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) )
{
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
ilen );
ctx->unprocessed_len += ilen;
return 0;
}
/*
* Process cached data first
*/
if( ctx->unprocessed_len != 0 )
{
copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len;
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
copy_len );
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
ctx->unprocessed_data, output ) ) )
{
return ret;
}
*olen += cipher_get_block_size( ctx );
output += cipher_get_block_size( ctx );
ctx->unprocessed_len = 0;
input += copy_len;
ilen -= copy_len;
}
/*
* Cache final, incomplete block
*/
if( 0 != ilen )
{
copy_len = ilen % cipher_get_block_size( ctx );
if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT )
copy_len = cipher_get_block_size(ctx);
memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
copy_len );
ctx->unprocessed_len += copy_len;
ilen -= copy_len;
}
/*
* Process remaining full blocks
*/
if( ilen )
{
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
ctx->operation, ilen, ctx->iv, input, output ) ) )
{
return ret;
}
*olen += ilen;
}
return 0;
}
if( ctx->cipher_info->mode == POLARSSL_MODE_CFB )
{
if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
input, output ) ) )
{
return ret;
}
*olen = ilen;
return 0;
}
if( ctx->cipher_info->mode == POLARSSL_MODE_CTR )
{
if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
ilen, &ctx->unprocessed_len, ctx->iv,
ctx->unprocessed_data, input, output ) ) )
{
return ret;
}
*olen = ilen;
return 0;
}
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
static void add_pkcs_padding( unsigned char *output, size_t output_len,
size_t data_len )
{
size_t padding_len = output_len - data_len;
unsigned char i = 0;
for( i = 0; i < padding_len; i++ )
output[data_len + i] = (unsigned char) padding_len;
}
static int get_pkcs_padding( unsigned char *input, unsigned int input_len,
size_t *data_len)
{
unsigned int i, padding_len = 0;
if( NULL == input || NULL == data_len )
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
padding_len = input[input_len - 1];
if( padding_len > input_len )
return POLARSSL_ERR_CIPHER_INVALID_PADDING;
for( i = input_len - padding_len; i < input_len; i++ )
if( input[i] != padding_len )
return POLARSSL_ERR_CIPHER_INVALID_PADDING;
*data_len = input_len - padding_len;
return 0;
}
int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen)
{
int ret = 0;
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
*olen = 0;
if( POLARSSL_MODE_CFB == ctx->cipher_info->mode ||
POLARSSL_MODE_CTR == ctx->cipher_info->mode ||
POLARSSL_MODE_NULL == ctx->cipher_info->mode )
{
return 0;
}
if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )
{
if( POLARSSL_ENCRYPT == ctx->operation )
{
add_pkcs_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ),
ctx->unprocessed_len );
}
else if ( cipher_get_block_size( ctx ) != ctx->unprocessed_len )
{
/* For decrypt operations, expect a full block */
return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED;
}
/* cipher block */
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
ctx->unprocessed_data, output ) ) )
{
return ret;
}
/* Set output size for decryption */
if( POLARSSL_DECRYPT == ctx->operation )
return get_pkcs_padding( output, cipher_get_block_size( ctx ), olen );
/* Set output size for encryption */
*olen = cipher_get_block_size( ctx );
return 0;
}
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
#if defined(POLARSSL_SELF_TEST)
#include <stdio.h>
#define ASSERT(x) if (!(x)) { \
printf( "failed with %i at %s\n", value, (#x) ); \
return( 1 ); \
}
/*
* Checkup routine
*/
int cipher_self_test( int verbose )
{
((void) verbose);
return( 0 );
}
#endif
#endif
+463
View File
@@ -0,0 +1,463 @@
/**
* \file cipher.h
*
* \brief Generic cipher wrapper.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_CIPHER_H
#define POLARSSL_CIPHER_H
#include <string.h>
#if defined(_MSC_VER) && !defined(inline)
#define inline _inline
#else
#if defined(__ARMCC_VERSION) && !defined(inline)
#define inline __inline
#endif /* __ARMCC_VERSION */
#endif /*_MSC_VER */
#define POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */
#define POLARSSL_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */
#define POLARSSL_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */
#define POLARSSL_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */
#define POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */
typedef enum {
POLARSSL_CIPHER_ID_NONE = 0,
POLARSSL_CIPHER_ID_NULL,
POLARSSL_CIPHER_ID_AES,
POLARSSL_CIPHER_ID_DES,
POLARSSL_CIPHER_ID_3DES,
POLARSSL_CIPHER_ID_CAMELLIA,
POLARSSL_CIPHER_ID_BLOWFISH,
} cipher_id_t;
typedef enum {
POLARSSL_CIPHER_NONE = 0,
POLARSSL_CIPHER_NULL,
POLARSSL_CIPHER_AES_128_CBC,
POLARSSL_CIPHER_AES_192_CBC,
POLARSSL_CIPHER_AES_256_CBC,
POLARSSL_CIPHER_AES_128_CFB128,
POLARSSL_CIPHER_AES_192_CFB128,
POLARSSL_CIPHER_AES_256_CFB128,
POLARSSL_CIPHER_AES_128_CTR,
POLARSSL_CIPHER_AES_192_CTR,
POLARSSL_CIPHER_AES_256_CTR,
POLARSSL_CIPHER_CAMELLIA_128_CBC,
POLARSSL_CIPHER_CAMELLIA_192_CBC,
POLARSSL_CIPHER_CAMELLIA_256_CBC,
POLARSSL_CIPHER_CAMELLIA_128_CFB128,
POLARSSL_CIPHER_CAMELLIA_192_CFB128,
POLARSSL_CIPHER_CAMELLIA_256_CFB128,
POLARSSL_CIPHER_CAMELLIA_128_CTR,
POLARSSL_CIPHER_CAMELLIA_192_CTR,
POLARSSL_CIPHER_CAMELLIA_256_CTR,
POLARSSL_CIPHER_DES_CBC,
POLARSSL_CIPHER_DES_EDE_CBC,
POLARSSL_CIPHER_DES_EDE3_CBC,
POLARSSL_CIPHER_BLOWFISH_CBC,
POLARSSL_CIPHER_BLOWFISH_CFB64,
POLARSSL_CIPHER_BLOWFISH_CTR,
} cipher_type_t;
typedef enum {
POLARSSL_MODE_NONE = 0,
POLARSSL_MODE_NULL,
POLARSSL_MODE_CBC,
POLARSSL_MODE_CFB,
POLARSSL_MODE_OFB,
POLARSSL_MODE_CTR,
} cipher_mode_t;
typedef enum {
POLARSSL_OPERATION_NONE = -1,
POLARSSL_DECRYPT = 0,
POLARSSL_ENCRYPT,
} operation_t;
enum {
/** Undefined key length */
POLARSSL_KEY_LENGTH_NONE = 0,
/** Key length, in bits (including parity), for DES keys */
POLARSSL_KEY_LENGTH_DES = 64,
/** Key length, in bits (including parity), for DES in two key EDE */
POLARSSL_KEY_LENGTH_DES_EDE = 128,
/** Key length, in bits (including parity), for DES in three-key EDE */
POLARSSL_KEY_LENGTH_DES_EDE3 = 192,
/** Maximum length of any IV, in bytes */
POLARSSL_MAX_IV_LENGTH = 16,
};
/**
* Base cipher information. The non-mode specific functions and values.
*/
typedef struct {
/** Base Cipher type (e.g. POLARSSL_CIPHER_ID_AES) */
cipher_id_t cipher;
/** Encrypt using CBC */
int (*cbc_func)( void *ctx, operation_t mode, size_t length, unsigned char *iv,
const unsigned char *input, unsigned char *output );
/** Encrypt using CFB (Full length) */
int (*cfb_func)( void *ctx, operation_t mode, size_t length, size_t *iv_off,
unsigned char *iv, const unsigned char *input, unsigned char *output );
/** Encrypt using CTR */
int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, unsigned char *nonce_counter,
unsigned char *stream_block, const unsigned char *input, unsigned char *output );
/** Set key for encryption purposes */
int (*setkey_enc_func)( void *ctx, const unsigned char *key, unsigned int key_length);
/** Set key for decryption purposes */
int (*setkey_dec_func)( void *ctx, const unsigned char *key, unsigned int key_length);
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
} cipher_base_t;
/**
* Cipher information. Allows cipher functions to be called in a generic way.
*/
typedef struct {
/** Full cipher identifier (e.g. POLARSSL_CIPHER_AES_256_CBC) */
cipher_type_t type;
/** Cipher mode (e.g. POLARSSL_MODE_CBC) */
cipher_mode_t mode;
/** Cipher key length, in bits (default length for variable sized ciphers)
* (Includes parity bits for ciphers like DES) */
unsigned int key_length;
/** Name of the cipher */
const char * name;
/** IV size, in bytes */
unsigned int iv_size;
/** block size, in bytes */
unsigned int block_size;
/** Base cipher information and functions */
const cipher_base_t *base;
} cipher_info_t;
/**
* Generic cipher context.
*/
typedef struct {
/** Information about the associated cipher */
const cipher_info_t *cipher_info;
/** Key length to use */
int key_length;
/** Operation that the context's key has been initialised for */
operation_t operation;
/** Buffer for data that hasn't been encrypted yet */
unsigned char unprocessed_data[POLARSSL_MAX_IV_LENGTH];
/** Number of bytes that still need processing */
size_t unprocessed_len;
/** Current IV or NONCE_COUNTER for CTR-mode */
unsigned char iv[POLARSSL_MAX_IV_LENGTH];
/** Cipher-specific context */
void *cipher_ctx;
} cipher_context_t;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Returns the list of ciphers supported by the generic cipher module.
*
* \return a statically allocated array of ciphers, the last entry
* is 0.
*/
const int *cipher_list( void );
/**
* \brief Returns the cipher information structure associated
* with the given cipher name.
*
* \param cipher_name Name of the cipher to search for.
*
* \return the cipher information structure associated with the
* given cipher_name, or NULL if not found.
*/
const cipher_info_t *cipher_info_from_string( const char *cipher_name );
/**
* \brief Returns the cipher information structure associated
* with the given cipher type.
*
* \param cipher_type Type of the cipher to search for.
*
* \return the cipher information structure associated with the
* given cipher_type, or NULL if not found.
*/
const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type );
/**
* \brief Initialises and fills the cipher context structure with
* the appropriate values.
*
* \param ctx context to initialise. May not be NULL.
* \param cipher_info cipher to use.
*
* \return \c 0 on success,
* \c POLARSSL_ERR_CIPHER_BAD_INPUT_DATA on parameter failure,
* \c POLARSSL_ERR_CIPHER_ALLOC_FAILED if allocation of the
* cipher-specific context failed.
*/
int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info );
/**
* \brief Free the cipher-specific context of ctx. Freeing ctx
* itself remains the responsibility of the caller.
*
* \param ctx Free the cipher-specific context
*
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails.
*/
int cipher_free_ctx( cipher_context_t *ctx );
/**
* \brief Returns the block size of the given cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return size of the cipher's blocks, or 0 if ctx has not been
* initialised.
*/
static inline unsigned int cipher_get_block_size( const cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
return ctx->cipher_info->block_size;
}
/**
* \brief Returns the mode of operation for the cipher.
* (e.g. POLARSSL_MODE_CBC)
*
* \param ctx cipher's context. Must have been initialised.
*
* \return mode of operation, or POLARSSL_MODE_NONE if ctx
* has not been initialised.
*/
static inline cipher_mode_t cipher_get_cipher_mode( const cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return POLARSSL_MODE_NONE;
return ctx->cipher_info->mode;
}
/**
* \brief Returns the size of the cipher's IV.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return size of the cipher's IV, or 0 if ctx has not been
* initialised.
*/
static inline int cipher_get_iv_size( const cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
return ctx->cipher_info->iv_size;
}
/**
* \brief Returns the type of the given cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return type of the cipher, or POLARSSL_CIPHER_NONE if ctx has
* not been initialised.
*/
static inline cipher_type_t cipher_get_type( const cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return POLARSSL_CIPHER_NONE;
return ctx->cipher_info->type;
}
/**
* \brief Returns the name of the given cipher, as a string.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return name of the cipher, or NULL if ctx was not initialised.
*/
static inline const char *cipher_get_name( const cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return 0;
return ctx->cipher_info->name;
}
/**
* \brief Returns the key length of the cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return cipher's key length, in bits, or
* POLARSSL_KEY_LENGTH_NONE if ctx has not been
* initialised.
*/
static inline int cipher_get_key_size ( const cipher_context_t *ctx )
{
if( NULL == ctx )
return POLARSSL_KEY_LENGTH_NONE;
return ctx->key_length;
}
/**
* \brief Returns the operation of the given cipher.
*
* \param ctx cipher's context. Must have been initialised.
*
* \return operation (POLARSSL_ENCRYPT or POLARSSL_DECRYPT),
* or POLARSSL_OPERATION_NONE if ctx has not been
* initialised.
*/
static inline operation_t cipher_get_operation( const cipher_context_t *ctx )
{
if( NULL == ctx || NULL == ctx->cipher_info )
return POLARSSL_OPERATION_NONE;
return ctx->operation;
}
/**
* \brief Set the key to use with the given context.
*
* \param ctx generic cipher context. May not be NULL. Must have been
* initialised using cipher_context_from_type or
* cipher_context_from_string.
* \param key The key to use.
* \param key_length key length to use, in bits.
* \param operation Operation that the key will be used for, either
* POLARSSL_ENCRYPT or POLARSSL_DECRYPT.
*
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails or a cipher specific
* error code.
*/
int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, int key_length,
const operation_t operation );
/**
* \brief Reset the given context, setting the IV to iv
*
* \param ctx generic cipher context
* \param iv IV to use or NONCE_COUNTER in the case of a CTR-mode cipher
*
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA
* if parameter verification fails.
*/
int cipher_reset( cipher_context_t *ctx, const unsigned char *iv );
/**
* \brief Generic cipher update function. Encrypts/decrypts
* using the given cipher context. Writes as many block
* size'd blocks of data as possible to output. Any data
* that cannot be written immediately will either be added
* to the next block, or flushed when cipher_final is
* called.
*
* \param ctx generic cipher context
* \param input buffer holding the input data
* \param ilen length of the input data
* \param output buffer for the output data. Should be able to hold at
* least ilen + block_size. Cannot be the same buffer as
* input!
* \param olen length of the output data, will be filled with the
* actual number of bytes written.
*
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails,
* POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE on an
* unsupported mode for a cipher or a cipher specific
* error code.
*/
int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen );
/**
* \brief Generic cipher finalisation function. If data still
* needs to be flushed from an incomplete block, data
* contained within it will be padded with the size of
* the last block, and written to the output buffer.
*
* \param ctx Generic cipher context
* \param output buffer to write data to. Needs block_size data available.
* \param olen length of the data written to the output buffer.
*
* \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if
* parameter verification fails,
* POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption
* expected a full block but was not provided one,
* POLARSSL_ERR_CIPHER_INVALID_PADDING on invalid padding
* while decrypting or a cipher specific error code.
*/
int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen);
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int cipher_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* POLARSSL_MD_H */
+711
View File
@@ -0,0 +1,711 @@
/**
* \file md_wrap.c
*
* \brief Generic cipher wrapper for PolarSSL
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_CIPHER_C)
#include "polarssl/cipher_wrap.h"
#if defined(POLARSSL_AES_C)
#include "polarssl/aes.h"
#endif
#if defined(POLARSSL_CAMELLIA_C)
#include "polarssl/camellia.h"
#endif
#if defined(POLARSSL_DES_C)
#include "polarssl/des.h"
#endif
#if defined(POLARSSL_BLOWFISH_C)
#include "polarssl/blowfish.h"
#endif
#include <stdlib.h>
#if defined(POLARSSL_AES_C)
int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return aes_crypt_cbc( (aes_context *) ctx, operation, length, iv, input, output );
}
int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CFB)
return aes_crypt_cfb128( (aes_context *) ctx, operation, length, iv_off, iv, input, output );
#else
((void) ctx);
((void) operation);
((void) length);
((void) iv_off);
((void) iv);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
#endif
}
int aes_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CTR)
return aes_crypt_ctr( (aes_context *) ctx, length, nc_off, nonce_counter,
stream_block, input, output );
#else
((void) ctx);
((void) length);
((void) nc_off);
((void) nonce_counter);
((void) stream_block);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
#endif
}
int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return aes_setkey_dec( (aes_context *) ctx, key, key_length );
}
int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return aes_setkey_enc( (aes_context *) ctx, key, key_length );
}
static void * aes_ctx_alloc( void )
{
return malloc( sizeof( aes_context ) );
}
static void aes_ctx_free( void *ctx )
{
free( ctx );
}
const cipher_base_t aes_info = {
POLARSSL_CIPHER_ID_AES,
aes_crypt_cbc_wrap,
aes_crypt_cfb128_wrap,
aes_crypt_ctr_wrap,
aes_setkey_enc_wrap,
aes_setkey_dec_wrap,
aes_ctx_alloc,
aes_ctx_free
};
const cipher_info_t aes_128_cbc_info = {
POLARSSL_CIPHER_AES_128_CBC,
POLARSSL_MODE_CBC,
128,
"AES-128-CBC",
16,
16,
&aes_info
};
const cipher_info_t aes_192_cbc_info = {
POLARSSL_CIPHER_AES_192_CBC,
POLARSSL_MODE_CBC,
192,
"AES-192-CBC",
16,
16,
&aes_info
};
const cipher_info_t aes_256_cbc_info = {
POLARSSL_CIPHER_AES_256_CBC,
POLARSSL_MODE_CBC,
256,
"AES-256-CBC",
16,
16,
&aes_info
};
#if defined(POLARSSL_CIPHER_MODE_CFB)
const cipher_info_t aes_128_cfb128_info = {
POLARSSL_CIPHER_AES_128_CFB128,
POLARSSL_MODE_CFB,
128,
"AES-128-CFB128",
16,
16,
&aes_info
};
const cipher_info_t aes_192_cfb128_info = {
POLARSSL_CIPHER_AES_192_CFB128,
POLARSSL_MODE_CFB,
192,
"AES-192-CFB128",
16,
16,
&aes_info
};
const cipher_info_t aes_256_cfb128_info = {
POLARSSL_CIPHER_AES_256_CFB128,
POLARSSL_MODE_CFB,
256,
"AES-256-CFB128",
16,
16,
&aes_info
};
#endif /* POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
const cipher_info_t aes_128_ctr_info = {
POLARSSL_CIPHER_AES_128_CTR,
POLARSSL_MODE_CTR,
128,
"AES-128-CTR",
16,
16,
&aes_info
};
const cipher_info_t aes_192_ctr_info = {
POLARSSL_CIPHER_AES_192_CTR,
POLARSSL_MODE_CTR,
192,
"AES-192-CTR",
16,
16,
&aes_info
};
const cipher_info_t aes_256_ctr_info = {
POLARSSL_CIPHER_AES_256_CTR,
POLARSSL_MODE_CTR,
256,
"AES-256-CTR",
16,
16,
&aes_info
};
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif
#if defined(POLARSSL_CAMELLIA_C)
int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return camellia_crypt_cbc( (camellia_context *) ctx, operation, length, iv, input, output );
}
int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CFB)
return camellia_crypt_cfb128( (camellia_context *) ctx, operation, length, iv_off, iv, input, output );
#else
((void) ctx);
((void) operation);
((void) length);
((void) iv_off);
((void) iv);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
#endif
}
int camellia_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CTR)
return camellia_crypt_ctr( (camellia_context *) ctx, length, nc_off, nonce_counter,
stream_block, input, output );
#else
((void) ctx);
((void) length);
((void) nc_off);
((void) nonce_counter);
((void) stream_block);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
#endif
}
int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return camellia_setkey_dec( (camellia_context *) ctx, key, key_length );
}
int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return camellia_setkey_enc( (camellia_context *) ctx, key, key_length );
}
static void * camellia_ctx_alloc( void )
{
return malloc( sizeof( camellia_context ) );
}
static void camellia_ctx_free( void *ctx )
{
free( ctx );
}
const cipher_base_t camellia_info = {
POLARSSL_CIPHER_ID_CAMELLIA,
camellia_crypt_cbc_wrap,
camellia_crypt_cfb128_wrap,
camellia_crypt_ctr_wrap,
camellia_setkey_enc_wrap,
camellia_setkey_dec_wrap,
camellia_ctx_alloc,
camellia_ctx_free
};
const cipher_info_t camellia_128_cbc_info = {
POLARSSL_CIPHER_CAMELLIA_128_CBC,
POLARSSL_MODE_CBC,
128,
"CAMELLIA-128-CBC",
16,
16,
&camellia_info
};
const cipher_info_t camellia_192_cbc_info = {
POLARSSL_CIPHER_CAMELLIA_192_CBC,
POLARSSL_MODE_CBC,
192,
"CAMELLIA-192-CBC",
16,
16,
&camellia_info
};
const cipher_info_t camellia_256_cbc_info = {
POLARSSL_CIPHER_CAMELLIA_256_CBC,
POLARSSL_MODE_CBC,
256,
"CAMELLIA-256-CBC",
16,
16,
&camellia_info
};
#if defined(POLARSSL_CIPHER_MODE_CFB)
const cipher_info_t camellia_128_cfb128_info = {
POLARSSL_CIPHER_CAMELLIA_128_CFB128,
POLARSSL_MODE_CFB,
128,
"CAMELLIA-128-CFB128",
16,
16,
&camellia_info
};
const cipher_info_t camellia_192_cfb128_info = {
POLARSSL_CIPHER_CAMELLIA_192_CFB128,
POLARSSL_MODE_CFB,
192,
"CAMELLIA-192-CFB128",
16,
16,
&camellia_info
};
const cipher_info_t camellia_256_cfb128_info = {
POLARSSL_CIPHER_CAMELLIA_256_CFB128,
POLARSSL_MODE_CFB,
256,
"CAMELLIA-256-CFB128",
16,
16,
&camellia_info
};
#endif /* POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
const cipher_info_t camellia_128_ctr_info = {
POLARSSL_CIPHER_CAMELLIA_128_CTR,
POLARSSL_MODE_CTR,
128,
"CAMELLIA-128-CTR",
16,
16,
&camellia_info
};
const cipher_info_t camellia_192_ctr_info = {
POLARSSL_CIPHER_CAMELLIA_192_CTR,
POLARSSL_MODE_CTR,
192,
"CAMELLIA-192-CTR",
16,
16,
&camellia_info
};
const cipher_info_t camellia_256_ctr_info = {
POLARSSL_CIPHER_CAMELLIA_256_CTR,
POLARSSL_MODE_CTR,
256,
"CAMELLIA-256-CTR",
16,
16,
&camellia_info
};
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif
#if defined(POLARSSL_DES_C)
int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return des_crypt_cbc( (des_context *) ctx, operation, length, iv, input, output );
}
int des3_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return des3_crypt_cbc( (des3_context *) ctx, operation, length, iv, input, output );
}
int des_crypt_cfb128_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
((void) ctx);
((void) operation);
((void) length);
((void) iv_off);
((void) iv);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
int des_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
((void) ctx);
((void) length);
((void) nc_off);
((void) nonce_counter);
((void) stream_block);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
int des_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des_setkey_dec( (des_context *) ctx, key );
}
int des_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des_setkey_enc( (des_context *) ctx, key );
}
int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des3_set2key_dec( (des3_context *) ctx, key );
}
int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des3_set2key_enc( (des3_context *) ctx, key );
}
int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des3_set3key_dec( (des3_context *) ctx, key );
}
int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
((void) key_length);
return des3_set3key_enc( (des3_context *) ctx, key );
}
static void * des_ctx_alloc( void )
{
return malloc( sizeof( des_context ) );
}
static void * des3_ctx_alloc( void )
{
return malloc( sizeof( des3_context ) );
}
static void des_ctx_free( void *ctx )
{
free( ctx );
}
const cipher_base_t des_info = {
POLARSSL_CIPHER_ID_DES,
des_crypt_cbc_wrap,
des_crypt_cfb128_wrap,
des_crypt_ctr_wrap,
des_setkey_enc_wrap,
des_setkey_dec_wrap,
des_ctx_alloc,
des_ctx_free
};
const cipher_info_t des_cbc_info = {
POLARSSL_CIPHER_DES_CBC,
POLARSSL_MODE_CBC,
POLARSSL_KEY_LENGTH_DES,
"DES-CBC",
8,
8,
&des_info
};
const cipher_base_t des_ede_info = {
POLARSSL_CIPHER_ID_DES,
des3_crypt_cbc_wrap,
des_crypt_cfb128_wrap,
des_crypt_ctr_wrap,
des3_set2key_enc_wrap,
des3_set2key_dec_wrap,
des3_ctx_alloc,
des_ctx_free
};
const cipher_info_t des_ede_cbc_info = {
POLARSSL_CIPHER_DES_EDE_CBC,
POLARSSL_MODE_CBC,
POLARSSL_KEY_LENGTH_DES_EDE,
"DES-EDE-CBC",
8,
8,
&des_ede_info
};
const cipher_base_t des_ede3_info = {
POLARSSL_CIPHER_ID_DES,
des3_crypt_cbc_wrap,
des_crypt_cfb128_wrap,
des_crypt_ctr_wrap,
des3_set3key_enc_wrap,
des3_set3key_dec_wrap,
des3_ctx_alloc,
des_ctx_free
};
const cipher_info_t des_ede3_cbc_info = {
POLARSSL_CIPHER_DES_EDE3_CBC,
POLARSSL_MODE_CBC,
POLARSSL_KEY_LENGTH_DES_EDE3,
"DES-EDE3-CBC",
8,
8,
&des_ede3_info
};
#endif
#if defined(POLARSSL_BLOWFISH_C)
int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length,
unsigned char *iv, const unsigned char *input, unsigned char *output )
{
return blowfish_crypt_cbc( (blowfish_context *) ctx, operation, length, iv, input, output );
}
int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, size_t length,
size_t *iv_off, unsigned char *iv, const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CFB)
return blowfish_crypt_cfb64( (blowfish_context *) ctx, operation, length, iv_off, iv, input, output );
#else
((void) ctx);
((void) operation);
((void) length);
((void) iv_off);
((void) iv);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
#endif
}
int blowfish_crypt_ctr_wrap( void *ctx, size_t length,
size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block,
const unsigned char *input, unsigned char *output )
{
#if defined(POLARSSL_CIPHER_MODE_CTR)
return blowfish_crypt_ctr( (blowfish_context *) ctx, length, nc_off, nonce_counter,
stream_block, input, output );
#else
((void) ctx);
((void) length);
((void) nc_off);
((void) nonce_counter);
((void) stream_block);
((void) input);
((void) output);
return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
#endif
}
int blowfish_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
}
int blowfish_setkey_enc_wrap( void *ctx, const unsigned char *key, unsigned int key_length )
{
return blowfish_setkey( (blowfish_context *) ctx, key, key_length );
}
static void * blowfish_ctx_alloc( void )
{
return malloc( sizeof( blowfish_context ) );
}
static void blowfish_ctx_free( void *ctx )
{
free( ctx );
}
const cipher_base_t blowfish_info = {
POLARSSL_CIPHER_ID_BLOWFISH,
blowfish_crypt_cbc_wrap,
blowfish_crypt_cfb64_wrap,
blowfish_crypt_ctr_wrap,
blowfish_setkey_enc_wrap,
blowfish_setkey_dec_wrap,
blowfish_ctx_alloc,
blowfish_ctx_free
};
const cipher_info_t blowfish_cbc_info = {
POLARSSL_CIPHER_BLOWFISH_CBC,
POLARSSL_MODE_CBC,
128,
"BLOWFISH-CBC",
8,
8,
&blowfish_info
};
#if defined(POLARSSL_CIPHER_MODE_CFB)
const cipher_info_t blowfish_cfb64_info = {
POLARSSL_CIPHER_BLOWFISH_CFB64,
POLARSSL_MODE_CFB,
128,
"BLOWFISH-CFB64",
8,
8,
&blowfish_info
};
#endif /* POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
const cipher_info_t blowfish_ctr_info = {
POLARSSL_CIPHER_BLOWFISH_CTR,
POLARSSL_MODE_CTR,
128,
"BLOWFISH-CTR",
8,
8,
&blowfish_info
};
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif /* POLARSSL_BLOWFISH_C */
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
static void * null_ctx_alloc( void )
{
return (void *) 1;
}
static void null_ctx_free( void *ctx )
{
((void) ctx);
}
const cipher_base_t null_base_info = {
POLARSSL_CIPHER_ID_NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
null_ctx_alloc,
null_ctx_free
};
const cipher_info_t null_cipher_info = {
POLARSSL_CIPHER_NULL,
POLARSSL_MODE_NULL,
0,
"NULL",
1,
1,
&null_base_info
};
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
#endif
+107
View File
@@ -0,0 +1,107 @@
/**
* \file cipher_wrap.h
*
* \brief Cipher wrappers.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_CIPHER_WRAP_H
#define POLARSSL_CIPHER_WRAP_H
#include "polarssl/config.h"
#include "polarssl/cipher.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(POLARSSL_AES_C)
extern const cipher_info_t aes_128_cbc_info;
extern const cipher_info_t aes_192_cbc_info;
extern const cipher_info_t aes_256_cbc_info;
#if defined(POLARSSL_CIPHER_MODE_CFB)
extern const cipher_info_t aes_128_cfb128_info;
extern const cipher_info_t aes_192_cfb128_info;
extern const cipher_info_t aes_256_cfb128_info;
#endif /* POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
extern const cipher_info_t aes_128_ctr_info;
extern const cipher_info_t aes_192_ctr_info;
extern const cipher_info_t aes_256_ctr_info;
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif /* defined(POLARSSL_AES_C) */
#if defined(POLARSSL_CAMELLIA_C)
extern const cipher_info_t camellia_128_cbc_info;
extern const cipher_info_t camellia_192_cbc_info;
extern const cipher_info_t camellia_256_cbc_info;
#if defined(POLARSSL_CIPHER_MODE_CFB)
extern const cipher_info_t camellia_128_cfb128_info;
extern const cipher_info_t camellia_192_cfb128_info;
extern const cipher_info_t camellia_256_cfb128_info;
#endif /* POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
extern const cipher_info_t camellia_128_ctr_info;
extern const cipher_info_t camellia_192_ctr_info;
extern const cipher_info_t camellia_256_ctr_info;
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif /* defined(POLARSSL_CAMELLIA_C) */
#if defined(POLARSSL_DES_C)
extern const cipher_info_t des_cbc_info;
extern const cipher_info_t des_ede_cbc_info;
extern const cipher_info_t des_ede3_cbc_info;
#endif /* defined(POLARSSL_DES_C) */
#if defined(POLARSSL_BLOWFISH_C)
extern const cipher_info_t blowfish_cbc_info;
#if defined(POLARSSL_CIPHER_MODE_CFB)
extern const cipher_info_t blowfish_cfb64_info;
#endif /* POLARSSL_CIPHER_MODE_CFB */
#if defined(POLARSSL_CIPHER_MODE_CTR)
extern const cipher_info_t blowfish_ctr_info;
#endif /* POLARSSL_CIPHER_MODE_CTR */
#endif /* defined(POLARSSL_BLOWFISH_C) */
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
extern const cipher_info_t null_cipher_info;
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
#ifdef __cplusplus
}
#endif
#endif /* POLARSSL_CIPHER_WRAP_H */
+1012
View File
File diff suppressed because it is too large Load Diff
+562
View File
@@ -0,0 +1,562 @@
/*
* CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The NIST SP 800-90 DRBGs are described in the following publucation.
*
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_CTR_DRBG_C)
#include "polarssl/ctr_drbg.h"
#if defined(POLARSSL_FS_IO)
#include <stdio.h>
#endif
/*
* Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
* tests to succeed (which require known length fixed entropy)
*/
int ctr_drbg_init_entropy_len(
ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len,
size_t entropy_len )
{
int ret;
unsigned char key[CTR_DRBG_KEYSIZE];
memset( ctx, 0, sizeof(ctr_drbg_context) );
memset( key, 0, CTR_DRBG_KEYSIZE );
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
ctx->entropy_len = entropy_len;
ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL;
/*
* Initialize with an empty key
*/
aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS );
if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
return( ret );
return( 0 );
}
int ctr_drbg_init( ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len )
{
return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len,
CTR_DRBG_ENTROPY_LEN ) );
}
void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
{
ctx->prediction_resistance = resistance;
}
void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len )
{
ctx->entropy_len = len;
}
void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval )
{
ctx->reseed_interval = interval;
}
int block_cipher_df( unsigned char *output,
const unsigned char *data, size_t data_len )
{
unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16];
unsigned char tmp[CTR_DRBG_SEEDLEN];
unsigned char key[CTR_DRBG_KEYSIZE];
unsigned char chain[CTR_DRBG_BLOCKSIZE];
unsigned char *p = buf, *iv;
aes_context aes_ctx;
int i, j, buf_len, use_len;
memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 );
/*
* Construct IV (16 bytes) and S in buffer
* IV = Counter (in 32-bits) padded to 16 with zeroes
* S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
* data || 0x80
* (Total is padded to a multiple of 16-bytes with zeroes)
*/
p = buf + CTR_DRBG_BLOCKSIZE;
*p++ = ( data_len >> 24 ) & 0xff;
*p++ = ( data_len >> 16 ) & 0xff;
*p++ = ( data_len >> 8 ) & 0xff;
*p++ = ( data_len ) & 0xff;
p += 3;
*p++ = CTR_DRBG_SEEDLEN;
memcpy( p, data, data_len );
p[data_len] = 0x80;
buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
for( i = 0; i < CTR_DRBG_KEYSIZE; i++ )
key[i] = i;
aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS );
/*
* Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data
*/
for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
{
p = buf;
memset( chain, 0, CTR_DRBG_BLOCKSIZE );
use_len = buf_len;
while( use_len > 0 )
{
for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ )
chain[i] ^= p[i];
p += CTR_DRBG_BLOCKSIZE;
use_len -= CTR_DRBG_BLOCKSIZE;
aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain );
}
memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
/*
* Update IV
*/
buf[3]++;
}
/*
* Do final encryption with reduced data
*/
aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS );
iv = tmp + CTR_DRBG_KEYSIZE;
p = output;
for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
{
aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv );
memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
p += CTR_DRBG_BLOCKSIZE;
}
return( 0 );
}
int ctr_drbg_update_internal( ctr_drbg_context *ctx,
const unsigned char data[CTR_DRBG_SEEDLEN] )
{
unsigned char tmp[CTR_DRBG_SEEDLEN];
unsigned char *p = tmp;
int i, j;
memset( tmp, 0, CTR_DRBG_SEEDLEN );
for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
{
/*
* Increase counter
*/
for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
if( ++ctx->counter[i - 1] != 0 )
break;
/*
* Crypt counter block
*/
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p );
p += CTR_DRBG_BLOCKSIZE;
}
for( i = 0; i < CTR_DRBG_SEEDLEN; i++ )
tmp[i] ^= data[i];
/*
* Update key and counter
*/
aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS );
memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
return( 0 );
}
void ctr_drbg_update( ctr_drbg_context *ctx,
const unsigned char *additional, size_t add_len )
{
unsigned char add_input[CTR_DRBG_SEEDLEN];
if( add_len > 0 )
{
block_cipher_df( add_input, additional, add_len );
ctr_drbg_update_internal( ctx, add_input );
}
}
int ctr_drbg_reseed( ctr_drbg_context *ctx,
const unsigned char *additional, size_t len )
{
unsigned char seed[CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0;
if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT )
return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT );
/*
* Gather enropy_len bytes of entropy to seed state
*/
if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
ctx->entropy_len ) )
{
return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
}
seedlen += ctx->entropy_len;
/*
* Add additional data
*/
if( additional && len )
{
memcpy( seed + seedlen, additional, len );
seedlen += len;
}
/*
* Reduce to 384 bits
*/
block_cipher_df( seed, seed, seedlen );
/*
* Update state
*/
ctr_drbg_update_internal( ctx, seed );
ctx->reseed_counter = 1;
return( 0 );
}
int ctr_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional, size_t add_len )
{
int ret = 0;
ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
unsigned char add_input[CTR_DRBG_SEEDLEN];
unsigned char *p = output;
unsigned char tmp[CTR_DRBG_BLOCKSIZE];
int i;
size_t use_len;
if( output_len > CTR_DRBG_MAX_REQUEST )
return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG );
if( add_len > CTR_DRBG_MAX_INPUT )
return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
memset( add_input, 0, CTR_DRBG_SEEDLEN );
if( ctx->reseed_counter > ctx->reseed_interval ||
ctx->prediction_resistance )
{
if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
return( ret );
add_len = 0;
}
if( add_len > 0 )
{
block_cipher_df( add_input, additional, add_len );
ctr_drbg_update_internal( ctx, add_input );
}
while( output_len > 0 )
{
/*
* Increase counter
*/
for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
if( ++ctx->counter[i - 1] != 0 )
break;
/*
* Crypt counter block
*/
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp );
use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len;
/*
* Copy random block to destination
*/
memcpy( p, tmp, use_len );
p += use_len;
output_len -= use_len;
}
ctr_drbg_update_internal( ctx, add_input );
ctx->reseed_counter++;
return( 0 );
}
int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
{
return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 );
}
#if defined(POLARSSL_FS_IO)
int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
{
int ret;
FILE *f;
unsigned char buf[ CTR_DRBG_MAX_INPUT ];
if( ( f = fopen( path, "wb" ) ) == NULL )
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 )
return( ret );
if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
{
fclose( f );
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
}
fclose( f );
return( 0 );
}
int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
{
FILE *f;
size_t n;
unsigned char buf[ CTR_DRBG_MAX_INPUT ];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
fseek( f, 0, SEEK_END );
n = (size_t) ftell( f );
fseek( f, 0, SEEK_SET );
if( n > CTR_DRBG_MAX_INPUT )
return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
if( fread( buf, 1, n, f ) != n )
{
fclose( f );
return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
}
ctr_drbg_update( ctx, buf, n );
fclose( f );
return( ctr_drbg_write_seed_file( ctx, path ) );
}
#endif /* POLARSSL_FS_IO */
#if defined(POLARSSL_SELF_TEST)
#include <stdio.h>
unsigned char entropy_source_pr[96] =
{ 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
unsigned char entropy_source_nopr[64] =
{ 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
unsigned char nonce_pers_pr[16] =
{ 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
unsigned char nonce_pers_nopr[16] =
{ 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
unsigned char result_pr[16] =
{ 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
unsigned char result_nopr[16] =
{ 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
int test_offset;
int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len )
{
unsigned char *p = data;
memcpy( buf, p + test_offset, len );
test_offset += 32;
return( 0 );
}
/*
* Checkup routine
*/
int ctr_drbg_self_test( int verbose )
{
ctr_drbg_context ctx;
unsigned char buf[16];
/*
* Based on a NIST CTR_DRBG test vector (PR = True)
*/
if( verbose != 0 )
printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0;
if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16, 32 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
/*
* Based on a NIST CTR_DRBG test vector (PR = FALSE)
*/
if( verbose != 0 )
printf( " CTR_DRBG (PR = FALSE): " );
test_offset = 0;
if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16, 32 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( memcmp( buf, result_nopr, 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif
+231
View File
@@ -0,0 +1,231 @@
/**
* \file ctr_drbg.h
*
* \brief CTR_DRBG based on AES-256 (NIST SP 800-90)
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_CTR_DRBG_H
#define POLARSSL_CTR_DRBG_H
#include <string.h>
#include "polarssl/aes.h"
#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */
#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */
#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read/write error in file. */
#define CTR_DRBG_BLOCKSIZE 16 /**< Block size used by the cipher */
#define CTR_DRBG_KEYSIZE 32 /**< Key size used by the cipher */
#define CTR_DRBG_KEYBITS ( CTR_DRBG_KEYSIZE * 8 )
#define CTR_DRBG_SEEDLEN ( CTR_DRBG_KEYSIZE + CTR_DRBG_BLOCKSIZE )
/**< The seed length (counter + AES key) */
#if !defined(POLARSSL_CONFIG_OPTIONS)
#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default */
#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
#endif /* !POLARSSL_CONFIG_OPTIONS */
#define CTR_DRBG_PR_OFF 0 /**< No prediction resistance */
#define CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief CTR_DRBG context structure
*/
typedef struct
{
unsigned char counter[16]; /*!< counter (V) */
int reseed_counter; /*!< reseed counter */
int prediction_resistance; /*!< enable prediction resistance (Automatic
reseed before every random generation) */
size_t entropy_len; /*!< amount of entropy grabbed on each (re)seed */
int reseed_interval; /*!< reseed interval */
aes_context aes_ctx; /*!< AES context */
/*
* Callbacks (Entropy)
*/
int (*f_entropy)(void *, unsigned char *, size_t);
void *p_entropy; /*!< context for the entropy function */
}
ctr_drbg_context;
/**
* \brief CTR_DRBG initialization
*
* Note: Personalization data can be provided in addition to the more generic
* entropy source to make this instantiation as unique as possible.
*
* \param ctx CTR_DRBG context to be initialized
* \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer
* length)
* \param p_entropy Entropy context
* \param custom Personalization data (Device specific identifiers)
* (Can be NULL)
* \param len Length of personalization data
*
* \return 0 if successful, or
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
*/
int ctr_drbg_init( ctr_drbg_context *ctx,
int (*f_entropy)(void *, unsigned char *, size_t),
void *p_entropy,
const unsigned char *custom,
size_t len );
/**
* \brief Enable / disable prediction resistance (Default: Off)
*
* Note: If enabled, entropy is used for ctx->entropy_len before each call!
* Only use this if you have ample supply of good entropy!
*
* \param ctx CTR_DRBG context
* \param resistance CTR_DRBG_PR_ON or CTR_DRBG_PR_OFF
*/
void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx,
int resistance );
/**
* \brief Set the amount of entropy grabbed on each (re)seed
* (Default: CTR_DRBG_ENTROPY_LEN)
*
* \param ctx CTR_DRBG context
* \param len Amount of entropy to grab
*/
void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx,
size_t len );
/**
* \brief Set the reseed interval
* (Default: CTR_DRBG_RESEED_INTERVAL)
*
* \param ctx CTR_DRBG context
* \param interval Reseed interval
*/
void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx,
int interval );
/**
* \brief CTR_DRBG reseeding (extracts data from entropy source)
*
* \param ctx CTR_DRBG context
* \param additional Additional data to add to state (Can be NULL)
* \param len Length of additional data
*
* \return 0 if successful, or
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
*/
int ctr_drbg_reseed( ctr_drbg_context *ctx,
const unsigned char *additional, size_t len );
/**
* \brief CTR_DRBG update state
*
* \param ctx CTR_DRBG context
* \param additional Additional data to update state with
* \param add_len Length of additional data
*/
void ctr_drbg_update( ctr_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
/**
* \brief CTR_DRBG generate random with additional update input
*
* Note: Automatically reseeds if reseed_counter is reached.
*
* \param p_rng CTR_DRBG context
* \param output Buffer to fill
* \param output_len Length of the buffer
* \param additional Additional data to update with (Can be NULL)
* \param add_len Length of additional data
*
* \return 0 if successful, or
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
* POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG
*/
int ctr_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t output_len,
const unsigned char *additional, size_t add_len );
/**
* \brief CTR_DRBG generate random
*
* Note: Automatically reseeds if reseed_counter is reached.
*
* \param p_rng CTR_DRBG context
* \param output Buffer to fill
* \param output_len Length of the buffer
*
* \return 0 if successful, or
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
* POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG
*/
int ctr_drbg_random( void *p_rng,
unsigned char *output, size_t output_len );
#if defined(POLARSSL_FS_IO)
/**
* \brief Write a seed file
*
* \param path Name of the file
*
* \return 0 if successful, 1 on file error, or
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
*/
int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path );
/**
* \brief Read and update a seed file. Seed is added to this
* instance
*
* \param path Name of the file
*
* \return 0 if successful, 1 on file error,
* POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
* POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG
*/
int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path );
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int ctr_drbg_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* ctr_drbg.h */
+238
View File
@@ -0,0 +1,238 @@
/*
* Debugging routines
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_DEBUG_C)
#include "polarssl/debug.h"
#include <stdarg.h>
#include <stdlib.h>
#if defined _MSC_VER && !defined snprintf
#define snprintf _snprintf
#endif
#if defined _MSC_VER && !defined vsnprintf
#define vsnprintf _vsnprintf
#endif
char *debug_fmt( const char *format, ... )
{
va_list argp;
static char str[512];
int maxlen = sizeof( str ) - 1;
va_start( argp, format );
vsnprintf( str, maxlen, format, argp );
va_end( argp );
str[maxlen] = '\0';
return( str );
}
void debug_print_msg( const ssl_context *ssl, int level,
const char *file, int line, const char *text )
{
char str[512];
int maxlen = sizeof( str ) - 1;
if( ssl->f_dbg == NULL )
return;
snprintf( str, maxlen, "%s(%04d): %s\n", file, line, text );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
void debug_print_ret( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret )
{
char str[512];
int maxlen = sizeof( str ) - 1;
if( ssl->f_dbg == NULL )
return;
snprintf( str, maxlen, "%s(%04d): %s() returned %d (0x%x)\n",
file, line, text, ret, ret );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
void debug_print_buf( const ssl_context *ssl, int level,
const char *file, int line, const char *text,
unsigned char *buf, size_t len )
{
char str[512];
size_t i, maxlen = sizeof( str ) - 1;
if( ssl->f_dbg == NULL )
return;
snprintf( str, maxlen, "%s(%04d): dumping '%s' (%d bytes)\n",
file, line, text, (unsigned int) len );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
for( i = 0; i < len; i++ )
{
if( i >= 4096 )
break;
if( i % 16 == 0 )
{
if( i > 0 )
ssl->f_dbg( ssl->p_dbg, level, "\n" );
snprintf( str, maxlen, "%s(%04d): %04x: ", file, line,
(unsigned int) i );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
snprintf( str, maxlen, " %02x", (unsigned int) buf[i] );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
if( len > 0 )
ssl->f_dbg( ssl->p_dbg, level, "\n" );
}
void debug_print_mpi( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mpi *X )
{
char str[512];
int j, k, maxlen = sizeof( str ) - 1, zeros = 1;
size_t i, n;
if( ssl->f_dbg == NULL || X == NULL )
return;
for( n = X->n - 1; n > 0; n-- )
if( X->p[n] != 0 )
break;
for( j = ( sizeof(t_uint) << 3 ) - 1; j >= 0; j-- )
if( ( ( X->p[n] >> j ) & 1 ) != 0 )
break;
snprintf( str, maxlen, "%s(%04d): value of '%s' (%d bits) is:\n",
file, line, text,
(int) ( ( n * ( sizeof(t_uint) << 3 ) ) + j + 1 ) );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
for( i = n + 1, j = 0; i > 0; i-- )
{
if( zeros && X->p[i - 1] == 0 )
continue;
for( k = sizeof( t_uint ) - 1; k >= 0; k-- )
{
if( zeros && ( ( X->p[i - 1] >> (k << 3) ) & 0xFF ) == 0 )
continue;
else
zeros = 0;
if( j % 16 == 0 )
{
if( j > 0 )
ssl->f_dbg( ssl->p_dbg, level, "\n" );
snprintf( str, maxlen, "%s(%04d): ", file, line );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
}
snprintf( str, maxlen, " %02x", (unsigned int)
( X->p[i - 1] >> (k << 3) ) & 0xFF );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
j++;
}
}
if( zeros == 1 )
{
snprintf( str, maxlen, "%s(%04d): ", file, line );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
ssl->f_dbg( ssl->p_dbg, level, " 00" );
}
ssl->f_dbg( ssl->p_dbg, level, "\n" );
}
void debug_print_crt( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const x509_cert *crt )
{
char str[1024], prefix[64];
int i = 0, maxlen = sizeof( prefix ) - 1;
if( ssl->f_dbg == NULL || crt == NULL )
return;
snprintf( prefix, maxlen, "%s(%04d): ", file, line );
prefix[maxlen] = '\0';
maxlen = sizeof( str ) - 1;
while( crt != NULL )
{
char buf[1024];
x509parse_cert_info( buf, sizeof( buf ) - 1, prefix, crt );
snprintf( str, maxlen, "%s(%04d): %s #%d:\n%s",
file, line, text, ++i, buf );
str[maxlen] = '\0';
ssl->f_dbg( ssl->p_dbg, level, str );
debug_print_mpi( ssl, level, file, line,
"crt->rsa.N", &crt->rsa.N );
debug_print_mpi( ssl, level, file, line,
"crt->rsa.E", &crt->rsa.E );
crt = crt->next;
}
}
#endif
+89
View File
@@ -0,0 +1,89 @@
/**
* \file debug.h
*
* \brief Debug functions
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_DEBUG_H
#define POLARSSL_DEBUG_H
#include "polarssl/config.h"
#include "polarssl/ssl.h"
#if defined(POLARSSL_DEBUG_C)
#define SSL_DEBUG_MSG( level, args ) \
debug_print_msg( ssl, level, __FILE__, __LINE__, debug_fmt args );
#define SSL_DEBUG_RET( level, text, ret ) \
debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret );
#define SSL_DEBUG_BUF( level, text, buf, len ) \
debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len );
#define SSL_DEBUG_MPI( level, text, X ) \
debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X );
#define SSL_DEBUG_CRT( level, text, crt ) \
debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt );
#else
#define SSL_DEBUG_MSG( level, args ) do { } while( 0 )
#define SSL_DEBUG_RET( level, text, ret ) do { } while( 0 )
#define SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 )
#define SSL_DEBUG_MPI( level, text, X ) do { } while( 0 )
#define SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
#endif
#ifdef __cplusplus
extern "C" {
#endif
char *debug_fmt( const char *format, ... );
void debug_print_msg( const ssl_context *ssl, int level,
const char *file, int line, const char *text );
void debug_print_ret( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, int ret );
void debug_print_buf( const ssl_context *ssl, int level,
const char *file, int line, const char *text,
unsigned char *buf, size_t len );
void debug_print_mpi( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mpi *X );
void debug_print_crt( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const x509_cert *crt );
#ifdef __cplusplus
}
#endif
#endif /* debug.h */
+997
View File
@@ -0,0 +1,997 @@
/*
* FIPS-46-3 compliant Triple-DES implementation
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* DES, on which TDES is based, was originally designed by Horst Feistel
* at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
*
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_DES_C)
#include "polarssl/des.h"
#if !defined(POLARSSL_DES_ALT)
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
/*
* Expanded DES S-boxes
*/
static const uint32_t SB1[64] =
{
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400,
0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004,
0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000,
0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004,
0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404,
0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004
};
static const uint32_t SB2[64] =
{
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000,
0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000,
0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000,
0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020,
0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020,
0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000
};
static const uint32_t SB3[64] =
{
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200,
0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208,
0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208,
0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200,
0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208,
0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200
};
static const uint32_t SB4[64] =
{
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080,
0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001,
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000,
0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080
};
static const uint32_t SB5[64] =
{
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000,
0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000,
0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000,
0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100,
0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100,
0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100
};
static const uint32_t SB6[64] =
{
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000,
0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000,
0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000,
0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010,
0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010,
0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010
};
static const uint32_t SB7[64] =
{
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800,
0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802,
0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802,
0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000,
0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000,
0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002
};
static const uint32_t SB8[64] =
{
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040,
0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040,
0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000,
0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000,
0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040,
0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000
};
/*
* PC1: left and right halves bit-swap
*/
static const uint32_t LHs[16] =
{
0x00000000, 0x00000001, 0x00000100, 0x00000101,
0x00010000, 0x00010001, 0x00010100, 0x00010101,
0x01000000, 0x01000001, 0x01000100, 0x01000101,
0x01010000, 0x01010001, 0x01010100, 0x01010101
};
static const uint32_t RHs[16] =
{
0x00000000, 0x01000000, 0x00010000, 0x01010000,
0x00000100, 0x01000100, 0x00010100, 0x01010100,
0x00000001, 0x01000001, 0x00010001, 0x01010001,
0x00000101, 0x01000101, 0x00010101, 0x01010101,
};
/*
* Initial Permutation macro
*/
#define DES_IP(X,Y) \
{ \
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
}
/*
* Final Permutation macro
*/
#define DES_FP(X,Y) \
{ \
X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
}
/*
* DES round macro
*/
#define DES_ROUND(X,Y) \
{ \
T = *SK++ ^ X; \
Y ^= SB8[ (T ) & 0x3F ] ^ \
SB6[ (T >> 8) & 0x3F ] ^ \
SB4[ (T >> 16) & 0x3F ] ^ \
SB2[ (T >> 24) & 0x3F ]; \
\
T = *SK++ ^ ((X << 28) | (X >> 4)); \
Y ^= SB7[ (T ) & 0x3F ] ^ \
SB5[ (T >> 8) & 0x3F ] ^ \
SB3[ (T >> 16) & 0x3F ] ^ \
SB1[ (T >> 24) & 0x3F ]; \
}
#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
254 };
void des_key_set_parity( unsigned char key[DES_KEY_SIZE] )
{
int i;
for( i = 0; i < DES_KEY_SIZE; i++ )
key[i] = odd_parity_table[key[i] / 2];
}
/*
* Check the given key's parity, returns 1 on failure, 0 on SUCCESS
*/
int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] )
{
int i;
for( i = 0; i < DES_KEY_SIZE; i++ )
if ( key[i] != odd_parity_table[key[i] / 2] )
return( 1 );
return( 0 );
}
/*
* Table of weak and semi-weak keys
*
* Source: http://en.wikipedia.org/wiki/Weak_key
*
* Weak:
* Alternating ones + zeros (0x0101010101010101)
* Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
* '0xE0E0E0E0F1F1F1F1'
* '0x1F1F1F1F0E0E0E0E'
*
* Semi-weak:
* 0x011F011F010E010E and 0x1F011F010E010E01
* 0x01E001E001F101F1 and 0xE001E001F101F101
* 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
* 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
* 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
* 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
*
*/
#define WEAK_KEY_COUNT 16
static const unsigned char weak_key_table[WEAK_KEY_COUNT][DES_KEY_SIZE] =
{
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
{ 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
{ 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
{ 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
{ 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
{ 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
{ 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
{ 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
{ 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
{ 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
{ 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
{ 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
{ 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
{ 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
};
int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] )
{
int i;
for( i = 0; i < WEAK_KEY_COUNT; i++ )
if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0)
return( 1 );
return( 0 );
}
static void des_setkey( uint32_t SK[32], const unsigned char key[DES_KEY_SIZE] )
{
int i;
uint32_t X, Y, T;
GET_UINT32_BE( X, key, 0 );
GET_UINT32_BE( Y, key, 4 );
/*
* Permuted Choice 1
*/
T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
| (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
| (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
| (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
| (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
| (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
| (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
X &= 0x0FFFFFFF;
Y &= 0x0FFFFFFF;
/*
* calculate subkeys
*/
for( i = 0; i < 16; i++ )
{
if( i < 2 || i == 8 || i == 15 )
{
X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
}
else
{
X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
}
*SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
| ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
| ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
| ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
| ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
| ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
| ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
| ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
| ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
| ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
| ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
*SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
| ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
| ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
| ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
| ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
| ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
| ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
| ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
| ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
| ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
| ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
}
}
/*
* DES key schedule (56-bit, encryption)
*/
int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] )
{
des_setkey( ctx->sk, key );
return( 0 );
}
/*
* DES key schedule (56-bit, decryption)
*/
int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] )
{
int i;
des_setkey( ctx->sk, key );
for( i = 0; i < 16; i += 2 )
{
SWAP( ctx->sk[i ], ctx->sk[30 - i] );
SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
}
return( 0 );
}
static void des3_set2key( uint32_t esk[96],
uint32_t dsk[96],
const unsigned char key[DES_KEY_SIZE*2] )
{
int i;
des_setkey( esk, key );
des_setkey( dsk + 32, key + 8 );
for( i = 0; i < 32; i += 2 )
{
dsk[i ] = esk[30 - i];
dsk[i + 1] = esk[31 - i];
esk[i + 32] = dsk[62 - i];
esk[i + 33] = dsk[63 - i];
esk[i + 64] = esk[i ];
esk[i + 65] = esk[i + 1];
dsk[i + 64] = dsk[i ];
dsk[i + 65] = dsk[i + 1];
}
}
/*
* Triple-DES key schedule (112-bit, encryption)
*/
int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] )
{
uint32_t sk[96];
des3_set2key( ctx->sk, sk, key );
memset( sk, 0, sizeof( sk ) );
return( 0 );
}
/*
* Triple-DES key schedule (112-bit, decryption)
*/
int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] )
{
uint32_t sk[96];
des3_set2key( sk, ctx->sk, key );
memset( sk, 0, sizeof( sk ) );
return( 0 );
}
static void des3_set3key( uint32_t esk[96],
uint32_t dsk[96],
const unsigned char key[24] )
{
int i;
des_setkey( esk, key );
des_setkey( dsk + 32, key + 8 );
des_setkey( esk + 64, key + 16 );
for( i = 0; i < 32; i += 2 )
{
dsk[i ] = esk[94 - i];
dsk[i + 1] = esk[95 - i];
esk[i + 32] = dsk[62 - i];
esk[i + 33] = dsk[63 - i];
dsk[i + 64] = esk[30 - i];
dsk[i + 65] = esk[31 - i];
}
}
/*
* Triple-DES key schedule (168-bit, encryption)
*/
int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] )
{
uint32_t sk[96];
des3_set3key( ctx->sk, sk, key );
memset( sk, 0, sizeof( sk ) );
return( 0 );
}
/*
* Triple-DES key schedule (168-bit, decryption)
*/
int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] )
{
uint32_t sk[96];
des3_set3key( sk, ctx->sk, key );
memset( sk, 0, sizeof( sk ) );
return( 0 );
}
/*
* DES-ECB block encryption/decryption
*/
int des_crypt_ecb( des_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
int i;
uint32_t X, Y, T, *SK;
SK = ctx->sk;
GET_UINT32_BE( X, input, 0 );
GET_UINT32_BE( Y, input, 4 );
DES_IP( X, Y );
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
DES_FP( Y, X );
PUT_UINT32_BE( Y, output, 0 );
PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
/*
* DES-CBC buffer encryption/decryption
*/
int des_crypt_cbc( des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[8];
if( length % 8 )
return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
if( mode == DES_ENCRYPT )
{
while( length > 0 )
{
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
des_crypt_ecb( ctx, output, output );
memcpy( iv, output, 8 );
input += 8;
output += 8;
length -= 8;
}
}
else /* DES_DECRYPT */
{
while( length > 0 )
{
memcpy( temp, input, 8 );
des_crypt_ecb( ctx, input, output );
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 8 );
input += 8;
output += 8;
length -= 8;
}
}
return( 0 );
}
/*
* 3DES-ECB block encryption/decryption
*/
int des3_crypt_ecb( des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] )
{
int i;
uint32_t X, Y, T, *SK;
SK = ctx->sk;
GET_UINT32_BE( X, input, 0 );
GET_UINT32_BE( Y, input, 4 );
DES_IP( X, Y );
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
for( i = 0; i < 8; i++ )
{
DES_ROUND( X, Y );
DES_ROUND( Y, X );
}
for( i = 0; i < 8; i++ )
{
DES_ROUND( Y, X );
DES_ROUND( X, Y );
}
DES_FP( Y, X );
PUT_UINT32_BE( Y, output, 0 );
PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
/*
* 3DES-CBC buffer encryption/decryption
*/
int des3_crypt_cbc( des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[8];
if( length % 8 )
return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
if( mode == DES_ENCRYPT )
{
while( length > 0 )
{
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
des3_crypt_ecb( ctx, output, output );
memcpy( iv, output, 8 );
input += 8;
output += 8;
length -= 8;
}
}
else /* DES_DECRYPT */
{
while( length > 0 )
{
memcpy( temp, input, 8 );
des3_crypt_ecb( ctx, input, output );
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 8 );
input += 8;
output += 8;
length -= 8;
}
}
return( 0 );
}
#endif /* !POLARSSL_DES_ALT */
#if defined(POLARSSL_SELF_TEST)
#include <stdio.h>
/*
* DES and 3DES test vectors from:
*
* http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
*/
static const unsigned char des3_test_keys[24] =
{
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
};
static const unsigned char des3_test_iv[8] =
{
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
};
static const unsigned char des3_test_buf[8] =
{
0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
};
static const unsigned char des3_test_ecb_dec[3][8] =
{
{ 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
{ 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
{ 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
};
static const unsigned char des3_test_ecb_enc[3][8] =
{
{ 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
{ 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
{ 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
};
static const unsigned char des3_test_cbc_dec[3][8] =
{
{ 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
{ 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
{ 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
};
static const unsigned char des3_test_cbc_enc[3][8] =
{
{ 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
{ 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
{ 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
};
/*
* Checkup routine
*/
int des_self_test( int verbose )
{
int i, j, u, v;
des_context ctx;
des3_context ctx3;
unsigned char key[24];
unsigned char buf[8];
unsigned char prv[8];
unsigned char iv[8];
memset( key, 0, 24 );
/*
* ECB mode
*/
for( i = 0; i < 6; i++ )
{
u = i >> 1;
v = i & 1;
if( verbose != 0 )
printf( " DES%c-ECB-%3d (%s): ",
( u == 0 ) ? ' ' : '3', 56 + u * 56,
( v == DES_DECRYPT ) ? "dec" : "enc" );
memcpy( buf, des3_test_buf, 8 );
switch( i )
{
case 0:
des_setkey_dec( &ctx, des3_test_keys );
break;
case 1:
des_setkey_enc( &ctx, des3_test_keys );
break;
case 2:
des3_set2key_dec( &ctx3, des3_test_keys );
break;
case 3:
des3_set2key_enc( &ctx3, des3_test_keys );
break;
case 4:
des3_set3key_dec( &ctx3, des3_test_keys );
break;
case 5:
des3_set3key_enc( &ctx3, des3_test_keys );
break;
default:
return( 1 );
}
for( j = 0; j < 10000; j++ )
{
if( u == 0 )
des_crypt_ecb( &ctx, buf, buf );
else
des3_crypt_ecb( &ctx3, buf, buf );
}
if( ( v == DES_DECRYPT &&
memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
( v != DES_DECRYPT &&
memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
/*
* CBC mode
*/
for( i = 0; i < 6; i++ )
{
u = i >> 1;
v = i & 1;
if( verbose != 0 )
printf( " DES%c-CBC-%3d (%s): ",
( u == 0 ) ? ' ' : '3', 56 + u * 56,
( v == DES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, des3_test_iv, 8 );
memcpy( prv, des3_test_iv, 8 );
memcpy( buf, des3_test_buf, 8 );
switch( i )
{
case 0:
des_setkey_dec( &ctx, des3_test_keys );
break;
case 1:
des_setkey_enc( &ctx, des3_test_keys );
break;
case 2:
des3_set2key_dec( &ctx3, des3_test_keys );
break;
case 3:
des3_set2key_enc( &ctx3, des3_test_keys );
break;
case 4:
des3_set3key_dec( &ctx3, des3_test_keys );
break;
case 5:
des3_set3key_enc( &ctx3, des3_test_keys );
break;
default:
return( 1 );
}
if( v == DES_DECRYPT )
{
for( j = 0; j < 10000; j++ )
{
if( u == 0 )
des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
else
des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
}
}
else
{
for( j = 0; j < 10000; j++ )
{
unsigned char tmp[8];
if( u == 0 )
des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
else
des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
memcpy( tmp, prv, 8 );
memcpy( prv, buf, 8 );
memcpy( buf, tmp, 8 );
}
memcpy( buf, prv, 8 );
}
if( ( v == DES_DECRYPT &&
memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
( v != DES_DECRYPT &&
memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif
+252
View File
@@ -0,0 +1,252 @@
/**
* \file des.h
*
* \brief DES block cipher
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_DES_H
#define POLARSSL_DES_H
#include "polarssl/config.h"
#include <string.h>
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
#define DES_KEY_SIZE 8
#if !defined(POLARSSL_DES_ALT)
// Regular implementation
//
/**
* \brief DES context structure
*/
typedef struct
{
int mode; /*!< encrypt/decrypt */
uint32_t sk[32]; /*!< DES subkeys */
}
des_context;
/**
* \brief Triple-DES context structure
*/
typedef struct
{
int mode; /*!< encrypt/decrypt */
uint32_t sk[96]; /*!< 3DES subkeys */
}
des3_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Set key parity on the given key to odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*/
void des_key_set_parity( unsigned char key[DES_KEY_SIZE] );
/**
* \brief Check that key parity on the given key is odd.
*
* DES keys are 56 bits long, but each byte is padded with
* a parity bit to allow verification.
*
* \param key 8-byte secret key
*
* \return 0 is parity was ok, 1 if parity was not correct.
*/
int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] );
/**
* \brief Check that key is not a weak or semi-weak DES key
*
* \param key 8-byte secret key
*
* \return 0 if no weak key was found, 1 if a weak key was identified.
*/
int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, encryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
/**
* \brief DES key schedule (56-bit, decryption)
*
* \param ctx DES context to be initialized
* \param key 8-byte secret key
*
* \return 0
*/
int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
/**
* \brief Triple-DES key schedule (112-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (112-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 16-byte secret key
*
* \return 0
*/
int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
/**
* \brief Triple-DES key schedule (168-bit, encryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
/**
* \brief Triple-DES key schedule (168-bit, decryption)
*
* \param ctx 3DES context to be initialized
* \param key 24-byte secret key
*
* \return 0
*/
int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
/**
* \brief DES-ECB block encryption/decryption
*
* \param ctx DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int des_crypt_ecb( des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
/**
* \brief DES-CBC buffer encryption/decryption
*
* \param ctx DES context
* \param mode DES_ENCRYPT or DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*/
int des_crypt_cbc( des_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
/**
* \brief 3DES-ECB block encryption/decryption
*
* \param ctx 3DES context
* \param input 64-bit input block
* \param output 64-bit output block
*
* \return 0 if successful
*/
int des3_crypt_ecb( des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
/**
* \brief 3DES-CBC buffer encryption/decryption
*
* \param ctx 3DES context
* \param mode DES_ENCRYPT or DES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or POLARSSL_ERR_DES_INVALID_INPUT_LENGTH
*/
int des3_crypt_cbc( des3_context *ctx,
int mode,
size_t length,
unsigned char iv[8],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_DES_ALT */
#include "polarssl/des_alt.h"
#endif /* POLARSSL_DES_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int des_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* des.h */
+302
View File
@@ -0,0 +1,302 @@
/*
* Diffie-Hellman-Merkle key exchange
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Reference:
*
* http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12)
*/
#include "polarssl/config.h"
#if defined(POLARSSL_DHM_C)
#include "polarssl/dhm.h"
/*
* helper to validate the mpi size and import it
*/
static int dhm_read_bignum( mpi *X,
unsigned char **p,
const unsigned char *end )
{
int ret, n;
if( end - *p < 2 )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
n = ( (*p)[0] << 8 ) | (*p)[1];
(*p) += 2;
if( (int)( end - *p ) < n )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mpi_read_binary( X, *p, n ) ) != 0 )
return( POLARSSL_ERR_DHM_READ_PARAMS_FAILED + ret );
(*p) += n;
return( 0 );
}
/*
* Verify sanity of parameter with regards to P
*
* Parameter should be: 2 <= public_param <= P - 2
*
* For more information on the attack, see:
* http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
*/
static int dhm_check_range( const mpi *param, const mpi *P )
{
mpi L, U;
int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA;
mpi_init( &L ); mpi_init( &U );
mpi_lset( &L, 2 );
mpi_sub_int( &U, P, 2 );
if( mpi_cmp_mpi( param, &L ) >= 0 &&
mpi_cmp_mpi( param, &U ) <= 0 )
{
ret = 0;
}
mpi_free( &L ); mpi_free( &U );
return( ret );
}
/*
* Parse the ServerKeyExchange parameters
*/
int dhm_read_params( dhm_context *ctx,
unsigned char **p,
const unsigned char *end )
{
int ret;
memset( ctx, 0, sizeof( dhm_context ) );
if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
return( ret );
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
return( ret );
ctx->len = mpi_size( &ctx->P );
if( end - *p < 2 )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
return( 0 );
}
/*
* Setup and write the ServerKeyExchange parameters
*/
int dhm_make_params( dhm_context *ctx, int x_size,
unsigned char *output, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret, count = 0;
size_t n1, n2, n3;
unsigned char *p;
if( mpi_cmp_int( &ctx->P, 0 ) == 0 )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
/*
* Generate X as large as possible ( < P )
*/
do
{
mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
mpi_shift_r( &ctx->X, 1 );
if( count++ > 10 )
return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED );
}
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
/*
* Calculate GX = G^X mod P
*/
MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
&ctx->P , &ctx->RP ) );
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
return( ret );
/*
* export P, G, GX
*/
#define DHM_MPI_EXPORT(X,n) \
MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \
*p++ = (unsigned char)( n >> 8 ); \
*p++ = (unsigned char)( n ); p += n;
n1 = mpi_size( &ctx->P );
n2 = mpi_size( &ctx->G );
n3 = mpi_size( &ctx->GX );
p = output;
DHM_MPI_EXPORT( &ctx->P , n1 );
DHM_MPI_EXPORT( &ctx->G , n2 );
DHM_MPI_EXPORT( &ctx->GX, n3 );
*olen = p - output;
ctx->len = n1;
cleanup:
if( ret != 0 )
return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED + ret );
return( 0 );
}
/*
* Import the peer's public value G^Y
*/
int dhm_read_public( dhm_context *ctx,
const unsigned char *input, size_t ilen )
{
int ret;
if( ctx == NULL || ilen < 1 || ilen > ctx->len )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
return( POLARSSL_ERR_DHM_READ_PUBLIC_FAILED + ret );
return( 0 );
}
/*
* Create own private value X and export G^X
*/
int dhm_make_public( dhm_context *ctx, int x_size,
unsigned char *output, size_t olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret, count = 0;
if( ctx == NULL || olen < 1 || olen > ctx->len )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
if( mpi_cmp_int( &ctx->P, 0 ) == 0 )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
/*
* generate X and calculate GX = G^X mod P
*/
do
{
mpi_fill_random( &ctx->X, x_size, f_rng, p_rng );
while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
mpi_shift_r( &ctx->X, 1 );
if( count++ > 10 )
return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED );
}
while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
&ctx->P , &ctx->RP ) );
if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
return( ret );
MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) );
cleanup:
if( ret != 0 )
return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
return( 0 );
}
/*
* Derive and export the shared secret (G^Y)^X mod P
*/
int dhm_calc_secret( dhm_context *ctx,
unsigned char *output, size_t *olen )
{
int ret;
if( ctx == NULL || *olen < ctx->len )
return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );
MPI_CHK( mpi_exp_mod( &ctx->K, &ctx->GY, &ctx->X,
&ctx->P, &ctx->RP ) );
if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
return( ret );
*olen = mpi_size( &ctx->K );
MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) );
cleanup:
if( ret != 0 )
return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret );
return( 0 );
}
/*
* Free the components of a DHM key
*/
void dhm_free( dhm_context *ctx )
{
mpi_free( &ctx->RP ); mpi_free( &ctx->K ); mpi_free( &ctx->GY );
mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G );
mpi_free( &ctx->P );
}
#if defined(POLARSSL_SELF_TEST)
/*
* Checkup routine
*/
int dhm_self_test( int verbose )
{
return( verbose++ );
}
#endif
#endif
+244
View File
@@ -0,0 +1,244 @@
/**
* \file dhm.h
*
* \brief Diffie-Hellman-Merkle key exchange
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_DHM_H
#define POLARSSL_DHM_H
#include "polarssl/bignum.h"
/*
* DHM Error codes
*/
#define POLARSSL_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters to function. */
#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */
#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */
#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */
#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */
#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */
/**
* RFC 3526 defines a number of standardized Diffie-Hellman groups
* for IKE.
* RFC 5114 defines a number of standardized Diffie-Hellman groups
* that can be used.
*
* Some are included here for convenience.
*
* Included are:
* RFC 3526 3. 2048-bit MODP Group
* RFC 3526 4. 3072-bit MODP Group
* RFC 5114 2.1. 1024-bit MODP Group with 160-bit Prime Order Subgroup
* RFC 5114 2.2. 2048-bit MODP Group with 224-bit Prime Order Subgroup
*/
#define POLARSSL_DHM_RFC3526_MODP_2048_P \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
"15728E5A8AACAA68FFFFFFFFFFFFFFFF"
#define POLARSSL_DHM_RFC3526_MODP_2048_G "02"
#define POLARSSL_DHM_RFC3526_MODP_3072_P \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \
"43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
#define POLARSSL_DHM_RFC3526_MODP_3072_G "02"
#define POLARSSL_DHM_RFC5114_MODP_1024_P \
"B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" \
"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" \
"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" \
"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" \
"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" \
"DF1FB2BC2E4A4371"
#define POLARSSL_DHM_RFC5114_MODP_1024_G \
"A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" \
"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" \
"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" \
"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" \
"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" \
"855E6EEB22B3B2E5"
#define POLARSSL_DHM_RFC5114_MODP_2048_P \
"AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \
"B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \
"EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \
"9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \
"C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \
"B3BF8A317091883681286130BC8985DB1602E714415D9330" \
"278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \
"CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \
"BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \
"C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \
"CF9DE5384E71B81C0AC4DFFE0C10E64F"
#define POLARSSL_DHM_RFC5114_MODP_2048_G \
"AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"\
"74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"\
"AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"\
"C17669101999024AF4D027275AC1348BB8A762D0521BC98A"\
"E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"\
"F180EB34118E98D119529A45D6F834566E3025E316A330EF"\
"BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"\
"10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"\
"B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"\
"EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"\
"81BC087F2A7065B384B890D3191F2BFA"
/**
* \brief DHM context structure
*/
typedef struct
{
size_t len; /*!< size(P) in chars */
mpi P; /*!< prime modulus */
mpi G; /*!< generator */
mpi X; /*!< secret value */
mpi GX; /*!< self = G^X mod P */
mpi GY; /*!< peer = G^Y mod P */
mpi K; /*!< key = GY^X mod P */
mpi RP; /*!< cached R^2 mod P */
}
dhm_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Parse the ServerKeyExchange parameters
*
* \param ctx DHM context
* \param p &(start of input buffer)
* \param end end of buffer
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_read_params( dhm_context *ctx,
unsigned char **p,
const unsigned char *end );
/**
* \brief Setup and write the ServerKeyExchange parameters
*
* \param ctx DHM context
* \param x_size private value size in bytes
* \param output destination buffer
* \param olen number of chars written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \note This function assumes that ctx->P and ctx->G
* have already been properly set (for example
* using mpi_read_string or mpi_read_binary).
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_make_params( dhm_context *ctx, int x_size,
unsigned char *output, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Import the peer's public value G^Y
*
* \param ctx DHM context
* \param input input buffer
* \param ilen size of buffer
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_read_public( dhm_context *ctx,
const unsigned char *input, size_t ilen );
/**
* \brief Create own private value X and export G^X
*
* \param ctx DHM context
* \param x_size private value size in bytes
* \param output destination buffer
* \param olen must be equal to ctx->P.len
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_make_public( dhm_context *ctx, int x_size,
unsigned char *output, size_t olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Derive and export the shared secret (G^Y)^X mod P
*
* \param ctx DHM context
* \param output destination buffer
* \param olen number of chars written
*
* \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
*/
int dhm_calc_secret( dhm_context *ctx,
unsigned char *output, size_t *olen );
/**
* \brief Free the components of a DHM key
*/
void dhm_free( dhm_context *ctx );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int dhm_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif
+204
View File
@@ -0,0 +1,204 @@
/*
* Entropy accumulator implementation
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_ENTROPY_C)
#include "polarssl/entropy.h"
#include "polarssl/entropy_poll.h"
#if defined(POLARSSL_HAVEGE_C)
#include "polarssl/havege.h"
#endif
#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
void entropy_init( entropy_context *ctx )
{
memset( ctx, 0, sizeof(entropy_context) );
sha4_starts( &ctx->accumulator, 0 );
#if defined(POLARSSL_HAVEGE_C)
havege_init( &ctx->havege_data );
#endif
#if !defined(POLARSSL_NO_DEFAULT_ENTROPY_SOURCES)
#if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
entropy_add_source( ctx, platform_entropy_poll, NULL,
ENTROPY_MIN_PLATFORM );
#endif
#if defined(POLARSSL_TIMING_C)
entropy_add_source( ctx, hardclock_poll, NULL, ENTROPY_MIN_HARDCLOCK );
#endif
#if defined(POLARSSL_HAVEGE_C)
entropy_add_source( ctx, havege_poll, &ctx->havege_data,
ENTROPY_MIN_HAVEGE );
#endif
#endif /* POLARSSL_NO_DEFAULT_ENTROPY_SOURCES */
}
int entropy_add_source( entropy_context *ctx,
f_source_ptr f_source, void *p_source,
size_t threshold )
{
int index = ctx->source_count;
if( index >= ENTROPY_MAX_SOURCES )
return( POLARSSL_ERR_ENTROPY_MAX_SOURCES );
ctx->source[index].f_source = f_source;
ctx->source[index].p_source = p_source;
ctx->source[index].threshold = threshold;
ctx->source_count++;
return( 0 );
}
/*
* Entropy accumulator update
*/
int entropy_update( entropy_context *ctx, unsigned char source_id,
const unsigned char *data, size_t len )
{
unsigned char header[2];
unsigned char tmp[ENTROPY_BLOCK_SIZE];
size_t use_len = len;
const unsigned char *p = data;
if( use_len > ENTROPY_BLOCK_SIZE )
{
sha4( data, len, tmp, 0 );
p = tmp;
use_len = ENTROPY_BLOCK_SIZE;
}
header[0] = source_id;
header[1] = use_len & 0xFF;
sha4_update( &ctx->accumulator, header, 2 );
sha4_update( &ctx->accumulator, p, use_len );
return( 0 );
}
int entropy_update_manual( entropy_context *ctx,
const unsigned char *data, size_t len )
{
return entropy_update( ctx, ENTROPY_SOURCE_MANUAL, data, len );
}
/*
* Run through the different sources to add entropy to our accumulator
*/
int entropy_gather( entropy_context *ctx )
{
int ret, i;
unsigned char buf[ENTROPY_MAX_GATHER];
size_t olen;
if( ctx->source_count == 0 )
return( POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED );
/*
* Run through our entropy sources
*/
for( i = 0; i < ctx->source_count; i++ )
{
olen = 0;
if ( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 )
{
return( ret );
}
/*
* Add if we actually gathered something
*/
if( olen > 0 )
{
entropy_update( ctx, (unsigned char) i, buf, olen );
ctx->source[i].size += olen;
}
}
return( 0 );
}
int entropy_func( void *data, unsigned char *output, size_t len )
{
int ret, count = 0, i, reached;
entropy_context *ctx = (entropy_context *) data;
unsigned char buf[ENTROPY_BLOCK_SIZE];
if( len > ENTROPY_BLOCK_SIZE )
return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
/*
* Always gather extra entropy before a call
*/
do
{
if( count++ > ENTROPY_MAX_LOOP )
return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED );
if( ( ret = entropy_gather( ctx ) ) != 0 )
return( ret );
reached = 0;
for( i = 0; i < ctx->source_count; i++ )
if( ctx->source[i].size >= ctx->source[i].threshold )
reached++;
}
while( reached != ctx->source_count );
memset( buf, 0, ENTROPY_BLOCK_SIZE );
sha4_finish( &ctx->accumulator, buf );
/*
* Perform second SHA-512 on entropy
*/
sha4( buf, ENTROPY_BLOCK_SIZE, buf, 0 );
/*
* Reset accumulator and counters and recycle existing entropy
*/
memset( &ctx->accumulator, 0, sizeof( sha4_context ) );
sha4_starts( &ctx->accumulator, 0 );
sha4_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE );
for( i = 0; i < ctx->source_count; i++ )
ctx->source[i].size = 0;
memcpy( output, buf, len );
return( 0 );
}
#endif
+153
View File
@@ -0,0 +1,153 @@
/**
* \file entropy.h
*
* \brief Entropy accumulator implementation
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_ENTROPY_H
#define POLARSSL_ENTROPY_H
#include <string.h>
#include "polarssl/config.h"
#include "polarssl/sha4.h"
#if defined(POLARSSL_HAVEGE_C)
#include "polarssl/havege.h"
#endif
#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */
#define POLARSSL_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */
#define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */
#if !defined(POLARSSL_CONFIG_OPTIONS)
#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
#endif /* !POLARSSL_CONFIG_OPTIONS */
#define ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
#define ENTROPY_SOURCE_MANUAL ENTROPY_MAX_SOURCES
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Entropy poll callback pointer
*
* \param data Callback-specific data pointer
* \param output Data to fill
* \param len Maximum size to provide
* \param olen The actual amount of bytes put into the buffer (Can be 0)
*
* \return 0 if no critical failures occurred,
* POLARSSL_ERR_ENTROPY_SOURCE_FAILED otherwise
*/
typedef int (*f_source_ptr)(void *, unsigned char *, size_t, size_t *);
/**
* \brief Entropy source state
*/
typedef struct
{
f_source_ptr f_source; /**< The entropy source callback */
void * p_source; /**< The callback data pointer */
size_t size; /**< Amount received */
size_t threshold; /**< Minimum level required before release */
}
source_state;
/**
* \brief Entropy context structure
*/
typedef struct
{
sha4_context accumulator;
int source_count;
source_state source[ENTROPY_MAX_SOURCES];
#if defined(POLARSSL_HAVEGE_C)
havege_state havege_data;
#endif
}
entropy_context;
/**
* \brief Initialize the context
*
* \param ctx Entropy context to initialize
*/
void entropy_init( entropy_context *ctx );
/**
* \brief Adds an entropy source to poll
*
* \param ctx Entropy context
* \param f_source Entropy function
* \param p_source Function data
* \param threshold Minimum required from source before entropy is released
* ( with entropy_func() )
*
* \return 0 if successful or POLARSSL_ERR_ENTROPY_MAX_SOURCES
*/
int entropy_add_source( entropy_context *ctx,
f_source_ptr f_source, void *p_source,
size_t threshold );
/**
* \brief Trigger an extra gather poll for the accumulator
*
* \param ctx Entropy context
*
* \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED
*/
int entropy_gather( entropy_context *ctx );
/**
* \brief Retrieve entropy from the accumulator (Max ENTROPY_BLOCK_SIZE)
*
* \param data Entropy context
* \param output Buffer to fill
* \param len Length of buffer
*
* \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED
*/
int entropy_func( void *data, unsigned char *output, size_t len );
/**
* \brief Add data to the accumulator manually
*
* \param ctx Entropy context
* \param data Data to add
* \param len Length of data
*
* \return 0 if successful
*/
int entropy_update_manual( entropy_context *ctx,
const unsigned char *data, size_t len );
#ifdef __cplusplus
}
#endif
#endif /* entropy.h */
+136
View File
@@ -0,0 +1,136 @@
/*
* Platform-specific and custom entropy polling functions
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_ENTROPY_C)
#include "polarssl/entropy.h"
#include "polarssl/entropy_poll.h"
#if defined(POLARSSL_TIMING_C)
#include "polarssl/timing.h"
#endif
#if defined(POLARSSL_HAVEGE_C)
#include "polarssl/havege.h"
#endif
#if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
#if defined(_WIN32)
#if !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0400
#endif
#include <windows.h>
#include <wincrypt.h>
int platform_entropy_poll( void *data, unsigned char *output, size_t len,
size_t *olen )
{
HCRYPTPROV provider;
((void) data);
*olen = 0;
if( CryptAcquireContext( &provider, NULL, NULL,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
{
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
}
if( CryptGenRandom( provider, len, output ) == FALSE )
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
CryptReleaseContext( provider, 0 );
*olen = len;
return( 0 );
}
#else
#include <stdio.h>
int platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
FILE *file;
size_t ret;
((void) data);
*olen = 0;
file = fopen( "/dev/urandom", "rb" );
if( file == NULL )
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
ret = fread( output, 1, len, file );
if( ret != len )
{
fclose( file );
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
}
fclose( file );
*olen = len;
return( 0 );
}
#endif
#endif
#if defined(POLARSSL_TIMING_C)
int hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
unsigned long timer = hardclock();
((void) data);
*olen = 0;
if( len < sizeof(unsigned long) )
return( 0 );
memcpy( output, &timer, sizeof(unsigned long) );
*olen = sizeof(unsigned long);
return( 0 );
}
#endif
#if defined(POLARSSL_HAVEGE_C)
int havege_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
havege_state *hs = (havege_state *) data;
*olen = 0;
if( havege_random( hs, output, len ) != 0 )
return POLARSSL_ERR_ENTROPY_SOURCE_FAILED;
*olen = len;
return( 0 );
}
#endif
#endif /* POLARSSL_ENTROPY_C */
+75
View File
@@ -0,0 +1,75 @@
/**
* \file entropy_poll.h
*
* \brief Platform-specific and custom entropy polling functions
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_ENTROPY_POLL_H
#define POLARSSL_ENTROPY_POLL_H
#include <string.h>
#include "polarssl/config.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Default thresholds for built-in sources
*/
#define ENTROPY_MIN_PLATFORM 128 /**< Minimum for platform source */
#define ENTROPY_MIN_HAVEGE 128 /**< Minimum for HAVEGE */
#define ENTROPY_MIN_HARDCLOCK 32 /**< Minimum for hardclock() */
#if !defined(POLARSSL_NO_PLATFORM_ENTROPY)
/**
* \brief Platform-specific entropy poll callback
*/
int platform_entropy_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(POLARSSL_HAVEGE_C)
/**
* \brief HAVEGE based entropy poll callback
*
* Requires an HAVEGE state as its data pointer.
*/
int havege_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#if defined(POLARSSL_TIMING_C)
/**
* \brief hardclock-based entropy poll callback
*/
int hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen );
#endif
#ifdef __cplusplus
}
#endif
#endif /* entropy_poll.h */
+612
View File
@@ -0,0 +1,612 @@
/*
* Error message information
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_ERROR_C)
#include "polarssl/error.h"
#if defined(POLARSSL_AES_C)
#include "polarssl/aes.h"
#endif
#if defined(POLARSSL_BASE64_C)
#include "polarssl/base64.h"
#endif
#if defined(POLARSSL_BIGNUM_C)
#include "polarssl/bignum.h"
#endif
#if defined(POLARSSL_BLOWFISH_C)
#include "polarssl/blowfish.h"
#endif
#if defined(POLARSSL_CAMELLIA_C)
#include "polarssl/camellia.h"
#endif
#if defined(POLARSSL_CIPHER_C)
#include "polarssl/cipher.h"
#endif
#if defined(POLARSSL_CTR_DRBG_C)
#include "polarssl/ctr_drbg.h"
#endif
#if defined(POLARSSL_DES_C)
#include "polarssl/des.h"
#endif
#if defined(POLARSSL_DHM_C)
#include "polarssl/dhm.h"
#endif
#if defined(POLARSSL_ENTROPY_C)
#include "polarssl/entropy.h"
#endif
#if defined(POLARSSL_GCM_C)
#include "polarssl/gcm.h"
#endif
#if defined(POLARSSL_MD_C)
#include "polarssl/md.h"
#endif
#if defined(POLARSSL_MD2_C)
#include "polarssl/md2.h"
#endif
#if defined(POLARSSL_MD4_C)
#include "polarssl/md4.h"
#endif
#if defined(POLARSSL_MD5_C)
#include "polarssl/md5.h"
#endif
#if defined(POLARSSL_NET_C)
#include "polarssl/net.h"
#endif
#if defined(POLARSSL_PADLOCK_C)
#include "polarssl/padlock.h"
#endif
#if defined(POLARSSL_PBKDF2_C)
#include "polarssl/pbkdf2.h"
#endif
#if defined(POLARSSL_PEM_C)
#include "polarssl/pem.h"
#endif
#if defined(POLARSSL_PKCS12_C)
#include "polarssl/pkcs12.h"
#endif
#if defined(POLARSSL_PKCS5_C)
#include "polarssl/pkcs5.h"
#endif
#if defined(POLARSSL_RSA_C)
#include "polarssl/rsa.h"
#endif
#if defined(POLARSSL_SHA1_C)
#include "polarssl/sha1.h"
#endif
#if defined(POLARSSL_SHA2_C)
#include "polarssl/sha2.h"
#endif
#if defined(POLARSSL_SHA4_C)
#include "polarssl/sha4.h"
#endif
#if defined(POLARSSL_SSL_TLS_C)
#include "polarssl/ssl.h"
#endif
#if defined(POLARSSL_X509_PARSE_C)
#include "polarssl/x509.h"
#endif
#if defined(POLARSSL_XTEA_C)
#include "polarssl/xtea.h"
#endif
#include <string.h>
#if defined _MSC_VER && !defined snprintf
#define snprintf _snprintf
#endif
void error_strerror( int ret, char *buf, size_t buflen )
{
size_t len;
int use_ret;
memset( buf, 0x00, buflen );
if( ret < 0 )
ret = -ret;
if( ret & 0xFF80 )
{
use_ret = ret & 0xFF80;
// High level error codes
//
#if defined(POLARSSL_CIPHER_C)
if( use_ret == -(POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
if( use_ret == -(POLARSSL_ERR_CIPHER_BAD_INPUT_DATA) )
snprintf( buf, buflen, "CIPHER - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_CIPHER_ALLOC_FAILED) )
snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
if( use_ret == -(POLARSSL_ERR_CIPHER_INVALID_PADDING) )
snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
if( use_ret == -(POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
#endif /* POLARSSL_CIPHER_C */
#if defined(POLARSSL_DHM_C)
if( use_ret == -(POLARSSL_ERR_DHM_BAD_INPUT_DATA) )
snprintf( buf, buflen, "DHM - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_DHM_READ_PARAMS_FAILED) )
snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
if( use_ret == -(POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED) )
snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
if( use_ret == -(POLARSSL_ERR_DHM_READ_PUBLIC_FAILED) )
snprintf( buf, buflen, "DHM - Reading of the public values failed" );
if( use_ret == -(POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED) )
snprintf( buf, buflen, "DHM - Making of the public value failed" );
if( use_ret == -(POLARSSL_ERR_DHM_CALC_SECRET_FAILED) )
snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
#endif /* POLARSSL_DHM_C */
#if defined(POLARSSL_MD_C)
if( use_ret == -(POLARSSL_ERR_MD_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "MD - The selected feature is not available" );
if( use_ret == -(POLARSSL_ERR_MD_BAD_INPUT_DATA) )
snprintf( buf, buflen, "MD - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_MD_ALLOC_FAILED) )
snprintf( buf, buflen, "MD - Failed to allocate memory" );
if( use_ret == -(POLARSSL_ERR_MD_FILE_IO_ERROR) )
snprintf( buf, buflen, "MD - Opening or reading of file failed" );
#endif /* POLARSSL_MD_C */
#if defined(POLARSSL_PEM_C)
if( use_ret == -(POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
snprintf( buf, buflen, "PEM - No PEM header or footer found" );
if( use_ret == -(POLARSSL_ERR_PEM_INVALID_DATA) )
snprintf( buf, buflen, "PEM - PEM string is not as expected" );
if( use_ret == -(POLARSSL_ERR_PEM_MALLOC_FAILED) )
snprintf( buf, buflen, "PEM - Failed to allocate memory" );
if( use_ret == -(POLARSSL_ERR_PEM_INVALID_ENC_IV) )
snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
if( use_ret == -(POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG) )
snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
if( use_ret == -(POLARSSL_ERR_PEM_PASSWORD_REQUIRED) )
snprintf( buf, buflen, "PEM - Private key password can't be empty" );
if( use_ret == -(POLARSSL_ERR_PEM_PASSWORD_MISMATCH) )
snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
if( use_ret == -(POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
if( use_ret == -(POLARSSL_ERR_PEM_BAD_INPUT_DATA) )
snprintf( buf, buflen, "PEM - Bad input parameters to function" );
#endif /* POLARSSL_PEM_C */
#if defined(POLARSSL_PKCS12_C)
if( use_ret == -(POLARSSL_ERR_PKCS12_BAD_INPUT_DATA) )
snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
if( use_ret == -(POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT) )
snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
if( use_ret == -(POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH) )
snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
#endif /* POLARSSL_PKCS12_C */
#if defined(POLARSSL_PKCS5_C)
if( use_ret == -(POLARSSL_ERR_PKCS5_BAD_INPUT_DATA) )
snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_PKCS5_INVALID_FORMAT) )
snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
if( use_ret == -(POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
if( use_ret == -(POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH) )
snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
#endif /* POLARSSL_PKCS5_C */
#if defined(POLARSSL_RSA_C)
if( use_ret == -(POLARSSL_ERR_RSA_BAD_INPUT_DATA) )
snprintf( buf, buflen, "RSA - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_RSA_INVALID_PADDING) )
snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
if( use_ret == -(POLARSSL_ERR_RSA_KEY_GEN_FAILED) )
snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
if( use_ret == -(POLARSSL_ERR_RSA_KEY_CHECK_FAILED) )
snprintf( buf, buflen, "RSA - Key failed to pass the libraries validity check" );
if( use_ret == -(POLARSSL_ERR_RSA_PUBLIC_FAILED) )
snprintf( buf, buflen, "RSA - The public key operation failed" );
if( use_ret == -(POLARSSL_ERR_RSA_PRIVATE_FAILED) )
snprintf( buf, buflen, "RSA - The private key operation failed" );
if( use_ret == -(POLARSSL_ERR_RSA_VERIFY_FAILED) )
snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
if( use_ret == -(POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE) )
snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
if( use_ret == -(POLARSSL_ERR_RSA_RNG_FAILED) )
snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_SSL_TLS_C)
if( use_ret == -(POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "SSL - The requested feature is not available" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_INPUT_DATA) )
snprintf( buf, buflen, "SSL - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_SSL_INVALID_MAC) )
snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
if( use_ret == -(POLARSSL_ERR_SSL_INVALID_RECORD) )
snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
if( use_ret == -(POLARSSL_ERR_SSL_CONN_EOF) )
snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
if( use_ret == -(POLARSSL_ERR_SSL_UNKNOWN_CIPHER) )
snprintf( buf, buflen, "SSL - An unknown cipher was received" );
if( use_ret == -(POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN) )
snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
if( use_ret == -(POLARSSL_ERR_SSL_NO_SESSION_FOUND) )
snprintf( buf, buflen, "SSL - No session to recover was found" );
if( use_ret == -(POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE) )
snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
if( use_ret == -(POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE) )
snprintf( buf, buflen, "SSL - DESCRIPTION MISSING" );
if( use_ret == -(POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED) )
snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
if( use_ret == -(POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED) )
snprintf( buf, buflen, "SSL - The own private key is not set, but needed" );
if( use_ret == -(POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED) )
snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
if( use_ret == -(POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE) )
snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
if( use_ret == -(POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE) )
{
snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
return;
}
if( use_ret == -(POLARSSL_ERR_SSL_PEER_VERIFY_FAILED) )
snprintf( buf, buflen, "SSL - Verification of our peer failed" );
if( use_ret == -(POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) )
snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO) )
snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO) )
snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE) )
snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_RP) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM Read Public" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_CS) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM Calculate Secret" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_FINISHED) )
snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_MALLOC_FAILED) )
snprintf( buf, buflen, "SSL - Memory allocation failed" );
if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FAILED) )
snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
if( use_ret == -(POLARSSL_ERR_SSL_COMPRESSION_FAILED) )
snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
#endif /* POLARSSL_SSL_TLS_C */
#if defined(POLARSSL_X509_PARSE_C)
if( use_ret == -(POLARSSL_ERR_X509_FEATURE_UNAVAILABLE) )
snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_PEM) )
snprintf( buf, buflen, "X509 - The PEM-encoded certificate contains invalid elements, e.g. invalid character" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_FORMAT) )
snprintf( buf, buflen, "X509 - The certificate format is invalid, e.g. different type expected" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_VERSION) )
snprintf( buf, buflen, "X509 - The certificate version element is invalid" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_SERIAL) )
snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_ALG) )
snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_NAME) )
snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_DATE) )
snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_PUBKEY) )
snprintf( buf, buflen, "X509 - The pubkey tag or value is invalid (only RSA is supported)" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE) )
snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS) )
snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION) )
snprintf( buf, buflen, "X509 - Certificate or CRL has an unsupported version number" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG) )
snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
if( use_ret == -(POLARSSL_ERR_X509_UNKNOWN_PK_ALG) )
snprintf( buf, buflen, "X509 - Key algorithm is unsupported (only RSA is supported)" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_SIG_MISMATCH) )
snprintf( buf, buflen, "X509 - Certificate signature algorithms do not match. (see \\c ::x509_cert sig_oid)" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_VERIFY_FAILED) )
snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
if( use_ret == -(POLARSSL_ERR_X509_KEY_INVALID_VERSION) )
snprintf( buf, buflen, "X509 - Unsupported RSA key version" );
if( use_ret == -(POLARSSL_ERR_X509_KEY_INVALID_FORMAT) )
snprintf( buf, buflen, "X509 - Invalid RSA key tag or value" );
if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT) )
snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
if( use_ret == -(POLARSSL_ERR_X509_INVALID_INPUT) )
snprintf( buf, buflen, "X509 - Input invalid" );
if( use_ret == -(POLARSSL_ERR_X509_MALLOC_FAILED) )
snprintf( buf, buflen, "X509 - Allocation of memory failed" );
if( use_ret == -(POLARSSL_ERR_X509_FILE_IO_ERROR) )
snprintf( buf, buflen, "X509 - Read/write of file failed" );
if( use_ret == -(POLARSSL_ERR_X509_PASSWORD_REQUIRED) )
snprintf( buf, buflen, "X509 - Private key password can't be empty" );
if( use_ret == -(POLARSSL_ERR_X509_PASSWORD_MISMATCH) )
snprintf( buf, buflen, "X509 - Given private key password does not allow for correct decryption" );
#endif /* POLARSSL_X509_PARSE_C */
if( strlen( buf ) == 0 )
snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
use_ret = ret & ~0xFF80;
if( use_ret == 0 )
return;
// If high level code is present, make a concatenation between both
// error strings.
//
len = strlen( buf );
if( len > 0 )
{
if( buflen - len < 5 )
return;
snprintf( buf + len, buflen - len, " : " );
buf += len + 3;
buflen -= len + 3;
}
// Low level error codes
//
#if defined(POLARSSL_AES_C)
if( use_ret == -(POLARSSL_ERR_AES_INVALID_KEY_LENGTH) )
snprintf( buf, buflen, "AES - Invalid key length" );
if( use_ret == -(POLARSSL_ERR_AES_INVALID_INPUT_LENGTH) )
snprintf( buf, buflen, "AES - Invalid data input length" );
#endif /* POLARSSL_AES_C */
#if defined(POLARSSL_ASN1_PARSE_C)
if( use_ret == -(POLARSSL_ERR_ASN1_OUT_OF_DATA) )
snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
if( use_ret == -(POLARSSL_ERR_ASN1_UNEXPECTED_TAG) )
snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
if( use_ret == -(POLARSSL_ERR_ASN1_INVALID_LENGTH) )
snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
if( use_ret == -(POLARSSL_ERR_ASN1_LENGTH_MISMATCH) )
snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
if( use_ret == -(POLARSSL_ERR_ASN1_INVALID_DATA) )
snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
if( use_ret == -(POLARSSL_ERR_ASN1_MALLOC_FAILED) )
snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
if( use_ret == -(POLARSSL_ERR_ASN1_BUF_TOO_SMALL) )
snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
#endif /* POLARSSL_ASN1_PARSE_C */
#if defined(POLARSSL_BASE64_C)
if( use_ret == -(POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) )
snprintf( buf, buflen, "BASE64 - Output buffer too small" );
if( use_ret == -(POLARSSL_ERR_BASE64_INVALID_CHARACTER) )
snprintf( buf, buflen, "BASE64 - Invalid character in input" );
#endif /* POLARSSL_BASE64_C */
#if defined(POLARSSL_BIGNUM_C)
if( use_ret == -(POLARSSL_ERR_MPI_FILE_IO_ERROR) )
snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
if( use_ret == -(POLARSSL_ERR_MPI_BAD_INPUT_DATA) )
snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_MPI_INVALID_CHARACTER) )
snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
if( use_ret == -(POLARSSL_ERR_MPI_BUFFER_TOO_SMALL) )
snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
if( use_ret == -(POLARSSL_ERR_MPI_NEGATIVE_VALUE) )
snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
if( use_ret == -(POLARSSL_ERR_MPI_DIVISION_BY_ZERO) )
snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
if( use_ret == -(POLARSSL_ERR_MPI_NOT_ACCEPTABLE) )
snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
if( use_ret == -(POLARSSL_ERR_MPI_MALLOC_FAILED) )
snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
#endif /* POLARSSL_BIGNUM_C */
#if defined(POLARSSL_BLOWFISH_C)
if( use_ret == -(POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
if( use_ret == -(POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
#endif /* POLARSSL_BLOWFISH_C */
#if defined(POLARSSL_CAMELLIA_C)
if( use_ret == -(POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH) )
snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
if( use_ret == -(POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
#endif /* POLARSSL_CAMELLIA_C */
#if defined(POLARSSL_CTR_DRBG_C)
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" );
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG) )
snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" );
if( use_ret == -(POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR) )
snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" );
#endif /* POLARSSL_CTR_DRBG_C */
#if defined(POLARSSL_DES_C)
if( use_ret == -(POLARSSL_ERR_DES_INVALID_INPUT_LENGTH) )
snprintf( buf, buflen, "DES - The data input has an invalid length" );
#endif /* POLARSSL_DES_C */
#if defined(POLARSSL_ENTROPY_C)
if( use_ret == -(POLARSSL_ERR_ENTROPY_SOURCE_FAILED) )
snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
if( use_ret == -(POLARSSL_ERR_ENTROPY_MAX_SOURCES) )
snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
if( use_ret == -(POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED) )
snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
#endif /* POLARSSL_ENTROPY_C */
#if defined(POLARSSL_GCM_C)
if( use_ret == -(POLARSSL_ERR_GCM_AUTH_FAILED) )
snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
if( use_ret == -(POLARSSL_ERR_GCM_BAD_INPUT) )
snprintf( buf, buflen, "GCM - Bad input parameters to function" );
#endif /* POLARSSL_GCM_C */
#if defined(POLARSSL_MD2_C)
if( use_ret == -(POLARSSL_ERR_MD2_FILE_IO_ERROR) )
snprintf( buf, buflen, "MD2 - Read/write error in file" );
#endif /* POLARSSL_MD2_C */
#if defined(POLARSSL_MD4_C)
if( use_ret == -(POLARSSL_ERR_MD4_FILE_IO_ERROR) )
snprintf( buf, buflen, "MD4 - Read/write error in file" );
#endif /* POLARSSL_MD4_C */
#if defined(POLARSSL_MD5_C)
if( use_ret == -(POLARSSL_ERR_MD5_FILE_IO_ERROR) )
snprintf( buf, buflen, "MD5 - Read/write error in file" );
#endif /* POLARSSL_MD5_C */
#if defined(POLARSSL_NET_C)
if( use_ret == -(POLARSSL_ERR_NET_UNKNOWN_HOST) )
snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
if( use_ret == -(POLARSSL_ERR_NET_SOCKET_FAILED) )
snprintf( buf, buflen, "NET - Failed to open a socket" );
if( use_ret == -(POLARSSL_ERR_NET_CONNECT_FAILED) )
snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
if( use_ret == -(POLARSSL_ERR_NET_BIND_FAILED) )
snprintf( buf, buflen, "NET - Binding of the socket failed" );
if( use_ret == -(POLARSSL_ERR_NET_LISTEN_FAILED) )
snprintf( buf, buflen, "NET - Could not listen on the socket" );
if( use_ret == -(POLARSSL_ERR_NET_ACCEPT_FAILED) )
snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
if( use_ret == -(POLARSSL_ERR_NET_RECV_FAILED) )
snprintf( buf, buflen, "NET - Reading information from the socket failed" );
if( use_ret == -(POLARSSL_ERR_NET_SEND_FAILED) )
snprintf( buf, buflen, "NET - Sending information through the socket failed" );
if( use_ret == -(POLARSSL_ERR_NET_CONN_RESET) )
snprintf( buf, buflen, "NET - Connection was reset by peer" );
if( use_ret == -(POLARSSL_ERR_NET_WANT_READ) )
snprintf( buf, buflen, "NET - Connection requires a read call" );
if( use_ret == -(POLARSSL_ERR_NET_WANT_WRITE) )
snprintf( buf, buflen, "NET - Connection requires a write call" );
#endif /* POLARSSL_NET_C */
#if defined(POLARSSL_PADLOCK_C)
if( use_ret == -(POLARSSL_ERR_PADLOCK_DATA_MISALIGNED) )
snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
#endif /* POLARSSL_PADLOCK_C */
#if defined(POLARSSL_PBKDF2_C)
if( use_ret == -(POLARSSL_ERR_PBKDF2_BAD_INPUT_DATA) )
snprintf( buf, buflen, "PBKDF2 - Bad input parameters to function" );
#endif /* POLARSSL_PBKDF2_C */
#if defined(POLARSSL_SHA1_C)
if( use_ret == -(POLARSSL_ERR_SHA1_FILE_IO_ERROR) )
snprintf( buf, buflen, "SHA1 - Read/write error in file" );
#endif /* POLARSSL_SHA1_C */
#if defined(POLARSSL_SHA2_C)
if( use_ret == -(POLARSSL_ERR_SHA2_FILE_IO_ERROR) )
snprintf( buf, buflen, "SHA2 - Read/write error in file" );
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_SHA4_C)
if( use_ret == -(POLARSSL_ERR_SHA4_FILE_IO_ERROR) )
snprintf( buf, buflen, "SHA4 - Read/write error in file" );
#endif /* POLARSSL_SHA4_C */
#if defined(POLARSSL_XTEA_C)
if( use_ret == -(POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH) )
snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
#endif /* POLARSSL_XTEA_C */
if( strlen( buf ) != 0 )
return;
snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
#else /* POLARSSL_ERROR_C */
#if defined(POLARSSL_ERROR_STRERROR_DUMMY)
#include <string.h>
/*
* Provide an non-function in case POLARSSL_ERROR_C is not defined
*/
void error_strerror( int ret, char *buf, size_t buflen )
{
((void) ret);
if( buflen > 0 )
buf[0] = '\0';
}
#endif /* POLARSSL_ERROR_STRERROR_DUMMY */
#endif /* POLARSSL_ERROR_C */
+108
View File
@@ -0,0 +1,108 @@
/**
* \file error.h
*
* \brief Error to string translation
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_ERROR_H
#define POLARSSL_ERROR_H
#include <string.h>
/**
* Error code layout.
*
* Currently we try to keep all error codes within the negative space of 16
* bytes signed integers to support all platforms (-0x0000 - -0x8000). In
* addition we'd like to give two layers of information on the error if
* possible.
*
* For that purpose the error codes are segmented in the following manner:
*
* 16 bit error code bit-segmentation
*
* 1 bit - Intentionally not used
* 3 bits - High level module ID
* 5 bits - Module-dependent error code
* 6 bits - Low level module errors
* 1 bit - Intentionally not used
*
* Low-level module errors (0x007E-0x0002)
*
* Module Nr Codes assigned
* MPI 7 0x0002-0x0010
* GCM 2 0x0012-0x0014
* BLOWFISH 2 0x0016-0x0018
* AES 2 0x0020-0x0022
* CAMELLIA 2 0x0024-0x0026
* XTEA 1 0x0028-0x0028
* BASE64 2 0x002A-0x002C
* PADLOCK 1 0x0030-0x0030
* DES 1 0x0032-0x0032
* CTR_DBRG 3 0x0034-0x003A
* ENTROPY 3 0x003C-0x0040
* NET 11 0x0042-0x0056
* ASN1 7 0x0060-0x006C
* MD2 1 0x0070-0x0070
* MD4 1 0x0072-0x0072
* MD5 1 0x0074-0x0074
* SHA1 1 0x0076-0x0076
* SHA2 1 0x0078-0x0078
* SHA4 1 0x007A-0x007A
*
* High-level module nr (3 bits - 0x1...-0x8...)
* Name ID Nr of Errors
* PEM 1 9
* PKCS#12 1 4 (Started from top)
* X509 2 23
* DHM 3 6
* PKCS5 3 4 (Started from top)
* RSA 4 9
* MD 5 4
* CIPHER 6 5
* SSL 6 2 (Started from top)
* SSL 7 31
*
* Module dependent error code (5 bits 0x.08.-0x.F8.)
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Translate a PolarSSL error code into a string representation,
* Result is truncated if necessary and always includes a terminating
* null byte.
*
* \param errnum error code
* \param buffer buffer to place representation in
* \param buflen length of the buffer
*/
void error_strerror( int errnum, char *buffer, size_t buflen );
#ifdef __cplusplus
}
#endif
#endif /* error.h */
+621
View File
@@ -0,0 +1,621 @@
/*
* NIST SP800-38D compliant GCM implementation
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_GCM_C)
#include "polarssl/gcm.h"
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_BE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 3] = (unsigned char) ( (n) ); \
}
#endif
static void gcm_gen_table( gcm_context *ctx )
{
int i, j;
uint64_t hi, lo;
uint64_t vl, vh;
unsigned char h[16];
memset( h, 0, 16 );
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, h, h );
ctx->HH[0] = 0;
ctx->HL[0] = 0;
GET_UINT32_BE( hi, h, 0 );
GET_UINT32_BE( lo, h, 4 );
vh = (uint64_t) hi << 32 | lo;
GET_UINT32_BE( hi, h, 8 );
GET_UINT32_BE( lo, h, 12 );
vl = (uint64_t) hi << 32 | lo;
ctx->HL[8] = vl;
ctx->HH[8] = vh;
for( i = 4; i > 0; i >>= 1 )
{
uint32_t T = ( vl & 1 ) * 0xe1000000U;
vl = ( vh << 63 ) | ( vl >> 1 );
vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
ctx->HL[i] = vl;
ctx->HH[i] = vh;
}
for (i = 2; i < 16; i <<= 1 )
{
uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
vh = *HiH;
vl = *HiL;
for( j = 1; j < i; j++ )
{
HiH[j] = vh ^ ctx->HH[j];
HiL[j] = vl ^ ctx->HL[j];
}
}
}
int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize )
{
int ret;
memset( ctx, 0, sizeof(gcm_context) );
if( ( ret = aes_setkey_enc( &ctx->aes_ctx, key, keysize ) ) != 0 )
return( ret );
gcm_gen_table( ctx );
return( 0 );
}
static const uint64_t last4[16] =
{
0x0000, 0x1c20, 0x3840, 0x2460,
0x7080, 0x6ca0, 0x48c0, 0x54e0,
0xe100, 0xfd20, 0xd940, 0xc560,
0x9180, 0x8da0, 0xa9c0, 0xb5e0
};
void gcm_mult( gcm_context *ctx, const unsigned char x[16], unsigned char output[16] )
{
int i = 0;
unsigned char z[16];
unsigned char lo, hi, rem;
uint64_t zh, zl;
memset( z, 0x00, 16 );
lo = x[15] & 0xf;
hi = x[15] >> 4;
zh = ctx->HH[lo];
zl = ctx->HL[lo];
for( i = 15; i >= 0; i-- )
{
lo = x[i] & 0xf;
hi = x[i] >> 4;
if( i != 15 )
{
rem = (unsigned char) zl & 0xf;
zl = ( zh << 60 ) | ( zl >> 4 );
zh = ( zh >> 4 );
zh ^= (uint64_t) last4[rem] << 48;
zh ^= ctx->HH[lo];
zl ^= ctx->HL[lo];
}
rem = (unsigned char) zl & 0xf;
zl = ( zh << 60 ) | ( zl >> 4 );
zh = ( zh >> 4 );
zh ^= (uint64_t) last4[rem] << 48;
zh ^= ctx->HH[hi];
zl ^= ctx->HL[hi];
}
PUT_UINT32_BE( zh >> 32, output, 0 );
PUT_UINT32_BE( zh, output, 4 );
PUT_UINT32_BE( zl >> 32, output, 8 );
PUT_UINT32_BE( zl, output, 12 );
}
int gcm_crypt_and_tag( gcm_context *ctx,
int mode,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
unsigned char *tag )
{
unsigned char y[16];
unsigned char ectr[16];
unsigned char buf[16];
unsigned char work_buf[16];
size_t i;
const unsigned char *p;
unsigned char *out_p = output;
size_t use_len;
uint64_t orig_len = length * 8;
uint64_t orig_add_len = add_len * 8;
memset( y, 0x00, 16 );
memset( work_buf, 0x00, 16 );
memset( tag, 0x00, tag_len );
memset( buf, 0x00, 16 );
if( ( mode == GCM_DECRYPT && output <= input && ( input - output ) < 8 ) ||
( output > input && (size_t) ( output - input ) < length ) )
{
return( POLARSSL_ERR_GCM_BAD_INPUT );
}
if( iv_len == 12 )
{
memcpy( y, iv, iv_len );
y[15] = 1;
}
else
{
memset( work_buf, 0x00, 16 );
PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
p = iv;
while( iv_len > 0 )
{
use_len = ( iv_len < 16 ) ? iv_len : 16;
for( i = 0; i < use_len; i++ )
y[i] ^= p[i];
gcm_mult( ctx, y, y );
iv_len -= use_len;
p += use_len;
}
for( i = 0; i < 16; i++ )
y[i] ^= work_buf[i];
gcm_mult( ctx, y, y );
}
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
memcpy( tag, ectr, tag_len );
p = add;
while( add_len > 0 )
{
use_len = ( add_len < 16 ) ? add_len : 16;
for( i = 0; i < use_len; i++ )
buf[i] ^= p[i];
gcm_mult( ctx, buf, buf );
add_len -= use_len;
p += use_len;
}
p = input;
while( length > 0 )
{
use_len = ( length < 16 ) ? length : 16;
for( i = 16; i > 12; i-- )
if( ++y[i - 1] != 0 )
break;
aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, y, ectr );
for( i = 0; i < use_len; i++ )
{
out_p[i] = ectr[i] ^ p[i];
if( mode == GCM_ENCRYPT )
buf[i] ^= out_p[i];
else
buf[i] ^= p[i];
}
gcm_mult( ctx, buf, buf );
length -= use_len;
p += use_len;
out_p += use_len;
}
if( orig_len || orig_add_len )
{
memset( work_buf, 0x00, 16 );
PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
for( i = 0; i < 16; i++ )
buf[i] ^= work_buf[i];
gcm_mult( ctx, buf, buf );
for( i = 0; i < tag_len; i++ )
tag[i] ^= buf[i];
}
return( 0 );
}
int gcm_auth_decrypt( gcm_context *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output )
{
unsigned char check_tag[16];
gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, tag_len, check_tag );
if( memcmp( check_tag, tag, tag_len ) == 0 )
return( 0 );
memset( output, 0, length );
return( POLARSSL_ERR_GCM_AUTH_FAILED );
}
#if defined(POLARSSL_SELF_TEST)
#include <stdio.h>
/*
* GCM test vectors from:
*
* http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
*/
#define MAX_TESTS 6
int key_index[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
unsigned char key[MAX_TESTS][32] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
};
size_t iv_len[MAX_TESTS] =
{ 12, 12, 12, 12, 8, 60 };
int iv_index[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 2 };
unsigned char iv[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
0xde, 0xca, 0xf8, 0x88 },
{ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b },
};
size_t add_len[MAX_TESTS] =
{ 0, 0, 0, 20, 20, 20 };
int add_index[MAX_TESTS] =
{ 0, 0, 0, 1, 1, 1 };
unsigned char additional[MAX_TESTS][64] =
{
{ 0x00 },
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xab, 0xad, 0xda, 0xd2 },
};
size_t pt_len[MAX_TESTS] =
{ 0, 16, 64, 60, 60, 60 };
int pt_index[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
unsigned char pt[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
};
unsigned char ct[MAX_TESTS * 3][64] =
{
{ 0x00 },
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91 },
{ 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
0xc2, 0x3f, 0x45, 0x98 },
{ 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
0x4c, 0x34, 0xae, 0xe5 },
{ 0x00 },
{ 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
{ 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
0xcc, 0xda, 0x27, 0x10 },
{ 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
0xa0, 0xf0, 0x62, 0xf7 },
{ 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
0xe9, 0xb7, 0x37, 0x3b },
{ 0x00 },
{ 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
{ 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
0xbc, 0xc9, 0xf6, 0x62 },
{ 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
0xf4, 0x7c, 0x9b, 0x1f },
{ 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
0x44, 0xae, 0x7e, 0x3f },
};
unsigned char tag[MAX_TESTS * 3][16] =
{
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
{ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
{ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
{ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
{ 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
{ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
{ 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
{ 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
{ 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
{ 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
{ 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
{ 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
{ 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
{ 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
{ 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
{ 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
{ 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
{ 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
};
int gcm_self_test( int verbose )
{
gcm_context ctx;
unsigned char buf[64];
unsigned char tag_buf[16];
int i, j, ret;
for( j = 0; j < 3; j++ )
{
int key_len = 128 + 64 * j;
for( i = 0; i < MAX_TESTS; i++ )
{
printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "enc" );
gcm_init( &ctx, key[key_index[i]], key_len );
ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT,
pt_len[i],
iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i],
pt[pt_index[i]], buf, 16, tag_buf );
if( ret != 0 ||
memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
printf( " AES-GCM-%3d #%d (%s): ", key_len, i, "dec" );
gcm_init( &ctx, key[key_index[i]], key_len );
ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT,
pt_len[i],
iv[iv_index[i]], iv_len[i],
additional[add_index[i]], add_len[i],
ct[j * 6 + i], buf, 16, tag_buf );
if( ret != 0 ||
memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
}
printf( "\n" );
return( 0 );
}
#endif
#endif
+147
View File
@@ -0,0 +1,147 @@
/**
* \file gcm.h
*
* \brief Galois/Counter mode for AES
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_GCM_H
#define POLARSSL_GCM_H
#include "polarssl/aes.h"
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT64 uint64_t;
#else
#include <stdint.h>
#endif
#define GCM_ENCRYPT 1
#define GCM_DECRYPT 0
#define POLARSSL_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */
#define POLARSSL_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */
/**
* \brief GCM context structure
*/
typedef struct {
aes_context aes_ctx; /*!< AES context used */
uint64_t HL[16]; /*!< Precalculated HTable */
uint64_t HH[16]; /*!< Precalculated HTable */
}
gcm_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief GCM initialization (encryption)
*
* \param ctx GCM context to be initialized
* \param key encryption key
* \param keysize must be 128, 192 or 256
*
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
*/
int gcm_init( gcm_context *ctx, const unsigned char *key, unsigned int keysize );
/**
* \brief GCM buffer encryption/decryption using AES
*
* \note On encryption, the output buffer can be the same as the input buffer.
* On decryption, the output buffer cannot be the same as input buffer.
* If buffers overlap, the output buffer must trail at least 8 bytes
* behind the input buffer.
*
* \param ctx GCM context
* \param mode GCM_ENCRYPT or GCM_DECRYPT
* \param length length of the input data
* \param iv initialization vector
* \param iv_len length of IV
* \param add additional data
* \param add_len length of additional data
* \param input buffer holding the input data
* \param output buffer for holding the output data
* \param tag_len length of the tag to generate
* \param tag buffer for holding the tag
*
* \return 0 if successful
*/
int gcm_crypt_and_tag( gcm_context *ctx,
int mode,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *input,
unsigned char *output,
size_t tag_len,
unsigned char *tag );
/**
* \brief GCM buffer authenticated decryption using AES
*
* \note On decryption, the output buffer cannot be the same as input buffer.
* If buffers overlap, the output buffer must trail at least 8 bytes
* behind the input buffer.
*
* \param ctx GCM context
* \param length length of the input data
* \param iv initialization vector
* \param iv_len length of IV
* \param add additional data
* \param add_len length of additional data
* \param tag buffer holding the tag
* \param tag_len length of the tag
* \param input buffer holding the input data
* \param output buffer for holding the output data
*
* \return 0 if successful and authenticated,
* POLARSSL_ERR_GCM_AUTH_FAILED if tag does not match
*/
int gcm_auth_decrypt( gcm_context *ctx,
size_t length,
const unsigned char *iv,
size_t iv_len,
const unsigned char *add,
size_t add_len,
const unsigned char *tag,
size_t tag_len,
const unsigned char *input,
unsigned char *output );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int gcm_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* gcm.h */
+231
View File
@@ -0,0 +1,231 @@
/**
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The HAVEGE RNG was designed by Andre Seznec in 2002.
*
* http://www.irisa.fr/caps/projects/hipsor/publi.php
*
* Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
*/
#include "polarssl/config.h"
#if defined(POLARSSL_HAVEGE_C)
#include "polarssl/havege.h"
#include "polarssl/timing.h"
#include <string.h>
#include <time.h>
/* ------------------------------------------------------------------------
* On average, one iteration accesses two 8-word blocks in the havege WALK
* table, and generates 16 words in the RES array.
*
* The data read in the WALK table is updated and permuted after each use.
* The result of the hardware clock counter read is used for this update.
*
* 25 conditional tests are present. The conditional tests are grouped in
* two nested groups of 12 conditional tests and 1 test that controls the
* permutation; on average, there should be 6 tests executed and 3 of them
* should be mispredicted.
* ------------------------------------------------------------------------
*/
#define SWAP(X,Y) { int *T = X; X = Y; Y = T; }
#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST1_LEAVE U1++; }
#define TST2_LEAVE U2++; }
#define ONE_ITERATION \
\
PTEST = PT1 >> 20; \
\
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \
\
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \
\
PTX = (PT1 >> 18) & 7; \
PT1 &= 0x1FFF; \
PT2 &= 0x1FFF; \
CLK = (int) hardclock(); \
\
i = 0; \
A = &WALK[PT1 ]; RES[i++] ^= *A; \
B = &WALK[PT2 ]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \
\
IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \
*A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \
*B = IN ^ U1; \
*C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \
*D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \
\
A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \
B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \
\
if( PTEST & 1 ) SWAP( A, C ); \
\
IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
*A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
*B = IN; CLK = (int) hardclock(); \
*C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
*D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
\
A = &WALK[PT1 ^ 4]; \
B = &WALK[PT2 ^ 1]; \
\
PTEST = PT2 >> 1; \
\
PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \
PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \
PTY = (PT2 >> 10) & 7; \
\
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \
\
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \
\
C = &WALK[PT1 ^ 5]; \
D = &WALK[PT2 ^ 5]; \
\
RES[i++] ^= *A; \
RES[i++] ^= *B; \
RES[i++] ^= *C; \
RES[i++] ^= *D; \
\
IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \
*A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \
*B = IN ^ U2; \
*C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \
*D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \
\
A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \
B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \
C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \
D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \
\
IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \
*A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \
*B = IN; \
*C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \
*D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \
\
PT1 = ( RES[(i - 8) ^ PTX] ^ \
WALK[PT1 ^ PTX ^ 7] ) & (~1); \
PT1 ^= (PT2 ^ 0x10) & 0x10; \
\
for( n++, i = 0; i < 16; i++ ) \
hs->pool[n % COLLECT_SIZE] ^= RES[i];
/*
* Entropy gathering function
*/
static void havege_fill( havege_state *hs )
{
int i, n = 0;
int U1, U2, *A, *B, *C, *D;
int PT1, PT2, *WALK, RES[16];
int PTX, PTY, CLK, PTEST, IN;
WALK = hs->WALK;
PT1 = hs->PT1;
PT2 = hs->PT2;
PTX = U1 = 0;
PTY = U2 = 0;
memset( RES, 0, sizeof( RES ) );
while( n < COLLECT_SIZE * 4 )
{
ONE_ITERATION
ONE_ITERATION
ONE_ITERATION
ONE_ITERATION
}
hs->PT1 = PT1;
hs->PT2 = PT2;
hs->offset[0] = 0;
hs->offset[1] = COLLECT_SIZE / 2;
}
/*
* HAVEGE initialization
*/
void havege_init( havege_state *hs )
{
memset( hs, 0, sizeof( havege_state ) );
havege_fill( hs );
}
/*
* HAVEGE rand function
*/
int havege_random( void *p_rng, unsigned char *buf, size_t len )
{
int val;
size_t use_len;
havege_state *hs = (havege_state *) p_rng;
unsigned char *p = buf;
while( len > 0 )
{
use_len = len;
if( use_len > sizeof(int) )
use_len = sizeof(int);
if( hs->offset[1] >= COLLECT_SIZE )
havege_fill( hs );
val = hs->pool[hs->offset[0]++];
val ^= hs->pool[hs->offset[1]++];
memcpy( p, &val, use_len );
len -= use_len;
p += use_len;
}
return( 0 );
}
#endif
+71
View File
@@ -0,0 +1,71 @@
/**
* \file havege.h
*
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_HAVEGE_H
#define POLARSSL_HAVEGE_H
#include <string.h>
#define COLLECT_SIZE 1024
/**
* \brief HAVEGE state structure
*/
typedef struct
{
int PT1, PT2, offset[2];
int pool[COLLECT_SIZE];
int WALK[8192];
}
havege_state;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief HAVEGE initialization
*
* \param hs HAVEGE state to be initialized
*/
void havege_init( havege_state *hs );
/**
* \brief HAVEGE rand function
*
* \param p_rng A HAVEGE state
* \param output Buffer to fill
* \param len Length of buffer
*
* \return 0
*/
int havege_random( void *p_rng, unsigned char *output, size_t len );
#ifdef __cplusplus
}
#endif
#endif /* havege.h */
+298
View File
@@ -0,0 +1,298 @@
/**
* \file md.c
*
* \brief Generic message digest wrapper for PolarSSL
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD_C)
#include "polarssl/md.h"
#include "polarssl/md_wrap.h"
#include <stdlib.h>
#include <strings.h>
//#if defined _MSC_VER && !defined strcasecmp
//#define strcasecmp _stricmp
//#endif
static const int supported_digests[] = {
#if defined(POLARSSL_MD2_C)
POLARSSL_MD_MD2,
#endif
#if defined(POLARSSL_MD4_C)
POLARSSL_MD_MD4,
#endif
#if defined(POLARSSL_MD5_C)
POLARSSL_MD_MD5,
#endif
#if defined(POLARSSL_SHA1_C)
POLARSSL_MD_SHA1,
#endif
#if defined(POLARSSL_SHA2_C)
POLARSSL_MD_SHA224,
POLARSSL_MD_SHA256,
#endif
#if defined(POLARSSL_SHA4_C)
POLARSSL_MD_SHA384,
POLARSSL_MD_SHA512,
#endif
0
};
const int *md_list( void )
{
return supported_digests;
}
const md_info_t *md_info_from_string( const char *md_name )
{
if( NULL == md_name )
return NULL;
/* Get the appropriate digest information */
#if defined(POLARSSL_MD2_C)
if( !strcasecmp( "MD2", md_name ) )
return md_info_from_type( POLARSSL_MD_MD2 );
#endif
#if defined(POLARSSL_MD4_C)
if( !strcasecmp( "MD4", md_name ) )
return md_info_from_type( POLARSSL_MD_MD4 );
#endif
#if defined(POLARSSL_MD5_C)
if( !strcasecmp( "MD5", md_name ) )
return md_info_from_type( POLARSSL_MD_MD5 );
#endif
#if defined(POLARSSL_SHA1_C)
if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA1 );
#endif
#if defined(POLARSSL_SHA2_C)
if( !strcasecmp( "SHA224", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA224 );
if( !strcasecmp( "SHA256", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA256 );
#endif
#if defined(POLARSSL_SHA4_C)
if( !strcasecmp( "SHA384", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA384 );
if( !strcasecmp( "SHA512", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA512 );
#endif
return NULL;
}
const md_info_t *md_info_from_type( md_type_t md_type )
{
switch( md_type )
{
#if defined(POLARSSL_MD2_C)
case POLARSSL_MD_MD2:
return &md2_info;
#endif
#if defined(POLARSSL_MD4_C)
case POLARSSL_MD_MD4:
return &md4_info;
#endif
#if defined(POLARSSL_MD5_C)
case POLARSSL_MD_MD5:
return &md5_info;
#endif
#if defined(POLARSSL_SHA1_C)
case POLARSSL_MD_SHA1:
return &sha1_info;
#endif
#if defined(POLARSSL_SHA2_C)
case POLARSSL_MD_SHA224:
return &sha224_info;
case POLARSSL_MD_SHA256:
return &sha256_info;
#endif
#if defined(POLARSSL_SHA4_C)
case POLARSSL_MD_SHA384:
return &sha384_info;
case POLARSSL_MD_SHA512:
return &sha512_info;
#endif
default:
return NULL;
}
}
int md_init_ctx( md_context_t *ctx, const md_info_t *md_info )
{
if( md_info == NULL || ctx == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
memset( ctx, 0, sizeof( md_context_t ) );
if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
return POLARSSL_ERR_MD_ALLOC_FAILED;
ctx->md_info = md_info;
md_info->starts_func( ctx->md_ctx );
return 0;
}
int md_free_ctx( md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->ctx_free_func( ctx->md_ctx );
ctx->md_ctx = NULL;
return 0;
}
int md_starts( md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->starts_func( ctx->md_ctx );
return 0;
}
int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->update_func( ctx->md_ctx, input, ilen );
return 0;
}
int md_finish( md_context_t *ctx, unsigned char *output )
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->finish_func( ctx->md_ctx, output );
return 0;
}
int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output )
{
if ( md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
md_info->digest_func( input, ilen, output );
return 0;
}
int md_file( const md_info_t *md_info, const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
int ret;
#endif
if( md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
#if defined(POLARSSL_FS_IO)
ret = md_info->file_func( path, output );
if( ret != 0 )
return( POLARSSL_ERR_MD_FILE_IO_ERROR + ret );
return( ret );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen )
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen);
return 0;
}
int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen );
return 0;
}
int md_hmac_finish( md_context_t *ctx, unsigned char *output)
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->hmac_finish_func( ctx->md_ctx, output);
return 0;
}
int md_hmac_reset( md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
ctx->md_info->hmac_reset_func( ctx->md_ctx);
return 0;
}
int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
if( md_info == NULL )
return POLARSSL_ERR_MD_BAD_INPUT_DATA;
md_info->hmac_func( key, keylen, input, ilen, output );
return 0;
}
#endif
+363
View File
@@ -0,0 +1,363 @@
/**
* \file md.h
*
* \brief Generic message digest wrapper
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD_H
#define POLARSSL_MD_H
#include <string.h>
#if defined(_MSC_VER) && !defined(inline)
#define inline _inline
#else
#if defined(__ARMCC_VERSION) && !defined(inline)
#define inline __inline
#endif /* __ARMCC_VERSION */
#endif /*_MSC_VER */
#define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define POLARSSL_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define POLARSSL_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
#define POLARSSL_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */
typedef enum {
POLARSSL_MD_NONE=0,
POLARSSL_MD_MD2,
POLARSSL_MD_MD4,
POLARSSL_MD_MD5,
POLARSSL_MD_SHA1,
POLARSSL_MD_SHA224,
POLARSSL_MD_SHA256,
POLARSSL_MD_SHA384,
POLARSSL_MD_SHA512,
} md_type_t;
#define POLARSSL_MD_MAX_SIZE 64 /* longest known is SHA512 */
/**
* Message digest information. Allows message digest functions to be called
* in a generic way.
*/
typedef struct {
/** Digest identifier */
md_type_t type;
/** Name of the message digest */
const char * name;
/** Output length of the digest function */
int size;
/** Digest initialisation function */
void (*starts_func)( void *ctx );
/** Digest update function */
void (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
/** Digest finalisation function */
void (*finish_func)( void *ctx, unsigned char *output );
/** Generic digest function */
void (*digest_func)( const unsigned char *input, size_t ilen,
unsigned char *output );
/** Generic file digest function */
int (*file_func)( const char *path, unsigned char *output );
/** HMAC Initialisation function */
void (*hmac_starts_func)( void *ctx, const unsigned char *key, size_t keylen );
/** HMAC update function */
void (*hmac_update_func)( void *ctx, const unsigned char *input, size_t ilen );
/** HMAC finalisation function */
void (*hmac_finish_func)( void *ctx, unsigned char *output);
/** HMAC context reset function */
void (*hmac_reset_func)( void *ctx );
/** Generic HMAC function */
void (*hmac_func)( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
/** Allocate a new context */
void * (*ctx_alloc_func)( void );
/** Free the given context */
void (*ctx_free_func)( void *ctx );
} md_info_t;
/**
* Generic message digest context.
*/
typedef struct {
/** Information about the associated message digest */
const md_info_t *md_info;
/** Digest-specific context */
void *md_ctx;
} md_context_t;
#define MD_CONTEXT_T_INIT { \
NULL, /* md_info */ \
NULL, /* md_ctx */ \
}
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Returns the list of digests supported by the generic digest module.
*
* \return a statically allocated array of digests, the last entry
* is 0.
*/
const int *md_list( void );
/**
* \brief Returns the message digest information associated with the
* given digest name.
*
* \param md_name Name of the digest to search for.
*
* \return The message digest information associated with md_name or
* NULL if not found.
*/
const md_info_t *md_info_from_string( const char *md_name );
/**
* \brief Returns the message digest information associated with the
* given digest type.
*
* \param md_type type of digest to search for.
*
* \return The message digest information associated with md_type or
* NULL if not found.
*/
const md_info_t *md_info_from_type( md_type_t md_type );
/**
* \brief Initialises and fills the message digest context structure with
* the appropriate values.
*
* \param ctx context to initialise. May not be NULL. The
* digest-specific context (ctx->md_ctx) must be NULL. It will
* be allocated, and must be freed using md_free_ctx() later.
* \param md_info message digest to use.
*
* \returns \c 0 on success, \c POLARSSL_ERR_MD_BAD_INPUT_DATA on
* parameter failure, \c POLARSSL_ERR_MD_ALLOC_FAILED if
* allocation of the digest-specific context failed.
*/
int md_init_ctx( md_context_t *ctx, const md_info_t *md_info );
/**
* \brief Free the message-specific context of ctx. Freeing ctx itself
* remains the responsibility of the caller.
*
* \param ctx Free the message-specific context
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_free_ctx( md_context_t *ctx );
/**
* \brief Returns the size of the message digest output.
*
* \param md_info message digest info
*
* \return size of the message digest output.
*/
static inline unsigned char md_get_size( const md_info_t *md_info )
{
if( md_info == NULL )
return( 0 );
return md_info->size;
}
/**
* \brief Returns the type of the message digest output.
*
* \param md_info message digest info
*
* \return type of the message digest output.
*/
static inline md_type_t md_get_type( const md_info_t *md_info )
{
if( md_info == NULL )
return( POLARSSL_MD_NONE );
return md_info->type;
}
/**
* \brief Returns the name of the message digest output.
*
* \param md_info message digest info
*
* \return name of the message digest output.
*/
static inline const char *md_get_name( const md_info_t *md_info )
{
if( md_info == NULL )
return( NULL );
return md_info->name;
}
/**
* \brief Set-up the given context for a new message digest
*
* \param ctx generic message digest context.
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_starts( md_context_t *ctx );
/**
* \brief Generic message digest process buffer
*
* \param ctx Generic message digest context
* \param input buffer holding the datal
* \param ilen length of the input data
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief Generic message digest final digest
*
* \param ctx Generic message digest context
* \param output Generic message digest checksum result
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_finish( md_context_t *ctx, unsigned char *output );
/**
* \brief Output = message_digest( input buffer )
*
* \param md_info message digest info
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic message digest checksum result
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
/**
* \brief Output = message_digest( file contents )
*
* \param md_info message digest info
* \param path input file name
* \param output generic message digest checksum result
*
* \return 0 if successful, POLARSSL_ERR_MD_FILE_OPEN_FAILED if fopen
* failed, POLARSSL_ERR_MD_FILE_READ_FAILED if fread failed,
* POLARSSL_ERR_MD_BAD_INPUT_DATA if md_info was NULL.
*/
int md_file( const md_info_t *md_info, const char *path, unsigned char *output );
/**
* \brief Generic HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen );
/**
* \brief Generic HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
* \brief Generic HMAC final digest
*
* \param ctx HMAC context
* \param output Generic HMAC checksum result
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_hmac_finish( md_context_t *ctx, unsigned char *output);
/**
* \brief Generic HMAC context reset
*
* \param ctx HMAC context to be reset
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_hmac_reset( md_context_t *ctx );
/**
* \brief Output = Generic_HMAC( hmac key, input buffer )
*
* \param md_info message digest info
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output Generic HMAC-result
*
* \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter
* verification fails.
*/
int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* POLARSSL_MD_H */
+368
View File
@@ -0,0 +1,368 @@
/*
* RFC 1115/1319 compliant MD2 implementation
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The MD2 algorithm was designed by Ron Rivest in 1989.
*
* http://www.ietf.org/rfc/rfc1115.txt
* http://www.ietf.org/rfc/rfc1319.txt
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD2_C)
#include "polarssl/md2.h"
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
#include <stdio.h>
#endif
#if !defined(POLARSSL_MD2_ALT)
static const unsigned char PI_SUBST[256] =
{
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
};
/*
* MD2 context setup
*/
void md2_starts( md2_context *ctx )
{
memset( ctx->cksum, 0, 16 );
memset( ctx->state, 0, 46 );
memset( ctx->buffer, 0, 16 );
ctx->left = 0;
}
static void md2_process( md2_context *ctx )
{
int i, j;
unsigned char t = 0;
for( i = 0; i < 16; i++ )
{
ctx->state[i + 16] = ctx->buffer[i];
ctx->state[i + 32] =
(unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
}
for( i = 0; i < 18; i++ )
{
for( j = 0; j < 48; j++ )
{
ctx->state[j] = (unsigned char)
( ctx->state[j] ^ PI_SUBST[t] );
t = ctx->state[j];
}
t = (unsigned char)( t + i );
}
t = ctx->cksum[15];
for( i = 0; i < 16; i++ )
{
ctx->cksum[i] = (unsigned char)
( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
t = ctx->cksum[i];
}
}
/*
* MD2 process buffer
*/
void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
while( ilen > 0 )
{
if( ctx->left + ilen > 16 )
fill = 16 - ctx->left;
else
fill = ilen;
memcpy( ctx->buffer + ctx->left, input, fill );
ctx->left += fill;
input += fill;
ilen -= fill;
if( ctx->left == 16 )
{
ctx->left = 0;
md2_process( ctx );
}
}
}
/*
* MD2 final digest
*/
void md2_finish( md2_context *ctx, unsigned char output[16] )
{
size_t i;
unsigned char x;
x = (unsigned char)( 16 - ctx->left );
for( i = ctx->left; i < 16; i++ )
ctx->buffer[i] = x;
md2_process( ctx );
memcpy( ctx->buffer, ctx->cksum, 16 );
md2_process( ctx );
memcpy( output, ctx->state, 16 );
}
#endif /* !POLARSSL_MD2_ALT */
/*
* output = MD2( input buffer )
*/
void md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
{
md2_context ctx;
md2_starts( &ctx );
md2_update( &ctx, input, ilen );
md2_finish( &ctx, output );
memset( &ctx, 0, sizeof( md2_context ) );
}
#if defined(POLARSSL_FS_IO)
/*
* output = MD2( file contents )
*/
int md2_file( const char *path, unsigned char output[16] )
{
FILE *f;
size_t n;
md2_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
md2_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md2_update( &ctx, buf, n );
md2_finish( &ctx, output );
memset( &ctx, 0, sizeof( md2_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
}
fclose( f );
return( 0 );
}
#endif /* POLARSSL_FS_IO */
/*
* MD2 HMAC context setup
*/
void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen )
{
size_t i;
unsigned char sum[16];
if( keylen > 16 )
{
md2( key, keylen, sum );
keylen = 16;
key = sum;
}
memset( ctx->ipad, 0x36, 16 );
memset( ctx->opad, 0x5C, 16 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
md2_starts( ctx );
md2_update( ctx, ctx->ipad, 16 );
memset( sum, 0, sizeof( sum ) );
}
/*
* MD2 HMAC process buffer
*/
void md2_hmac_update( md2_context *ctx, const unsigned char *input, size_t ilen )
{
md2_update( ctx, input, ilen );
}
/*
* MD2 HMAC final digest
*/
void md2_hmac_finish( md2_context *ctx, unsigned char output[16] )
{
unsigned char tmpbuf[16];
md2_finish( ctx, tmpbuf );
md2_starts( ctx );
md2_update( ctx, ctx->opad, 16 );
md2_update( ctx, tmpbuf, 16 );
md2_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* MD2 HMAC context reset
*/
void md2_hmac_reset( md2_context *ctx )
{
md2_starts( ctx );
md2_update( ctx, ctx->ipad, 16 );
}
/*
* output = HMAC-MD2( hmac key, input buffer )
*/
void md2_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[16] )
{
md2_context ctx;
md2_hmac_starts( &ctx, key, keylen );
md2_hmac_update( &ctx, input, ilen );
md2_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( md2_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* RFC 1319 test vectors
*/
static const char md2_test_str[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const unsigned char md2_test_sum[7][16] =
{
{ 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
{ 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
{ 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
{ 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
{ 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
{ 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
{ 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
};
/*
* Checkup routine
*/
int md2_self_test( int verbose )
{
int i;
unsigned char md2sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " MD2 test #%d: ", i + 1 );
md2( (unsigned char *) md2_test_str[i],
strlen( md2_test_str[i] ), md2sum );
if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif
+171
View File
@@ -0,0 +1,171 @@
/**
* \file md2.h
*
* \brief MD2 message digest algorithm (hash function)
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD2_H
#define POLARSSL_MD2_H
#include "polarssl/config.h"
#include <string.h>
#define POLARSSL_ERR_MD2_FILE_IO_ERROR -0x0070 /**< Read/write error in file. */
#if !defined(POLARSSL_MD2_ALT)
// Regular implementation
//
/**
* \brief MD2 context structure
*/
typedef struct
{
unsigned char cksum[16]; /*!< checksum of the data block */
unsigned char state[48]; /*!< intermediate digest state */
unsigned char buffer[16]; /*!< data block being processed */
unsigned char ipad[16]; /*!< HMAC: inner padding */
unsigned char opad[16]; /*!< HMAC: outer padding */
size_t left; /*!< amount of data in buffer */
}
md2_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD2 context setup
*
* \param ctx context to be initialized
*/
void md2_starts( md2_context *ctx );
/**
* \brief MD2 process buffer
*
* \param ctx MD2 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD2 final digest
*
* \param ctx MD2 context
* \param output MD2 checksum result
*/
void md2_finish( md2_context *ctx, unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_MD2_ALT */
#include "polarssl/md2_alt.h"
#endif /* POLARSSL_MD2_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD2( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD2 checksum result
*/
void md2( const unsigned char *input, size_t ilen, unsigned char output[16] );
/**
* \brief Output = MD2( file contents )
*
* \param path input file name
* \param output MD2 checksum result
*
* \return 0 if successful, or POLARSSL_ERR_MD2_FILE_IO_ERROR
*/
int md2_file( const char *path, unsigned char output[16] );
/**
* \brief MD2 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen );
/**
* \brief MD2 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md2_hmac_update( md2_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD2 HMAC final digest
*
* \param ctx HMAC context
* \param output MD2 HMAC checksum result
*/
void md2_hmac_finish( md2_context *ctx, unsigned char output[16] );
/**
* \brief MD2 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void md2_hmac_reset( md2_context *ctx );
/**
* \brief Output = HMAC-MD2( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD2 result
*/
void md2_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md2_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md2.h */
+464
View File
@@ -0,0 +1,464 @@
/*
* RFC 1186/1320 compliant MD4 implementation
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The MD4 algorithm was designed by Ron Rivest in 1990.
*
* http://www.ietf.org/rfc/rfc1186.txt
* http://www.ietf.org/rfc/rfc1320.txt
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD4_C)
#include "polarssl/md4.h"
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
#include <stdio.h>
#endif
#if !defined(POLARSSL_MD4_ALT)
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_UINT32_LE
#define PUT_UINT32_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
}
#endif
/*
* MD4 context setup
*/
void md4_starts( md4_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
static void md4_process( md4_context *ctx, const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x, y, z) ((x & y) | ((~x) & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 1], 7 );
P( C, D, A, B, X[ 2], 11 );
P( B, C, D, A, X[ 3], 19 );
P( A, B, C, D, X[ 4], 3 );
P( D, A, B, C, X[ 5], 7 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[ 7], 19 );
P( A, B, C, D, X[ 8], 3 );
P( D, A, B, C, X[ 9], 7 );
P( C, D, A, B, X[10], 11 );
P( B, C, D, A, X[11], 19 );
P( A, B, C, D, X[12], 3 );
P( D, A, B, C, X[13], 7 );
P( C, D, A, B, X[14], 11 );
P( B, C, D, A, X[15], 19 );
#undef P
#undef F
#define F(x,y,z) ((x & y) | (x & z) | (y & z))
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 4], 5 );
P( C, D, A, B, X[ 8], 9 );
P( B, C, D, A, X[12], 13 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 5], 5 );
P( C, D, A, B, X[ 9], 9 );
P( B, C, D, A, X[13], 13 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[ 6], 5 );
P( C, D, A, B, X[10], 9 );
P( B, C, D, A, X[14], 13 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[ 7], 5 );
P( C, D, A, B, X[11], 9 );
P( B, C, D, A, X[15], 13 );
#undef P
#undef F
#define F(x,y,z) (x ^ y ^ z)
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
P( A, B, C, D, X[ 0], 3 );
P( D, A, B, C, X[ 8], 9 );
P( C, D, A, B, X[ 4], 11 );
P( B, C, D, A, X[12], 15 );
P( A, B, C, D, X[ 2], 3 );
P( D, A, B, C, X[10], 9 );
P( C, D, A, B, X[ 6], 11 );
P( B, C, D, A, X[14], 15 );
P( A, B, C, D, X[ 1], 3 );
P( D, A, B, C, X[ 9], 9 );
P( C, D, A, B, X[ 5], 11 );
P( B, C, D, A, X[13], 15 );
P( A, B, C, D, X[ 3], 3 );
P( D, A, B, C, X[11], 9 );
P( C, D, A, B, X[ 7], 11 );
P( B, C, D, A, X[15], 15 );
#undef F
#undef P
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
/*
* MD4 process buffer
*/
void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
md4_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
md4_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, ilen );
}
}
static const unsigned char md4_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD4 final digest
*/
void md4_finish( md4_context *ctx, unsigned char output[16] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 );
PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
md4_update( ctx, (unsigned char *) md4_padding, padn );
md4_update( ctx, msglen, 8 );
PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 );
}
#endif /* !POLARSSL_MD4_ALT */
/*
* output = MD4( input buffer )
*/
void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
{
md4_context ctx;
md4_starts( &ctx );
md4_update( &ctx, input, ilen );
md4_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
}
#if defined(POLARSSL_FS_IO)
/*
* output = MD4( file contents )
*/
int md4_file( const char *path, unsigned char output[16] )
{
FILE *f;
size_t n;
md4_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
md4_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md4_update( &ctx, buf, n );
md4_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
}
fclose( f );
return( 0 );
}
#endif /* POLARSSL_FS_IO */
/*
* MD4 HMAC context setup
*/
void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
{
size_t i;
unsigned char sum[16];
if( keylen > 64 )
{
md4( key, keylen, sum );
keylen = 16;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
md4_starts( ctx );
md4_update( ctx, ctx->ipad, 64 );
memset( sum, 0, sizeof( sum ) );
}
/*
* MD4 HMAC process buffer
*/
void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
{
md4_update( ctx, input, ilen );
}
/*
* MD4 HMAC final digest
*/
void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
{
unsigned char tmpbuf[16];
md4_finish( ctx, tmpbuf );
md4_starts( ctx );
md4_update( ctx, ctx->opad, 64 );
md4_update( ctx, tmpbuf, 16 );
md4_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* MD4 HMAC context reset
*/
void md4_hmac_reset( md4_context *ctx )
{
md4_starts( ctx );
md4_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-MD4( hmac key, input buffer )
*/
void md4_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[16] )
{
md4_context ctx;
md4_hmac_starts( &ctx, key, keylen );
md4_hmac_update( &ctx, input, ilen );
md4_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( md4_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* RFC 1320 test vectors
*/
static const char md4_test_str[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const unsigned char md4_test_sum[7][16] =
{
{ 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
{ 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
{ 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
{ 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
{ 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
{ 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
{ 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
};
/*
* Checkup routine
*/
int md4_self_test( int verbose )
{
int i;
unsigned char md4sum[16];
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " MD4 test #%d: ", i + 1 );
md4( (unsigned char *) md4_test_str[i],
strlen( md4_test_str[i] ), md4sum );
if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif
+177
View File
@@ -0,0 +1,177 @@
/**
* \file md4.h
*
* \brief MD4 message digest algorithm (hash function)
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD4_H
#define POLARSSL_MD4_H
#include "polarssl/config.h"
#include <string.h>
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define POLARSSL_ERR_MD4_FILE_IO_ERROR -0x0072 /**< Read/write error in file. */
#if !defined(POLARSSL_MD4_ALT)
// Regular implementation
//
/**
* \brief MD4 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md4_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD4 context setup
*
* \param ctx context to be initialized
*/
void md4_starts( md4_context *ctx );
/**
* \brief MD4 process buffer
*
* \param ctx MD4 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD4 final digest
*
* \param ctx MD4 context
* \param output MD4 checksum result
*/
void md4_finish( md4_context *ctx, unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_MD4_ALT */
#include "polarssl/md4_alt.h"
#endif /* POLARSSL_MD4_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD4( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD4 checksum result
*/
void md4( const unsigned char *input, size_t ilen, unsigned char output[16] );
/**
* \brief Output = MD4( file contents )
*
* \param path input file name
* \param output MD4 checksum result
*
* \return 0 if successful, or POLARSSL_ERR_MD4_FILE_IO_ERROR
*/
int md4_file( const char *path, unsigned char output[16] );
/**
* \brief MD4 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen );
/**
* \brief MD4 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD4 HMAC final digest
*
* \param ctx HMAC context
* \param output MD4 HMAC checksum result
*/
void md4_hmac_finish( md4_context *ctx, unsigned char output[16] );
/**
* \brief MD4 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void md4_hmac_reset( md4_context *ctx );
/**
* \brief Output = HMAC-MD4( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD4 result
*/
void md4_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md4_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md4.h */
+585
View File
@@ -0,0 +1,585 @@
/*
* RFC 1321 compliant MD5 implementation
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* The MD5 algorithm was designed by Ron Rivest in 1991.
*
* http://www.ietf.org/rfc/rfc1321.txt
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD5_C)
#include "polarssl/md5.h"
#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
#include <stdio.h>
#endif
#if !defined(POLARSSL_MD5_ALT)
/*
* 32-bit integer manipulation macros (little endian)
*/
#ifndef GET_UINT32_LE
#define GET_UINT32_LE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] ) \
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
| ( (uint32_t) (b)[(i) + 2] << 16 ) \
| ( (uint32_t) (b)[(i) + 3] << 24 ); \
}
#endif
#ifndef PUT_UINT32_LE
#define PUT_UINT32_LE(n,b,i) \
{ \
(b)[(i) ] = (unsigned char) ( (n) ); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
}
#endif
/*
* MD5 context setup
*/
void md5_starts( md5_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
}
void md5_process( md5_context *ctx, const unsigned char data[64] )
{
uint32_t X[16], A, B, C, D;
GET_UINT32_LE( X[ 0], data, 0 );
GET_UINT32_LE( X[ 1], data, 4 );
GET_UINT32_LE( X[ 2], data, 8 );
GET_UINT32_LE( X[ 3], data, 12 );
GET_UINT32_LE( X[ 4], data, 16 );
GET_UINT32_LE( X[ 5], data, 20 );
GET_UINT32_LE( X[ 6], data, 24 );
GET_UINT32_LE( X[ 7], data, 28 );
GET_UINT32_LE( X[ 8], data, 32 );
GET_UINT32_LE( X[ 9], data, 36 );
GET_UINT32_LE( X[10], data, 40 );
GET_UINT32_LE( X[11], data, 44 );
GET_UINT32_LE( X[12], data, 48 );
GET_UINT32_LE( X[13], data, 52 );
GET_UINT32_LE( X[14], data, 56 );
GET_UINT32_LE( X[15], data, 60 );
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) \
{ \
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
}
A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
#define F(x,y,z) (z ^ (x & (y ^ z)))
P( A, B, C, D, 0, 7, 0xD76AA478 );
P( D, A, B, C, 1, 12, 0xE8C7B756 );
P( C, D, A, B, 2, 17, 0x242070DB );
P( B, C, D, A, 3, 22, 0xC1BDCEEE );
P( A, B, C, D, 4, 7, 0xF57C0FAF );
P( D, A, B, C, 5, 12, 0x4787C62A );
P( C, D, A, B, 6, 17, 0xA8304613 );
P( B, C, D, A, 7, 22, 0xFD469501 );
P( A, B, C, D, 8, 7, 0x698098D8 );
P( D, A, B, C, 9, 12, 0x8B44F7AF );
P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
P( B, C, D, A, 11, 22, 0x895CD7BE );
P( A, B, C, D, 12, 7, 0x6B901122 );
P( D, A, B, C, 13, 12, 0xFD987193 );
P( C, D, A, B, 14, 17, 0xA679438E );
P( B, C, D, A, 15, 22, 0x49B40821 );
#undef F
#define F(x,y,z) (y ^ (z & (x ^ y)))
P( A, B, C, D, 1, 5, 0xF61E2562 );
P( D, A, B, C, 6, 9, 0xC040B340 );
P( C, D, A, B, 11, 14, 0x265E5A51 );
P( B, C, D, A, 0, 20, 0xE9B6C7AA );
P( A, B, C, D, 5, 5, 0xD62F105D );
P( D, A, B, C, 10, 9, 0x02441453 );
P( C, D, A, B, 15, 14, 0xD8A1E681 );
P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
P( A, B, C, D, 9, 5, 0x21E1CDE6 );
P( D, A, B, C, 14, 9, 0xC33707D6 );
P( C, D, A, B, 3, 14, 0xF4D50D87 );
P( B, C, D, A, 8, 20, 0x455A14ED );
P( A, B, C, D, 13, 5, 0xA9E3E905 );
P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
P( C, D, A, B, 7, 14, 0x676F02D9 );
P( B, C, D, A, 12, 20, 0x8D2A4C8A );
#undef F
#define F(x,y,z) (x ^ y ^ z)
P( A, B, C, D, 5, 4, 0xFFFA3942 );
P( D, A, B, C, 8, 11, 0x8771F681 );
P( C, D, A, B, 11, 16, 0x6D9D6122 );
P( B, C, D, A, 14, 23, 0xFDE5380C );
P( A, B, C, D, 1, 4, 0xA4BEEA44 );
P( D, A, B, C, 4, 11, 0x4BDECFA9 );
P( C, D, A, B, 7, 16, 0xF6BB4B60 );
P( B, C, D, A, 10, 23, 0xBEBFBC70 );
P( A, B, C, D, 13, 4, 0x289B7EC6 );
P( D, A, B, C, 0, 11, 0xEAA127FA );
P( C, D, A, B, 3, 16, 0xD4EF3085 );
P( B, C, D, A, 6, 23, 0x04881D05 );
P( A, B, C, D, 9, 4, 0xD9D4D039 );
P( D, A, B, C, 12, 11, 0xE6DB99E5 );
P( C, D, A, B, 15, 16, 0x1FA27CF8 );
P( B, C, D, A, 2, 23, 0xC4AC5665 );
#undef F
#define F(x,y,z) (y ^ (x | ~z))
P( A, B, C, D, 0, 6, 0xF4292244 );
P( D, A, B, C, 7, 10, 0x432AFF97 );
P( C, D, A, B, 14, 15, 0xAB9423A7 );
P( B, C, D, A, 5, 21, 0xFC93A039 );
P( A, B, C, D, 12, 6, 0x655B59C3 );
P( D, A, B, C, 3, 10, 0x8F0CCC92 );
P( C, D, A, B, 10, 15, 0xFFEFF47D );
P( B, C, D, A, 1, 21, 0x85845DD1 );
P( A, B, C, D, 8, 6, 0x6FA87E4F );
P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
P( C, D, A, B, 6, 15, 0xA3014314 );
P( B, C, D, A, 13, 21, 0x4E0811A1 );
P( A, B, C, D, 4, 6, 0xF7537E82 );
P( D, A, B, C, 11, 10, 0xBD3AF235 );
P( C, D, A, B, 2, 15, 0x2AD7D2BB );
P( B, C, D, A, 9, 21, 0xEB86D391 );
#undef F
ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
}
/*
* MD5 process buffer
*/
void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
{
size_t fill;
uint32_t left;
if( ilen <= 0 )
return;
left = ctx->total[0] & 0x3F;
fill = 64 - left;
ctx->total[0] += (uint32_t) ilen;
ctx->total[0] &= 0xFFFFFFFF;
if( ctx->total[0] < (uint32_t) ilen )
ctx->total[1]++;
if( left && ilen >= fill )
{
memcpy( (void *) (ctx->buffer + left), input, fill );
md5_process( ctx, ctx->buffer );
input += fill;
ilen -= fill;
left = 0;
}
while( ilen >= 64 )
{
md5_process( ctx, input );
input += 64;
ilen -= 64;
}
if( ilen > 0 )
{
memcpy( (void *) (ctx->buffer + left), input, ilen );
}
}
static const unsigned char md5_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* MD5 final digest
*/
void md5_finish( md5_context *ctx, unsigned char output[16] )
{
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
PUT_UINT32_LE( low, msglen, 0 );
PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
md5_update( ctx, md5_padding, padn );
md5_update( ctx, msglen, 8 );
PUT_UINT32_LE( ctx->state[0], output, 0 );
PUT_UINT32_LE( ctx->state[1], output, 4 );
PUT_UINT32_LE( ctx->state[2], output, 8 );
PUT_UINT32_LE( ctx->state[3], output, 12 );
}
#endif /* !POLARSSL_MD5_ALT */
/*
* output = MD5( input buffer )
*/
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
{
md5_context ctx;
md5_starts( &ctx );
md5_update( &ctx, input, ilen );
md5_finish( &ctx, output );
memset( &ctx, 0, sizeof( md5_context ) );
}
#if defined(POLARSSL_FS_IO)
/*
* output = MD5( file contents )
*/
int md5_file( const char *path, unsigned char output[16] )
{
FILE *f;
size_t n;
md5_context ctx;
unsigned char buf[1024];
if( ( f = fopen( path, "rb" ) ) == NULL )
return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
md5_starts( &ctx );
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
md5_update( &ctx, buf, n );
md5_finish( &ctx, output );
memset( &ctx, 0, sizeof( md5_context ) );
if( ferror( f ) != 0 )
{
fclose( f );
return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
}
fclose( f );
return( 0 );
}
#endif /* POLARSSL_FS_IO */
/*
* MD5 HMAC context setup
*/
void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen )
{
size_t i;
unsigned char sum[16];
if( keylen > 64 )
{
md5( key, keylen, sum );
keylen = 16;
key = sum;
}
memset( ctx->ipad, 0x36, 64 );
memset( ctx->opad, 0x5C, 64 );
for( i = 0; i < keylen; i++ )
{
ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
}
md5_starts( ctx );
md5_update( ctx, ctx->ipad, 64 );
memset( sum, 0, sizeof( sum ) );
}
/*
* MD5 HMAC process buffer
*/
void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen )
{
md5_update( ctx, input, ilen );
}
/*
* MD5 HMAC final digest
*/
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
{
unsigned char tmpbuf[16];
md5_finish( ctx, tmpbuf );
md5_starts( ctx );
md5_update( ctx, ctx->opad, 64 );
md5_update( ctx, tmpbuf, 16 );
md5_finish( ctx, output );
memset( tmpbuf, 0, sizeof( tmpbuf ) );
}
/*
* MD5 HMAC context reset
*/
void md5_hmac_reset( md5_context *ctx )
{
md5_starts( ctx );
md5_update( ctx, ctx->ipad, 64 );
}
/*
* output = HMAC-MD5( hmac key, input buffer )
*/
void md5_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[16] )
{
md5_context ctx;
md5_hmac_starts( &ctx, key, keylen );
md5_hmac_update( &ctx, input, ilen );
md5_hmac_finish( &ctx, output );
memset( &ctx, 0, sizeof( md5_context ) );
}
#if defined(POLARSSL_SELF_TEST)
/*
* RFC 1321 test vectors
*/
static unsigned char md5_test_buf[7][81] =
{
{ "" },
{ "a" },
{ "abc" },
{ "message digest" },
{ "abcdefghijklmnopqrstuvwxyz" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
{ "12345678901234567890123456789012345678901234567890123456789012" \
"345678901234567890" }
};
static const int md5_test_buflen[7] =
{
0, 1, 3, 14, 26, 62, 80
};
static const unsigned char md5_test_sum[7][16] =
{
{ 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
{ 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
{ 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
{ 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
{ 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
{ 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
{ 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
};
/*
* RFC 2202 test vectors
*/
static unsigned char md5_hmac_test_key[7][26] =
{
{ "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
{ "Jefe" },
{ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
{ "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
{ "" }, /* 0xAA 80 times */
{ "" }
};
static const int md5_hmac_test_keylen[7] =
{
16, 4, 16, 25, 16, 80, 80
};
static unsigned char md5_hmac_test_buf[7][74] =
{
{ "Hi There" },
{ "what do ya want for nothing?" },
{ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
{ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
{ "Test With Truncation" },
{ "Test Using Larger Than Block-Size Key - Hash Key First" },
{ "Test Using Larger Than Block-Size Key and Larger"
" Than One Block-Size Data" }
};
static const int md5_hmac_test_buflen[7] =
{
8, 28, 50, 50, 20, 54, 73
};
static const unsigned char md5_hmac_test_sum[7][16] =
{
{ 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
{ 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
{ 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
{ 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
{ 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
0xF9, 0xBA, 0xB9, 0x95 },
{ 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
{ 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
};
/*
* Checkup routine
*/
int md5_self_test( int verbose )
{
int i, buflen;
unsigned char buf[1024];
unsigned char md5sum[16];
md5_context ctx;
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " MD5 test #%d: ", i + 1 );
md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
for( i = 0; i < 7; i++ )
{
if( verbose != 0 )
printf( " HMAC-MD5 test #%d: ", i + 1 );
if( i == 5 || i == 6 )
{
memset( buf, '\xAA', buflen = 80 );
md5_hmac_starts( &ctx, buf, buflen );
}
else
md5_hmac_starts( &ctx, md5_hmac_test_key[i],
md5_hmac_test_keylen[i] );
md5_hmac_update( &ctx, md5_hmac_test_buf[i],
md5_hmac_test_buflen[i] );
md5_hmac_finish( &ctx, md5sum );
buflen = ( i == 4 ) ? 12 : 16;
if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
{
if( verbose != 0 )
printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
printf( "passed\n" );
}
if( verbose != 0 )
printf( "\n" );
return( 0 );
}
#endif
#endif
+182
View File
@@ -0,0 +1,182 @@
/**
* \file md5.h
*
* \brief MD5 message digest algorithm (hash function)
*
* Copyright (C) 2006-2013, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD5_H
#define POLARSSL_MD5_H
#include "polarssl/config.h"
#include <string.h>
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#define POLARSSL_ERR_MD5_FILE_IO_ERROR -0x0074 /**< Read/write error in file. */
#if !defined(POLARSSL_MD5_ALT)
// Regular implementation
//
/**
* \brief MD5 context structure
*/
typedef struct
{
uint32_t total[2]; /*!< number of bytes processed */
uint32_t state[4]; /*!< intermediate digest state */
unsigned char buffer[64]; /*!< data block being processed */
unsigned char ipad[64]; /*!< HMAC: inner padding */
unsigned char opad[64]; /*!< HMAC: outer padding */
}
md5_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MD5 context setup
*
* \param ctx context to be initialized
*/
void md5_starts( md5_context *ctx );
/**
* \brief MD5 process buffer
*
* \param ctx MD5 context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen );
/**
* \brief MD5 final digest
*
* \param ctx MD5 context
* \param output MD5 checksum result
*/
void md5_finish( md5_context *ctx, unsigned char output[16] );
/* Internal use */
void md5_process( md5_context *ctx, const unsigned char data[64] );
#ifdef __cplusplus
}
#endif
#else /* POLARSSL_MD5_ALT */
#include "polarssl/md5_alt.h"
#endif /* POLARSSL_MD5_ALT */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Output = MD5( input buffer )
*
* \param input buffer holding the data
* \param ilen length of the input data
* \param output MD5 checksum result
*/
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] );
/**
* \brief Output = MD5( file contents )
*
* \param path input file name
* \param output MD5 checksum result
*
* \return 0 if successful, or POLARSSL_ERR_MD5_FILE_IO_ERROR
*/
int md5_file( const char *path, unsigned char output[16] );
/**
* \brief MD5 HMAC context setup
*
* \param ctx HMAC context to be initialized
* \param key HMAC secret key
* \param keylen length of the HMAC key
*/
void md5_hmac_starts( md5_context *ctx,
const unsigned char *key, size_t keylen );
/**
* \brief MD5 HMAC process buffer
*
* \param ctx HMAC context
* \param input buffer holding the data
* \param ilen length of the input data
*/
void md5_hmac_update( md5_context *ctx,
const unsigned char *input, size_t ilen );
/**
* \brief MD5 HMAC final digest
*
* \param ctx HMAC context
* \param output MD5 HMAC checksum result
*/
void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
/**
* \brief MD5 HMAC context reset
*
* \param ctx HMAC context to be reset
*/
void md5_hmac_reset( md5_context *ctx );
/**
* \brief Output = HMAC-MD5( hmac key, input buffer )
*
* \param key HMAC secret key
* \param keylen length of the HMAC key
* \param input buffer holding the data
* \param ilen length of the input data
* \param output HMAC-MD5 result
*/
void md5_hmac( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char output[16] );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int md5_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* md5.h */
+733
View File
@@ -0,0 +1,733 @@
/**
* \file md_wrap.c
* \brief Generic message digest wrapper for PolarSSL
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_MD_C)
#include "polarssl/md_wrap.h"
#if defined(POLARSSL_MD2_C)
#include "polarssl/md2.h"
#endif
#if defined(POLARSSL_MD4_C)
#include "polarssl/md4.h"
#endif
#if defined(POLARSSL_MD5_C)
#include "polarssl/md5.h"
#endif
#if defined(POLARSSL_SHA1_C)
#include "polarssl/sha1.h"
#endif
#if defined(POLARSSL_SHA2_C)
#include "polarssl/sha2.h"
#endif
#if defined(POLARSSL_SHA4_C)
#include "polarssl/sha4.h"
#endif
#include <stdlib.h>
#if defined(POLARSSL_MD2_C)
static void md2_starts_wrap( void *ctx )
{
md2_starts( (md2_context *) ctx );
}
static void md2_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md2_update( (md2_context *) ctx, input, ilen );
}
static void md2_finish_wrap( void *ctx, unsigned char *output )
{
md2_finish( (md2_context *) ctx, output );
}
int md2_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return md2_file( path, output );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
md2_hmac_starts( (md2_context *) ctx, key, keylen );
}
static void md2_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md2_hmac_update( (md2_context *) ctx, input, ilen );
}
static void md2_hmac_finish_wrap( void *ctx, unsigned char *output )
{
md2_hmac_finish( (md2_context *) ctx, output );
}
static void md2_hmac_reset_wrap( void *ctx )
{
md2_hmac_reset( (md2_context *) ctx );
}
static void * md2_ctx_alloc( void )
{
return malloc( sizeof( md2_context ) );
}
static void md2_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t md2_info = {
POLARSSL_MD_MD2,
"MD2",
16,
md2_starts_wrap,
md2_update_wrap,
md2_finish_wrap,
md2,
md2_file_wrap,
md2_hmac_starts_wrap,
md2_hmac_update_wrap,
md2_hmac_finish_wrap,
md2_hmac_reset_wrap,
md2_hmac,
md2_ctx_alloc,
md2_ctx_free,
};
#endif
#if defined(POLARSSL_MD4_C)
void md4_starts_wrap( void *ctx )
{
md4_starts( (md4_context *) ctx );
}
void md4_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md4_update( (md4_context *) ctx, input, ilen );
}
void md4_finish_wrap( void *ctx, unsigned char *output )
{
md4_finish( (md4_context *) ctx, output );
}
int md4_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return md4_file( path, output );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
md4_hmac_starts( (md4_context *) ctx, key, keylen );
}
void md4_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md4_hmac_update( (md4_context *) ctx, input, ilen );
}
void md4_hmac_finish_wrap( void *ctx, unsigned char *output )
{
md4_hmac_finish( (md4_context *) ctx, output );
}
void md4_hmac_reset_wrap( void *ctx )
{
md4_hmac_reset( (md4_context *) ctx );
}
void *md4_ctx_alloc( void )
{
return malloc( sizeof( md4_context ) );
}
void md4_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t md4_info = {
POLARSSL_MD_MD4,
"MD4",
16,
md4_starts_wrap,
md4_update_wrap,
md4_finish_wrap,
md4,
md4_file_wrap,
md4_hmac_starts_wrap,
md4_hmac_update_wrap,
md4_hmac_finish_wrap,
md4_hmac_reset_wrap,
md4_hmac,
md4_ctx_alloc,
md4_ctx_free,
};
#endif
#if defined(POLARSSL_MD5_C)
static void md5_starts_wrap( void *ctx )
{
md5_starts( (md5_context *) ctx );
}
static void md5_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md5_update( (md5_context *) ctx, input, ilen );
}
static void md5_finish_wrap( void *ctx, unsigned char *output )
{
md5_finish( (md5_context *) ctx, output );
}
int md5_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return md5_file( path, output );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
md5_hmac_starts( (md5_context *) ctx, key, keylen );
}
static void md5_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
md5_hmac_update( (md5_context *) ctx, input, ilen );
}
static void md5_hmac_finish_wrap( void *ctx, unsigned char *output )
{
md5_hmac_finish( (md5_context *) ctx, output );
}
static void md5_hmac_reset_wrap( void *ctx )
{
md5_hmac_reset( (md5_context *) ctx );
}
static void * md5_ctx_alloc( void )
{
return malloc( sizeof( md5_context ) );
}
static void md5_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t md5_info = {
POLARSSL_MD_MD5,
"MD5",
16,
md5_starts_wrap,
md5_update_wrap,
md5_finish_wrap,
md5,
md5_file_wrap,
md5_hmac_starts_wrap,
md5_hmac_update_wrap,
md5_hmac_finish_wrap,
md5_hmac_reset_wrap,
md5_hmac,
md5_ctx_alloc,
md5_ctx_free,
};
#endif
#if defined(POLARSSL_SHA1_C)
void sha1_starts_wrap( void *ctx )
{
sha1_starts( (sha1_context *) ctx );
}
void sha1_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha1_update( (sha1_context *) ctx, input, ilen );
}
void sha1_finish_wrap( void *ctx, unsigned char *output )
{
sha1_finish( (sha1_context *) ctx, output );
}
int sha1_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha1_file( path, output );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha1_hmac_starts( (sha1_context *) ctx, key, keylen );
}
void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha1_hmac_update( (sha1_context *) ctx, input, ilen );
}
void sha1_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha1_hmac_finish( (sha1_context *) ctx, output );
}
void sha1_hmac_reset_wrap( void *ctx )
{
sha1_hmac_reset( (sha1_context *) ctx );
}
void * sha1_ctx_alloc( void )
{
return malloc( sizeof( sha1_context ) );
}
void sha1_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t sha1_info = {
POLARSSL_MD_SHA1,
"SHA1",
20,
sha1_starts_wrap,
sha1_update_wrap,
sha1_finish_wrap,
sha1,
sha1_file_wrap,
sha1_hmac_starts_wrap,
sha1_hmac_update_wrap,
sha1_hmac_finish_wrap,
sha1_hmac_reset_wrap,
sha1_hmac,
sha1_ctx_alloc,
sha1_ctx_free,
};
#endif
/*
* Wrappers for generic message digests
*/
#if defined(POLARSSL_SHA2_C)
void sha224_starts_wrap( void *ctx )
{
sha2_starts( (sha2_context *) ctx, 1 );
}
void sha224_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_update( (sha2_context *) ctx, input, ilen );
}
void sha224_finish_wrap( void *ctx, unsigned char *output )
{
sha2_finish( (sha2_context *) ctx, output );
}
void sha224_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2( input, ilen, output, 1 );
}
int sha224_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha2_file( path, output, 1 );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha2_hmac_starts( (sha2_context *) ctx, key, keylen, 1 );
}
void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_hmac_update( (sha2_context *) ctx, input, ilen );
}
void sha224_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha2_hmac_finish( (sha2_context *) ctx, output );
}
void sha224_hmac_reset_wrap( void *ctx )
{
sha2_hmac_reset( (sha2_context *) ctx );
}
void sha224_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2_hmac( key, keylen, input, ilen, output, 1 );
}
void * sha224_ctx_alloc( void )
{
return malloc( sizeof( sha2_context ) );
}
void sha224_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t sha224_info = {
POLARSSL_MD_SHA224,
"SHA224",
28,
sha224_starts_wrap,
sha224_update_wrap,
sha224_finish_wrap,
sha224_wrap,
sha224_file_wrap,
sha224_hmac_starts_wrap,
sha224_hmac_update_wrap,
sha224_hmac_finish_wrap,
sha224_hmac_reset_wrap,
sha224_hmac_wrap,
sha224_ctx_alloc,
sha224_ctx_free,
};
void sha256_starts_wrap( void *ctx )
{
sha2_starts( (sha2_context *) ctx, 0 );
}
void sha256_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_update( (sha2_context *) ctx, input, ilen );
}
void sha256_finish_wrap( void *ctx, unsigned char *output )
{
sha2_finish( (sha2_context *) ctx, output );
}
void sha256_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2( input, ilen, output, 0 );
}
int sha256_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha2_file( path, output, 0 );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha2_hmac_starts( (sha2_context *) ctx, key, keylen, 0 );
}
void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha2_hmac_update( (sha2_context *) ctx, input, ilen );
}
void sha256_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha2_hmac_finish( (sha2_context *) ctx, output );
}
void sha256_hmac_reset_wrap( void *ctx )
{
sha2_hmac_reset( (sha2_context *) ctx );
}
void sha256_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha2_hmac( key, keylen, input, ilen, output, 0 );
}
void * sha256_ctx_alloc( void )
{
return malloc( sizeof( sha2_context ) );
}
void sha256_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t sha256_info = {
POLARSSL_MD_SHA256,
"SHA256",
32,
sha256_starts_wrap,
sha256_update_wrap,
sha256_finish_wrap,
sha256_wrap,
sha256_file_wrap,
sha256_hmac_starts_wrap,
sha256_hmac_update_wrap,
sha256_hmac_finish_wrap,
sha256_hmac_reset_wrap,
sha256_hmac_wrap,
sha256_ctx_alloc,
sha256_ctx_free,
};
#endif
#if defined(POLARSSL_SHA4_C)
void sha384_starts_wrap( void *ctx )
{
sha4_starts( (sha4_context *) ctx, 1 );
}
void sha384_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_update( (sha4_context *) ctx, input, ilen );
}
void sha384_finish_wrap( void *ctx, unsigned char *output )
{
sha4_finish( (sha4_context *) ctx, output );
}
void sha384_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4( input, ilen, output, 1 );
}
int sha384_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha4_file( path, output, 1 );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha4_hmac_starts( (sha4_context *) ctx, key, keylen, 1 );
}
void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_hmac_update( (sha4_context *) ctx, input, ilen );
}
void sha384_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha4_hmac_finish( (sha4_context *) ctx, output );
}
void sha384_hmac_reset_wrap( void *ctx )
{
sha4_hmac_reset( (sha4_context *) ctx );
}
void sha384_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4_hmac( key, keylen, input, ilen, output, 1 );
}
void * sha384_ctx_alloc( void )
{
return malloc( sizeof( sha4_context ) );
}
void sha384_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t sha384_info = {
POLARSSL_MD_SHA384,
"SHA384",
48,
sha384_starts_wrap,
sha384_update_wrap,
sha384_finish_wrap,
sha384_wrap,
sha384_file_wrap,
sha384_hmac_starts_wrap,
sha384_hmac_update_wrap,
sha384_hmac_finish_wrap,
sha384_hmac_reset_wrap,
sha384_hmac_wrap,
sha384_ctx_alloc,
sha384_ctx_free,
};
void sha512_starts_wrap( void *ctx )
{
sha4_starts( (sha4_context *) ctx, 0 );
}
void sha512_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_update( (sha4_context *) ctx, input, ilen );
}
void sha512_finish_wrap( void *ctx, unsigned char *output )
{
sha4_finish( (sha4_context *) ctx, output );
}
void sha512_wrap( const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4( input, ilen, output, 0 );
}
int sha512_file_wrap( const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
return sha4_file( path, output, 0 );
#else
((void) path);
((void) output);
return POLARSSL_ERR_MD_FEATURE_UNAVAILABLE;
#endif
}
void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, size_t keylen )
{
sha4_hmac_starts( (sha4_context *) ctx, key, keylen, 0 );
}
void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, size_t ilen )
{
sha4_hmac_update( (sha4_context *) ctx, input, ilen );
}
void sha512_hmac_finish_wrap( void *ctx, unsigned char *output )
{
sha4_hmac_finish( (sha4_context *) ctx, output );
}
void sha512_hmac_reset_wrap( void *ctx )
{
sha4_hmac_reset( (sha4_context *) ctx );
}
void sha512_hmac_wrap( const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
sha4_hmac( key, keylen, input, ilen, output, 0 );
}
void * sha512_ctx_alloc( void )
{
return malloc( sizeof( sha4_context ) );
}
void sha512_ctx_free( void *ctx )
{
free( ctx );
}
const md_info_t sha512_info = {
POLARSSL_MD_SHA512,
"SHA512",
64,
sha512_starts_wrap,
sha512_update_wrap,
sha512_finish_wrap,
sha512_wrap,
sha512_file_wrap,
sha512_hmac_starts_wrap,
sha512_hmac_update_wrap,
sha512_hmac_finish_wrap,
sha512_hmac_reset_wrap,
sha512_hmac_wrap,
sha512_ctx_alloc,
sha512_ctx_free,
};
#endif
#endif
+64
View File
@@ -0,0 +1,64 @@
/**
* \file md_wrap.h
*
* \brief Message digest wrappers.
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_MD_WRAP_H
#define POLARSSL_MD_WRAP_H
#include "polarssl/config.h"
#include "polarssl/md.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(POLARSSL_MD2_C)
extern const md_info_t md2_info;
#endif
#if defined(POLARSSL_MD4_C)
extern const md_info_t md4_info;
#endif
#if defined(POLARSSL_MD5_C)
extern const md_info_t md5_info;
#endif
#if defined(POLARSSL_SHA1_C)
extern const md_info_t sha1_info;
#endif
#if defined(POLARSSL_SHA2_C)
extern const md_info_t sha224_info;
extern const md_info_t sha256_info;
#endif
#if defined(POLARSSL_SHA4_C)
extern const md_info_t sha384_info;
extern const md_info_t sha512_info;
#endif
#ifdef __cplusplus
}
#endif
#endif /* POLARSSL_MD_WRAP_H */
+374
View File
@@ -0,0 +1,374 @@
/*
* TCP networking functions
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "polarssl/config.h"
#if defined(POLARSSL_NET_C)
#include "polarssl/net.h"
#if defined(_WIN32) || defined(_WIN32_WCE)
#include <winsock2.h>
#include <windows.h>
#if defined(_WIN32_WCE)
#pragma comment( lib, "ws2.lib" )
#else
#pragma comment( lib, "ws2_32.lib" )
#endif
#define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0)
#define write(fd,buf,len) send(fd,(char*)buf,(int) len,0)
#define close(fd) closesocket(fd)
static int wsa_init_done = 0;
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
defined(__DragonflyBSD__)
#include <sys/endian.h>
#elif defined(__APPLE__)
#include <machine/endian.h>
#elif defined(sun)
#include <sys/isa_defs.h>
#else
#include <endian.h>
#endif
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#ifdef _MSC_VER
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
/*
* htons() is not always available.
* By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and __BIG_ENDIAN
* to help determine endianess.
*/
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
#define POLARSSL_HTONS(n) (n)
#define POLARSSL_HTONL(n) (n)
#else
#define POLARSSL_HTONS(n) ((((unsigned short)(n) & 0xFF ) << 8 ) | \
(((unsigned short)(n) & 0xFF00 ) >> 8 ))
#define POLARSSL_HTONL(n) ((((unsigned long )(n) & 0xFF ) << 24) | \
(((unsigned long )(n) & 0xFF00 ) << 8 ) | \
(((unsigned long )(n) & 0xFF0000 ) >> 8 ) | \
(((unsigned long )(n) & 0xFF000000) >> 24))
#endif
unsigned short net_htons(unsigned short n);
unsigned long net_htonl(unsigned long n);
#define net_htons(n) POLARSSL_HTONS(n)
#define net_htonl(n) POLARSSL_HTONL(n)
/*
* Initiate a TCP connection with host:port
*/
int net_connect( int *fd, const char *host, int port )
{
struct sockaddr_in server_addr;
struct hostent *server_host;
#if defined(_WIN32) || defined(_WIN32_WCE)
WSADATA wsaData;
if( wsa_init_done == 0 )
{
if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
wsa_init_done = 1;
}
#else
signal( SIGPIPE, SIG_IGN );
#endif
if( ( server_host = gethostbyname( host ) ) == NULL )
return( POLARSSL_ERR_NET_UNKNOWN_HOST );
if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
memcpy( (void *) &server_addr.sin_addr,
(void *) server_host->h_addr,
server_host->h_length );
server_addr.sin_family = AF_INET;
server_addr.sin_port = net_htons( port );
if( connect( *fd, (struct sockaddr *) &server_addr,
sizeof( server_addr ) ) < 0 )
{
close( *fd );
return( POLARSSL_ERR_NET_CONNECT_FAILED );
}
return( 0 );
}
/*
* Create a listening socket on bind_ip:port
*/
int net_bind( int *fd, const char *bind_ip, int port )
{
int n, c[4];
struct sockaddr_in server_addr;
#if defined(_WIN32) || defined(_WIN32_WCE)
WSADATA wsaData;
if( wsa_init_done == 0 )
{
if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
wsa_init_done = 1;
}
#else
signal( SIGPIPE, SIG_IGN );
#endif
if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
return( POLARSSL_ERR_NET_SOCKET_FAILED );
n = 1;
setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &n, sizeof( n ) );
server_addr.sin_addr.s_addr = net_htonl( INADDR_ANY );
server_addr.sin_family = AF_INET;
server_addr.sin_port = net_htons( port );
if( bind_ip != NULL )
{
memset( c, 0, sizeof( c ) );
sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] );
for( n = 0; n < 4; n++ )
if( c[n] < 0 || c[n] > 255 )
break;
if( n == 4 )
server_addr.sin_addr.s_addr = net_htonl(
( (uint32_t) c[0] << 24 ) |
( (uint32_t) c[1] << 16 ) |
( (uint32_t) c[2] << 8 ) |
( (uint32_t) c[3] ) );
}
if( bind( *fd, (struct sockaddr *) &server_addr,
sizeof( server_addr ) ) < 0 )
{
close( *fd );
return( POLARSSL_ERR_NET_BIND_FAILED );
}
if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 )
{
close( *fd );
return( POLARSSL_ERR_NET_LISTEN_FAILED );
}
return( 0 );
}
/*
* Check if the current operation is blocking
*/
static int net_is_blocking( void )
{
#if defined(_WIN32) || defined(_WIN32_WCE)
return( WSAGetLastError() == WSAEWOULDBLOCK );
#else
switch( errno )
{
#if defined EAGAIN
case EAGAIN:
#endif
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
return( 1 );
}
return( 0 );
#endif
}
/*
* Accept a connection from a remote client
*/
int net_accept( int bind_fd, int *client_fd, void *client_ip )
{
struct sockaddr_in client_addr;
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
defined(_SOCKLEN_T_DECLARED)
socklen_t n = (socklen_t) sizeof( client_addr );
#else
int n = (int) sizeof( client_addr );
#endif
*client_fd = accept( bind_fd, (struct sockaddr *)
&client_addr, &n );
if( *client_fd < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_WANT_READ );
return( POLARSSL_ERR_NET_ACCEPT_FAILED );
}
if( client_ip != NULL )
memcpy( client_ip, &client_addr.sin_addr.s_addr,
sizeof( client_addr.sin_addr.s_addr ) );
return( 0 );
}
/*
* Set the socket blocking or non-blocking
*/
int net_set_block( int fd )
{
#if defined(_WIN32) || defined(_WIN32_WCE)
u_long n = 0;
return( ioctlsocket( fd, FIONBIO, &n ) );
#else
return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) );
#endif
}
int net_set_nonblock( int fd )
{
#if defined(_WIN32) || defined(_WIN32_WCE)
u_long n = 1;
return( ioctlsocket( fd, FIONBIO, &n ) );
#else
return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) );
#endif
}
/*
* Portable usleep helper
*/
void net_usleep( unsigned long usec )
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = usec;
select( 0, NULL, NULL, NULL, &tv );
}
/*
* Read at most 'len' characters
*/
int net_recv( void *ctx, unsigned char *buf, size_t len )
{
int ret = read( *((int *) ctx), buf, len );
if( ret < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_WANT_READ );
#if defined(_WIN32) || defined(_WIN32_WCE)
if( WSAGetLastError() == WSAECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
#else
if( errno == EPIPE || errno == ECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( POLARSSL_ERR_NET_WANT_READ );
#endif
return( POLARSSL_ERR_NET_RECV_FAILED );
}
return( ret );
}
/*
* Write at most 'len' characters
*/
int net_send( void *ctx, const unsigned char *buf, size_t len )
{
int ret = write( *((int *) ctx), buf, len );
if( ret < 0 )
{
if( net_is_blocking() != 0 )
return( POLARSSL_ERR_NET_WANT_WRITE );
#if defined(_WIN32) || defined(_WIN32_WCE)
if( WSAGetLastError() == WSAECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
#else
if( errno == EPIPE || errno == ECONNRESET )
return( POLARSSL_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( POLARSSL_ERR_NET_WANT_WRITE );
#endif
return( POLARSSL_ERR_NET_SEND_FAILED );
}
return( ret );
}
/*
* Gracefully close the connection
*/
void net_close( int fd )
{
shutdown( fd, 2 );
close( fd );
}
#endif
+159
View File
@@ -0,0 +1,159 @@
/**
* \file net.h
*
* \brief Network communication functions
*
* Copyright (C) 2006-2011, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_NET_H
#define POLARSSL_NET_H
#include <string.h>
#define POLARSSL_ERR_NET_UNKNOWN_HOST -0x0056 /**< Failed to get an IP address for the given hostname. */
#define POLARSSL_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */
#define POLARSSL_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */
#define POLARSSL_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */
#define POLARSSL_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */
#define POLARSSL_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */
#define POLARSSL_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */
#define POLARSSL_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */
#define POLARSSL_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */
#define POLARSSL_ERR_NET_WANT_READ -0x0052 /**< Connection requires a read call. */
#define POLARSSL_ERR_NET_WANT_WRITE -0x0054 /**< Connection requires a write call. */
#define POLARSSL_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Initiate a TCP connection with host:port
*
* \param fd Socket to use
* \param host Host to connect to
* \param port Port to connect to
*
* \return 0 if successful, or one of:
* POLARSSL_ERR_NET_SOCKET_FAILED,
* POLARSSL_ERR_NET_UNKNOWN_HOST,
* POLARSSL_ERR_NET_CONNECT_FAILED
*/
int net_connect( int *fd, const char *host, int port );
/**
* \brief Create a listening socket on bind_ip:port.
* If bind_ip == NULL, all interfaces are binded.
*
* \param fd Socket to use
* \param bind_ip IP to bind to, can be NULL
* \param port Port number to use
*
* \return 0 if successful, or one of:
* POLARSSL_ERR_NET_SOCKET_FAILED,
* POLARSSL_ERR_NET_BIND_FAILED,
* POLARSSL_ERR_NET_LISTEN_FAILED
*/
int net_bind( int *fd, const char *bind_ip, int port );
/**
* \brief Accept a connection from a remote client
*
* \param bind_fd Relevant socket
* \param client_fd Will contain the connected client socket
* \param client_ip Will contain the client IP address
*
* \return 0 if successful, POLARSSL_ERR_NET_ACCEPT_FAILED, or
* POLARSSL_ERR_NET_WOULD_BLOCK is bind_fd was set to
* non-blocking and accept() is blocking.
*/
int net_accept( int bind_fd, int *client_fd, void *client_ip );
/**
* \brief Set the socket blocking
*
* \param fd Socket to set
*
* \return 0 if successful, or a non-zero error code
*/
int net_set_block( int fd );
/**
* \brief Set the socket non-blocking
*
* \param fd Socket to set
*
* \return 0 if successful, or a non-zero error code
*/
int net_set_nonblock( int fd );
/**
* \brief Portable usleep helper
*
* \param usec Amount of microseconds to sleep
*
* \note Real amount of time slept will not be less than
* select()'s timeout granularity (typically, 10ms).
*/
void net_usleep( unsigned long usec );
/**
* \brief Read at most 'len' characters. If no error occurs,
* the actual amount read is returned.
*
* \param ctx Socket
* \param buf The buffer to write to
* \param len Maximum length of the buffer
*
* \return This function returns the number of bytes received,
* or a non-zero error code; POLARSSL_ERR_NET_WANT_READ
* indicates read() is blocking.
*/
int net_recv( void *ctx, unsigned char *buf, size_t len );
/**
* \brief Write at most 'len' characters. If no error occurs,
* the actual amount read is returned.
*
* \param ctx Socket
* \param buf The buffer to read from
* \param len The length of the buffer
*
* \return This function returns the number of bytes sent,
* or a non-zero error code; POLARSSL_ERR_NET_WANT_WRITE
* indicates write() is blocking.
*/
int net_send( void *ctx, const unsigned char *buf, size_t len );
/**
* \brief Gracefully shutdown the connection
*
* \param fd The socket to close
*/
void net_close( int fd );
#ifdef __cplusplus
}
#endif
#endif /* net.h */
+136
View File
@@ -0,0 +1,136 @@
/**
* \file openssl.h
*
* \brief OpenSSL wrapper (definitions, inline functions).
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* OpenSSL wrapper contributed by David Barett
*/
#ifndef POLARSSL_OPENSSL_H
#define POLARSSL_OPENSSL_H
#include "polarssl/aes.h"
#include "polarssl/md5.h"
#include "polarssl/rsa.h"
#include "polarssl/sha1.h"
#define AES_SIZE 16
#define AES_BLOCK_SIZE 16
#define AES_KEY aes_context
#define MD5_CTX md5_context
#define SHA_CTX sha1_context
#define SHA1_Init( CTX ) \
sha1_starts( (CTX) )
#define SHA1_Update( CTX, BUF, LEN ) \
sha1_update( (CTX), (unsigned char *)(BUF), (LEN) )
#define SHA1_Final( OUT, CTX ) \
sha1_finish( (CTX), (OUT) )
#define MD5_Init( CTX ) \
md5_starts( (CTX) )
#define MD5_Update( CTX, BUF, LEN ) \
md5_update( (CTX), (unsigned char *)(BUF), (LEN) )
#define MD5_Final( OUT, CTX ) \
md5_finish( (CTX), (OUT) )
#define AES_set_encrypt_key( KEY, KEYSIZE, CTX ) \
aes_setkey_enc( (CTX), (KEY), (KEYSIZE) )
#define AES_set_decrypt_key( KEY, KEYSIZE, CTX ) \
aes_setkey_dec( (CTX), (KEY), (KEYSIZE) )
#define AES_cbc_encrypt( INPUT, OUTPUT, LEN, CTX, IV, MODE ) \
aes_crypt_cbc( (CTX), (MODE), (LEN), (IV), (INPUT), (OUTPUT) )
/*
* RSA stuff follows. TODO: needs cleanup
*/
inline int __RSA_Passthrough( void *output, void *input, int size )
{
memcpy( output, input, size );
return size;
}
inline rsa_context* d2i_RSA_PUBKEY( void *ignore, unsigned char **bufptr,
int len )
{
unsigned char *buffer = *(unsigned char **) bufptr;
rsa_context *rsa;
/*
* Not a general-purpose parser: only parses public key from *exactly*
* openssl genrsa -out privkey.pem 512 (or 1024)
* openssl rsa -in privkey.pem -out privatekey.der -outform der
* openssl rsa -in privkey.pem -out pubkey.der -outform der -pubout
*
* TODO: make a general-purpose parse
*/
if( ignore != 0 || ( len != 94 && len != 162 ) )
return( 0 );
rsa = (rsa_context *) malloc( sizeof( rsa_rsa ) );
if( rsa == NULL )
return( 0 );
memset( rsa, 0, sizeof( rsa_context ) );
if( ( len == 94 &&
mpi_read_binary( &rsa->N, &buffer[ 25], 64 ) == 0 &&
mpi_read_binary( &rsa->E, &buffer[ 91], 3 ) == 0 ) ||
( len == 162 &&
mpi_read_binary( &rsa->N, &buffer[ 29], 128 ) == 0 ) &&
mpi_read_binary( &rsa->E, &buffer[159], 3 ) == 0 )
{
/*
* key read successfully
*/
rsa->len = ( mpi_msb( &rsa->N ) + 7 ) >> 3;
return( rsa );
}
else
{
memset( rsa, 0, sizeof( rsa_context ) );
free( rsa );
return( 0 );
}
}
#define RSA rsa_context
#define RSA_PKCS1_PADDING 1 /* ignored; always encrypt with this */
#define RSA_size( CTX ) (CTX)->len
#define RSA_free( CTX ) rsa_free( CTX )
#define ERR_get_error( ) "ERR_get_error() not supported"
#define RSA_blinding_off( IGNORE )
#define d2i_RSAPrivateKey( a, b, c ) new rsa_context /* TODO: C++ bleh */
inline int RSA_public_decrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PUBLIC, &outsize, input, output ) ) return outsize; else return -1; }
inline int RSA_private_decrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PRIVATE, &outsize, input, output ) ) return outsize; else return -1; }
inline int RSA_public_encrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PUBLIC, size, input, output ) ) return RSA_size(key); else return -1; }
inline int RSA_private_encrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PRIVATE, size, input, output ) ) return RSA_size(key); else return -1; }
#ifdef __cplusplus
}
#endif
#endif /* openssl.h */
+162
View File
@@ -0,0 +1,162 @@
/*
* VIA PadLock support functions
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* This implementation is based on the VIA PadLock Programming Guide:
*
* http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
* programming_guide.pdf
*/
#include "polarssl/config.h"
#if defined(POLARSSL_PADLOCK_C)
#include "polarssl/padlock.h"
#if defined(POLARSSL_HAVE_X86)
/*
* PadLock detection routine
*/
int padlock_supports( int feature )
{
static int flags = -1;
int ebx, edx;
if( flags == -1 )
{
__asm__( "movl %%ebx, %0 \n" \
"movl $0xC0000000, %%eax \n" \
"cpuid \n" \
"cmpl $0xC0000001, %%eax \n" \
"movl $0, %%edx \n" \
"jb unsupported \n" \
"movl $0xC0000001, %%eax \n" \
"cpuid \n" \
"unsupported: \n" \
"movl %%edx, %1 \n" \
"movl %2, %%ebx \n"
: "=m" (ebx), "=m" (edx)
: "m" (ebx)
: "eax", "ecx", "edx" );
flags = edx;
}
return( flags & feature );
}
/*
* PadLock AES-ECB block en(de)cryption
*/
int padlock_xcryptecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
int ebx;
uint32_t *rk;
uint32_t *blk;
uint32_t *ctrl;
unsigned char buf[256];
rk = ctx->rk;
blk = PADLOCK_ALIGN16( buf );
memcpy( blk, input, 16 );
ctrl = blk + 4;
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 );
__asm__( "pushfl; popfl \n" \
"movl %%ebx, %0 \n" \
"movl $1, %%ecx \n" \
"movl %2, %%edx \n" \
"movl %3, %%ebx \n" \
"movl %4, %%esi \n" \
"movl %4, %%edi \n" \
".byte 0xf3,0x0f,0xa7,0xc8\n" \
"movl %1, %%ebx \n"
: "=m" (ebx)
: "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk)
: "ecx", "edx", "esi", "edi" );
memcpy( output, blk, 16 );
return( 0 );
}
/*
* PadLock AES-CBC buffer en(de)cryption
*/
int padlock_xcryptcbc( aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int ebx;
size_t count;
uint32_t *rk;
uint32_t *iw;
uint32_t *ctrl;
unsigned char buf[256];
if( ( (long) input & 15 ) != 0 ||
( (long) output & 15 ) != 0 )
return( POLARSSL_ERR_PADLOCK_DATA_MISALIGNED );
rk = ctx->rk;
iw = PADLOCK_ALIGN16( buf );
memcpy( iw, iv, 16 );
ctrl = iw + 4;
*ctrl = 0x80 | ctx->nr | ( ( ctx->nr + (mode^1) - 10 ) << 9 );
count = (length + 15) >> 4;
__asm__( "pushfl; popfl \n" \
"movl %%ebx, %0 \n" \
"movl %2, %%ecx \n" \
"movl %3, %%edx \n" \
"movl %4, %%ebx \n" \
"movl %5, %%esi \n" \
"movl %6, %%edi \n" \
"movl %7, %%eax \n" \
".byte 0xf3,0x0f,0xa7,0xd0\n" \
"movl %1, %%ebx \n"
: "=m" (ebx)
: "m" (ebx), "m" (count), "m" (ctrl),
"m" (rk), "m" (input), "m" (output), "m" (iw)
: "eax", "ecx", "edx", "esi", "edi" );
memcpy( iv, iw, 16 );
return( 0 );
}
#endif
#endif
+108
View File
@@ -0,0 +1,108 @@
/**
* \file padlock.h
*
* \brief VIA PadLock ACE for HW encryption/decryption supported by some processors
*
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef POLARSSL_PADLOCK_H
#define POLARSSL_PADLOCK_H
#include "polarssl/aes.h"
#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */
#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__)
#ifndef POLARSSL_HAVE_X86
#define POLARSSL_HAVE_X86
#endif
#ifdef _MSC_VER
#include <basetsd.h>
typedef INT32 int32_t;
#else
#include <inttypes.h>
#endif
#define PADLOCK_RNG 0x000C
#define PADLOCK_ACE 0x00C0
#define PADLOCK_PHE 0x0C00
#define PADLOCK_PMM 0x3000
#define PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15))
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief PadLock detection routine
*
* \param The feature to detect
*
* \return 1 if CPU has support for the feature, 0 otherwise
*/
int padlock_supports( int feature );
/**
* \brief PadLock AES-ECB block en(de)cryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if success, 1 if operation failed
*/
int padlock_xcryptecb( aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] );
/**
* \brief PadLock AES-CBC buffer en(de)cryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if success, 1 if operation failed
*/
int padlock_xcryptcbc( aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* HAVE_X86 */
#endif /* padlock.h */
+60
View File
@@ -0,0 +1,60 @@
/**
* \file pbkdf2.c
*
* \brief Password-Based Key Derivation Function 2 (from PKCS#5)
* DEPRECATED: Use pkcs5.c instead
*
* \author Mathias Olsson <mathias@kompetensum.com>
*
* Copyright (C) 2006-2012, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* PBKDF2 is part of PKCS#5
*
* http://tools.ietf.org/html/rfc2898 (Specification)
* http://tools.ietf.org/html/rfc6070 (Test vectors)
*/
#include "polarssl/config.h"
#if defined(POLARSSL_PBKDF2_C)
#include "polarssl/pbkdf2.h"
#include "polarssl/pkcs5.h"
int pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, size_t plen,
const unsigned char *salt, size_t slen,
unsigned int iteration_count,
uint32_t key_length, unsigned char *output )
{
return pkcs5_pbkdf2_hmac( ctx, password, plen, salt, slen, iteration_count,
key_length, output );
}
#if defined(POLARSSL_SELF_TEST)
int pbkdf2_self_test( int verbose )
{
return pkcs5_self_test( verbose );
}
#endif /* POLARSSL_SELF_TEST */
#endif /* POLARSSL_PBKDF2_C */

Some files were not shown because too many files have changed in this diff Show More