mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 00:39:14 +00:00
makerom v0.1
This commit is contained in:
@@ -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
|
||||||
@@ -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 ????????
|
||||||
@@ -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
|
||||||
File diff suppressed because one or more lines are too long
@@ -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 --*/
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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 );
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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"
|
||||||
|
|
||||||
|
|
||||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
File diff suppressed because one or more lines are too long
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
File diff suppressed because it is too large
Load Diff
+202
@@ -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
@@ -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
|
||||||
@@ -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
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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
@@ -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
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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
@@ -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
@@ -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 */
|
||||||
@@ -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 */
|
||||||
@@ -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
|
||||||
@@ -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 */
|
||||||
@@ -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
Reference in New Issue
Block a user