diff --git a/Makefile.am b/Makefile.am index 744e56874..922d664d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,11 +72,6 @@ include support/include.am include wolfcrypt/benchmark/include.am include wolfcrypt/src/include.am include wolfcrypt/test/include.am - -if BUILD_FIPS -include ctaocrypt/src/include.am -endif - include examples/client/include.am include examples/server/include.am include examples/echoclient/include.am diff --git a/ctaocrypt/src/aes_asm.asm b/ctaocrypt/src/aes_asm.asm deleted file mode 100755 index c02d46133..000000000 --- a/ctaocrypt/src/aes_asm.asm +++ /dev/null @@ -1,972 +0,0 @@ -; /*aes_asm . asm -; * -; *Copyright[C]2006 -2014 wolfSSL Inc . -; * -; *This file is part of CyaSSL . -; * -; *CyaSSL 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 . -; * -; *CyaSSL ,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 -; */ -; -; -; /*See IntelA dvanced Encryption Standard[AES]Instructions Set White Paper -; *by Israel,Intel Mobility Group Development Center,Israel Shay Gueron -; */ -; -; /* This file is in intel asm syntax, see .s for at&t syntax */ -; -; /* -; AES_CBC_encrypt[const ,unsigned char*in -; unsigned ,char*out -; unsigned ,char ivec+16 -; unsigned ,long length -; const ,unsigned char*KS -; int nr] -; */ -_text SEGMENT -AES_CBC_encrypt PROC -;# parameter 1: rdi -;# parameter 2: rsi -;# parameter 3: rdx -;# parameter 4: rcx -;# parameter 5: r8 -;# parameter 6: r9d - -; save rdi and rsi to rax and r11, restore before ret - mov rax,rdi - mov r11,rsi - -; convert to what we had for att&t convention - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8,[rsp+40] - mov r9d,[rsp+48] - - mov r10,rcx - shr rcx,4 - shl r10,60 - je NO_PARTS - add rcx,1 -NO_PARTS: - sub rsi,16 - movdqa xmm1,[rdx] -LOOP_1: - pxor xmm1,[rdi] - pxor xmm1,[r8] - add rsi,16 - add rdi,16 - cmp r9d,12 - aesenc xmm1,16[r8] - aesenc xmm1,32[r8] - aesenc xmm1,48[r8] - aesenc xmm1,64[r8] - aesenc xmm1,80[r8] - aesenc xmm1,96[r8] - aesenc xmm1,112[r8] - aesenc xmm1,128[r8] - aesenc xmm1,144[r8] - movdqa xmm2,160[r8] - jb LAST - cmp r9d,14 - - aesenc xmm1,160[r8] - aesenc xmm1,176[r8] - movdqa xmm2,192[r8] - jb LAST - aesenc xmm1,192[r8] - aesenc xmm1,208[r8] - movdqa xmm2,224[r8] -LAST: - dec rcx - aesenclast xmm1,xmm2 - movdqu [rsi],xmm1 - jne LOOP_1 - ; restore non volatile rdi,rsi - mov rdi,rax - mov rsi,r11 - ret -AES_CBC_encrypt ENDP - - - -; /* -; AES_CBC_decrypt[const ,unsigned char*in -; unsigned ,char*out -; unsigned ,char ivec+16 -; unsigned ,long length -; const ,unsigned char*KS -; int nr] -; */ -; . globl AES_CBC_decrypt -AES_CBC_decrypt PROC -;# parameter 1: rdi -;# parameter 2: rsi -;# parameter 3: rdx -;# parameter 4: rcx -;# parameter 5: r8 -;# parameter 6: r9d - -; save rdi and rsi to rax and r11, restore before ret - mov rax,rdi - mov r11,rsi - -; convert to what we had for att&t convention - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8,[rsp+40] - mov r9d,[rsp+48] - -; on microsoft xmm6-xmm15 are non volaitle, let's save on stack and restore at end - sub rsp,8+8*16 ; 8 = align stack , 8 xmm6-12,15 16 bytes each - movdqa [rsp+0], xmm6 - movdqa [rsp+16], xmm7 - movdqa [rsp+32], xmm8 - movdqa [rsp+48], xmm9 - movdqa [rsp+64], xmm10 - movdqa [rsp+80], xmm11 - movdqa [rsp+96], xmm12 - movdqa [rsp+112], xmm15 - - mov r10,rcx - shr rcx,4 - shl r10,60 - je DNO_PARTS_4 - add rcx,1 -DNO_PARTS_4: - mov r10,rcx - shl r10,62 - shr r10,62 - shr rcx,2 - movdqu xmm5,[rdx] - je DREMAINDER_4 - sub rsi,64 -DLOOP_4: - movdqu xmm1,[rdi] - movdqu xmm2,16[rdi] - movdqu xmm3,32[rdi] - movdqu xmm4,48[rdi] - movdqa xmm6,xmm1 - movdqa xmm7,xmm2 - movdqa xmm8,xmm3 - movdqa xmm15,xmm4 - movdqa xmm9,[r8] - movdqa xmm10,16[r8] - movdqa xmm11,32[r8] - movdqa xmm12,48[r8] - pxor xmm1,xmm9 - pxor xmm2,xmm9 - pxor xmm3,xmm9 - - pxor xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - aesdec xmm1,xmm11 - aesdec xmm2,xmm11 - aesdec xmm3,xmm11 - aesdec xmm4,xmm11 - aesdec xmm1,xmm12 - aesdec xmm2,xmm12 - aesdec xmm3,xmm12 - aesdec xmm4,xmm12 - movdqa xmm9,64[r8] - movdqa xmm10,80[r8] - movdqa xmm11,96[r8] - movdqa xmm12,112[r8] - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - aesdec xmm1,xmm11 - aesdec xmm2,xmm11 - aesdec xmm3,xmm11 - aesdec xmm4,xmm11 - aesdec xmm1,xmm12 - aesdec xmm2,xmm12 - aesdec xmm3,xmm12 - aesdec xmm4,xmm12 - movdqa xmm9,128[r8] - movdqa xmm10,144[r8] - movdqa xmm11,160[r8] - cmp r9d,12 - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - jb DLAST_4 - movdqa xmm9,160[r8] - movdqa xmm10,176[r8] - movdqa xmm11,192[r8] - cmp r9d,14 - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - jb DLAST_4 - - movdqa xmm9,192[r8] - movdqa xmm10,208[r8] - movdqa xmm11,224[r8] - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 -DLAST_4: - add rdi,64 - add rsi,64 - dec rcx - aesdeclast xmm1,xmm11 - aesdeclast xmm2,xmm11 - aesdeclast xmm3,xmm11 - aesdeclast xmm4,xmm11 - pxor xmm1,xmm5 - pxor xmm2,xmm6 - pxor xmm3,xmm7 - pxor xmm4,xmm8 - movdqu [rsi],xmm1 - movdqu 16[rsi],xmm2 - movdqu 32[rsi],xmm3 - movdqu 48[rsi],xmm4 - movdqa xmm5,xmm15 - jne DLOOP_4 - add rsi,64 -DREMAINDER_4: - cmp r10,0 - je DEND_4 -DLOOP_4_2: - movdqu xmm1,[rdi] - movdqa xmm15,xmm1 - add rdi,16 - pxor xmm1,[r8] - movdqu xmm2,160[r8] - cmp r9d,12 - aesdec xmm1,16[r8] - aesdec xmm1,32[r8] - aesdec xmm1,48[r8] - aesdec xmm1,64[r8] - aesdec xmm1,80[r8] - aesdec xmm1,96[r8] - aesdec xmm1,112[r8] - aesdec xmm1,128[r8] - aesdec xmm1,144[r8] - jb DLAST_4_2 - movdqu xmm2,192[r8] - cmp r9d,14 - aesdec xmm1,160[r8] - aesdec xmm1,176[r8] - jb DLAST_4_2 - movdqu xmm2,224[r8] - aesdec xmm1,192[r8] - aesdec xmm1,208[r8] -DLAST_4_2: - aesdeclast xmm1,xmm2 - pxor xmm1,xmm5 - movdqa xmm5,xmm15 - movdqu [rsi],xmm1 - - add rsi,16 - dec r10 - jne DLOOP_4_2 -DEND_4: - ; restore non volatile rdi,rsi - mov rdi,rax - mov rsi,r11 - ; restore non volatile xmms from stack - movdqa xmm6, [rsp+0] - movdqa xmm7, [rsp+16] - movdqa xmm8, [rsp+32] - movdqa xmm9, [rsp+48] - movdqa xmm10, [rsp+64] - movdqa xmm11, [rsp+80] - movdqa xmm12, [rsp+96] - movdqa xmm15, [rsp+112] - add rsp,8+8*16 ; 8 = align stack , 8 xmm6-12,15 16 bytes each - ret -AES_CBC_decrypt ENDP - -; /* -; AES_ECB_encrypt[const ,unsigned char*in -; unsigned ,char*out -; unsigned ,long length -; const ,unsigned char*KS -; int nr] -; */ -; . globl AES_ECB_encrypt -AES_ECB_encrypt PROC -;# parameter 1: rdi -;# parameter 2: rsi -;# parameter 3: rdx -;# parameter 4: rcx -;# parameter 5: r8d - -; save rdi and rsi to rax and r11, restore before ret - mov rax,rdi - mov r11,rsi - -; convert to what we had for att&t convention - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8d,[rsp+40] - -; on microsoft xmm6-xmm15 are non volaitle, let's save on stack and restore at end - sub rsp,8+4*16 ; 8 = align stack , 4 xmm9-12, 16 bytes each - movdqa [rsp+0], xmm9 - movdqa [rsp+16], xmm10 - movdqa [rsp+32], xmm11 - movdqa [rsp+48], xmm12 - - - mov r10,rdx - shr rdx,4 - shl r10,60 - je EECB_NO_PARTS_4 - add rdx,1 -EECB_NO_PARTS_4: - mov r10,rdx - shl r10,62 - shr r10,62 - shr rdx,2 - je EECB_REMAINDER_4 - sub rsi,64 -EECB_LOOP_4: - movdqu xmm1,[rdi] - movdqu xmm2,16[rdi] - movdqu xmm3,32[rdi] - movdqu xmm4,48[rdi] - movdqa xmm9,[rcx] - movdqa xmm10,16[rcx] - movdqa xmm11,32[rcx] - movdqa xmm12,48[rcx] - pxor xmm1,xmm9 - pxor xmm2,xmm9 - pxor xmm3,xmm9 - pxor xmm4,xmm9 - aesenc xmm1,xmm10 - aesenc xmm2,xmm10 - aesenc xmm3,xmm10 - aesenc xmm4,xmm10 - aesenc xmm1,xmm11 - aesenc xmm2,xmm11 - aesenc xmm3,xmm11 - aesenc xmm4,xmm11 - aesenc xmm1,xmm12 - aesenc xmm2,xmm12 - aesenc xmm3,xmm12 - aesenc xmm4,xmm12 - movdqa xmm9,64[rcx] - movdqa xmm10,80[rcx] - movdqa xmm11,96[rcx] - movdqa xmm12,112[rcx] - aesenc xmm1,xmm9 - aesenc xmm2,xmm9 - aesenc xmm3,xmm9 - aesenc xmm4,xmm9 - aesenc xmm1,xmm10 - aesenc xmm2,xmm10 - aesenc xmm3,xmm10 - aesenc xmm4,xmm10 - aesenc xmm1,xmm11 - aesenc xmm2,xmm11 - aesenc xmm3,xmm11 - aesenc xmm4,xmm11 - aesenc xmm1,xmm12 - aesenc xmm2,xmm12 - aesenc xmm3,xmm12 - aesenc xmm4,xmm12 - movdqa xmm9,128[rcx] - movdqa xmm10,144[rcx] - movdqa xmm11,160[rcx] - cmp r8d,12 - aesenc xmm1,xmm9 - aesenc xmm2,xmm9 - aesenc xmm3,xmm9 - aesenc xmm4,xmm9 - aesenc xmm1,xmm10 - aesenc xmm2,xmm10 - aesenc xmm3,xmm10 - aesenc xmm4,xmm10 - jb EECB_LAST_4 - movdqa xmm9,160[rcx] - movdqa xmm10,176[rcx] - movdqa xmm11,192[rcx] - cmp r8d,14 - aesenc xmm1,xmm9 - aesenc xmm2,xmm9 - aesenc xmm3,xmm9 - aesenc xmm4,xmm9 - aesenc xmm1,xmm10 - aesenc xmm2,xmm10 - aesenc xmm3,xmm10 - aesenc xmm4,xmm10 - jb EECB_LAST_4 - movdqa xmm9,192[rcx] - movdqa xmm10,208[rcx] - movdqa xmm11,224[rcx] - aesenc xmm1,xmm9 - aesenc xmm2,xmm9 - aesenc xmm3,xmm9 - aesenc xmm4,xmm9 - aesenc xmm1,xmm10 - aesenc xmm2,xmm10 - aesenc xmm3,xmm10 - aesenc xmm4,xmm10 -EECB_LAST_4: - add rdi,64 - add rsi,64 - dec rdx - aesenclast xmm1,xmm11 - aesenclast xmm2,xmm11 - aesenclast xmm3,xmm11 - aesenclast xmm4,xmm11 - movdqu [rsi],xmm1 - movdqu 16[rsi],xmm2 - movdqu 32[rsi],xmm3 - movdqu 48[rsi],xmm4 - jne EECB_LOOP_4 - add rsi,64 -EECB_REMAINDER_4: - cmp r10,0 - je EECB_END_4 -EECB_LOOP_4_2: - movdqu xmm1,[rdi] - add rdi,16 - pxor xmm1,[rcx] - movdqu xmm2,160[rcx] - aesenc xmm1,16[rcx] - aesenc xmm1,32[rcx] - aesenc xmm1,48[rcx] - aesenc xmm1,64[rcx] - aesenc xmm1,80[rcx] - aesenc xmm1,96[rcx] - aesenc xmm1,112[rcx] - aesenc xmm1,128[rcx] - aesenc xmm1,144[rcx] - cmp r8d,12 - jb EECB_LAST_4_2 - movdqu xmm2,192[rcx] - aesenc xmm1,160[rcx] - aesenc xmm1,176[rcx] - cmp r8d,14 - jb EECB_LAST_4_2 - movdqu xmm2,224[rcx] - aesenc xmm1,192[rcx] - aesenc xmm1,208[rcx] -EECB_LAST_4_2: - aesenclast xmm1,xmm2 - movdqu [rsi],xmm1 - add rsi,16 - dec r10 - jne EECB_LOOP_4_2 -EECB_END_4: - ; restore non volatile rdi,rsi - mov rdi,rax - mov rsi,r11 - ; restore non volatile xmms from stack - movdqa xmm9, [rsp+0] - movdqa xmm10, [rsp+16] - movdqa xmm11, [rsp+32] - movdqa xmm12, [rsp+48] - add rsp,8+4*16 ; 8 = align stack , 4 xmm9-12 16 bytes each - ret -AES_ECB_encrypt ENDP - -; /* -; AES_ECB_decrypt[const ,unsigned char*in -; unsigned ,char*out -; unsigned ,long length -; const ,unsigned char*KS -; int nr] -; */ -; . globl AES_ECB_decrypt -AES_ECB_decrypt PROC -;# parameter 1: rdi -;# parameter 2: rsi -;# parameter 3: rdx -;# parameter 4: rcx -;# parameter 5: r8d - -; save rdi and rsi to rax and r11, restore before ret - mov rax,rdi - mov r11,rsi - -; convert to what we had for att&t convention - mov rdi,rcx - mov rsi,rdx - mov rdx,r8 - mov rcx,r9 - mov r8d,[rsp+40] - -; on microsoft xmm6-xmm15 are non volaitle, let's save on stack and restore at end - sub rsp,8+4*16 ; 8 = align stack , 4 xmm9-12, 16 bytes each - movdqa [rsp+0], xmm9 - movdqa [rsp+16], xmm10 - movdqa [rsp+32], xmm11 - movdqa [rsp+48], xmm12 - - mov r10,rdx - shr rdx,4 - shl r10,60 - je DECB_NO_PARTS_4 - add rdx,1 -DECB_NO_PARTS_4: - mov r10,rdx - shl r10,62 - shr r10,62 - shr rdx,2 - je DECB_REMAINDER_4 - sub rsi,64 -DECB_LOOP_4: - movdqu xmm1,[rdi] - movdqu xmm2,16[rdi] - movdqu xmm3,32[rdi] - movdqu xmm4,48[rdi] - movdqa xmm9,[rcx] - movdqa xmm10,16[rcx] - movdqa xmm11,32[rcx] - movdqa xmm12,48[rcx] - pxor xmm1,xmm9 - pxor xmm2,xmm9 - pxor xmm3,xmm9 - pxor xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - aesdec xmm1,xmm11 - aesdec xmm2,xmm11 - aesdec xmm3,xmm11 - aesdec xmm4,xmm11 - aesdec xmm1,xmm12 - aesdec xmm2,xmm12 - aesdec xmm3,xmm12 - aesdec xmm4,xmm12 - movdqa xmm9,64[rcx] - movdqa xmm10,80[rcx] - movdqa xmm11,96[rcx] - movdqa xmm12,112[rcx] - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - aesdec xmm1,xmm11 - aesdec xmm2,xmm11 - aesdec xmm3,xmm11 - aesdec xmm4,xmm11 - aesdec xmm1,xmm12 - aesdec xmm2,xmm12 - aesdec xmm3,xmm12 - aesdec xmm4,xmm12 - movdqa xmm9,128[rcx] - movdqa xmm10,144[rcx] - movdqa xmm11,160[rcx] - cmp r8d,12 - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - jb DECB_LAST_4 - movdqa xmm9,160[rcx] - movdqa xmm10,176[rcx] - movdqa xmm11,192[rcx] - cmp r8d,14 - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 - jb DECB_LAST_4 - movdqa xmm9,192[rcx] - movdqa xmm10,208[rcx] - movdqa xmm11,224[rcx] - aesdec xmm1,xmm9 - aesdec xmm2,xmm9 - aesdec xmm3,xmm9 - aesdec xmm4,xmm9 - aesdec xmm1,xmm10 - aesdec xmm2,xmm10 - aesdec xmm3,xmm10 - aesdec xmm4,xmm10 -DECB_LAST_4: - add rdi,64 - add rsi,64 - dec rdx - aesdeclast xmm1,xmm11 - aesdeclast xmm2,xmm11 - aesdeclast xmm3,xmm11 - aesdeclast xmm4,xmm11 - movdqu [rsi],xmm1 - movdqu 16[rsi],xmm2 - movdqu 32[rsi],xmm3 - movdqu 48[rsi],xmm4 - jne DECB_LOOP_4 - add rsi,64 -DECB_REMAINDER_4: - cmp r10,0 - je DECB_END_4 -DECB_LOOP_4_2: - movdqu xmm1,[rdi] - add rdi,16 - pxor xmm1,[rcx] - movdqu xmm2,160[rcx] - cmp r8d,12 - aesdec xmm1,16[rcx] - aesdec xmm1,32[rcx] - aesdec xmm1,48[rcx] - aesdec xmm1,64[rcx] - aesdec xmm1,80[rcx] - aesdec xmm1,96[rcx] - aesdec xmm1,112[rcx] - aesdec xmm1,128[rcx] - aesdec xmm1,144[rcx] - jb DECB_LAST_4_2 - cmp r8d,14 - movdqu xmm2,192[rcx] - aesdec xmm1,160[rcx] - aesdec xmm1,176[rcx] - jb DECB_LAST_4_2 - movdqu xmm2,224[rcx] - aesdec xmm1,192[rcx] - aesdec xmm1,208[rcx] -DECB_LAST_4_2: - aesdeclast xmm1,xmm2 - movdqu [rsi],xmm1 - add rsi,16 - dec r10 - jne DECB_LOOP_4_2 -DECB_END_4: - ; restore non volatile rdi,rsi - mov rdi,rax - mov rsi,r11 - ; restore non volatile xmms from stack - movdqa xmm9, [rsp+0] - movdqa xmm10, [rsp+16] - movdqa xmm11, [rsp+32] - movdqa xmm12, [rsp+48] - add rsp,8+4*16 ; 8 = align stack , 4 xmm9-12 16 bytes each - ret -AES_ECB_decrypt ENDP - - - -; /* -; void ,AES_128_Key_Expansion[const unsigned char*userkey -; unsigned char*key_schedule]/ -; */ -; . align 16,0x90 -; . globl AES_128_Key_Expansion -AES_128_Key_Expansion PROC -;# parameter 1: rdi -;# parameter 2: rsi - -; save rdi and rsi to rax and r11, restore before ret - mov rax,rdi - mov r11,rsi - -; convert to what we had for att&t convention - mov rdi,rcx - mov rsi,rdx - - mov dword ptr 240[rsi],10 - - movdqu xmm1,[rdi] - movdqa [rsi],xmm1 - - -ASSISTS: - aeskeygenassist xmm2,xmm1,1 - call PREPARE_ROUNDKEY_128 - movdqa 16[rsi],xmm1 - - aeskeygenassist xmm2,xmm1,2 - call PREPARE_ROUNDKEY_128 - movdqa 32[rsi],xmm1 - - aeskeygenassist xmm2,xmm1,4 - call PREPARE_ROUNDKEY_128 - movdqa 48[rsi],xmm1 - - aeskeygenassist xmm2,xmm1,8 - call PREPARE_ROUNDKEY_128 - movdqa 64[rsi],xmm1 - - aeskeygenassist xmm2,xmm1,16 - call PREPARE_ROUNDKEY_128 - movdqa 80[rsi],xmm1 - - aeskeygenassist xmm2,xmm1,32 - call PREPARE_ROUNDKEY_128 - movdqa 96[rsi],xmm1 - - aeskeygenassist xmm2,xmm1,64 - call PREPARE_ROUNDKEY_128 - movdqa 112[rsi],xmm1 - aeskeygenassist xmm2,xmm1,80h - call PREPARE_ROUNDKEY_128 - movdqa 128[rsi],xmm1 - aeskeygenassist xmm2,xmm1,1bh - call PREPARE_ROUNDKEY_128 - movdqa 144[rsi],xmm1 - aeskeygenassist xmm2,xmm1,36h - call PREPARE_ROUNDKEY_128 - movdqa 160[rsi],xmm1 - ; restore non volatile rdi,rsi - mov rdi,rax - mov rsi,r11 - ret - -PREPARE_ROUNDKEY_128: - pshufd xmm2,xmm2,255 - movdqa xmm3,xmm1 - pslldq xmm3,4 - pxor xmm1,xmm3 - pslldq xmm3,4 - pxor xmm1,xmm3 - pslldq xmm3,4 - pxor xmm1,xmm3 - pxor xmm1,xmm2 - ret -AES_128_Key_Expansion ENDP - -; /* -; void ,AES_192_Key_Expansion[const unsigned char*userkey -; unsigned char*key] -; */ -; . globl AES_192_Key_Expansion -AES_192_Key_Expansion PROC -;# parameter 1: rdi -;# parameter 2: rsi - -; save rdi and rsi to rax and r11, restore before ret - mov rax,rdi - mov r11,rsi - -; convert to what we had for att&t convention - mov rdi,rcx - mov rsi,rdx - -; on microsoft xmm6-xmm15 are non volaitle, let's save on stack and restore at end - sub rsp,8+1*16 ; 8 = align stack , 1 xmm6, 16 bytes each - movdqa [rsp+0], xmm6 - - movdqu xmm1,[rdi] - movdqu xmm3,16[rdi] - movdqa [rsi],xmm1 - movdqa xmm5,xmm3 - - aeskeygenassist xmm2,xmm3,1h - call PREPARE_ROUNDKEY_192 - shufpd xmm5,xmm1,0 - movdqa 16[rsi],xmm5 - movdqa xmm6,xmm1 - shufpd xmm6,xmm3,1 - movdqa 32[rsi],xmm6 - - aeskeygenassist xmm2,xmm3,2h - call PREPARE_ROUNDKEY_192 - movdqa 48[rsi],xmm1 - movdqa xmm5,xmm3 - - aeskeygenassist xmm2,xmm3,4h - call PREPARE_ROUNDKEY_192 - shufpd xmm5,xmm1,0 - movdqa 64[rsi],xmm5 - movdqa xmm6,xmm1 - shufpd xmm6,xmm3,1 - movdqa 80[rsi],xmm6 - - aeskeygenassist xmm2,xmm3,8h - call PREPARE_ROUNDKEY_192 - movdqa 96[rsi],xmm1 - movdqa xmm5,xmm3 - - aeskeygenassist xmm2,xmm3,10h - call PREPARE_ROUNDKEY_192 - shufpd xmm5,xmm1,0 - movdqa 112[rsi],xmm5 - movdqa xmm6,xmm1 - shufpd xmm6,xmm3,1 - movdqa 128[rsi],xmm6 - - aeskeygenassist xmm2,xmm3,20h - call PREPARE_ROUNDKEY_192 - movdqa 144[rsi],xmm1 - movdqa xmm5,xmm3 - - aeskeygenassist xmm2,xmm3,40h - call PREPARE_ROUNDKEY_192 - shufpd xmm5,xmm1,0 - movdqa 160[rsi],xmm5 - movdqa xmm6,xmm1 - shufpd xmm6,xmm3,1 - movdqa 176[rsi],xmm6 - - aeskeygenassist xmm2,xmm3,80h - call PREPARE_ROUNDKEY_192 - movdqa 192[rsi],xmm1 - movdqa 208[rsi],xmm3 - ; restore non volatile rdi,rsi - mov rdi,rax - mov rsi,r11 -; restore non volatile xmms from stack - movdqa xmm6, [rsp+0] - add rsp,8+1*16 ; 8 = align stack , 1 xmm6 16 bytes each - ret - -PREPARE_ROUNDKEY_192: - pshufd xmm2,xmm2,55h - movdqu xmm4,xmm1 - pslldq xmm4,4 - pxor xmm1,xmm4 - - pslldq xmm4,4 - pxor xmm1,xmm4 - pslldq xmm4,4 - pxor xmm1,xmm4 - pxor xmm1,xmm2 - pshufd xmm2,xmm1,0ffh - movdqu xmm4,xmm3 - pslldq xmm4,4 - pxor xmm3,xmm4 - pxor xmm3,xmm2 - ret -AES_192_Key_Expansion ENDP - -; /* -; void ,AES_256_Key_Expansion[const unsigned char*userkey -; unsigned char*key] -; */ -; . globl AES_256_Key_Expansion -AES_256_Key_Expansion PROC -;# parameter 1: rdi -;# parameter 2: rsi - -; save rdi and rsi to rax and r11, restore before ret - mov rax,rdi - mov r11,rsi - -; convert to what we had for att&t convention - mov rdi,rcx - mov rsi,rdx - - movdqu xmm1,[rdi] - movdqu xmm3,16[rdi] - movdqa [rsi],xmm1 - movdqa 16[rsi],xmm3 - - aeskeygenassist xmm2,xmm3,1h - call MAKE_RK256_a - movdqa 32[rsi],xmm1 - aeskeygenassist xmm2,xmm1,0h - call MAKE_RK256_b - movdqa 48[rsi],xmm3 - aeskeygenassist xmm2,xmm3,2h - call MAKE_RK256_a - movdqa 64[rsi],xmm1 - aeskeygenassist xmm2,xmm1,0h - call MAKE_RK256_b - movdqa 80[rsi],xmm3 - aeskeygenassist xmm2,xmm3,4h - call MAKE_RK256_a - movdqa 96[rsi],xmm1 - aeskeygenassist xmm2,xmm1,0h - call MAKE_RK256_b - movdqa 112[rsi],xmm3 - aeskeygenassist xmm2,xmm3,8h - call MAKE_RK256_a - movdqa 128[rsi],xmm1 - aeskeygenassist xmm2,xmm1,0h - call MAKE_RK256_b - movdqa 144[rsi],xmm3 - aeskeygenassist xmm2,xmm3,10h - call MAKE_RK256_a - movdqa 160[rsi],xmm1 - aeskeygenassist xmm2,xmm1,0h - call MAKE_RK256_b - movdqa 176[rsi],xmm3 - aeskeygenassist xmm2,xmm3,20h - call MAKE_RK256_a - movdqa 192[rsi],xmm1 - - aeskeygenassist xmm2,xmm1,0h - call MAKE_RK256_b - movdqa 208[rsi],xmm3 - aeskeygenassist xmm2,xmm3,40h - call MAKE_RK256_a - movdqa 224[rsi],xmm1 - - ; restore non volatile rdi,rsi - mov rdi,rax - mov rsi,r11 - ret -AES_256_Key_Expansion ENDP - -MAKE_RK256_a: - pshufd xmm2,xmm2,0ffh - movdqa xmm4,xmm1 - pslldq xmm4,4 - pxor xmm1,xmm4 - pslldq xmm4,4 - pxor xmm1,xmm4 - pslldq xmm4,4 - pxor xmm1,xmm4 - pxor xmm1,xmm2 - ret - -MAKE_RK256_b: - pshufd xmm2,xmm2,0aah - movdqa xmm4,xmm3 - pslldq xmm4,4 - pxor xmm3,xmm4 - pslldq xmm4,4 - pxor xmm3,xmm4 - pslldq xmm4,4 - pxor xmm3,xmm4 - pxor xmm3,xmm2 - ret - -END diff --git a/ctaocrypt/src/aes_asm.s b/ctaocrypt/src/aes_asm.s deleted file mode 100755 index 5313a6d16..000000000 --- a/ctaocrypt/src/aes_asm.s +++ /dev/null @@ -1,816 +0,0 @@ -/* aes_asm.s - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - - -/* See Intel® Advanced Encryption Standard (AES) Instructions Set White Paper - * by Intel Mobility Group, Israel Development Center, Israel Shay Gueron - */ - -/* This file is in at&t asm syntax, see .asm for intel syntax */ - - -/* -AES_CBC_encrypt (const unsigned char *in, - unsigned char *out, - unsigned char ivec[16], - unsigned long length, - const unsigned char *KS, - int nr) -*/ -.globl AES_CBC_encrypt -AES_CBC_encrypt: -# parameter 1: %rdi -# parameter 2: %rsi -# parameter 3: %rdx -# parameter 4: %rcx -# parameter 5: %r8 -# parameter 6: %r9d -movq %rcx, %r10 -shrq $4, %rcx -shlq $60, %r10 -je NO_PARTS -addq $1, %rcx -NO_PARTS: -subq $16, %rsi -movdqa (%rdx), %xmm1 -LOOP: -pxor (%rdi), %xmm1 -pxor (%r8), %xmm1 -addq $16,%rsi -addq $16,%rdi -cmpl $12, %r9d -aesenc 16(%r8),%xmm1 -aesenc 32(%r8),%xmm1 -aesenc 48(%r8),%xmm1 -aesenc 64(%r8),%xmm1 -aesenc 80(%r8),%xmm1 -aesenc 96(%r8),%xmm1 -aesenc 112(%r8),%xmm1 -aesenc 128(%r8),%xmm1 -aesenc 144(%r8),%xmm1 -movdqa 160(%r8),%xmm2 -jb LAST -cmpl $14, %r9d - -aesenc 160(%r8),%xmm1 -aesenc 176(%r8),%xmm1 -movdqa 192(%r8),%xmm2 -jb LAST -aesenc 192(%r8),%xmm1 -aesenc 208(%r8),%xmm1 -movdqa 224(%r8),%xmm2 -LAST: -decq %rcx -aesenclast %xmm2,%xmm1 -movdqu %xmm1,(%rsi) -jne LOOP -ret - - - - -/* -AES_CBC_decrypt (const unsigned char *in, - unsigned char *out, - unsigned char ivec[16], - unsigned long length, - const unsigned char *KS, - int nr) -*/ -.globl AES_CBC_decrypt -AES_CBC_decrypt: -# parameter 1: %rdi -# parameter 2: %rsi -# parameter 3: %rdx -# parameter 4: %rcx -# parameter 5: %r8 -# parameter 6: %r9d - -movq %rcx, %r10 -shrq $4, %rcx -shlq $60, %r10 -je DNO_PARTS_4 -addq $1, %rcx -DNO_PARTS_4: -movq %rcx, %r10 -shlq $62, %r10 -shrq $62, %r10 -shrq $2, %rcx -movdqu (%rdx),%xmm5 -je DREMAINDER_4 -subq $64, %rsi -DLOOP_4: -movdqu (%rdi), %xmm1 -movdqu 16(%rdi), %xmm2 -movdqu 32(%rdi), %xmm3 -movdqu 48(%rdi), %xmm4 -movdqa %xmm1, %xmm6 -movdqa %xmm2, %xmm7 -movdqa %xmm3, %xmm8 -movdqa %xmm4, %xmm15 -movdqa (%r8), %xmm9 -movdqa 16(%r8), %xmm10 -movdqa 32(%r8), %xmm11 -movdqa 48(%r8), %xmm12 -pxor %xmm9, %xmm1 -pxor %xmm9, %xmm2 -pxor %xmm9, %xmm3 - -pxor %xmm9, %xmm4 -aesdec %xmm10, %xmm1 -aesdec %xmm10, %xmm2 -aesdec %xmm10, %xmm3 -aesdec %xmm10, %xmm4 -aesdec %xmm11, %xmm1 -aesdec %xmm11, %xmm2 -aesdec %xmm11, %xmm3 -aesdec %xmm11, %xmm4 -aesdec %xmm12, %xmm1 -aesdec %xmm12, %xmm2 -aesdec %xmm12, %xmm3 -aesdec %xmm12, %xmm4 -movdqa 64(%r8), %xmm9 -movdqa 80(%r8), %xmm10 -movdqa 96(%r8), %xmm11 -movdqa 112(%r8), %xmm12 -aesdec %xmm9, %xmm1 -aesdec %xmm9, %xmm2 -aesdec %xmm9, %xmm3 -aesdec %xmm9, %xmm4 -aesdec %xmm10, %xmm1 -aesdec %xmm10, %xmm2 -aesdec %xmm10, %xmm3 -aesdec %xmm10, %xmm4 -aesdec %xmm11, %xmm1 -aesdec %xmm11, %xmm2 -aesdec %xmm11, %xmm3 -aesdec %xmm11, %xmm4 -aesdec %xmm12, %xmm1 -aesdec %xmm12, %xmm2 -aesdec %xmm12, %xmm3 -aesdec %xmm12, %xmm4 -movdqa 128(%r8), %xmm9 -movdqa 144(%r8), %xmm10 -movdqa 160(%r8), %xmm11 -cmpl $12, %r9d -aesdec %xmm9, %xmm1 -aesdec %xmm9, %xmm2 -aesdec %xmm9, %xmm3 -aesdec %xmm9, %xmm4 -aesdec %xmm10, %xmm1 -aesdec %xmm10, %xmm2 -aesdec %xmm10, %xmm3 -aesdec %xmm10, %xmm4 -jb DLAST_4 -movdqa 160(%r8), %xmm9 -movdqa 176(%r8), %xmm10 -movdqa 192(%r8), %xmm11 -cmpl $14, %r9d -aesdec %xmm9, %xmm1 -aesdec %xmm9, %xmm2 -aesdec %xmm9, %xmm3 -aesdec %xmm9, %xmm4 -aesdec %xmm10, %xmm1 -aesdec %xmm10, %xmm2 -aesdec %xmm10, %xmm3 -aesdec %xmm10, %xmm4 -jb DLAST_4 - -movdqa 192(%r8), %xmm9 -movdqa 208(%r8), %xmm10 -movdqa 224(%r8), %xmm11 -aesdec %xmm9, %xmm1 -aesdec %xmm9, %xmm2 -aesdec %xmm9, %xmm3 -aesdec %xmm9, %xmm4 -aesdec %xmm10, %xmm1 -aesdec %xmm10, %xmm2 -aesdec %xmm10, %xmm3 -aesdec %xmm10, %xmm4 -DLAST_4: -addq $64, %rdi -addq $64, %rsi -decq %rcx -aesdeclast %xmm11, %xmm1 -aesdeclast %xmm11, %xmm2 -aesdeclast %xmm11, %xmm3 -aesdeclast %xmm11, %xmm4 -pxor %xmm5 ,%xmm1 -pxor %xmm6 ,%xmm2 -pxor %xmm7 ,%xmm3 -pxor %xmm8 ,%xmm4 -movdqu %xmm1, (%rsi) -movdqu %xmm2, 16(%rsi) -movdqu %xmm3, 32(%rsi) -movdqu %xmm4, 48(%rsi) -movdqa %xmm15,%xmm5 -jne DLOOP_4 -addq $64, %rsi -DREMAINDER_4: -cmpq $0, %r10 -je DEND_4 -DLOOP_4_2: -movdqu (%rdi), %xmm1 -movdqa %xmm1 ,%xmm15 -addq $16, %rdi -pxor (%r8), %xmm1 -movdqu 160(%r8), %xmm2 -cmpl $12, %r9d -aesdec 16(%r8), %xmm1 -aesdec 32(%r8), %xmm1 -aesdec 48(%r8), %xmm1 -aesdec 64(%r8), %xmm1 -aesdec 80(%r8), %xmm1 -aesdec 96(%r8), %xmm1 -aesdec 112(%r8), %xmm1 -aesdec 128(%r8), %xmm1 -aesdec 144(%r8), %xmm1 -jb DLAST_4_2 -movdqu 192(%r8), %xmm2 -cmpl $14, %r9d -aesdec 160(%r8), %xmm1 -aesdec 176(%r8), %xmm1 -jb DLAST_4_2 -movdqu 224(%r8), %xmm2 -aesdec 192(%r8), %xmm1 -aesdec 208(%r8), %xmm1 -DLAST_4_2: -aesdeclast %xmm2, %xmm1 -pxor %xmm5, %xmm1 -movdqa %xmm15, %xmm5 -movdqu %xmm1, (%rsi) - -addq $16, %rsi -decq %r10 -jne DLOOP_4_2 -DEND_4: -ret - - -/* -AES_ECB_encrypt (const unsigned char *in, - unsigned char *out, - unsigned long length, - const unsigned char *KS, - int nr) -*/ -.globl AES_ECB_encrypt -AES_ECB_encrypt: -# parameter 1: %rdi -# parameter 2: %rsi -# parameter 3: %rdx -# parameter 4: %rcx -# parameter 5: %r8d - movq %rdx, %r10 - shrq $4, %rdx - shlq $60, %r10 - je EECB_NO_PARTS_4 - addq $1, %rdx -EECB_NO_PARTS_4: - movq %rdx, %r10 - shlq $62, %r10 - shrq $62, %r10 - shrq $2, %rdx - je EECB_REMAINDER_4 - subq $64, %rsi -EECB_LOOP_4: - movdqu (%rdi), %xmm1 - movdqu 16(%rdi), %xmm2 - movdqu 32(%rdi), %xmm3 - movdqu 48(%rdi), %xmm4 - movdqa (%rcx), %xmm9 - movdqa 16(%rcx), %xmm10 - movdqa 32(%rcx), %xmm11 - movdqa 48(%rcx), %xmm12 - pxor %xmm9, %xmm1 - pxor %xmm9, %xmm2 - pxor %xmm9, %xmm3 - pxor %xmm9, %xmm4 - aesenc %xmm10, %xmm1 - aesenc %xmm10, %xmm2 - aesenc %xmm10, %xmm3 - aesenc %xmm10, %xmm4 - aesenc %xmm11, %xmm1 - aesenc %xmm11, %xmm2 - aesenc %xmm11, %xmm3 - aesenc %xmm11, %xmm4 - aesenc %xmm12, %xmm1 - aesenc %xmm12, %xmm2 - aesenc %xmm12, %xmm3 - aesenc %xmm12, %xmm4 - movdqa 64(%rcx), %xmm9 - movdqa 80(%rcx), %xmm10 - movdqa 96(%rcx), %xmm11 - movdqa 112(%rcx), %xmm12 - aesenc %xmm9, %xmm1 - aesenc %xmm9, %xmm2 - aesenc %xmm9, %xmm3 - aesenc %xmm9, %xmm4 - aesenc %xmm10, %xmm1 - aesenc %xmm10, %xmm2 - aesenc %xmm10, %xmm3 - aesenc %xmm10, %xmm4 - aesenc %xmm11, %xmm1 - aesenc %xmm11, %xmm2 - aesenc %xmm11, %xmm3 - aesenc %xmm11, %xmm4 - aesenc %xmm12, %xmm1 - aesenc %xmm12, %xmm2 - aesenc %xmm12, %xmm3 - aesenc %xmm12, %xmm4 - movdqa 128(%rcx), %xmm9 - movdqa 144(%rcx), %xmm10 - movdqa 160(%rcx), %xmm11 - cmpl $12, %r8d - aesenc %xmm9, %xmm1 - aesenc %xmm9, %xmm2 - aesenc %xmm9, %xmm3 - aesenc %xmm9, %xmm4 - aesenc %xmm10, %xmm1 - aesenc %xmm10, %xmm2 - aesenc %xmm10, %xmm3 - aesenc %xmm10, %xmm4 - jb EECB_LAST_4 - movdqa 160(%rcx), %xmm9 - movdqa 176(%rcx), %xmm10 - movdqa 192(%rcx), %xmm11 - cmpl $14, %r8d - aesenc %xmm9, %xmm1 - aesenc %xmm9, %xmm2 - aesenc %xmm9, %xmm3 - aesenc %xmm9, %xmm4 - aesenc %xmm10, %xmm1 - aesenc %xmm10, %xmm2 - aesenc %xmm10, %xmm3 - aesenc %xmm10, %xmm4 - jb EECB_LAST_4 - movdqa 192(%rcx), %xmm9 - movdqa 208(%rcx), %xmm10 - movdqa 224(%rcx), %xmm11 - aesenc %xmm9, %xmm1 - aesenc %xmm9, %xmm2 - aesenc %xmm9, %xmm3 - aesenc %xmm9, %xmm4 - aesenc %xmm10, %xmm1 - aesenc %xmm10, %xmm2 - aesenc %xmm10, %xmm3 - aesenc %xmm10, %xmm4 -EECB_LAST_4: - addq $64, %rdi - addq $64, %rsi - decq %rdx - aesenclast %xmm11, %xmm1 - aesenclast %xmm11, %xmm2 - aesenclast %xmm11, %xmm3 - aesenclast %xmm11, %xmm4 - movdqu %xmm1, (%rsi) - movdqu %xmm2, 16(%rsi) - movdqu %xmm3, 32(%rsi) - movdqu %xmm4, 48(%rsi) - jne EECB_LOOP_4 - addq $64, %rsi -EECB_REMAINDER_4: - cmpq $0, %r10 - je EECB_END_4 -EECB_LOOP_4_2: - movdqu (%rdi), %xmm1 - addq $16, %rdi - pxor (%rcx), %xmm1 - movdqu 160(%rcx), %xmm2 - aesenc 16(%rcx), %xmm1 - aesenc 32(%rcx), %xmm1 - aesenc 48(%rcx), %xmm1 - aesenc 64(%rcx), %xmm1 - aesenc 80(%rcx), %xmm1 - aesenc 96(%rcx), %xmm1 - aesenc 112(%rcx), %xmm1 - aesenc 128(%rcx), %xmm1 - aesenc 144(%rcx), %xmm1 - cmpl $12, %r8d - jb EECB_LAST_4_2 - movdqu 192(%rcx), %xmm2 - aesenc 160(%rcx), %xmm1 - aesenc 176(%rcx), %xmm1 - cmpl $14, %r8d - jb EECB_LAST_4_2 - movdqu 224(%rcx), %xmm2 - aesenc 192(%rcx), %xmm1 - aesenc 208(%rcx), %xmm1 -EECB_LAST_4_2: - aesenclast %xmm2, %xmm1 - movdqu %xmm1, (%rsi) - addq $16, %rsi - decq %r10 - jne EECB_LOOP_4_2 -EECB_END_4: - ret - - -/* -AES_ECB_decrypt (const unsigned char *in, - unsigned char *out, - unsigned long length, - const unsigned char *KS, - int nr) -*/ -.globl AES_ECB_decrypt -AES_ECB_decrypt: -# parameter 1: %rdi -# parameter 2: %rsi -# parameter 3: %rdx -# parameter 4: %rcx -# parameter 5: %r8d - - movq %rdx, %r10 - shrq $4, %rdx - shlq $60, %r10 - je DECB_NO_PARTS_4 - addq $1, %rdx -DECB_NO_PARTS_4: - movq %rdx, %r10 - shlq $62, %r10 - shrq $62, %r10 - shrq $2, %rdx - je DECB_REMAINDER_4 - subq $64, %rsi -DECB_LOOP_4: - movdqu (%rdi), %xmm1 - movdqu 16(%rdi), %xmm2 - movdqu 32(%rdi), %xmm3 - movdqu 48(%rdi), %xmm4 - movdqa (%rcx), %xmm9 - movdqa 16(%rcx), %xmm10 - movdqa 32(%rcx), %xmm11 - movdqa 48(%rcx), %xmm12 - pxor %xmm9, %xmm1 - pxor %xmm9, %xmm2 - pxor %xmm9, %xmm3 - pxor %xmm9, %xmm4 - aesdec %xmm10, %xmm1 - aesdec %xmm10, %xmm2 - aesdec %xmm10, %xmm3 - aesdec %xmm10, %xmm4 - aesdec %xmm11, %xmm1 - aesdec %xmm11, %xmm2 - aesdec %xmm11, %xmm3 - aesdec %xmm11, %xmm4 - aesdec %xmm12, %xmm1 - aesdec %xmm12, %xmm2 - aesdec %xmm12, %xmm3 - aesdec %xmm12, %xmm4 - movdqa 64(%rcx), %xmm9 - movdqa 80(%rcx), %xmm10 - movdqa 96(%rcx), %xmm11 - movdqa 112(%rcx), %xmm12 - aesdec %xmm9, %xmm1 - aesdec %xmm9, %xmm2 - aesdec %xmm9, %xmm3 - aesdec %xmm9, %xmm4 - aesdec %xmm10, %xmm1 - aesdec %xmm10, %xmm2 - aesdec %xmm10, %xmm3 - aesdec %xmm10, %xmm4 - aesdec %xmm11, %xmm1 - aesdec %xmm11, %xmm2 - aesdec %xmm11, %xmm3 - aesdec %xmm11, %xmm4 - aesdec %xmm12, %xmm1 - aesdec %xmm12, %xmm2 - aesdec %xmm12, %xmm3 - aesdec %xmm12, %xmm4 - movdqa 128(%rcx), %xmm9 - movdqa 144(%rcx), %xmm10 - movdqa 160(%rcx), %xmm11 - cmpl $12, %r8d - aesdec %xmm9, %xmm1 - aesdec %xmm9, %xmm2 - aesdec %xmm9, %xmm3 - aesdec %xmm9, %xmm4 - aesdec %xmm10, %xmm1 - aesdec %xmm10, %xmm2 - aesdec %xmm10, %xmm3 - aesdec %xmm10, %xmm4 - jb DECB_LAST_4 - movdqa 160(%rcx), %xmm9 - movdqa 176(%rcx), %xmm10 - movdqa 192(%rcx), %xmm11 - cmpl $14, %r8d - aesdec %xmm9, %xmm1 - aesdec %xmm9, %xmm2 - aesdec %xmm9, %xmm3 - aesdec %xmm9, %xmm4 - aesdec %xmm10, %xmm1 - aesdec %xmm10, %xmm2 - aesdec %xmm10, %xmm3 - aesdec %xmm10, %xmm4 - jb DECB_LAST_4 - movdqa 192(%rcx), %xmm9 - movdqa 208(%rcx), %xmm10 - movdqa 224(%rcx), %xmm11 - aesdec %xmm9, %xmm1 - aesdec %xmm9, %xmm2 - aesdec %xmm9, %xmm3 - aesdec %xmm9, %xmm4 - aesdec %xmm10, %xmm1 - aesdec %xmm10, %xmm2 - aesdec %xmm10, %xmm3 - aesdec %xmm10, %xmm4 -DECB_LAST_4: - addq $64, %rdi - addq $64, %rsi - decq %rdx - aesdeclast %xmm11, %xmm1 - aesdeclast %xmm11, %xmm2 - aesdeclast %xmm11, %xmm3 - aesdeclast %xmm11, %xmm4 - movdqu %xmm1, (%rsi) - movdqu %xmm2, 16(%rsi) - movdqu %xmm3, 32(%rsi) - movdqu %xmm4, 48(%rsi) - jne DECB_LOOP_4 - addq $64, %rsi -DECB_REMAINDER_4: - cmpq $0, %r10 - je DECB_END_4 -DECB_LOOP_4_2: - movdqu (%rdi), %xmm1 - addq $16, %rdi - pxor (%rcx), %xmm1 - movdqu 160(%rcx), %xmm2 - cmpl $12, %r8d - aesdec 16(%rcx), %xmm1 - aesdec 32(%rcx), %xmm1 - aesdec 48(%rcx), %xmm1 - aesdec 64(%rcx), %xmm1 - aesdec 80(%rcx), %xmm1 - aesdec 96(%rcx), %xmm1 - aesdec 112(%rcx), %xmm1 - aesdec 128(%rcx), %xmm1 - aesdec 144(%rcx), %xmm1 - jb DECB_LAST_4_2 - cmpl $14, %r8d - movdqu 192(%rcx), %xmm2 - aesdec 160(%rcx), %xmm1 - aesdec 176(%rcx), %xmm1 - jb DECB_LAST_4_2 - movdqu 224(%rcx), %xmm2 - aesdec 192(%rcx), %xmm1 - aesdec 208(%rcx), %xmm1 -DECB_LAST_4_2: - aesdeclast %xmm2, %xmm1 - movdqu %xmm1, (%rsi) - addq $16, %rsi - decq %r10 - jne DECB_LOOP_4_2 -DECB_END_4: - ret - - - - -/* -void AES_128_Key_Expansion(const unsigned char* userkey, - unsigned char* key_schedule); -*/ -.align 16,0x90 -.globl AES_128_Key_Expansion -AES_128_Key_Expansion: -# parameter 1: %rdi -# parameter 2: %rsi -movl $10, 240(%rsi) - -movdqu (%rdi), %xmm1 -movdqa %xmm1, (%rsi) - - -ASSISTS: -aeskeygenassist $1, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 16(%rsi) -aeskeygenassist $2, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 32(%rsi) -aeskeygenassist $4, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 48(%rsi) -aeskeygenassist $8, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 64(%rsi) -aeskeygenassist $16, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 80(%rsi) -aeskeygenassist $32, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 96(%rsi) -aeskeygenassist $64, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 112(%rsi) -aeskeygenassist $0x80, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 128(%rsi) -aeskeygenassist $0x1b, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 144(%rsi) -aeskeygenassist $0x36, %xmm1, %xmm2 -call PREPARE_ROUNDKEY_128 -movdqa %xmm1, 160(%rsi) -ret - -PREPARE_ROUNDKEY_128: -pshufd $255, %xmm2, %xmm2 -movdqa %xmm1, %xmm3 -pslldq $4, %xmm3 -pxor %xmm3, %xmm1 -pslldq $4, %xmm3 -pxor %xmm3, %xmm1 -pslldq $4, %xmm3 -pxor %xmm3, %xmm1 -pxor %xmm2, %xmm1 -ret - - -/* -void AES_192_Key_Expansion (const unsigned char *userkey, - unsigned char *key) -*/ -.globl AES_192_Key_Expansion -AES_192_Key_Expansion: -# parameter 1: %rdi -# parameter 2: %rsi - -movdqu (%rdi), %xmm1 -movdqu 16(%rdi), %xmm3 -movdqa %xmm1, (%rsi) -movdqa %xmm3, %xmm5 - -aeskeygenassist $0x1, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -shufpd $0, %xmm1, %xmm5 -movdqa %xmm5, 16(%rsi) -movdqa %xmm1, %xmm6 -shufpd $1, %xmm3, %xmm6 -movdqa %xmm6, 32(%rsi) - -aeskeygenassist $0x2, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -movdqa %xmm1, 48(%rsi) -movdqa %xmm3, %xmm5 - -aeskeygenassist $0x4, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -shufpd $0, %xmm1, %xmm5 -movdqa %xmm5, 64(%rsi) -movdqa %xmm1, %xmm6 -shufpd $1, %xmm3, %xmm6 -movdqa %xmm6, 80(%rsi) - -aeskeygenassist $0x8, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -movdqa %xmm1, 96(%rsi) -movdqa %xmm3, %xmm5 - -aeskeygenassist $0x10, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -shufpd $0, %xmm1, %xmm5 -movdqa %xmm5, 112(%rsi) -movdqa %xmm1, %xmm6 -shufpd $1, %xmm3, %xmm6 -movdqa %xmm6, 128(%rsi) - -aeskeygenassist $0x20, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -movdqa %xmm1, 144(%rsi) -movdqa %xmm3, %xmm5 - -aeskeygenassist $0x40, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -shufpd $0, %xmm1, %xmm5 -movdqa %xmm5, 160(%rsi) -movdqa %xmm1, %xmm6 -shufpd $1, %xmm3, %xmm6 -movdqa %xmm6, 176(%rsi) - -aeskeygenassist $0x80, %xmm3, %xmm2 -call PREPARE_ROUNDKEY_192 -movdqa %xmm1, 192(%rsi) -movdqa %xmm3, 208(%rsi) -ret - -PREPARE_ROUNDKEY_192: -pshufd $0x55, %xmm2, %xmm2 -movdqu %xmm1, %xmm4 -pslldq $4, %xmm4 -pxor %xmm4, %xmm1 - -pslldq $4, %xmm4 -pxor %xmm4, %xmm1 -pslldq $4, %xmm4 -pxor %xmm4, %xmm1 -pxor %xmm2, %xmm1 -pshufd $0xff, %xmm1, %xmm2 -movdqu %xmm3, %xmm4 -pslldq $4, %xmm4 -pxor %xmm4, %xmm3 -pxor %xmm2, %xmm3 -ret - - -/* -void AES_256_Key_Expansion (const unsigned char *userkey, - unsigned char *key) -*/ -.globl AES_256_Key_Expansion -AES_256_Key_Expansion: -# parameter 1: %rdi -# parameter 2: %rsi - -movdqu (%rdi), %xmm1 -movdqu 16(%rdi), %xmm3 -movdqa %xmm1, (%rsi) -movdqa %xmm3, 16(%rsi) - -aeskeygenassist $0x1, %xmm3, %xmm2 -call MAKE_RK256_a -movdqa %xmm1, 32(%rsi) -aeskeygenassist $0x0, %xmm1, %xmm2 -call MAKE_RK256_b -movdqa %xmm3, 48(%rsi) -aeskeygenassist $0x2, %xmm3, %xmm2 -call MAKE_RK256_a -movdqa %xmm1, 64(%rsi) -aeskeygenassist $0x0, %xmm1, %xmm2 -call MAKE_RK256_b -movdqa %xmm3, 80(%rsi) -aeskeygenassist $0x4, %xmm3, %xmm2 -call MAKE_RK256_a -movdqa %xmm1, 96(%rsi) -aeskeygenassist $0x0, %xmm1, %xmm2 -call MAKE_RK256_b -movdqa %xmm3, 112(%rsi) -aeskeygenassist $0x8, %xmm3, %xmm2 -call MAKE_RK256_a -movdqa %xmm1, 128(%rsi) -aeskeygenassist $0x0, %xmm1, %xmm2 -call MAKE_RK256_b -movdqa %xmm3, 144(%rsi) -aeskeygenassist $0x10, %xmm3, %xmm2 -call MAKE_RK256_a -movdqa %xmm1, 160(%rsi) -aeskeygenassist $0x0, %xmm1, %xmm2 -call MAKE_RK256_b -movdqa %xmm3, 176(%rsi) -aeskeygenassist $0x20, %xmm3, %xmm2 -call MAKE_RK256_a -movdqa %xmm1, 192(%rsi) - -aeskeygenassist $0x0, %xmm1, %xmm2 -call MAKE_RK256_b -movdqa %xmm3, 208(%rsi) -aeskeygenassist $0x40, %xmm3, %xmm2 -call MAKE_RK256_a -movdqa %xmm1, 224(%rsi) - -ret - -MAKE_RK256_a: -pshufd $0xff, %xmm2, %xmm2 -movdqa %xmm1, %xmm4 -pslldq $4, %xmm4 -pxor %xmm4, %xmm1 -pslldq $4, %xmm4 -pxor %xmm4, %xmm1 -pslldq $4, %xmm4 -pxor %xmm4, %xmm1 -pxor %xmm2, %xmm1 -ret - -MAKE_RK256_b: -pshufd $0xaa, %xmm2, %xmm2 -movdqa %xmm3, %xmm4 -pslldq $4, %xmm4 -pxor %xmm4, %xmm3 -pslldq $4, %xmm4 -pxor %xmm4, %xmm3 -pslldq $4, %xmm4 -pxor %xmm4, %xmm3 -pxor %xmm2, %xmm3 -ret - diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c deleted file mode 100644 index 6246dfe11..000000000 --- a/ctaocrypt/src/asn.c +++ /dev/null @@ -1,7688 +0,0 @@ -/* asn.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifndef NO_ASN - -#ifdef HAVE_RTP_SYS - #include "os.h" /* dc_rtc_api needs */ - #include "dc_rtc_api.h" /* to get current time */ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#ifndef NO_RC4 - #include -#endif - -#ifdef HAVE_NTRU - #include "ntru_crypto.h" -#endif - -#ifdef HAVE_ECC - #include -#endif - -#ifdef CYASSL_DEBUG_ENCODING - #ifdef FREESCALE_MQX - #include - #else - #include - #endif -#endif - -#ifdef _MSC_VER - /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */ - #pragma warning(disable: 4996) -#endif - - -#ifndef TRUE - #define TRUE 1 -#endif -#ifndef FALSE - #define FALSE 0 -#endif - - -#ifdef HAVE_RTP_SYS - /* uses parital structures */ - #define XTIME(tl) (0) - #define XGMTIME(c) my_gmtime((c)) - #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) -#elif defined(MICRIUM) - #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) - #define XVALIDATE_DATE(d,f,t) NetSecure_ValidateDateHandler((d),(f),(t)) - #else - #define XVALIDATE_DATE(d, f, t) (0) - #endif - #define NO_TIME_H - /* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */ -#elif defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP) - #include - #define XTIME(t1) pic32_time((t1)) - #define XGMTIME(c) gmtime((c)) - #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) -#elif defined(FREESCALE_MQX) - #define XTIME(t1) mqx_time((t1)) - #define XGMTIME(c) mqx_gmtime((c)) - #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) -#elif defined(CYASSL_MDK_ARM) - #if defined(CYASSL_MDK5) - #include "cmsis_os.h" - #else - #include - #endif - #undef RNG - #include "cyassl_MDK_ARM.h" - #undef RNG - #define RNG CyaSSL_RNG /*for avoiding name conflict in "stm32f2xx.h" */ - #define XTIME(tl) (0) - #define XGMTIME(c) Cyassl_MDK_gmtime((c)) - #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) -#elif defined(USER_TIME) - /* user time, and gmtime compatible functions, there is a gmtime - implementation here that WINCE uses, so really just need some ticks - since the EPOCH - */ - - struct tm { - int tm_sec; /* seconds after the minute [0-60] */ - int tm_min; /* minutes after the hour [0-59] */ - int tm_hour; /* hours since midnight [0-23] */ - int tm_mday; /* day of the month [1-31] */ - int tm_mon; /* months since January [0-11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday [0-6] */ - int tm_yday; /* days since January 1 [0-365] */ - int tm_isdst; /* Daylight Savings Time flag */ - long tm_gmtoff; /* offset from CUT in seconds */ - char *tm_zone; /* timezone abbreviation */ - }; - typedef long time_t; - - /* forward declaration */ - struct tm* gmtime(const time_t* timer); - extern time_t XTIME(time_t * timer); - - #define XGMTIME(c) gmtime((c)) - #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) - - #ifdef STACK_TRAP - /* for stack trap tracking, don't call os gmtime on OS X/linux, - uses a lot of stack spce */ - extern time_t time(time_t * timer); - #define XTIME(tl) time((tl)) - #endif /* STACK_TRAP */ - -#else - /* default */ - /* uses complete facility */ - #include - #define XTIME(tl) time((tl)) - #define XGMTIME(c) gmtime((c)) - #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t)) -#endif - - -#ifdef _WIN32_WCE -/* no time() or gmtime() even though in time.h header?? */ - -#include - - -time_t time(time_t* timer) -{ - SYSTEMTIME sysTime; - FILETIME fTime; - ULARGE_INTEGER intTime; - time_t localTime; - - if (timer == NULL) - timer = &localTime; - - GetSystemTime(&sysTime); - SystemTimeToFileTime(&sysTime, &fTime); - - XMEMCPY(&intTime, &fTime, sizeof(FILETIME)); - /* subtract EPOCH */ - intTime.QuadPart -= 0x19db1ded53e8000; - /* to secs */ - intTime.QuadPart /= 10000000; - *timer = (time_t)intTime.QuadPart; - - return *timer; -} - -#endif /* _WIN32_WCE */ -#if defined( _WIN32_WCE ) || defined( USER_TIME ) - -struct tm* gmtime(const time_t* timer) -{ - #define YEAR0 1900 - #define EPOCH_YEAR 1970 - #define SECS_DAY (24L * 60L * 60L) - #define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) %400))) - #define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365) - - static const int _ytab[2][12] = - { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} - }; - - static struct tm st_time; - struct tm* ret = &st_time; - time_t secs = *timer; - unsigned long dayclock, dayno; - int year = EPOCH_YEAR; - - dayclock = (unsigned long)secs % SECS_DAY; - dayno = (unsigned long)secs / SECS_DAY; - - ret->tm_sec = (int) dayclock % 60; - ret->tm_min = (int)(dayclock % 3600) / 60; - ret->tm_hour = (int) dayclock / 3600; - ret->tm_wday = (int) (dayno + 4) % 7; /* day 0 a Thursday */ - - while(dayno >= (unsigned long)YEARSIZE(year)) { - dayno -= YEARSIZE(year); - year++; - } - - ret->tm_year = year - YEAR0; - ret->tm_yday = (int)dayno; - ret->tm_mon = 0; - - while(dayno >= (unsigned long)_ytab[LEAPYEAR(year)][ret->tm_mon]) { - dayno -= _ytab[LEAPYEAR(year)][ret->tm_mon]; - ret->tm_mon++; - } - - ret->tm_mday = (int)++dayno; - ret->tm_isdst = 0; - - return ret; -} - -#endif /* _WIN32_WCE || USER_TIME */ - - -#ifdef HAVE_RTP_SYS - -#define YEAR0 1900 - -struct tm* my_gmtime(const time_t* timer) /* has a gmtime() but hangs */ -{ - static struct tm st_time; - struct tm* ret = &st_time; - - DC_RTC_CALENDAR cal; - dc_rtc_time_get(&cal, TRUE); - - ret->tm_year = cal.year - YEAR0; /* gm starts at 1900 */ - ret->tm_mon = cal.month - 1; /* gm starts at 0 */ - ret->tm_mday = cal.day; - ret->tm_hour = cal.hour; - ret->tm_min = cal.minute; - ret->tm_sec = cal.second; - - return ret; -} - -#endif /* HAVE_RTP_SYS */ - - -#if defined(MICROCHIP_TCPIP_V5) || defined(MICROCHIP_TCPIP) - -/* - * time() is just a stub in Microchip libraries. We need our own - * implementation. Use SNTP client to get seconds since epoch. - */ -time_t pic32_time(time_t* timer) -{ -#ifdef MICROCHIP_TCPIP_V5 - DWORD sec = 0; -#else - uint32_t sec = 0; -#endif - time_t localTime; - - if (timer == NULL) - timer = &localTime; - -#ifdef MICROCHIP_MPLAB_HARMONY - sec = TCPIP_SNTP_UTCSecondsGet(); -#else - sec = SNTPGetUTCSeconds(); -#endif - *timer = (time_t) sec; - - return *timer; -} - -#endif /* MICROCHIP_TCPIP */ - - -#ifdef FREESCALE_MQX - -time_t mqx_time(time_t* timer) -{ - time_t localTime; - TIME_STRUCT time_s; - - if (timer == NULL) - timer = &localTime; - - _time_get(&time_s); - *timer = (time_t) time_s.SECONDS; - - return *timer; -} - -/* CodeWarrior GCC toolchain only has gmtime_r(), no gmtime() */ -struct tm* mqx_gmtime(const time_t* clock) -{ - struct tm tmpTime; - - return gmtime_r(clock, &tmpTime); -} - -#endif /* FREESCALE_MQX */ - -#ifdef CYASSL_TIRTOS - -time_t XTIME(time_t * timer) -{ - time_t sec = 0; - - sec = (time_t) MYTIME_gettime(); - - if (timer != NULL) - *timer = sec; - - return sec; -} - -#endif /* CYASSL_TIRTOS */ - -static INLINE word32 btoi(byte b) -{ - return b - 0x30; -} - - -/* two byte date/time, add to value */ -static INLINE void GetTime(int* value, const byte* date, int* idx) -{ - int i = *idx; - - *value += btoi(date[i++]) * 10; - *value += btoi(date[i++]); - - *idx = i; -} - - -#if defined(MICRIUM) - -CPU_INT32S NetSecure_ValidateDateHandler(CPU_INT08U *date, CPU_INT08U format, - CPU_INT08U dateType) -{ - CPU_BOOLEAN rtn_code; - CPU_INT32S i; - CPU_INT32S val; - CPU_INT16U year; - CPU_INT08U month; - CPU_INT16U day; - CPU_INT08U hour; - CPU_INT08U min; - CPU_INT08U sec; - - i = 0; - year = 0u; - - if (format == ASN_UTC_TIME) { - if (btoi(date[0]) >= 5) - year = 1900; - else - year = 2000; - } - else { /* format == GENERALIZED_TIME */ - year += btoi(date[i++]) * 1000; - year += btoi(date[i++]) * 100; - } - - val = year; - GetTime(&val, date, &i); - year = (CPU_INT16U)val; - - val = 0; - GetTime(&val, date, &i); - month = (CPU_INT08U)val; - - val = 0; - GetTime(&val, date, &i); - day = (CPU_INT16U)val; - - val = 0; - GetTime(&val, date, &i); - hour = (CPU_INT08U)val; - - val = 0; - GetTime(&val, date, &i); - min = (CPU_INT08U)val; - - val = 0; - GetTime(&val, date, &i); - sec = (CPU_INT08U)val; - - return NetSecure_ValidateDate(year, month, day, hour, min, sec, dateType); -} - -#endif /* MICRIUM */ - - -CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, - word32 maxIdx) -{ - int length = 0; - word32 i = *inOutIdx; - byte b; - - *len = 0; /* default length */ - - if ( (i+1) > maxIdx) { /* for first read */ - CYASSL_MSG("GetLength bad index on input"); - return BUFFER_E; - } - - b = input[i++]; - if (b >= ASN_LONG_LENGTH) { - word32 bytes = b & 0x7F; - - if ( (i+bytes) > maxIdx) { /* for reading bytes */ - CYASSL_MSG("GetLength bad long length"); - return BUFFER_E; - } - - while (bytes--) { - b = input[i++]; - length = (length << 8) | b; - } - } - else - length = b; - - if ( (i+length) > maxIdx) { /* for user of length */ - CYASSL_MSG("GetLength value exceeds buffer length"); - return BUFFER_E; - } - - *inOutIdx = i; - if (length > 0) - *len = length; - - return length; -} - - -CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len, - word32 maxIdx) -{ - int length = -1; - word32 idx = *inOutIdx; - - if (input[idx++] != (ASN_SEQUENCE | ASN_CONSTRUCTED) || - GetLength(input, &idx, &length, maxIdx) < 0) - return ASN_PARSE_E; - - *len = length; - *inOutIdx = idx; - - return length; -} - - -CYASSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len, - word32 maxIdx) -{ - int length = -1; - word32 idx = *inOutIdx; - - if (input[idx++] != (ASN_SET | ASN_CONSTRUCTED) || - GetLength(input, &idx, &length, maxIdx) < 0) - return ASN_PARSE_E; - - *len = length; - *inOutIdx = idx; - - return length; -} - - -/* winodws header clash for WinCE using GetVersion */ -CYASSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, int* version) -{ - word32 idx = *inOutIdx; - - CYASSL_ENTER("GetMyVersion"); - - if (input[idx++] != ASN_INTEGER) - return ASN_PARSE_E; - - if (input[idx++] != 0x01) - return ASN_VERSION_E; - - *version = input[idx++]; - *inOutIdx = idx; - - return *version; -} - - -#ifndef NO_PWDBASED -/* Get small count integer, 32 bits or less */ -static int GetShortInt(const byte* input, word32* inOutIdx, int* number) -{ - word32 idx = *inOutIdx; - word32 len; - - *number = 0; - - if (input[idx++] != ASN_INTEGER) - return ASN_PARSE_E; - - len = input[idx++]; - if (len > 4) - return ASN_PARSE_E; - - while (len--) { - *number = *number << 8 | input[idx++]; - } - - *inOutIdx = idx; - - return *number; -} -#endif /* !NO_PWDBASED */ - - -/* May not have one, not an error */ -static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version) -{ - word32 idx = *inOutIdx; - - CYASSL_ENTER("GetExplicitVersion"); - if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { - *inOutIdx = ++idx; /* eat header */ - return GetMyVersion(input, inOutIdx, version); - } - - /* go back as is */ - *version = 0; - - return 0; -} - - -CYASSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, - word32 maxIdx) -{ - word32 i = *inOutIdx; - byte b = input[i++]; - int length; - - if (b != ASN_INTEGER) - return ASN_PARSE_E; - - if (GetLength(input, &i, &length, maxIdx) < 0) - return ASN_PARSE_E; - - if ( (b = input[i++]) == 0x00) - length--; - else - i--; - - if (mp_init(mpi) != MP_OKAY) - return MP_INIT_E; - - if (mp_read_unsigned_bin(mpi, (byte*)input + i, length) != 0) { - mp_clear(mpi); - return ASN_GETINT_E; - } - - *inOutIdx = i + length; - return 0; -} - - -static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, - word32 maxIdx) -{ - int length; - word32 i = *inOutIdx; - byte b; - *oid = 0; - - b = input[i++]; - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; - - if (GetLength(input, &i, &length, maxIdx) < 0) - return ASN_PARSE_E; - - while(length--) - *oid += input[i++]; - /* just sum it up for now */ - - *inOutIdx = i; - - return 0; -} - - -CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, - word32 maxIdx) -{ - int length; - word32 i = *inOutIdx; - byte b; - *oid = 0; - - CYASSL_ENTER("GetAlgoId"); - - if (GetSequence(input, &i, &length, maxIdx) < 0) - return ASN_PARSE_E; - - b = input[i++]; - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; - - if (GetLength(input, &i, &length, maxIdx) < 0) - return ASN_PARSE_E; - - while(length--) { - /* odd HC08 compiler behavior here when input[i++] */ - *oid += input[i]; - i++; - } - /* just sum it up for now */ - - /* could have NULL tag and 0 terminator, but may not */ - b = input[i++]; - - if (b == ASN_TAG_NULL) { - b = input[i++]; - if (b != 0) - return ASN_EXPECT_0_E; - } - else - /* go back, didn't have it */ - i--; - - *inOutIdx = i; - - return 0; -} - -#ifndef NO_RSA - - -#ifdef HAVE_CAVIUM - -static int GetCaviumInt(byte** buff, word16* buffSz, const byte* input, - word32* inOutIdx, word32 maxIdx, void* heap) -{ - word32 i = *inOutIdx; - byte b = input[i++]; - int length; - - if (b != ASN_INTEGER) - return ASN_PARSE_E; - - if (GetLength(input, &i, &length, maxIdx) < 0) - return ASN_PARSE_E; - - if ( (b = input[i++]) == 0x00) - length--; - else - i--; - - *buffSz = (word16)length; - *buff = XMALLOC(*buffSz, heap, DYNAMIC_TYPE_CAVIUM_RSA); - if (*buff == NULL) - return MEMORY_E; - - XMEMCPY(*buff, input + i, *buffSz); - - *inOutIdx = i + length; - return 0; -} - -static int CaviumRsaPrivateKeyDecode(const byte* input, word32* inOutIdx, - RsaKey* key, word32 inSz) -{ - int version, length; - void* h = key->heap; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetMyVersion(input, inOutIdx, &version) < 0) - return ASN_PARSE_E; - - key->type = RSA_PRIVATE; - - if (GetCaviumInt(&key->c_n, &key->c_nSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_e, &key->c_eSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_d, &key->c_dSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_p, &key->c_pSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_q, &key->c_qSz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_dP, &key->c_dP_Sz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_dQ, &key->c_dQ_Sz, input, inOutIdx, inSz, h) < 0 || - GetCaviumInt(&key->c_u, &key->c_uSz, input, inOutIdx, inSz, h) < 0 ) - return ASN_RSA_KEY_E; - - return 0; -} - - -#endif /* HAVE_CAVIUM */ - -int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, - word32 inSz) -{ - int version, length; - -#ifdef HAVE_CAVIUM - if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) - return CaviumRsaPrivateKeyDecode(input, inOutIdx, key, inSz); -#endif - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetMyVersion(input, inOutIdx, &version) < 0) - return ASN_PARSE_E; - - key->type = RSA_PRIVATE; - - if (GetInt(&key->n, input, inOutIdx, inSz) < 0 || - GetInt(&key->e, input, inOutIdx, inSz) < 0 || - GetInt(&key->d, input, inOutIdx, inSz) < 0 || - GetInt(&key->p, input, inOutIdx, inSz) < 0 || - GetInt(&key->q, input, inOutIdx, inSz) < 0 || - GetInt(&key->dP, input, inOutIdx, inSz) < 0 || - GetInt(&key->dQ, input, inOutIdx, inSz) < 0 || - GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E; - - return 0; -} - -#endif /* NO_RSA */ - -/* Remove PKCS8 header, move beginning of traditional to beginning of input */ -int ToTraditional(byte* input, word32 sz) -{ - word32 inOutIdx = 0, oid; - int version, length; - - if (GetSequence(input, &inOutIdx, &length, sz) < 0) - return ASN_PARSE_E; - - if (GetMyVersion(input, &inOutIdx, &version) < 0) - return ASN_PARSE_E; - - if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) - return ASN_PARSE_E; - - if (input[inOutIdx] == ASN_OBJECT_ID) { - /* pkcs8 ecc uses slightly different format */ - inOutIdx++; /* past id */ - if (GetLength(input, &inOutIdx, &length, sz) < 0) - return ASN_PARSE_E; - inOutIdx += length; /* over sub id, key input will verify */ - } - - if (input[inOutIdx++] != ASN_OCTET_STRING) - return ASN_PARSE_E; - - if (GetLength(input, &inOutIdx, &length, sz) < 0) - return ASN_PARSE_E; - - XMEMMOVE(input, input + inOutIdx, length); - - return length; -} - - -#ifndef NO_PWDBASED - -/* Check To see if PKCS version algo is supported, set id if it is return 0 - < 0 on error */ -static int CheckAlgo(int first, int second, int* id, int* version) -{ - *id = ALGO_ID_E; - *version = PKCS5; /* default */ - - if (first == 1) { - switch (second) { - case 1: - *id = PBE_SHA1_RC4_128; - *version = PKCS12; - return 0; - case 3: - *id = PBE_SHA1_DES3; - *version = PKCS12; - return 0; - default: - return ALGO_ID_E; - } - } - - if (first != PKCS5) - return ASN_INPUT_E; /* VERSION ERROR */ - - if (second == PBES2) { - *version = PKCS5v2; - return 0; - } - - switch (second) { - case 3: /* see RFC 2898 for ids */ - *id = PBE_MD5_DES; - return 0; - case 10: - *id = PBE_SHA1_DES; - return 0; - default: - return ALGO_ID_E; - - } -} - - -/* Check To see if PKCS v2 algo is supported, set id if it is return 0 - < 0 on error */ -static int CheckAlgoV2(int oid, int* id) -{ - switch (oid) { - case 69: - *id = PBE_SHA1_DES; - return 0; - case 652: - *id = PBE_SHA1_DES3; - return 0; - default: - return ALGO_ID_E; - - } -} - - -/* Decrypt intput in place from parameters based on id */ -static int DecryptKey(const char* password, int passwordSz, byte* salt, - int saltSz, int iterations, int id, byte* input, - int length, int version, byte* cbcIv) -{ - int typeH; - int derivedLen; - int decryptionType; - int ret = 0; -#ifdef CYASSL_SMALL_STACK - byte* key; -#else - byte key[MAX_KEY_SIZE]; -#endif - - switch (id) { - case PBE_MD5_DES: - typeH = MD5; - derivedLen = 16; /* may need iv for v1.5 */ - decryptionType = DES_TYPE; - break; - - case PBE_SHA1_DES: - typeH = SHA; - derivedLen = 16; /* may need iv for v1.5 */ - decryptionType = DES_TYPE; - break; - - case PBE_SHA1_DES3: - typeH = SHA; - derivedLen = 32; /* may need iv for v1.5 */ - decryptionType = DES3_TYPE; - break; - - case PBE_SHA1_RC4_128: - typeH = SHA; - derivedLen = 16; - decryptionType = RC4_TYPE; - break; - - default: - return ALGO_ID_E; - } - -#ifdef CYASSL_SMALL_STACK - key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (key == NULL) - return MEMORY_E; -#endif - - if (version == PKCS5v2) - ret = PBKDF2(key, (byte*)password, passwordSz, salt, saltSz, iterations, - derivedLen, typeH); - else if (version == PKCS5) - ret = PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations, - derivedLen, typeH); - else if (version == PKCS12) { - int i, idx = 0; - byte unicodePasswd[MAX_UNICODE_SZ]; - - if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) { -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return UNICODE_SIZE_E; - } - - for (i = 0; i < passwordSz; i++) { - unicodePasswd[idx++] = 0x00; - unicodePasswd[idx++] = (byte)password[i]; - } - /* add trailing NULL */ - unicodePasswd[idx++] = 0x00; - unicodePasswd[idx++] = 0x00; - - ret = PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz, - iterations, derivedLen, typeH, 1); - if (decryptionType != RC4_TYPE) - ret += PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz, - iterations, 8, typeH, 2); - } - else { -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ALGO_ID_E; - } - - if (ret != 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } - - switch (decryptionType) { -#ifndef NO_DES3 - case DES_TYPE: - { - Des dec; - byte* desIv = key + 8; - - if (version == PKCS5v2 || version == PKCS12) - desIv = cbcIv; - - ret = Des_SetKey(&dec, key, desIv, DES_DECRYPTION); - if (ret != 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } - - Des_CbcDecrypt(&dec, input, input, length); - break; - } - - case DES3_TYPE: - { - Des3 dec; - byte* desIv = key + 24; - - if (version == PKCS5v2 || version == PKCS12) - desIv = cbcIv; - ret = Des3_SetKey(&dec, key, desIv, DES_DECRYPTION); - if (ret != 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } - ret = Des3_CbcDecrypt(&dec, input, input, length); - if (ret != 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } - break; - } -#endif -#ifndef NO_RC4 - case RC4_TYPE: - { - Arc4 dec; - - Arc4SetKey(&dec, key, derivedLen); - Arc4Process(&dec, input, input, length); - break; - } -#endif - - default: -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ALGO_ID_E; - } - -#ifdef CYASSL_SMALL_STACK - XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return 0; -} - - -/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning - of input */ -int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz) -{ - word32 inOutIdx = 0, oid; - int first, second, length, version, saltSz, id; - int iterations = 0; -#ifdef CYASSL_SMALL_STACK - byte* salt = NULL; - byte* cbcIv = NULL; -#else - byte salt[MAX_SALT_SIZE]; - byte cbcIv[MAX_IV_SIZE]; -#endif - - if (GetSequence(input, &inOutIdx, &length, sz) < 0) - return ASN_PARSE_E; - - if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) - return ASN_PARSE_E; - - first = input[inOutIdx - 2]; /* PKCS version alwyas 2nd to last byte */ - second = input[inOutIdx - 1]; /* version.algo, algo id last byte */ - - if (CheckAlgo(first, second, &id, &version) < 0) - return ASN_INPUT_E; /* Algo ID error */ - - if (version == PKCS5v2) { - - if (GetSequence(input, &inOutIdx, &length, sz) < 0) - return ASN_PARSE_E; - - if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) - return ASN_PARSE_E; - - if (oid != PBKDF2_OID) - return ASN_PARSE_E; - } - - if (GetSequence(input, &inOutIdx, &length, sz) < 0) - return ASN_PARSE_E; - - if (input[inOutIdx++] != ASN_OCTET_STRING) - return ASN_PARSE_E; - - if (GetLength(input, &inOutIdx, &saltSz, sz) < 0) - return ASN_PARSE_E; - - if (saltSz > MAX_SALT_SIZE) - return ASN_PARSE_E; - -#ifdef CYASSL_SMALL_STACK - salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (salt == NULL) - return MEMORY_E; -#endif - - XMEMCPY(salt, &input[inOutIdx], saltSz); - inOutIdx += saltSz; - - if (GetShortInt(input, &inOutIdx, &iterations) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; - } - -#ifdef CYASSL_SMALL_STACK - cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (cbcIv == NULL) { - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - if (version == PKCS5v2) { - /* get encryption algo */ - if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; - } - - if (CheckAlgoV2(oid, &id) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; /* PKCS v2 algo id error */ - } - - if (input[inOutIdx++] != ASN_OCTET_STRING) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; - } - - if (GetLength(input, &inOutIdx, &length, sz) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; - } - - XMEMCPY(cbcIv, &input[inOutIdx], length); - inOutIdx += length; - } - - if (input[inOutIdx++] != ASN_OCTET_STRING) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; - } - - if (GetLength(input, &inOutIdx, &length, sz) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; - } - - if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id, - input + inOutIdx, length, version, cbcIv) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_INPUT_E; /* decrypt failure */ - } - -#ifdef CYASSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - XMEMMOVE(input, input + inOutIdx, length); - return ToTraditional(input, length); -} - -#endif /* NO_PWDBASED */ - -#ifndef NO_RSA - -int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, - word32 inSz) -{ - int length; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - key->type = RSA_PUBLIC; - -#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA) - { - byte b = input[*inOutIdx]; - if (b != ASN_INTEGER) { - /* not from decoded cert, will have algo id, skip past */ - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - b = input[(*inOutIdx)++]; - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; - - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - *inOutIdx += length; /* skip past */ - - /* could have NULL tag and 0 terminator, but may not */ - b = input[(*inOutIdx)++]; - - if (b == ASN_TAG_NULL) { - b = input[(*inOutIdx)++]; - if (b != 0) - return ASN_EXPECT_0_E; - } - else - /* go back, didn't have it */ - (*inOutIdx)--; - - /* should have bit tag length and seq next */ - b = input[(*inOutIdx)++]; - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; - - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - /* could have 0 */ - b = input[(*inOutIdx)++]; - if (b != 0) - (*inOutIdx)--; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - } /* end if */ - } /* openssl var block */ -#endif /* OPENSSL_EXTRA */ - - if (GetInt(&key->n, input, inOutIdx, inSz) < 0 || - GetInt(&key->e, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E; - - return 0; -} - -int RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, word32 eSz, - RsaKey* key) -{ - if (n == NULL || e == NULL || key == NULL) - return BAD_FUNC_ARG; - - key->type = RSA_PUBLIC; - - if (mp_init(&key->n) != MP_OKAY) - return MP_INIT_E; - - if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) { - mp_clear(&key->n); - return ASN_GETINT_E; - } - - if (mp_init(&key->e) != MP_OKAY) { - mp_clear(&key->n); - return MP_INIT_E; - } - - if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) { - mp_clear(&key->n); - mp_clear(&key->e); - return ASN_GETINT_E; - } - - return 0; -} - -#endif - -#ifndef NO_DH - -int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz) -{ - int length; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetInt(&key->p, input, inOutIdx, inSz) < 0 || - GetInt(&key->g, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; - - return 0; -} - -int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz) -{ - if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) - return BAD_FUNC_ARG; - - /* may have leading 0 */ - if (p[0] == 0) { - pSz--; p++; - } - - if (g[0] == 0) { - gSz--; g++; - } - - if (mp_init(&key->p) != MP_OKAY) - return MP_INIT_E; - if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) { - mp_clear(&key->p); - return ASN_DH_KEY_E; - } - - if (mp_init(&key->g) != MP_OKAY) { - mp_clear(&key->p); - return MP_INIT_E; - } - if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) { - mp_clear(&key->g); - mp_clear(&key->p); - return ASN_DH_KEY_E; - } - - return 0; -} - - -int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz, - byte* g, word32* gInOutSz) -{ - word32 i = 0; - byte b; - int length; - - if (GetSequence(input, &i, &length, inSz) < 0) - return ASN_PARSE_E; - - b = input[i++]; - if (b != ASN_INTEGER) - return ASN_PARSE_E; - - if (GetLength(input, &i, &length, inSz) < 0) - return ASN_PARSE_E; - - if ( (b = input[i++]) == 0x00) - length--; - else - i--; - - if (length <= (int)*pInOutSz) { - XMEMCPY(p, &input[i], length); - *pInOutSz = length; - } - else - return BUFFER_E; - - i += length; - - b = input[i++]; - if (b != ASN_INTEGER) - return ASN_PARSE_E; - - if (GetLength(input, &i, &length, inSz) < 0) - return ASN_PARSE_E; - - if (length <= (int)*gInOutSz) { - XMEMCPY(g, &input[i], length); - *gInOutSz = length; - } - else - return BUFFER_E; - - return 0; -} - -#endif /* NO_DH */ - - -#ifndef NO_DSA - -int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, - word32 inSz) -{ - int length; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetInt(&key->p, input, inOutIdx, inSz) < 0 || - GetInt(&key->q, input, inOutIdx, inSz) < 0 || - GetInt(&key->g, input, inOutIdx, inSz) < 0 || - GetInt(&key->y, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; - - key->type = DSA_PUBLIC; - return 0; -} - - -int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key, - word32 inSz) -{ - int length, version; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetMyVersion(input, inOutIdx, &version) < 0) - return ASN_PARSE_E; - - if (GetInt(&key->p, input, inOutIdx, inSz) < 0 || - GetInt(&key->q, input, inOutIdx, inSz) < 0 || - GetInt(&key->g, input, inOutIdx, inSz) < 0 || - GetInt(&key->y, input, inOutIdx, inSz) < 0 || - GetInt(&key->x, input, inOutIdx, inSz) < 0 ) return ASN_DH_KEY_E; - - key->type = DSA_PRIVATE; - return 0; -} - -#endif /* NO_DSA */ - - -void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap) -{ - cert->publicKey = 0; - cert->pubKeySize = 0; - cert->pubKeyStored = 0; - cert->version = 0; - cert->signature = 0; - cert->subjectCN = 0; - cert->subjectCNLen = 0; - cert->subjectCNEnc = CTC_UTF8; - cert->subjectCNStored = 0; - cert->altNames = NULL; -#ifndef IGNORE_NAME_CONSTRAINTS - cert->altEmailNames = NULL; - cert->permittedNames = NULL; - cert->excludedNames = NULL; -#endif /* IGNORE_NAME_CONSTRAINTS */ - cert->issuer[0] = '\0'; - cert->subject[0] = '\0'; - cert->source = source; /* don't own */ - cert->srcIdx = 0; - cert->maxIdx = inSz; /* can't go over this index */ - cert->heap = heap; - XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE); - cert->serialSz = 0; - cert->extensions = 0; - cert->extensionsSz = 0; - cert->extensionsIdx = 0; - cert->extAuthInfo = NULL; - cert->extAuthInfoSz = 0; - cert->extCrlInfo = NULL; - cert->extCrlInfoSz = 0; - XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE); - cert->extSubjKeyIdSet = 0; - XMEMSET(cert->extAuthKeyId, 0, SHA_SIZE); - cert->extAuthKeyIdSet = 0; - cert->extKeyUsageSet = 0; - cert->extKeyUsage = 0; - cert->extExtKeyUsageSet = 0; - cert->extExtKeyUsage = 0; - cert->isCA = 0; -#ifdef HAVE_PKCS7 - cert->issuerRaw = NULL; - cert->issuerRawLen = 0; -#endif -#ifdef CYASSL_CERT_GEN - cert->subjectSN = 0; - cert->subjectSNLen = 0; - cert->subjectSNEnc = CTC_UTF8; - cert->subjectC = 0; - cert->subjectCLen = 0; - cert->subjectCEnc = CTC_PRINTABLE; - cert->subjectL = 0; - cert->subjectLLen = 0; - cert->subjectLEnc = CTC_UTF8; - cert->subjectST = 0; - cert->subjectSTLen = 0; - cert->subjectSTEnc = CTC_UTF8; - cert->subjectO = 0; - cert->subjectOLen = 0; - cert->subjectOEnc = CTC_UTF8; - cert->subjectOU = 0; - cert->subjectOULen = 0; - cert->subjectOUEnc = CTC_UTF8; - cert->subjectEmail = 0; - cert->subjectEmailLen = 0; -#endif /* CYASSL_CERT_GEN */ - cert->beforeDate = NULL; - cert->beforeDateLen = 0; - cert->afterDate = NULL; - cert->afterDateLen = 0; -#ifdef OPENSSL_EXTRA - XMEMSET(&cert->issuerName, 0, sizeof(DecodedName)); - XMEMSET(&cert->subjectName, 0, sizeof(DecodedName)); - cert->extBasicConstSet = 0; - cert->extBasicConstCrit = 0; - cert->extBasicConstPlSet = 0; - cert->pathLength = 0; - cert->extSubjAltNameSet = 0; - cert->extSubjAltNameCrit = 0; - cert->extAuthKeyIdCrit = 0; - cert->extSubjKeyIdCrit = 0; - cert->extKeyUsageCrit = 0; - cert->extExtKeyUsageCrit = 0; - cert->extExtKeyUsageSrc = NULL; - cert->extExtKeyUsageSz = 0; - cert->extExtKeyUsageCount = 0; - cert->extAuthKeyIdSrc = NULL; - cert->extAuthKeyIdSz = 0; - cert->extSubjKeyIdSrc = NULL; - cert->extSubjKeyIdSz = 0; -#endif /* OPENSSL_EXTRA */ -#if defined(OPENSSL_EXTRA) || !defined(IGNORE_NAME_CONSTRAINTS) - cert->extNameConstraintSet = 0; -#endif /* OPENSSL_EXTRA || !IGNORE_NAME_CONSTRAINTS */ -#ifdef HAVE_ECC - cert->pkCurveOID = 0; -#endif /* HAVE_ECC */ -#ifdef CYASSL_SEP - cert->deviceTypeSz = 0; - cert->deviceType = NULL; - cert->hwTypeSz = 0; - cert->hwType = NULL; - cert->hwSerialNumSz = 0; - cert->hwSerialNum = NULL; - #ifdef OPENSSL_EXTRA - cert->extCertPolicySet = 0; - cert->extCertPolicyCrit = 0; - #endif /* OPENSSL_EXTRA */ -#endif /* CYASSL_SEP */ -} - - -void FreeAltNames(DNS_entry* altNames, void* heap) -{ - (void)heap; - - while (altNames) { - DNS_entry* tmp = altNames->next; - - XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME); - XFREE(altNames, heap, DYNAMIC_TYPE_ALTNAME); - altNames = tmp; - } -} - -#ifndef IGNORE_NAME_CONSTRAINTS - -void FreeNameSubtrees(Base_entry* names, void* heap) -{ - (void)heap; - - while (names) { - Base_entry* tmp = names->next; - - XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME); - XFREE(names, heap, DYNAMIC_TYPE_ALTNAME); - names = tmp; - } -} - -#endif /* IGNORE_NAME_CONSTRAINTS */ - -void FreeDecodedCert(DecodedCert* cert) -{ - if (cert->subjectCNStored == 1) - XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN); - if (cert->pubKeyStored == 1) - XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); - if (cert->altNames) - FreeAltNames(cert->altNames, cert->heap); -#ifndef IGNORE_NAME_CONSTRAINTS - if (cert->altEmailNames) - FreeAltNames(cert->altEmailNames, cert->heap); - if (cert->permittedNames) - FreeNameSubtrees(cert->permittedNames, cert->heap); - if (cert->excludedNames) - FreeNameSubtrees(cert->excludedNames, cert->heap); -#endif /* IGNORE_NAME_CONSTRAINTS */ -#ifdef CYASSL_SEP - XFREE(cert->deviceType, cert->heap, 0); - XFREE(cert->hwType, cert->heap, 0); - XFREE(cert->hwSerialNum, cert->heap, 0); -#endif /* CYASSL_SEP */ -#ifdef OPENSSL_EXTRA - if (cert->issuerName.fullName != NULL) - XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509); - if (cert->subjectName.fullName != NULL) - XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509); -#endif /* OPENSSL_EXTRA */ -} - - -static int GetCertHeader(DecodedCert* cert) -{ - int ret = 0, len; - byte serialTmp[EXTERNAL_SERIAL_SIZE]; -#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) - mp_int* mpi = NULL; -#else - mp_int stack_mpi; - mp_int* mpi = &stack_mpi; -#endif - - if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) - return ASN_PARSE_E; - - cert->certBegin = cert->srcIdx; - - if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0) - return ASN_PARSE_E; - cert->sigIndex = len + cert->srcIdx; - - if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0) - return ASN_PARSE_E; - -#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) - mpi = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (mpi == NULL) - return MEMORY_E; -#endif - - if (GetInt(mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0) { -#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) - XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_PARSE_E; - } - - len = mp_unsigned_bin_size(mpi); - if (len < (int)sizeof(serialTmp)) { - if ( (ret = mp_to_unsigned_bin(mpi, serialTmp)) == MP_OKAY) { - XMEMCPY(cert->serial, serialTmp, len); - cert->serialSz = len; - } - } - mp_clear(mpi); - -#if defined(CYASSL_SMALL_STACK) && defined(USE_FAST_MATH) - XFREE(mpi, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - -#if !defined(NO_RSA) -/* Store Rsa Key, may save later, Dsa could use in future */ -static int StoreRsaKey(DecodedCert* cert) -{ - int length; - word32 recvd = cert->srcIdx; - - if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - - recvd = cert->srcIdx - recvd; - length += recvd; - - while (recvd--) - cert->srcIdx--; - - cert->pubKeySize = length; - cert->publicKey = cert->source + cert->srcIdx; - cert->srcIdx += length; - - return 0; -} -#endif - - -#ifdef HAVE_ECC - - /* return 0 on sucess if the ECC curve oid sum is supported */ - static int CheckCurve(word32 oid) - { - if (oid != ECC_256R1 && oid != ECC_384R1 && oid != ECC_521R1 && oid != - ECC_160R1 && oid != ECC_192R1 && oid != ECC_224R1) - return ALGO_ID_E; - - return 0; - } - -#endif /* HAVE_ECC */ - - -static int GetKey(DecodedCert* cert) -{ - int length; -#ifdef HAVE_NTRU - int tmpIdx = cert->srcIdx; -#endif - - if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - - if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0) - return ASN_PARSE_E; - - switch (cert->keyOID) { - #ifndef NO_RSA - case RSAk: - { - byte b = cert->source[cert->srcIdx++]; - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; - - if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0) - return ASN_PARSE_E; - b = cert->source[cert->srcIdx++]; - if (b != 0x00) - return ASN_EXPECT_0_E; - - return StoreRsaKey(cert); - } - - #endif /* NO_RSA */ - #ifdef HAVE_NTRU - case NTRUk: - { - const byte* key = &cert->source[tmpIdx]; - byte* next = (byte*)key; - word16 keyLen; - word32 rc; - word32 remaining = cert->maxIdx - cert->srcIdx; -#ifdef CYASSL_SMALL_STACK - byte* keyBlob = NULL; -#else - byte keyBlob[MAX_NTRU_KEY_SZ]; -#endif - rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, - &keyLen, NULL, &next, &remaining); - if (rc != NTRU_OK) - return ASN_NTRU_KEY_E; - if (keyLen > MAX_NTRU_KEY_SZ) - return ASN_NTRU_KEY_E; - -#ifdef CYASSL_SMALL_STACK - keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (keyBlob == NULL) - return MEMORY_E; -#endif - - rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, - &keyLen, keyBlob, &next, &remaining); - if (rc != NTRU_OK) { -#ifdef CYASSL_SMALL_STACK - XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_NTRU_KEY_E; - } - - if ( (next - key) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ASN_NTRU_KEY_E; - } - - cert->srcIdx = tmpIdx + (int)(next - key); - - cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (cert->publicKey == NULL) { -#ifdef CYASSL_SMALL_STACK - XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return MEMORY_E; - } - XMEMCPY(cert->publicKey, keyBlob, keyLen); - cert->pubKeyStored = 1; - cert->pubKeySize = keyLen; - -#ifdef CYASSL_SMALL_STACK - XFREE(keyBlob, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return 0; - } - #endif /* HAVE_NTRU */ - #ifdef HAVE_ECC - case ECDSAk: - { - int oidSz = 0; - byte b = cert->source[cert->srcIdx++]; - - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; - - if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0) - return ASN_PARSE_E; - - while(oidSz--) - cert->pkCurveOID += cert->source[cert->srcIdx++]; - - if (CheckCurve(cert->pkCurveOID) < 0) - return ECC_CURVE_OID_E; - - /* key header */ - b = cert->source[cert->srcIdx++]; - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; - - if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0) - return ASN_PARSE_E; - b = cert->source[cert->srcIdx++]; - if (b != 0x00) - return ASN_EXPECT_0_E; - - /* actual key, use length - 1 since ate preceding 0 */ - length -= 1; - - cert->publicKey = (byte*) XMALLOC(length, cert->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (cert->publicKey == NULL) - return MEMORY_E; - XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length); - cert->pubKeyStored = 1; - cert->pubKeySize = length; - - cert->srcIdx += length; - - return 0; - } - #endif /* HAVE_ECC */ - default: - return ASN_UNKNOWN_OID_E; - } -} - - -/* process NAME, either issuer or subject */ -static int GetName(DecodedCert* cert, int nameType) -{ - Sha sha; /* MUST have SHA-1 hash for cert names */ - int length; /* length of all distinguished names */ - int dummy; - int ret; - char* full = (nameType == ISSUER) ? cert->issuer : cert->subject; - word32 idx; - #ifdef OPENSSL_EXTRA - DecodedName* dName = - (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName; - #endif /* OPENSSL_EXTRA */ - - CYASSL_MSG("Getting Cert Name"); - - if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) { - CYASSL_MSG("Trying optional prefix..."); - - if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - - cert->srcIdx += length; - CYASSL_MSG("Got optional prefix"); - } - - /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be - * calculated over the entire DER encoding of the Name field, including - * the tag and length. */ - idx = cert->srcIdx; - if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - - ret = InitSha(&sha); - if (ret != 0) - return ret; - ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx); - if (nameType == ISSUER) - ShaFinal(&sha, cert->issuerHash); - else - ShaFinal(&sha, cert->subjectHash); - - length += cert->srcIdx; - idx = 0; - -#ifdef HAVE_PKCS7 - /* store pointer to raw issuer */ - if (nameType == ISSUER) { - cert->issuerRaw = &cert->source[cert->srcIdx]; - cert->issuerRawLen = length - cert->srcIdx; - } -#endif -#ifndef IGNORE_NAME_CONSTRAINTS - if (nameType == SUBJECT) { - cert->subjectRaw = &cert->source[cert->srcIdx]; - cert->subjectRawLen = length - cert->srcIdx; - } -#endif - - while (cert->srcIdx < (word32)length) { - byte b; - byte joint[2]; - byte tooBig = FALSE; - int oidSz; - - if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) { - CYASSL_MSG("Cert name lacks set header, trying sequence"); - } - - if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) - return ASN_PARSE_E; - - b = cert->source[cert->srcIdx++]; - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; - - if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0) - return ASN_PARSE_E; - - XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint)); - - /* v1 name types */ - if (joint[0] == 0x55 && joint[1] == 0x04) { - byte id; - byte copy = FALSE; - int strLen; - - cert->srcIdx += 2; - id = cert->source[cert->srcIdx++]; - b = cert->source[cert->srcIdx++]; /* encoding */ - - if (GetLength(cert->source, &cert->srcIdx, &strLen, - cert->maxIdx) < 0) - return ASN_PARSE_E; - - if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) { - /* include biggest pre fix header too 4 = "/serialNumber=" */ - CYASSL_MSG("ASN Name too big, skipping"); - tooBig = TRUE; - } - - if (id == ASN_COMMON_NAME) { - if (nameType == SUBJECT) { - cert->subjectCN = (char *)&cert->source[cert->srcIdx]; - cert->subjectCNLen = strLen; - cert->subjectCNEnc = b; - } - - if (!tooBig) { - XMEMCPY(&full[idx], "/CN=", 4); - idx += 4; - copy = TRUE; - } - #ifdef OPENSSL_EXTRA - dName->cnIdx = cert->srcIdx; - dName->cnLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - else if (id == ASN_SUR_NAME) { - if (!tooBig) { - XMEMCPY(&full[idx], "/SN=", 4); - idx += 4; - copy = TRUE; - } - #ifdef CYASSL_CERT_GEN - if (nameType == SUBJECT) { - cert->subjectSN = (char*)&cert->source[cert->srcIdx]; - cert->subjectSNLen = strLen; - cert->subjectSNEnc = b; - } - #endif /* CYASSL_CERT_GEN */ - #ifdef OPENSSL_EXTRA - dName->snIdx = cert->srcIdx; - dName->snLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - else if (id == ASN_COUNTRY_NAME) { - if (!tooBig) { - XMEMCPY(&full[idx], "/C=", 3); - idx += 3; - copy = TRUE; - } - #ifdef CYASSL_CERT_GEN - if (nameType == SUBJECT) { - cert->subjectC = (char*)&cert->source[cert->srcIdx]; - cert->subjectCLen = strLen; - cert->subjectCEnc = b; - } - #endif /* CYASSL_CERT_GEN */ - #ifdef OPENSSL_EXTRA - dName->cIdx = cert->srcIdx; - dName->cLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - else if (id == ASN_LOCALITY_NAME) { - if (!tooBig) { - XMEMCPY(&full[idx], "/L=", 3); - idx += 3; - copy = TRUE; - } - #ifdef CYASSL_CERT_GEN - if (nameType == SUBJECT) { - cert->subjectL = (char*)&cert->source[cert->srcIdx]; - cert->subjectLLen = strLen; - cert->subjectLEnc = b; - } - #endif /* CYASSL_CERT_GEN */ - #ifdef OPENSSL_EXTRA - dName->lIdx = cert->srcIdx; - dName->lLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - else if (id == ASN_STATE_NAME) { - if (!tooBig) { - XMEMCPY(&full[idx], "/ST=", 4); - idx += 4; - copy = TRUE; - } - #ifdef CYASSL_CERT_GEN - if (nameType == SUBJECT) { - cert->subjectST = (char*)&cert->source[cert->srcIdx]; - cert->subjectSTLen = strLen; - cert->subjectSTEnc = b; - } - #endif /* CYASSL_CERT_GEN */ - #ifdef OPENSSL_EXTRA - dName->stIdx = cert->srcIdx; - dName->stLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - else if (id == ASN_ORG_NAME) { - if (!tooBig) { - XMEMCPY(&full[idx], "/O=", 3); - idx += 3; - copy = TRUE; - } - #ifdef CYASSL_CERT_GEN - if (nameType == SUBJECT) { - cert->subjectO = (char*)&cert->source[cert->srcIdx]; - cert->subjectOLen = strLen; - cert->subjectOEnc = b; - } - #endif /* CYASSL_CERT_GEN */ - #ifdef OPENSSL_EXTRA - dName->oIdx = cert->srcIdx; - dName->oLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - else if (id == ASN_ORGUNIT_NAME) { - if (!tooBig) { - XMEMCPY(&full[idx], "/OU=", 4); - idx += 4; - copy = TRUE; - } - #ifdef CYASSL_CERT_GEN - if (nameType == SUBJECT) { - cert->subjectOU = (char*)&cert->source[cert->srcIdx]; - cert->subjectOULen = strLen; - cert->subjectOUEnc = b; - } - #endif /* CYASSL_CERT_GEN */ - #ifdef OPENSSL_EXTRA - dName->ouIdx = cert->srcIdx; - dName->ouLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - else if (id == ASN_SERIAL_NUMBER) { - if (!tooBig) { - XMEMCPY(&full[idx], "/serialNumber=", 14); - idx += 14; - copy = TRUE; - } - #ifdef OPENSSL_EXTRA - dName->snIdx = cert->srcIdx; - dName->snLen = strLen; - #endif /* OPENSSL_EXTRA */ - } - - if (copy && !tooBig) { - XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen); - idx += strLen; - } - - cert->srcIdx += strLen; - } - else { - /* skip */ - byte email = FALSE; - byte uid = FALSE; - int adv; - - if (joint[0] == 0x2a && joint[1] == 0x86) /* email id hdr */ - email = TRUE; - - if (joint[0] == 0x9 && joint[1] == 0x92) /* uid id hdr */ - uid = TRUE; - - cert->srcIdx += oidSz + 1; - - if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0) - return ASN_PARSE_E; - - if (adv > (int)(ASN_NAME_MAX - idx)) { - CYASSL_MSG("ASN name too big, skipping"); - tooBig = TRUE; - } - - if (email) { - if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) { - CYASSL_MSG("ASN name too big, skipping"); - tooBig = TRUE; - } - if (!tooBig) { - XMEMCPY(&full[idx], "/emailAddress=", 14); - idx += 14; - } - - #ifdef CYASSL_CERT_GEN - if (nameType == SUBJECT) { - cert->subjectEmail = (char*)&cert->source[cert->srcIdx]; - cert->subjectEmailLen = adv; - } - #endif /* CYASSL_CERT_GEN */ - #ifdef OPENSSL_EXTRA - dName->emailIdx = cert->srcIdx; - dName->emailLen = adv; - #endif /* OPENSSL_EXTRA */ - #ifndef IGNORE_NAME_CONSTRAINTS - { - DNS_entry* emailName = NULL; - - emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry), - cert->heap, DYNAMIC_TYPE_ALTNAME); - if (emailName == NULL) { - CYASSL_MSG("\tOut of Memory"); - return MEMORY_E; - } - emailName->name = (char*)XMALLOC(adv + 1, - cert->heap, DYNAMIC_TYPE_ALTNAME); - if (emailName->name == NULL) { - CYASSL_MSG("\tOut of Memory"); - return MEMORY_E; - } - XMEMCPY(emailName->name, - &cert->source[cert->srcIdx], adv); - emailName->name[adv] = 0; - - emailName->next = cert->altEmailNames; - cert->altEmailNames = emailName; - } - #endif /* IGNORE_NAME_CONSTRAINTS */ - if (!tooBig) { - XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv); - idx += adv; - } - } - - if (uid) { - if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) { - CYASSL_MSG("ASN name too big, skipping"); - tooBig = TRUE; - } - if (!tooBig) { - XMEMCPY(&full[idx], "/UID=", 5); - idx += 5; - - XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv); - idx += adv; - } - #ifdef OPENSSL_EXTRA - dName->uidIdx = cert->srcIdx; - dName->uidLen = adv; - #endif /* OPENSSL_EXTRA */ - } - - cert->srcIdx += adv; - } - } - full[idx++] = 0; - - #ifdef OPENSSL_EXTRA - { - int totalLen = 0; - - if (dName->cnLen != 0) - totalLen += dName->cnLen + 4; - if (dName->snLen != 0) - totalLen += dName->snLen + 4; - if (dName->cLen != 0) - totalLen += dName->cLen + 3; - if (dName->lLen != 0) - totalLen += dName->lLen + 3; - if (dName->stLen != 0) - totalLen += dName->stLen + 4; - if (dName->oLen != 0) - totalLen += dName->oLen + 3; - if (dName->ouLen != 0) - totalLen += dName->ouLen + 4; - if (dName->emailLen != 0) - totalLen += dName->emailLen + 14; - if (dName->uidLen != 0) - totalLen += dName->uidLen + 5; - if (dName->serialLen != 0) - totalLen += dName->serialLen + 14; - - dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509); - if (dName->fullName != NULL) { - idx = 0; - - if (dName->cnLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/CN=", 4); - idx += 4; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->cnIdx], dName->cnLen); - dName->cnIdx = idx; - idx += dName->cnLen; - } - if (dName->snLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/SN=", 4); - idx += 4; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->snIdx], dName->snLen); - dName->snIdx = idx; - idx += dName->snLen; - } - if (dName->cLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/C=", 3); - idx += 3; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->cIdx], dName->cLen); - dName->cIdx = idx; - idx += dName->cLen; - } - if (dName->lLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/L=", 3); - idx += 3; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->lIdx], dName->lLen); - dName->lIdx = idx; - idx += dName->lLen; - } - if (dName->stLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/ST=", 4); - idx += 4; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->stIdx], dName->stLen); - dName->stIdx = idx; - idx += dName->stLen; - } - if (dName->oLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/O=", 3); - idx += 3; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->oIdx], dName->oLen); - dName->oIdx = idx; - idx += dName->oLen; - } - if (dName->ouLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/OU=", 4); - idx += 4; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->ouIdx], dName->ouLen); - dName->ouIdx = idx; - idx += dName->ouLen; - } - if (dName->emailLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14); - idx += 14; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->emailIdx], dName->emailLen); - dName->emailIdx = idx; - idx += dName->emailLen; - } - if (dName->uidLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/UID=", 5); - idx += 5; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->uidIdx], dName->uidLen); - dName->uidIdx = idx; - idx += dName->uidLen; - } - if (dName->serialLen != 0) { - dName->entryCount++; - XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14); - idx += 14; - XMEMCPY(&dName->fullName[idx], - &cert->source[dName->serialIdx], dName->serialLen); - dName->serialIdx = idx; - idx += dName->serialLen; - } - dName->fullName[idx] = '\0'; - dName->fullNameLen = totalLen; - } - } - #endif /* OPENSSL_EXTRA */ - - return 0; -} - - -#ifndef NO_TIME_H - -/* to the second */ -static int DateGreaterThan(const struct tm* a, const struct tm* b) -{ - if (a->tm_year > b->tm_year) - return 1; - - if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon) - return 1; - - if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && - a->tm_mday > b->tm_mday) - return 1; - - if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && - a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour) - return 1; - - if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && - a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && - a->tm_min > b->tm_min) - return 1; - - if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon && - a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour && - a->tm_min == b->tm_min && a->tm_sec > b->tm_sec) - return 1; - - return 0; /* false */ -} - - -static INLINE int DateLessThan(const struct tm* a, const struct tm* b) -{ - return DateGreaterThan(b,a); -} - - -/* like atoi but only use first byte */ -/* Make sure before and after dates are valid */ -int ValidateDate(const byte* date, byte format, int dateType) -{ - time_t ltime; - struct tm certTime; - struct tm* localTime; - int i = 0; - - ltime = XTIME(0); - XMEMSET(&certTime, 0, sizeof(certTime)); - - if (format == ASN_UTC_TIME) { - if (btoi(date[0]) >= 5) - certTime.tm_year = 1900; - else - certTime.tm_year = 2000; - } - else { /* format == GENERALIZED_TIME */ - certTime.tm_year += btoi(date[i++]) * 1000; - certTime.tm_year += btoi(date[i++]) * 100; - } - - /* adjust tm_year, tm_mon */ - GetTime((int*)&certTime.tm_year, date, &i); certTime.tm_year -= 1900; - GetTime((int*)&certTime.tm_mon, date, &i); certTime.tm_mon -= 1; - GetTime((int*)&certTime.tm_mday, date, &i); - GetTime((int*)&certTime.tm_hour, date, &i); - GetTime((int*)&certTime.tm_min, date, &i); - GetTime((int*)&certTime.tm_sec, date, &i); - - if (date[i] != 'Z') { /* only Zulu supported for this profile */ - CYASSL_MSG("Only Zulu time supported for this profile"); - return 0; - } - - localTime = XGMTIME(<ime); - - if (dateType == BEFORE) { - if (DateLessThan(localTime, &certTime)) - return 0; - } - else - if (DateGreaterThan(localTime, &certTime)) - return 0; - - return 1; -} - -#endif /* NO_TIME_H */ - - -static int GetDate(DecodedCert* cert, int dateType) -{ - int length; - byte date[MAX_DATE_SIZE]; - byte b; - word32 startIdx = 0; - - if (dateType == BEFORE) - cert->beforeDate = &cert->source[cert->srcIdx]; - else - cert->afterDate = &cert->source[cert->srcIdx]; - startIdx = cert->srcIdx; - - b = cert->source[cert->srcIdx++]; - if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) - return ASN_TIME_E; - - if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - - if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) - return ASN_DATE_SZ_E; - - XMEMCPY(date, &cert->source[cert->srcIdx], length); - cert->srcIdx += length; - - if (dateType == BEFORE) - cert->beforeDateLen = cert->srcIdx - startIdx; - else - cert->afterDateLen = cert->srcIdx - startIdx; - - if (!XVALIDATE_DATE(date, b, dateType)) { - if (dateType == BEFORE) - return ASN_BEFORE_DATE_E; - else - return ASN_AFTER_DATE_E; - } - - return 0; -} - - -static int GetValidity(DecodedCert* cert, int verify) -{ - int length; - int badDate = 0; - - if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - - if (GetDate(cert, BEFORE) < 0 && verify) - badDate = ASN_BEFORE_DATE_E; /* continue parsing */ - - if (GetDate(cert, AFTER) < 0 && verify) - return ASN_AFTER_DATE_E; - - if (badDate != 0) - return badDate; - - return 0; -} - - -int DecodeToKey(DecodedCert* cert, int verify) -{ - int badDate = 0; - int ret; - - if ( (ret = GetCertHeader(cert)) < 0) - return ret; - - CYASSL_MSG("Got Cert Header"); - - if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID, - cert->maxIdx)) < 0) - return ret; - - CYASSL_MSG("Got Algo ID"); - - if ( (ret = GetName(cert, ISSUER)) < 0) - return ret; - - if ( (ret = GetValidity(cert, verify)) < 0) - badDate = ret; - - if ( (ret = GetName(cert, SUBJECT)) < 0) - return ret; - - CYASSL_MSG("Got Subject Name"); - - if ( (ret = GetKey(cert)) < 0) - return ret; - - CYASSL_MSG("Got Key"); - - if (badDate != 0) - return badDate; - - return ret; -} - - -static int GetSignature(DecodedCert* cert) -{ - int length; - byte b = cert->source[cert->srcIdx++]; - - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; - - if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - - cert->sigLength = length; - - b = cert->source[cert->srcIdx++]; - if (b != 0x00) - return ASN_EXPECT_0_E; - - cert->sigLength--; - cert->signature = &cert->source[cert->srcIdx]; - cert->srcIdx += cert->sigLength; - - return 0; -} - - -static word32 SetDigest(const byte* digest, word32 digSz, byte* output) -{ - output[0] = ASN_OCTET_STRING; - output[1] = (byte)digSz; - XMEMCPY(&output[2], digest, digSz); - - return digSz + 2; -} - - -static word32 BytePrecision(word32 value) -{ - word32 i; - for (i = sizeof(value); i; --i) - if (value >> ((i - 1) * CYASSL_BIT_SIZE)) - break; - - return i; -} - - -CYASSL_LOCAL word32 SetLength(word32 length, byte* output) -{ - word32 i = 0, j; - - if (length < ASN_LONG_LENGTH) - output[i++] = (byte)length; - else { - output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH); - - for (j = BytePrecision(length); j; --j) { - output[i] = (byte)(length >> ((j - 1) * CYASSL_BIT_SIZE)); - i++; - } - } - - return i; -} - - -CYASSL_LOCAL word32 SetSequence(word32 len, byte* output) -{ - output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED; - return SetLength(len, output + 1) + 1; -} - -CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output) -{ - output[0] = ASN_OCTET_STRING; - return SetLength(len, output + 1) + 1; -} - -/* Write a set header to output */ -CYASSL_LOCAL word32 SetSet(word32 len, byte* output) -{ - output[0] = ASN_SET | ASN_CONSTRUCTED; - return SetLength(len, output + 1) + 1; -} - -CYASSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output) -{ - - output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0) - | ASN_CONTEXT_SPECIFIC | number; - return SetLength(len, output + 1) + 1; -} - -CYASSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output) -{ - output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number; - return SetLength(len, output + 1) + 1; -} - - -#if defined(HAVE_ECC) && (defined(CYASSL_CERT_GEN) || defined(CYASSL_KEY_GEN)) - -static word32 SetCurve(ecc_key* key, byte* output) -{ - - /* curve types */ - static const byte ECC_192v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, - 0x03, 0x01, 0x01}; - static const byte ECC_256v1_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, - 0x03, 0x01, 0x07}; - static const byte ECC_160r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x02}; - static const byte ECC_224r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x21}; - static const byte ECC_384r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x22}; - static const byte ECC_521r1_AlgoID[] = { 0x2b, 0x81, 0x04, 0x00, - 0x23}; - - int oidSz = 0; - int idx = 0; - int lenSz = 0; - const byte* oid = 0; - - output[0] = ASN_OBJECT_ID; - idx++; - - switch (key->dp->size) { - case 20: - oidSz = sizeof(ECC_160r1_AlgoID); - oid = ECC_160r1_AlgoID; - break; - - case 24: - oidSz = sizeof(ECC_192v1_AlgoID); - oid = ECC_192v1_AlgoID; - break; - - case 28: - oidSz = sizeof(ECC_224r1_AlgoID); - oid = ECC_224r1_AlgoID; - break; - - case 32: - oidSz = sizeof(ECC_256v1_AlgoID); - oid = ECC_256v1_AlgoID; - break; - - case 48: - oidSz = sizeof(ECC_384r1_AlgoID); - oid = ECC_384r1_AlgoID; - break; - - case 66: - oidSz = sizeof(ECC_521r1_AlgoID); - oid = ECC_521r1_AlgoID; - break; - - default: - return ASN_UNKNOWN_OID_E; - } - lenSz = SetLength(oidSz, output+idx); - idx += lenSz; - - XMEMCPY(output+idx, oid, oidSz); - idx += oidSz; - - return idx; -} - -#endif /* HAVE_ECC && CYASSL_CERT_GEN */ - - -CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz) -{ - /* adding TAG_NULL and 0 to end */ - - /* hashTypes */ - static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a, - 0x05, 0x00 }; - static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x01, 0x05, 0x00 }; - static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x02, 0x05, 0x00 }; - static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x03, 0x05, 0x00 }; - static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x02, 0x05, 0x05, 0x00 }; - static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x02, 0x02, 0x05, 0x00}; - - /* blkTypes, no NULL tags because IV is there instead */ - static const byte desCbcAlgoID[] = { 0x2B, 0x0E, 0x03, 0x02, 0x07 }; - static const byte des3CbcAlgoID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, - 0x0D, 0x03, 0x07 }; - - /* RSA sigTypes */ - #ifndef NO_RSA - static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00}; - static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00}; - static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00}; - static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00}; - static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00}; - #endif /* NO_RSA */ - - /* ECDSA sigTypes */ - #ifdef HAVE_ECC - static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, - 0x04, 0x01, 0x05, 0x00}; - static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, - 0x04, 0x03, 0x02, 0x05, 0x00}; - static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, - 0x04, 0x03, 0x03, 0x05, 0x00}; - static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d, - 0x04, 0x03, 0x04, 0x05, 0x00}; - #endif /* HAVE_ECC */ - - /* RSA keyType */ - #ifndef NO_RSA - static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00}; - #endif /* NO_RSA */ - - #ifdef HAVE_ECC - /* ECC keyType */ - /* no tags, so set tagSz smaller later */ - static const byte ECC_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d, - 0x02, 0x01}; - #endif /* HAVE_ECC */ - - int algoSz = 0; - int tagSz = 2; /* tag null and terminator */ - word32 idSz, seqSz; - const byte* algoName = 0; - byte ID_Length[MAX_LENGTH_SZ]; - byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */ - - if (type == hashType) { - switch (algoOID) { - case SHAh: - algoSz = sizeof(shaAlgoID); - algoName = shaAlgoID; - break; - - case SHA256h: - algoSz = sizeof(sha256AlgoID); - algoName = sha256AlgoID; - break; - - case SHA384h: - algoSz = sizeof(sha384AlgoID); - algoName = sha384AlgoID; - break; - - case SHA512h: - algoSz = sizeof(sha512AlgoID); - algoName = sha512AlgoID; - break; - - case MD2h: - algoSz = sizeof(md2AlgoID); - algoName = md2AlgoID; - break; - - case MD5h: - algoSz = sizeof(md5AlgoID); - algoName = md5AlgoID; - break; - - default: - CYASSL_MSG("Unknown Hash Algo"); - return 0; /* UNKOWN_HASH_E; */ - } - } - else if (type == blkType) { - switch (algoOID) { - case DESb: - algoSz = sizeof(desCbcAlgoID); - algoName = desCbcAlgoID; - tagSz = 0; - break; - case DES3b: - algoSz = sizeof(des3CbcAlgoID); - algoName = des3CbcAlgoID; - tagSz = 0; - break; - default: - CYASSL_MSG("Unknown Block Algo"); - return 0; - } - } - else if (type == sigType) { /* sigType */ - switch (algoOID) { - #ifndef NO_RSA - case CTC_MD5wRSA: - algoSz = sizeof(md5wRSA_AlgoID); - algoName = md5wRSA_AlgoID; - break; - - case CTC_SHAwRSA: - algoSz = sizeof(shawRSA_AlgoID); - algoName = shawRSA_AlgoID; - break; - - case CTC_SHA256wRSA: - algoSz = sizeof(sha256wRSA_AlgoID); - algoName = sha256wRSA_AlgoID; - break; - - case CTC_SHA384wRSA: - algoSz = sizeof(sha384wRSA_AlgoID); - algoName = sha384wRSA_AlgoID; - break; - - case CTC_SHA512wRSA: - algoSz = sizeof(sha512wRSA_AlgoID); - algoName = sha512wRSA_AlgoID; - break; - #endif /* NO_RSA */ - #ifdef HAVE_ECC - case CTC_SHAwECDSA: - algoSz = sizeof(shawECDSA_AlgoID); - algoName = shawECDSA_AlgoID; - break; - - case CTC_SHA256wECDSA: - algoSz = sizeof(sha256wECDSA_AlgoID); - algoName = sha256wECDSA_AlgoID; - break; - - case CTC_SHA384wECDSA: - algoSz = sizeof(sha384wECDSA_AlgoID); - algoName = sha384wECDSA_AlgoID; - break; - - case CTC_SHA512wECDSA: - algoSz = sizeof(sha512wECDSA_AlgoID); - algoName = sha512wECDSA_AlgoID; - break; - #endif /* HAVE_ECC */ - default: - CYASSL_MSG("Unknown Signature Algo"); - return 0; - } - } - else if (type == keyType) { /* keyType */ - switch (algoOID) { - #ifndef NO_RSA - case RSAk: - algoSz = sizeof(RSA_AlgoID); - algoName = RSA_AlgoID; - break; - #endif /* NO_RSA */ - #ifdef HAVE_ECC - case ECDSAk: - algoSz = sizeof(ECC_AlgoID); - algoName = ECC_AlgoID; - tagSz = 0; - break; - #endif /* HAVE_ECC */ - default: - CYASSL_MSG("Unknown Key Algo"); - return 0; - } - } - else { - CYASSL_MSG("Unknown Algo type"); - return 0; - } - - idSz = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */ - seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray); - /* +1 for object id, curveID of curveSz follows for ecc */ - seqArray[seqSz++] = ASN_OBJECT_ID; - - XMEMCPY(output, seqArray, seqSz); - XMEMCPY(output + seqSz, ID_Length, idSz); - XMEMCPY(output + seqSz + idSz, algoName, algoSz); - - return seqSz + idSz + algoSz; - -} - - -word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID) -{ - byte digArray[MAX_ENCODED_DIG_SZ]; - byte algoArray[MAX_ALGO_SZ]; - byte seqArray[MAX_SEQ_SZ]; - word32 encDigSz, algoSz, seqSz; - - encDigSz = SetDigest(digest, digSz, digArray); - algoSz = SetAlgoID(hashOID, algoArray, hashType, 0); - seqSz = SetSequence(encDigSz + algoSz, seqArray); - - XMEMCPY(out, seqArray, seqSz); - XMEMCPY(out + seqSz, algoArray, algoSz); - XMEMCPY(out + seqSz + algoSz, digArray, encDigSz); - - return encDigSz + algoSz + seqSz; -} - - -int GetCTC_HashOID(int type) -{ - switch (type) { -#ifdef CYASSL_MD2 - case MD2: - return MD2h; -#endif -#ifndef NO_MD5 - case MD5: - return MD5h; -#endif -#ifndef NO_SHA - case SHA: - return SHAh; -#endif -#ifndef NO_SHA256 - case SHA256: - return SHA256h; -#endif -#ifdef CYASSL_SHA384 - case SHA384: - return SHA384h; -#endif -#ifdef CYASSL_SHA512 - case SHA512: - return SHA512h; -#endif - default: - return 0; - }; -} - - -/* return true (1) or false (0) for Confirmation */ -static int ConfirmSignature(const byte* buf, word32 bufSz, - const byte* key, word32 keySz, word32 keyOID, - const byte* sig, word32 sigSz, word32 sigOID, - void* heap) -{ - int typeH = 0, digestSz = 0, ret = 0; -#ifdef CYASSL_SMALL_STACK - byte* digest; -#else - byte digest[MAX_DIGEST_SIZE]; -#endif - -#ifdef CYASSL_SMALL_STACK - digest = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (digest == NULL) - return 0; /* not confirmed */ -#endif - - (void)key; - (void)keySz; - (void)sig; - (void)sigSz; - (void)heap; - - switch (sigOID) { - #ifndef NO_MD5 - case CTC_MD5wRSA: - if (Md5Hash(buf, bufSz, digest) == 0) { - typeH = MD5h; - digestSz = MD5_DIGEST_SIZE; - } - break; - #endif - #if defined(CYASSL_MD2) - case CTC_MD2wRSA: - if (Md2Hash(buf, bufSz, digest) == 0) { - typeH = MD2h; - digestSz = MD2_DIGEST_SIZE; - } - break; - #endif - #ifndef NO_SHA - case CTC_SHAwRSA: - case CTC_SHAwDSA: - case CTC_SHAwECDSA: - if (ShaHash(buf, bufSz, digest) == 0) { - typeH = SHAh; - digestSz = SHA_DIGEST_SIZE; - } - break; - #endif - #ifndef NO_SHA256 - case CTC_SHA256wRSA: - case CTC_SHA256wECDSA: - if (Sha256Hash(buf, bufSz, digest) == 0) { - typeH = SHA256h; - digestSz = SHA256_DIGEST_SIZE; - } - break; - #endif - #ifdef CYASSL_SHA512 - case CTC_SHA512wRSA: - case CTC_SHA512wECDSA: - if (Sha512Hash(buf, bufSz, digest) == 0) { - typeH = SHA512h; - digestSz = SHA512_DIGEST_SIZE; - } - break; - #endif - #ifdef CYASSL_SHA384 - case CTC_SHA384wRSA: - case CTC_SHA384wECDSA: - if (Sha384Hash(buf, bufSz, digest) == 0) { - typeH = SHA384h; - digestSz = SHA384_DIGEST_SIZE; - } - break; - #endif - default: - CYASSL_MSG("Verify Signautre has unsupported type"); - } - - if (typeH == 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return 0; /* not confirmed */ - } - - switch (keyOID) { - #ifndef NO_RSA - case RSAk: - { - word32 idx = 0; - int encodedSigSz, verifySz; - byte* out; -#ifdef CYASSL_SMALL_STACK - RsaKey* pubKey; - byte* plain; - byte* encodedSig; -#else - RsaKey pubKey[1]; - byte plain[MAX_ENCODED_SIG_SZ]; - byte encodedSig[MAX_ENCODED_SIG_SZ]; -#endif - -#ifdef CYASSL_SMALL_STACK - pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - - if (pubKey == NULL || plain == NULL || encodedSig == NULL) { - CYASSL_MSG("Failed to allocate memory at ConfirmSignature"); - - if (pubKey) - XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (plain) - XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (encodedSig) - XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); - - break; /* not confirmed */ - } -#endif - - if (sigSz > MAX_ENCODED_SIG_SZ) { - CYASSL_MSG("Verify Signautre is too big"); - } - else if (InitRsaKey(pubKey, heap) != 0) { - CYASSL_MSG("InitRsaKey failed"); - } - else if (RsaPublicKeyDecode(key, &idx, pubKey, keySz) < 0) { - CYASSL_MSG("ASN Key decode error RSA"); - } - else { - XMEMCPY(plain, sig, sigSz); - - if ((verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, - pubKey)) < 0) { - CYASSL_MSG("Rsa SSL verify error"); - } - else { - /* make sure we're right justified */ - encodedSigSz = - EncodeSignature(encodedSig, digest, digestSz, typeH); - if (encodedSigSz != verifySz || - XMEMCMP(out, encodedSig, encodedSigSz) != 0) { - CYASSL_MSG("Rsa SSL verify match encode error"); - } - else - ret = 1; /* match */ - - #ifdef CYASSL_DEBUG_ENCODING - { - int x; - - printf("cyassl encodedSig:\n"); - - for (x = 0; x < encodedSigSz; x++) { - printf("%02x ", encodedSig[x]); - if ( (x % 16) == 15) - printf("\n"); - } - - printf("\n"); - printf("actual digest:\n"); - - for (x = 0; x < verifySz; x++) { - printf("%02x ", out[x]); - if ( (x % 16) == 15) - printf("\n"); - } - - printf("\n"); - } - #endif /* CYASSL_DEBUG_ENCODING */ - - } - - } - - FreeRsaKey(pubKey); - -#ifdef CYASSL_SMALL_STACK - XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - break; - } - - #endif /* NO_RSA */ - #ifdef HAVE_ECC - case ECDSAk: - { - int verify = 0; -#ifdef CYASSL_SMALL_STACK - ecc_key* pubKey; -#else - ecc_key pubKey[1]; -#endif - -#ifdef CYASSL_SMALL_STACK - pubKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (pubKey == NULL) { - CYASSL_MSG("Failed to allocate pubKey"); - break; /* not confirmed */ - } -#endif - - if (ecc_import_x963(key, keySz, pubKey) < 0) { - CYASSL_MSG("ASN Key import error ECC"); - } - else { - if (ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, - pubKey) != 0) { - CYASSL_MSG("ECC verify hash error"); - } - else if (1 != verify) { - CYASSL_MSG("ECC Verify didn't match"); - } else - ret = 1; /* match */ - - ecc_free(pubKey); - } -#ifdef CYASSL_SMALL_STACK - XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - break; - } - #endif /* HAVE_ECC */ - default: - CYASSL_MSG("Verify Key type unknown"); - } - -#ifdef CYASSL_SMALL_STACK - XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - - -#ifndef IGNORE_NAME_CONSTRAINTS - -static int MatchBaseName(int type, const char* name, int nameSz, - const char* base, int baseSz) -{ - if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 || - name[0] == '.' || nameSz < baseSz || - (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE)) - return 0; - - /* If an email type, handle special cases where the base is only - * a domain, or is an email address itself. */ - if (type == ASN_RFC822_TYPE) { - const char* p = NULL; - int count = 0; - - if (base[0] != '.') { - p = base; - count = 0; - - /* find the '@' in the base */ - while (*p != '@' && count < baseSz) { - count++; - p++; - } - - /* No '@' in base, reset p to NULL */ - if (count >= baseSz) - p = NULL; - } - - if (p == NULL) { - /* Base isn't an email address, it is a domain name, - * wind the name forward one character past its '@'. */ - p = name; - count = 0; - while (*p != '@' && count < baseSz) { - count++; - p++; - } - - if (count < baseSz && *p == '@') { - name = p + 1; - nameSz -= count + 1; - } - } - } - - if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') { - int szAdjust = nameSz - baseSz; - name += szAdjust; - nameSz -= szAdjust; - } - - while (nameSz > 0) { - if (XTOLOWER(*name++) != XTOLOWER(*base++)) - return 0; - nameSz--; - } - - return 1; -} - - -static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert) -{ - if (signer == NULL || cert == NULL) - return 0; - - /* Check against the excluded list */ - if (signer->excludedNames) { - Base_entry* base = signer->excludedNames; - - while (base != NULL) { - if (base->type == ASN_DNS_TYPE) { - DNS_entry* name = cert->altNames; - while (name != NULL) { - if (MatchBaseName(ASN_DNS_TYPE, - name->name, (int)XSTRLEN(name->name), - base->name, base->nameSz)) - return 0; - name = name->next; - } - } - else if (base->type == ASN_RFC822_TYPE) { - DNS_entry* name = cert->altEmailNames; - while (name != NULL) { - if (MatchBaseName(ASN_RFC822_TYPE, - name->name, (int)XSTRLEN(name->name), - base->name, base->nameSz)) - return 0; - - name = name->next; - } - } - else if (base->type == ASN_DIR_TYPE) { - if (cert->subjectRawLen == base->nameSz && - XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { - - return 0; - } - } - base = base->next; - } - } - - /* Check against the permitted list */ - if (signer->permittedNames != NULL) { - int needDns = 0; - int matchDns = 0; - int needEmail = 0; - int matchEmail = 0; - int needDir = 0; - int matchDir = 0; - Base_entry* base = signer->permittedNames; - - while (base != NULL) { - if (base->type == ASN_DNS_TYPE) { - DNS_entry* name = cert->altNames; - - if (name != NULL) - needDns = 1; - - while (name != NULL) { - matchDns = MatchBaseName(ASN_DNS_TYPE, - name->name, (int)XSTRLEN(name->name), - base->name, base->nameSz); - name = name->next; - } - } - else if (base->type == ASN_RFC822_TYPE) { - DNS_entry* name = cert->altEmailNames; - - if (name != NULL) - needEmail = 1; - - while (name != NULL) { - matchEmail = MatchBaseName(ASN_DNS_TYPE, - name->name, (int)XSTRLEN(name->name), - base->name, base->nameSz); - name = name->next; - } - } - else if (base->type == ASN_DIR_TYPE) { - needDir = 1; - if (cert->subjectRaw != NULL && - cert->subjectRawLen == base->nameSz && - XMEMCMP(cert->subjectRaw, base->name, base->nameSz) == 0) { - - matchDir = 1; - } - } - base = base->next; - } - - if ((needDns && !matchDns) || (needEmail && !matchEmail) || - (needDir && !matchDir)) { - - return 0; - } - } - - return 1; -} - -#endif /* IGNORE_NAME_CONSTRAINTS */ - - -static int DecodeAltNames(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0; - int length = 0; - - CYASSL_ENTER("DecodeAltNames"); - - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tBad Sequence"); - return ASN_PARSE_E; - } - - while (length > 0) { - byte b = input[idx++]; - - length--; - - /* Save DNS Type names in the altNames list. */ - /* Save Other Type names in the cert's OidMap */ - if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) { - DNS_entry* dnsEntry; - int strLen; - word32 lenStartIdx = idx; - - if (GetLength(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tfail: str length"); - return ASN_PARSE_E; - } - length -= (idx - lenStartIdx); - - dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, - DYNAMIC_TYPE_ALTNAME); - if (dnsEntry == NULL) { - CYASSL_MSG("\tOut of Memory"); - return ASN_PARSE_E; - } - - dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap, - DYNAMIC_TYPE_ALTNAME); - if (dnsEntry->name == NULL) { - CYASSL_MSG("\tOut of Memory"); - XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); - return ASN_PARSE_E; - } - - XMEMCPY(dnsEntry->name, &input[idx], strLen); - dnsEntry->name[strLen] = '\0'; - - dnsEntry->next = cert->altNames; - cert->altNames = dnsEntry; - - length -= strLen; - idx += strLen; - } -#ifndef IGNORE_NAME_CONSTRAINTS - else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) { - DNS_entry* emailEntry; - int strLen; - word32 lenStartIdx = idx; - - if (GetLength(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tfail: str length"); - return ASN_PARSE_E; - } - length -= (idx - lenStartIdx); - - emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, - DYNAMIC_TYPE_ALTNAME); - if (emailEntry == NULL) { - CYASSL_MSG("\tOut of Memory"); - return ASN_PARSE_E; - } - - emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap, - DYNAMIC_TYPE_ALTNAME); - if (emailEntry->name == NULL) { - CYASSL_MSG("\tOut of Memory"); - XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); - return ASN_PARSE_E; - } - - XMEMCPY(emailEntry->name, &input[idx], strLen); - emailEntry->name[strLen] = '\0'; - - emailEntry->next = cert->altEmailNames; - cert->altEmailNames = emailEntry; - - length -= strLen; - idx += strLen; - } -#endif /* IGNORE_NAME_CONSTRAINTS */ -#ifdef CYASSL_SEP - else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) - { - int strLen; - word32 lenStartIdx = idx; - word32 oid = 0; - - if (GetLength(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tfail: other name length"); - return ASN_PARSE_E; - } - /* Consume the rest of this sequence. */ - length -= (strLen + idx - lenStartIdx); - - if (GetObjectId(input, &idx, &oid, sz) < 0) { - CYASSL_MSG("\tbad OID"); - return ASN_PARSE_E; - } - - if (oid != HW_NAME_OID) { - CYASSL_MSG("\tincorrect OID"); - return ASN_PARSE_E; - } - - if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) { - CYASSL_MSG("\twrong type"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tfail: str len"); - return ASN_PARSE_E; - } - - if (GetSequence(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tBad Sequence"); - return ASN_PARSE_E; - } - - if (input[idx++] != ASN_OBJECT_ID) { - CYASSL_MSG("\texpected OID"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tfailed: str len"); - return ASN_PARSE_E; - } - - cert->hwType = (byte*)XMALLOC(strLen, cert->heap, 0); - if (cert->hwType == NULL) { - CYASSL_MSG("\tOut of Memory"); - return MEMORY_E; - } - - XMEMCPY(cert->hwType, &input[idx], strLen); - cert->hwTypeSz = strLen; - idx += strLen; - - if (input[idx++] != ASN_OCTET_STRING) { - CYASSL_MSG("\texpected Octet String"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tfailed: str len"); - return ASN_PARSE_E; - } - - cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap, 0); - if (cert->hwSerialNum == NULL) { - CYASSL_MSG("\tOut of Memory"); - return MEMORY_E; - } - - XMEMCPY(cert->hwSerialNum, &input[idx], strLen); - cert->hwSerialNum[strLen] = '\0'; - cert->hwSerialNumSz = strLen; - idx += strLen; - } -#endif /* CYASSL_SEP */ - else { - int strLen; - word32 lenStartIdx = idx; - - CYASSL_MSG("\tUnsupported name type, skipping"); - - if (GetLength(input, &idx, &strLen, sz) < 0) { - CYASSL_MSG("\tfail: unsupported name length"); - return ASN_PARSE_E; - } - length -= (strLen + idx - lenStartIdx); - idx += strLen; - } - } - return 0; -} - - -static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0; - int length = 0; - - CYASSL_ENTER("DecodeBasicCaConstraint"); - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: bad SEQUENCE"); - return ASN_PARSE_E; - } - - if (length == 0) - return 0; - - /* If the basic ca constraint is false, this extension may be named, but - * left empty. So, if the length is 0, just return. */ - - if (input[idx++] != ASN_BOOLEAN) - { - CYASSL_MSG("\tfail: constraint not BOOLEAN"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &length, sz) < 0) - { - CYASSL_MSG("\tfail: length"); - return ASN_PARSE_E; - } - - if (input[idx++]) - cert->isCA = 1; - - #ifdef OPENSSL_EXTRA - /* If there isn't any more data, return. */ - if (idx >= (word32)sz) - return 0; - - /* Anything left should be the optional pathlength */ - if (input[idx++] != ASN_INTEGER) { - CYASSL_MSG("\tfail: pathlen not INTEGER"); - return ASN_PARSE_E; - } - - if (input[idx++] != 1) { - CYASSL_MSG("\tfail: pathlen too long"); - return ASN_PARSE_E; - } - - cert->pathLength = input[idx]; - cert->extBasicConstPlSet = 1; - #endif /* OPENSSL_EXTRA */ - - return 0; -} - - -#define CRLDP_FULL_NAME 0 - /* From RFC3280 SS4.2.1.14, Distribution Point Name*/ -#define GENERALNAME_URI 6 - /* From RFC3280 SS4.2.1.7, GeneralName */ - -static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0; - int length = 0; - - CYASSL_ENTER("DecodeCrlDist"); - - /* Unwrap the list of Distribution Points*/ - if (GetSequence(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - /* Unwrap a single Distribution Point */ - if (GetSequence(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - /* The Distribution Point has three explicit optional members - * First check for a DistributionPointName - */ - if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) - { - idx++; - if (GetLength(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - if (input[idx] == - (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME)) - { - idx++; - if (GetLength(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI)) - { - idx++; - if (GetLength(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - cert->extCrlInfoSz = length; - cert->extCrlInfo = input + idx; - idx += length; - } - else - /* This isn't a URI, skip it. */ - idx += length; - } - else - /* This isn't a FULLNAME, skip it. */ - idx += length; - } - - /* Check for reasonFlags */ - if (idx < (word32)sz && - input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) - { - idx++; - if (GetLength(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - idx += length; - } - - /* Check for cRLIssuer */ - if (idx < (word32)sz && - input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) - { - idx++; - if (GetLength(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - idx += length; - } - - if (idx < (word32)sz) - { - CYASSL_MSG("\tThere are more CRL Distribution Point records, " - "but we only use the first one."); - } - - return 0; -} - - -static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert) -/* - * Read the first of the Authority Information Access records. If there are - * any issues, return without saving the record. - */ -{ - word32 idx = 0; - int length = 0; - byte b; - word32 oid; - - CYASSL_ENTER("DecodeAuthInfo"); - - /* Unwrap the list of AIAs */ - if (GetSequence(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - while (idx < (word32)sz) { - /* Unwrap a single AIA */ - if (GetSequence(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - oid = 0; - if (GetObjectId(input, &idx, &oid, sz) < 0) - return ASN_PARSE_E; - - /* Only supporting URIs right now. */ - b = input[idx++]; - if (GetLength(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) && - oid == AIA_OCSP_OID) - { - cert->extAuthInfoSz = length; - cert->extAuthInfo = input + idx; - break; - } - idx += length; - } - - return 0; -} - - -static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0; - int length = 0, ret = 0; - - CYASSL_ENTER("DecodeAuthKeyId"); - - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: should be a SEQUENCE\n"); - return ASN_PARSE_E; - } - - if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { - CYASSL_MSG("\tinfo: OPTIONAL item 0, not available\n"); - return 0; - } - - if (GetLength(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: extension data length"); - return ASN_PARSE_E; - } - - #ifdef OPENSSL_EXTRA - cert->extAuthKeyIdSrc = &input[idx]; - cert->extAuthKeyIdSz = length; - #endif /* OPENSSL_EXTRA */ - - if (length == SHA_SIZE) { - XMEMCPY(cert->extAuthKeyId, input + idx, length); - } - else { - Sha sha; - ret = InitSha(&sha); - if (ret != 0) - return ret; - ShaUpdate(&sha, input + idx, length); - ShaFinal(&sha, cert->extAuthKeyId); - } - - return 0; -} - - -static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0; - int length = 0, ret = 0; - - CYASSL_ENTER("DecodeSubjKeyId"); - - if (input[idx++] != ASN_OCTET_STRING) { - CYASSL_MSG("\tfail: should be an OCTET STRING"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: extension data length"); - return ASN_PARSE_E; - } - - #ifdef OPENSSL_EXTRA - cert->extSubjKeyIdSrc = &input[idx]; - cert->extSubjKeyIdSz = length; - #endif /* OPENSSL_EXTRA */ - - if (length == SIGNER_DIGEST_SIZE) { - XMEMCPY(cert->extSubjKeyId, input + idx, length); - } - else { - Sha sha; - ret = InitSha(&sha); - if (ret != 0) - return ret; - ShaUpdate(&sha, input + idx, length); - ShaFinal(&sha, cert->extSubjKeyId); - } - - return ret; -} - - -static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0; - int length; - byte unusedBits; - CYASSL_ENTER("DecodeKeyUsage"); - - if (input[idx++] != ASN_BIT_STRING) { - CYASSL_MSG("\tfail: key usage expected bit string"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: key usage bad length"); - return ASN_PARSE_E; - } - - unusedBits = input[idx++]; - length--; - - if (length == 2) { - cert->extKeyUsage = (word16)((input[idx] << 8) | input[idx+1]); - cert->extKeyUsage >>= unusedBits; - } - else if (length == 1) - cert->extKeyUsage = (word16)(input[idx] << 1); - - return 0; -} - - -static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0, oid; - int length; - - CYASSL_ENTER("DecodeExtKeyUsage"); - - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: should be a SEQUENCE"); - return ASN_PARSE_E; - } - - #ifdef OPENSSL_EXTRA - cert->extExtKeyUsageSrc = input + idx; - cert->extExtKeyUsageSz = length; - #endif - - while (idx < (word32)sz) { - if (GetObjectId(input, &idx, &oid, sz) < 0) - return ASN_PARSE_E; - - switch (oid) { - case EKU_ANY_OID: - cert->extExtKeyUsage |= EXTKEYUSE_ANY; - break; - case EKU_SERVER_AUTH_OID: - cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH; - break; - case EKU_CLIENT_AUTH_OID: - cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH; - break; - case EKU_OCSP_SIGN_OID: - cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN; - break; - } - - #ifdef OPENSSL_EXTRA - cert->extExtKeyUsageCount++; - #endif - } - - return 0; -} - - -#ifndef IGNORE_NAME_CONSTRAINTS -static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap) -{ - word32 idx = 0; - - (void)heap; - - while (idx < (word32)sz) { - int seqLength, strLength; - word32 nameIdx; - byte b; - - if (GetSequence(input, &idx, &seqLength, sz) < 0) { - CYASSL_MSG("\tfail: should be a SEQUENCE"); - return ASN_PARSE_E; - } - - nameIdx = idx; - b = input[nameIdx++]; - if (GetLength(input, &nameIdx, &strLength, sz) <= 0) { - CYASSL_MSG("\tinvalid length"); - return ASN_PARSE_E; - } - - if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE) || - b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE) || - b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE)) { - - Base_entry* entry = (Base_entry*)XMALLOC(sizeof(Base_entry), - heap, DYNAMIC_TYPE_ALTNAME); - - if (entry == NULL) { - CYASSL_MSG("allocate error"); - return MEMORY_E; - } - - entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME); - if (entry->name == NULL) { - CYASSL_MSG("allocate error"); - return MEMORY_E; - } - - XMEMCPY(entry->name, &input[nameIdx], strLength); - entry->nameSz = strLength; - entry->type = b & 0x0F; - - entry->next = *head; - *head = entry; - } - - idx += seqLength; - } - - return 0; -} - - -static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert) -{ - word32 idx = 0; - int length = 0; - - CYASSL_ENTER("DecodeNameConstraints"); - - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: should be a SEQUENCE"); - return ASN_PARSE_E; - } - - while (idx < (word32)sz) { - byte b = input[idx++]; - Base_entry** subtree = NULL; - - if (GetLength(input, &idx, &length, sz) <= 0) { - CYASSL_MSG("\tinvalid length"); - return ASN_PARSE_E; - } - - if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) - subtree = &cert->permittedNames; - else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) - subtree = &cert->excludedNames; - else { - CYASSL_MSG("\tinvalid subtree"); - return ASN_PARSE_E; - } - - DecodeSubtree(input + idx, length, subtree, cert->heap); - - idx += length; - } - - return 0; -} -#endif /* IGNORE_NAME_CONSTRAINTS */ - - -#ifdef CYASSL_SEP - static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert) - { - word32 idx = 0; - int length = 0; - - CYASSL_ENTER("DecodeCertPolicy"); - - /* Unwrap certificatePolicies */ - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tdeviceType isn't OID"); - return ASN_PARSE_E; - } - - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tdeviceType isn't OID"); - return ASN_PARSE_E; - } - - if (input[idx++] != ASN_OBJECT_ID) { - CYASSL_MSG("\tdeviceType isn't OID"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tCouldn't read length of deviceType"); - return ASN_PARSE_E; - } - - if (length > 0) { - cert->deviceType = (byte*)XMALLOC(length, cert->heap, 0); - if (cert->deviceType == NULL) { - CYASSL_MSG("\tCouldn't alloc memory for deviceType"); - return MEMORY_E; - } - cert->deviceTypeSz = length; - XMEMCPY(cert->deviceType, input + idx, length); - } - - CYASSL_LEAVE("DecodeCertPolicy", 0); - return 0; - } -#endif /* CYASSL_SEP */ - - -static int DecodeCertExtensions(DecodedCert* cert) -/* - * Processing the Certificate Extensions. This does not modify the current - * index. It is works starting with the recorded extensions pointer. - */ -{ - word32 idx = 0; - int sz = cert->extensionsSz; - byte* input = cert->extensions; - int length; - word32 oid; - byte critical = 0; - byte criticalFail = 0; - - CYASSL_ENTER("DecodeCertExtensions"); - - if (input == NULL || sz == 0) - return BAD_FUNC_ARG; - - if (input[idx++] != ASN_EXTENSIONS) - return ASN_PARSE_E; - - if (GetLength(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - if (GetSequence(input, &idx, &length, sz) < 0) - return ASN_PARSE_E; - - while (idx < (word32)sz) { - if (GetSequence(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: should be a SEQUENCE"); - return ASN_PARSE_E; - } - - oid = 0; - if (GetObjectId(input, &idx, &oid, sz) < 0) { - CYASSL_MSG("\tfail: OBJECT ID"); - return ASN_PARSE_E; - } - - /* check for critical flag */ - critical = 0; - if (input[idx] == ASN_BOOLEAN) { - int boolLength = 0; - idx++; - if (GetLength(input, &idx, &boolLength, sz) < 0) { - CYASSL_MSG("\tfail: critical boolean length"); - return ASN_PARSE_E; - } - if (input[idx++]) - critical = 1; - } - - /* process the extension based on the OID */ - if (input[idx++] != ASN_OCTET_STRING) { - CYASSL_MSG("\tfail: should be an OCTET STRING"); - return ASN_PARSE_E; - } - - if (GetLength(input, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: extension data length"); - return ASN_PARSE_E; - } - - switch (oid) { - case BASIC_CA_OID: - #ifdef OPENSSL_EXTRA - cert->extBasicConstSet = 1; - cert->extBasicConstCrit = critical; - #endif - if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - case CRL_DIST_OID: - if (DecodeCrlDist(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - case AUTH_INFO_OID: - if (DecodeAuthInfo(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - case ALT_NAMES_OID: - #ifdef OPENSSL_EXTRA - cert->extSubjAltNameSet = 1; - cert->extSubjAltNameCrit = critical; - #endif - if (DecodeAltNames(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - case AUTH_KEY_OID: - cert->extAuthKeyIdSet = 1; - #ifdef OPENSSL_EXTRA - cert->extAuthKeyIdCrit = critical; - #endif - if (DecodeAuthKeyId(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - case SUBJ_KEY_OID: - cert->extSubjKeyIdSet = 1; - #ifdef OPENSSL_EXTRA - cert->extSubjKeyIdCrit = critical; - #endif - if (DecodeSubjKeyId(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - case CERT_POLICY_OID: - CYASSL_MSG("Certificate Policy extension not supported yet."); - #ifdef CYASSL_SEP - #ifdef OPENSSL_EXTRA - cert->extCertPolicySet = 1; - cert->extCertPolicyCrit = critical; - #endif - if (DecodeCertPolicy(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - #endif - break; - - case KEY_USAGE_OID: - cert->extKeyUsageSet = 1; - #ifdef OPENSSL_EXTRA - cert->extKeyUsageCrit = critical; - #endif - if (DecodeKeyUsage(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - case EXT_KEY_USAGE_OID: - cert->extExtKeyUsageSet = 1; - #ifdef OPENSSL_EXTRA - cert->extExtKeyUsageCrit = critical; - #endif - if (DecodeExtKeyUsage(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - - #ifndef IGNORE_NAME_CONSTRAINTS - case NAME_CONS_OID: - cert->extNameConstraintSet = 1; - #ifdef OPENSSL_EXTRA - cert->extNameConstraintCrit = critical; - #endif - if (DecodeNameConstraints(&input[idx], length, cert) < 0) - return ASN_PARSE_E; - break; - #endif /* IGNORE_NAME_CONSTRAINTS */ - - case INHIBIT_ANY_OID: - CYASSL_MSG("Inhibit anyPolicy extension not supported yet."); - break; - - default: - /* While it is a failure to not support critical extensions, - * still parse the certificate ignoring the unsupported - * extention to allow caller to accept it with the verify - * callback. */ - if (critical) - criticalFail = 1; - break; - } - idx += length; - } - - return criticalFail ? ASN_CRIT_EXT_E : 0; -} - - -int ParseCert(DecodedCert* cert, int type, int verify, void* cm) -{ - int ret; - char* ptr; - - ret = ParseCertRelative(cert, type, verify, cm); - if (ret < 0) - return ret; - - if (cert->subjectCNLen > 0) { - ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap, - DYNAMIC_TYPE_SUBJECT_CN); - if (ptr == NULL) - return MEMORY_E; - XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen); - ptr[cert->subjectCNLen] = '\0'; - cert->subjectCN = ptr; - cert->subjectCNStored = 1; - } - - if (cert->keyOID == RSAk && - cert->publicKey != NULL && cert->pubKeySize > 0) { - ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (ptr == NULL) - return MEMORY_E; - XMEMCPY(ptr, cert->publicKey, cert->pubKeySize); - cert->publicKey = (byte *)ptr; - cert->pubKeyStored = 1; - } - - return ret; -} - - -/* from SSL proper, for locking can't do find here anymore */ -#ifdef __cplusplus - extern "C" { -#endif - CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash); - #ifndef NO_SKID - CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash); - #endif -#ifdef __cplusplus - } -#endif - - -int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) -{ - word32 confirmOID; - int ret; - int badDate = 0; - int criticalExt = 0; - - if ((ret = DecodeToKey(cert, verify)) < 0) { - if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E) - badDate = ret; - else - return ret; - } - - CYASSL_MSG("Parsed Past Key"); - - if (cert->srcIdx < cert->sigIndex) { - #ifndef ALLOW_V1_EXTENSIONS - if (cert->version < 2) { - CYASSL_MSG(" v1 and v2 certs not allowed extensions"); - return ASN_VERSION_E; - } - #endif - /* save extensions */ - cert->extensions = &cert->source[cert->srcIdx]; - cert->extensionsSz = cert->sigIndex - cert->srcIdx; - cert->extensionsIdx = cert->srcIdx; /* for potential later use */ - - if ((ret = DecodeCertExtensions(cert)) < 0) { - if (ret == ASN_CRIT_EXT_E) - criticalExt = ret; - else - return ret; - } - - /* advance past extensions */ - cert->srcIdx = cert->sigIndex; - } - - if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID, - cert->maxIdx)) < 0) - return ret; - - if ((ret = GetSignature(cert)) < 0) - return ret; - - if (confirmOID != cert->signatureOID) - return ASN_SIG_OID_E; - - #ifndef NO_SKID - if (cert->extSubjKeyIdSet == 0 - && cert->publicKey != NULL && cert->pubKeySize > 0) { - Sha sha; - ret = InitSha(&sha); - if (ret != 0) - return ret; - ShaUpdate(&sha, cert->publicKey, cert->pubKeySize); - ShaFinal(&sha, cert->extSubjKeyId); - } - #endif - - if (verify && type != CA_TYPE) { - Signer* ca = NULL; - #ifndef NO_SKID - if (cert->extAuthKeyIdSet) - ca = GetCA(cm, cert->extAuthKeyId); - if (ca == NULL) - ca = GetCAByName(cm, cert->issuerHash); - #else /* NO_SKID */ - ca = GetCA(cm, cert->issuerHash); - #endif /* NO SKID */ - CYASSL_MSG("About to verify certificate signature"); - - if (ca) { -#ifdef HAVE_OCSP - /* Need the ca's public key hash for OCSP */ - { - Sha sha; - ret = InitSha(&sha); - if (ret != 0) - return ret; - ShaUpdate(&sha, ca->publicKey, ca->pubKeySize); - ShaFinal(&sha, cert->issuerKeyHash); - } -#endif /* HAVE_OCSP */ - /* try to confirm/verify signature */ - if (!ConfirmSignature(cert->source + cert->certBegin, - cert->sigIndex - cert->certBegin, - ca->publicKey, ca->pubKeySize, ca->keyOID, - cert->signature, cert->sigLength, cert->signatureOID, - cert->heap)) { - CYASSL_MSG("Confirm signature failed"); - return ASN_SIG_CONFIRM_E; - } -#ifndef IGNORE_NAME_CONSTRAINTS - /* check that this cert's name is permitted by the signer's - * name constraints */ - if (!ConfirmNameConstraints(ca, cert)) { - CYASSL_MSG("Confirm name constraint failed"); - return ASN_NAME_INVALID_E; - } -#endif /* IGNORE_NAME_CONSTRAINTS */ - } - else { - /* no signer */ - CYASSL_MSG("No CA signer to verify with"); - return ASN_NO_SIGNER_E; - } - } - - if (badDate != 0) - return badDate; - - if (criticalExt != 0) - return criticalExt; - - return 0; -} - - -/* Create and init an new signer */ -Signer* MakeSigner(void* heap) -{ - Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap, - DYNAMIC_TYPE_SIGNER); - if (signer) { - signer->pubKeySize = 0; - signer->keyOID = 0; - signer->publicKey = NULL; - signer->nameLen = 0; - signer->name = NULL; - #ifndef IGNORE_NAME_CONSTRAINTS - signer->permittedNames = NULL; - signer->excludedNames = NULL; - #endif /* IGNORE_NAME_CONSTRAINTS */ - signer->next = NULL; - } - (void)heap; - - return signer; -} - - -/* Free an individual signer */ -void FreeSigner(Signer* signer, void* heap) -{ - XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN); - XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); - #ifndef IGNORE_NAME_CONSTRAINTS - if (signer->permittedNames) - FreeNameSubtrees(signer->permittedNames, heap); - if (signer->excludedNames) - FreeNameSubtrees(signer->excludedNames, heap); - #endif - XFREE(signer, heap, DYNAMIC_TYPE_SIGNER); - - (void)heap; -} - - -/* Free the whole singer table with number of rows */ -void FreeSignerTable(Signer** table, int rows, void* heap) -{ - int i; - - for (i = 0; i < rows; i++) { - Signer* signer = table[i]; - while (signer) { - Signer* next = signer->next; - FreeSigner(signer, heap); - signer = next; - } - table[i] = NULL; - } -} - - -CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header) -{ - int i = 0; - - if (header) { - output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED; - output[i++] = ASN_BIT_STRING; - } - output[i++] = ASN_INTEGER; - output[i++] = 0x01; - output[i++] = (byte)version; - - return i; -} - - -CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output) -{ - int result = 0; - - CYASSL_ENTER("SetSerialNumber"); - - if (snSz <= EXTERNAL_SERIAL_SIZE) { - output[0] = ASN_INTEGER; - /* The serial number is always positive. When encoding the - * INTEGER, if the MSB is 1, add a padding zero to keep the - * number positive. */ - if (sn[0] & 0x80) { - output[1] = (byte)snSz + 1; - output[2] = 0; - XMEMCPY(&output[3], sn, snSz); - result = snSz + 3; - } - else { - output[1] = (byte)snSz; - XMEMCPY(&output[2], sn, snSz); - result = snSz + 2; - } - } - return result; -} - - - - -#if defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) - -/* convert der buffer to pem into output, can't do inplace, der and output - need to be different */ -int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, - int type) -{ -#ifdef CYASSL_SMALL_STACK - char* header = NULL; - char* footer = NULL; -#else - char header[80]; - char footer[80]; -#endif - - int headerLen = 80; - int footerLen = 80; - int i; - int err; - int outLen; /* return length or error */ - - if (der == output) /* no in place conversion */ - return BAD_FUNC_ARG; - -#ifdef CYASSL_SMALL_STACK - header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (header == NULL) - return MEMORY_E; - - footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (footer == NULL) { - XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - if (type == CERT_TYPE) { - XSTRNCPY(header, "-----BEGIN CERTIFICATE-----\n", headerLen); - XSTRNCPY(footer, "-----END CERTIFICATE-----\n", footerLen); - } - else if (type == PRIVATEKEY_TYPE) { - XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----\n", headerLen); - XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----\n", footerLen); - } - #ifdef HAVE_ECC - else if (type == ECC_PRIVATEKEY_TYPE) { - XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----\n", headerLen); - XSTRNCPY(footer, "-----END EC PRIVATE KEY-----\n", footerLen); - } - #endif - #ifdef CYASSL_CERT_REQ - else if (type == CERTREQ_TYPE) - { - XSTRNCPY(header, - "-----BEGIN CERTIFICATE REQUEST-----\n", headerLen); - XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----\n", footerLen); - } - #endif - else { -#ifdef CYASSL_SMALL_STACK - XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BAD_FUNC_ARG; - } - - headerLen = (int)XSTRLEN(header); - footerLen = (int)XSTRLEN(footer); - - if (!der || !output) { -#ifdef CYASSL_SMALL_STACK - XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BAD_FUNC_ARG; - } - - /* don't even try if outSz too short */ - if (outSz < headerLen + footerLen + derSz) { -#ifdef CYASSL_SMALL_STACK - XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BAD_FUNC_ARG; - } - - /* header */ - XMEMCPY(output, header, headerLen); - i = headerLen; - -#ifdef CYASSL_SMALL_STACK - XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - /* body */ - outLen = outSz - (headerLen + footerLen); /* input to Base64_Encode */ - if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return err; - } - i += outLen; - - /* footer */ - if ( (i + footerLen) > (int)outSz) { -#ifdef CYASSL_SMALL_STACK - XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BAD_FUNC_ARG; - } - XMEMCPY(output + i, footer, footerLen); - -#ifdef CYASSL_SMALL_STACK - XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return outLen + headerLen + footerLen; -} - - -#endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */ - - -#if defined(CYASSL_KEY_GEN) && !defined(NO_RSA) - - -static mp_int* GetRsaInt(RsaKey* key, int idx) -{ - if (idx == 0) - return &key->n; - if (idx == 1) - return &key->e; - if (idx == 2) - return &key->d; - if (idx == 3) - return &key->p; - if (idx == 4) - return &key->q; - if (idx == 5) - return &key->dP; - if (idx == 6) - return &key->dQ; - if (idx == 7) - return &key->u; - - return NULL; -} - - -/* Release Tmp RSA resources */ -static INLINE void FreeTmpRsas(byte** tmps, void* heap) -{ - int i; - - (void)heap; - - for (i = 0; i < RSA_INTS; i++) - XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA); -} - - -/* Convert RsaKey key to DER format, write to output (inLen), return bytes - written */ -int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) -{ - word32 seqSz, verSz, rawLen, intTotalLen = 0; - word32 sizes[RSA_INTS]; - int i, j, outLen, ret = 0; - - byte seq[MAX_SEQ_SZ]; - byte ver[MAX_VERSION_SZ]; - byte* tmps[RSA_INTS]; - - if (!key || !output) - return BAD_FUNC_ARG; - - if (key->type != RSA_PRIVATE) - return BAD_FUNC_ARG; - - for (i = 0; i < RSA_INTS; i++) - tmps[i] = NULL; - - /* write all big ints from key to DER tmps */ - for (i = 0; i < RSA_INTS; i++) { - mp_int* keyInt = GetRsaInt(key, i); - rawLen = mp_unsigned_bin_size(keyInt); - tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap, - DYNAMIC_TYPE_RSA); - if (tmps[i] == NULL) { - ret = MEMORY_E; - break; - } - - tmps[i][0] = ASN_INTEGER; - sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1; /* int tag */ - - if (sizes[i] <= MAX_SEQ_SZ) { - int err = mp_to_unsigned_bin(keyInt, tmps[i] + sizes[i]); - if (err == MP_OKAY) { - sizes[i] += rawLen; - intTotalLen += sizes[i]; - } - else { - ret = err; - break; - } - } - else { - ret = ASN_INPUT_E; - break; - } - } - - if (ret != 0) { - FreeTmpRsas(tmps, key->heap); - return ret; - } - - /* make headers */ - verSz = SetMyVersion(0, ver, FALSE); - seqSz = SetSequence(verSz + intTotalLen, seq); - - outLen = seqSz + verSz + intTotalLen; - if (outLen > (int)inLen) - return BAD_FUNC_ARG; - - /* write to output */ - XMEMCPY(output, seq, seqSz); - j = seqSz; - XMEMCPY(output + j, ver, verSz); - j += verSz; - - for (i = 0; i < RSA_INTS; i++) { - XMEMCPY(output + j, tmps[i], sizes[i]); - j += sizes[i]; - } - FreeTmpRsas(tmps, key->heap); - - return outLen; -} - -#endif /* CYASSL_KEY_GEN && !NO_RSA */ - - -#if defined(CYASSL_CERT_GEN) && !defined(NO_RSA) - - -#ifndef min - - static INLINE word32 min(word32 a, word32 b) - { - return a > b ? b : a; - } - -#endif /* min */ - - -/* Initialize and Set Certficate defaults: - version = 3 (0x2) - serial = 0 - sigType = SHA_WITH_RSA - issuer = blank - daysValid = 500 - selfSigned = 1 (true) use subject as issuer - subject = blank -*/ -void InitCert(Cert* cert) -{ - cert->version = 2; /* version 3 is hex 2 */ - cert->sigType = CTC_SHAwRSA; - cert->daysValid = 500; - cert->selfSigned = 1; - cert->isCA = 0; - cert->bodySz = 0; -#ifdef CYASSL_ALT_NAMES - cert->altNamesSz = 0; - cert->beforeDateSz = 0; - cert->afterDateSz = 0; -#endif - cert->keyType = RSA_KEY; - XMEMSET(cert->serial, 0, CTC_SERIAL_SIZE); - - cert->issuer.country[0] = '\0'; - cert->issuer.countryEnc = CTC_PRINTABLE; - cert->issuer.state[0] = '\0'; - cert->issuer.stateEnc = CTC_UTF8; - cert->issuer.locality[0] = '\0'; - cert->issuer.localityEnc = CTC_UTF8; - cert->issuer.sur[0] = '\0'; - cert->issuer.surEnc = CTC_UTF8; - cert->issuer.org[0] = '\0'; - cert->issuer.orgEnc = CTC_UTF8; - cert->issuer.unit[0] = '\0'; - cert->issuer.unitEnc = CTC_UTF8; - cert->issuer.commonName[0] = '\0'; - cert->issuer.commonNameEnc = CTC_UTF8; - cert->issuer.email[0] = '\0'; - - cert->subject.country[0] = '\0'; - cert->subject.countryEnc = CTC_PRINTABLE; - cert->subject.state[0] = '\0'; - cert->subject.stateEnc = CTC_UTF8; - cert->subject.locality[0] = '\0'; - cert->subject.localityEnc = CTC_UTF8; - cert->subject.sur[0] = '\0'; - cert->subject.surEnc = CTC_UTF8; - cert->subject.org[0] = '\0'; - cert->subject.orgEnc = CTC_UTF8; - cert->subject.unit[0] = '\0'; - cert->subject.unitEnc = CTC_UTF8; - cert->subject.commonName[0] = '\0'; - cert->subject.commonNameEnc = CTC_UTF8; - cert->subject.email[0] = '\0'; - -#ifdef CYASSL_CERT_REQ - cert->challengePw[0] ='\0'; -#endif -} - - -/* DER encoded x509 Certificate */ -typedef struct DerCert { - byte size[MAX_LENGTH_SZ]; /* length encoded */ - byte version[MAX_VERSION_SZ]; /* version encoded */ - byte serial[CTC_SERIAL_SIZE + MAX_LENGTH_SZ]; /* serial number encoded */ - byte sigAlgo[MAX_ALGO_SZ]; /* signature algo encoded */ - byte issuer[ASN_NAME_MAX]; /* issuer encoded */ - byte subject[ASN_NAME_MAX]; /* subject encoded */ - byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2]; /* before and after dates */ - byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */ - byte ca[MAX_CA_SZ]; /* basic constraint CA true size */ - byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */ -#ifdef CYASSL_CERT_REQ - byte attrib[MAX_ATTRIB_SZ]; /* Cert req attributes encoded */ -#endif - int sizeSz; /* encoded size length */ - int versionSz; /* encoded version length */ - int serialSz; /* encoded serial length */ - int sigAlgoSz; /* enocded sig alog length */ - int issuerSz; /* encoded issuer length */ - int subjectSz; /* encoded subject length */ - int validitySz; /* encoded validity length */ - int publicKeySz; /* encoded public key length */ - int caSz; /* encoded CA extension length */ - int extensionsSz; /* encoded extensions total length */ - int total; /* total encoded lengths */ -#ifdef CYASSL_CERT_REQ - int attribSz; -#endif -} DerCert; - - -#ifdef CYASSL_CERT_REQ - -/* Write a set header to output */ -static word32 SetUTF8String(word32 len, byte* output) -{ - output[0] = ASN_UTF8STRING; - return SetLength(len, output + 1) + 1; -} - -#endif /* CYASSL_CERT_REQ */ - - -/* Write a serial number to output */ -static int SetSerial(const byte* serial, byte* output) -{ - int length = 0; - - output[length++] = ASN_INTEGER; - length += SetLength(CTC_SERIAL_SIZE, &output[length]); - XMEMCPY(&output[length], serial, CTC_SERIAL_SIZE); - - return length + CTC_SERIAL_SIZE; -} - - -#ifdef HAVE_ECC - - -/* Write a public ECC key to output */ -static int SetEccPublicKey(byte* output, ecc_key* key) -{ - byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ - int algoSz; - int curveSz; - int lenSz; - int idx; - word32 pubSz = ECC_BUFSIZE; -#ifdef CYASSL_SMALL_STACK - byte* algo = NULL; - byte* curve = NULL; - byte* pub = NULL; -#else - byte algo[MAX_ALGO_SZ]; - byte curve[MAX_ALGO_SZ]; - byte pub[ECC_BUFSIZE]; -#endif - -#ifdef CYASSL_SMALL_STACK - pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (pub == NULL) - return MEMORY_E; -#endif - - int ret = ecc_export_x963(key, pub, &pubSz); - if (ret != 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return ret; - } - -#ifdef CYASSL_SMALL_STACK - curve = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (curve == NULL) { - XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - /* headers */ - curveSz = SetCurve(key, curve); - if (curveSz <= 0) { -#ifdef CYASSL_SMALL_STACK - XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return curveSz; - } - -#ifdef CYASSL_SMALL_STACK - algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (algo == NULL) { - XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - algoSz = SetAlgoID(ECDSAk, algo, keyType, curveSz); - lenSz = SetLength(pubSz + 1, len); - len[lenSz++] = 0; /* trailing 0 */ - - /* write */ - idx = SetSequence(pubSz + curveSz + lenSz + 1 + algoSz, output); - /* 1 is for ASN_BIT_STRING */ - /* algo */ - XMEMCPY(output + idx, algo, algoSz); - idx += algoSz; - /* curve */ - XMEMCPY(output + idx, curve, curveSz); - idx += curveSz; - /* bit string */ - output[idx++] = ASN_BIT_STRING; - /* length */ - XMEMCPY(output + idx, len, lenSz); - idx += lenSz; - /* pub */ - XMEMCPY(output + idx, pub, pubSz); - idx += pubSz; - -#ifdef CYASSL_SMALL_STACK - XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(curve, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return idx; -} - - -#endif /* HAVE_ECC */ - - -/* Write a public RSA key to output */ -static int SetRsaPublicKey(byte* output, RsaKey* key) -{ -#ifdef CYASSL_SMALL_STACK - byte* n = NULL; - byte* e = NULL; - byte* algo = NULL; -#else - byte n[MAX_RSA_INT_SZ]; - byte e[MAX_RSA_E_SZ]; - byte algo[MAX_ALGO_SZ]; -#endif - byte seq[MAX_SEQ_SZ]; - byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */ - int nSz; - int eSz; - int algoSz; - int seqSz; - int lenSz; - int idx; - int rawLen; - int leadingBit; - int err; - - /* n */ -#ifdef CYASSL_SMALL_STACK - n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (n == NULL) - return MEMORY_E; -#endif - - leadingBit = mp_leading_bit(&key->n); - rawLen = mp_unsigned_bin_size(&key->n) + leadingBit; - n[0] = ASN_INTEGER; - nSz = SetLength(rawLen, n + 1) + 1; /* int tag */ - - if ( (nSz + rawLen) < MAX_RSA_INT_SZ) { - if (leadingBit) - n[nSz] = 0; - err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit); - if (err == MP_OKAY) - nSz += rawLen; - else { -#ifdef CYASSL_SMALL_STACK - XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return MP_TO_E; - } - } - else { -#ifdef CYASSL_SMALL_STACK - XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BUFFER_E; - } - - /* e */ -#ifdef CYASSL_SMALL_STACK - e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (e == NULL) { -#ifdef CYASSL_SMALL_STACK - XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return MEMORY_E; - } -#endif - - leadingBit = mp_leading_bit(&key->e); - rawLen = mp_unsigned_bin_size(&key->e) + leadingBit; - e[0] = ASN_INTEGER; - eSz = SetLength(rawLen, e + 1) + 1; /* int tag */ - - if ( (eSz + rawLen) < MAX_RSA_E_SZ) { - if (leadingBit) - e[eSz] = 0; - err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit); - if (err == MP_OKAY) - eSz += rawLen; - else { -#ifdef CYASSL_SMALL_STACK - XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return MP_TO_E; - } - } - else { -#ifdef CYASSL_SMALL_STACK - XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BUFFER_E; - } - -#ifdef CYASSL_SMALL_STACK - algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (algo == NULL) { - XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - /* headers */ - algoSz = SetAlgoID(RSAk, algo, keyType, 0); - seqSz = SetSequence(nSz + eSz, seq); - lenSz = SetLength(seqSz + nSz + eSz + 1, len); - len[lenSz++] = 0; /* trailing 0 */ - - /* write */ - idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output); - /* 1 is for ASN_BIT_STRING */ - /* algo */ - XMEMCPY(output + idx, algo, algoSz); - idx += algoSz; - /* bit string */ - output[idx++] = ASN_BIT_STRING; - /* length */ - XMEMCPY(output + idx, len, lenSz); - idx += lenSz; - /* seq */ - XMEMCPY(output + idx, seq, seqSz); - idx += seqSz; - /* n */ - XMEMCPY(output + idx, n, nSz); - idx += nSz; - /* e */ - XMEMCPY(output + idx, e, eSz); - idx += eSz; - -#ifdef CYASSL_SMALL_STACK - XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return idx; -} - - -static INLINE byte itob(int number) -{ - return (byte)number + 0x30; -} - - -/* write time to output, format */ -static void SetTime(struct tm* date, byte* output) -{ - int i = 0; - - output[i++] = itob((date->tm_year % 10000) / 1000); - output[i++] = itob((date->tm_year % 1000) / 100); - output[i++] = itob((date->tm_year % 100) / 10); - output[i++] = itob( date->tm_year % 10); - - output[i++] = itob(date->tm_mon / 10); - output[i++] = itob(date->tm_mon % 10); - - output[i++] = itob(date->tm_mday / 10); - output[i++] = itob(date->tm_mday % 10); - - output[i++] = itob(date->tm_hour / 10); - output[i++] = itob(date->tm_hour % 10); - - output[i++] = itob(date->tm_min / 10); - output[i++] = itob(date->tm_min % 10); - - output[i++] = itob(date->tm_sec / 10); - output[i++] = itob(date->tm_sec % 10); - - output[i] = 'Z'; /* Zulu profile */ -} - - -#ifdef CYASSL_ALT_NAMES - -/* Copy Dates from cert, return bytes written */ -static int CopyValidity(byte* output, Cert* cert) -{ - int seqSz; - - CYASSL_ENTER("CopyValidity"); - - /* headers and output */ - seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output); - XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz); - XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate, - cert->afterDateSz); - return seqSz + cert->beforeDateSz + cert->afterDateSz; -} - -#endif - - -/* Set Date validity from now until now + daysValid */ -static int SetValidity(byte* output, int daysValid) -{ - byte before[MAX_DATE_SIZE]; - byte after[MAX_DATE_SIZE]; - - int beforeSz; - int afterSz; - int seqSz; - - time_t ticks; - struct tm* now; - struct tm local; - - ticks = XTIME(0); - now = XGMTIME(&ticks); - - /* before now */ - local = *now; - before[0] = ASN_GENERALIZED_TIME; - beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */ - - /* subtract 1 day for more compliance */ - local.tm_mday -= 1; - mktime(&local); - - /* adjust */ - local.tm_year += 1900; - local.tm_mon += 1; - - SetTime(&local, before + beforeSz); - beforeSz += ASN_GEN_TIME_SZ; - - /* after now + daysValid */ - local = *now; - after[0] = ASN_GENERALIZED_TIME; - afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */ - - /* add daysValid */ - local.tm_mday += daysValid; - mktime(&local); - - /* adjust */ - local.tm_year += 1900; - local.tm_mon += 1; - - SetTime(&local, after + afterSz); - afterSz += ASN_GEN_TIME_SZ; - - /* headers and output */ - seqSz = SetSequence(beforeSz + afterSz, output); - XMEMCPY(output + seqSz, before, beforeSz); - XMEMCPY(output + seqSz + beforeSz, after, afterSz); - - return seqSz + beforeSz + afterSz; -} - - -/* ASN Encoded Name field */ -typedef struct EncodedName { - int nameLen; /* actual string value length */ - int totalLen; /* total encoded length */ - int type; /* type of name */ - int used; /* are we actually using this one */ - byte encoded[CTC_NAME_SIZE * 2]; /* encoding */ -} EncodedName; - - -/* Get Which Name from index */ -static const char* GetOneName(CertName* name, int idx) -{ - switch (idx) { - case 0: - return name->country; - - case 1: - return name->state; - - case 2: - return name->locality; - - case 3: - return name->sur; - - case 4: - return name->org; - - case 5: - return name->unit; - - case 6: - return name->commonName; - - case 7: - return name->email; - - default: - return 0; - } -} - - -/* Get Which Name Encoding from index */ -static char GetNameType(CertName* name, int idx) -{ - switch (idx) { - case 0: - return name->countryEnc; - - case 1: - return name->stateEnc; - - case 2: - return name->localityEnc; - - case 3: - return name->surEnc; - - case 4: - return name->orgEnc; - - case 5: - return name->unitEnc; - - case 6: - return name->commonNameEnc; - - default: - return 0; - } -} - - -/* Get ASN Name from index */ -static byte GetNameId(int idx) -{ - switch (idx) { - case 0: - return ASN_COUNTRY_NAME; - - case 1: - return ASN_STATE_NAME; - - case 2: - return ASN_LOCALITY_NAME; - - case 3: - return ASN_SUR_NAME; - - case 4: - return ASN_ORG_NAME; - - case 5: - return ASN_ORGUNIT_NAME; - - case 6: - return ASN_COMMON_NAME; - - case 7: - /* email uses different id type */ - return 0; - - default: - return 0; - } -} - - -/* encode all extensions, return total bytes written */ -static int SetExtensions(byte* output, const byte* ext, int extSz, int header) -{ - byte sequence[MAX_SEQ_SZ]; - byte len[MAX_LENGTH_SZ]; - - int sz = 0; - int seqSz = SetSequence(extSz, sequence); - - if (header) { - int lenSz = SetLength(seqSz + extSz, len); - output[0] = ASN_EXTENSIONS; /* extensions id */ - sz++; - XMEMCPY(&output[sz], len, lenSz); /* length */ - sz += lenSz; - } - XMEMCPY(&output[sz], sequence, seqSz); /* sequence */ - sz += seqSz; - XMEMCPY(&output[sz], ext, extSz); /* extensions */ - sz += extSz; - - return sz; -} - - -/* encode CA basic constraint true, return total bytes written */ -static int SetCa(byte* output) -{ - static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, - 0x05, 0x30, 0x03, 0x01, 0x01, 0xff }; - - XMEMCPY(output, ca, sizeof(ca)); - - return (int)sizeof(ca); -} - - -/* encode CertName into output, return total bytes written */ -static int SetName(byte* output, CertName* name) -{ - int totalBytes = 0, i, idx; -#ifdef CYASSL_SMALL_STACK - EncodedName* names = NULL; -#else - EncodedName names[NAME_ENTRIES]; -#endif - -#ifdef CYASSL_SMALL_STACK - names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (names == NULL) - return MEMORY_E; -#endif - - for (i = 0; i < NAME_ENTRIES; i++) { - const char* nameStr = GetOneName(name, i); - if (nameStr) { - /* bottom up */ - byte firstLen[MAX_LENGTH_SZ]; - byte secondLen[MAX_LENGTH_SZ]; - byte sequence[MAX_SEQ_SZ]; - byte set[MAX_SET_SZ]; - - int email = i == (NAME_ENTRIES - 1) ? 1 : 0; - int strLen = (int)XSTRLEN(nameStr); - int thisLen = strLen; - int firstSz, secondSz, seqSz, setSz; - - if (strLen == 0) { /* no user data for this item */ - names[i].used = 0; - continue; - } - - secondSz = SetLength(strLen, secondLen); - thisLen += secondSz; - if (email) { - thisLen += EMAIL_JOINT_LEN; - thisLen ++; /* id type */ - firstSz = SetLength(EMAIL_JOINT_LEN, firstLen); - } - else { - thisLen++; /* str type */ - thisLen++; /* id type */ - thisLen += JOINT_LEN; - firstSz = SetLength(JOINT_LEN + 1, firstLen); - } - thisLen += firstSz; - thisLen++; /* object id */ - - seqSz = SetSequence(thisLen, sequence); - thisLen += seqSz; - setSz = SetSet(thisLen, set); - thisLen += setSz; - - if (thisLen > (int)sizeof(names[i].encoded)) { -#ifdef CYASSL_SMALL_STACK - XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BUFFER_E; - } - - /* store it */ - idx = 0; - /* set */ - XMEMCPY(names[i].encoded, set, setSz); - idx += setSz; - /* seq */ - XMEMCPY(names[i].encoded + idx, sequence, seqSz); - idx += seqSz; - /* asn object id */ - names[i].encoded[idx++] = ASN_OBJECT_ID; - /* first length */ - XMEMCPY(names[i].encoded + idx, firstLen, firstSz); - idx += firstSz; - if (email) { - const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x01, 0x16 }; - /* email joint id */ - XMEMCPY(names[i].encoded + idx, EMAIL_OID, sizeof(EMAIL_OID)); - idx += (int)sizeof(EMAIL_OID); - } - else { - /* joint id */ - byte bType = GetNameId(i); - names[i].encoded[idx++] = 0x55; - names[i].encoded[idx++] = 0x04; - /* id type */ - names[i].encoded[idx++] = bType; - /* str type */ - names[i].encoded[idx++] = GetNameType(name, i); - } - /* second length */ - XMEMCPY(names[i].encoded + idx, secondLen, secondSz); - idx += secondSz; - /* str value */ - XMEMCPY(names[i].encoded + idx, nameStr, strLen); - idx += strLen; - - totalBytes += idx; - names[i].totalLen = idx; - names[i].used = 1; - } - else - names[i].used = 0; - } - - /* header */ - idx = SetSequence(totalBytes, output); - totalBytes += idx; - if (totalBytes > ASN_NAME_MAX) { -#ifdef CYASSL_SMALL_STACK - XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return BUFFER_E; - } - - for (i = 0; i < NAME_ENTRIES; i++) { - if (names[i].used) { - XMEMCPY(output + idx, names[i].encoded, names[i].totalLen); - idx += names[i].totalLen; - } - } - -#ifdef CYASSL_SMALL_STACK - XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return totalBytes; -} - -/* encode info from cert into DER encoded format */ -static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, - RNG* rng, const byte* ntruKey, word16 ntruSz) -{ - int ret; - - (void)eccKey; - (void)ntruKey; - (void)ntruSz; - - /* init */ - XMEMSET(der, 0, sizeof(DerCert)); - - /* version */ - der->versionSz = SetMyVersion(cert->version, der->version, TRUE); - - /* serial number */ - ret = RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE); - if (ret != 0) - return ret; - - cert->serial[0] = 0x01; /* ensure positive */ - der->serialSz = SetSerial(cert->serial, der->serial); - - /* signature algo */ - der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, sigType, 0); - if (der->sigAlgoSz == 0) - return ALGO_ID_E; - - /* public key */ - if (cert->keyType == RSA_KEY) { - if (rsaKey == NULL) - return PUBLIC_KEY_E; - der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey); - if (der->publicKeySz <= 0) - return PUBLIC_KEY_E; - } - -#ifdef HAVE_ECC - if (cert->keyType == ECC_KEY) { - if (eccKey == NULL) - return PUBLIC_KEY_E; - der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey); - if (der->publicKeySz <= 0) - return PUBLIC_KEY_E; - } -#endif /* HAVE_ECC */ - -#ifdef HAVE_NTRU - if (cert->keyType == NTRU_KEY) { - word32 rc; - word16 encodedSz; - - rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, - ntruKey, &encodedSz, NULL); - if (rc != NTRU_OK) - return PUBLIC_KEY_E; - if (encodedSz > MAX_PUBLIC_KEY_SZ) - return PUBLIC_KEY_E; - - rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( ntruSz, - ntruKey, &encodedSz, der->publicKey); - if (rc != NTRU_OK) - return PUBLIC_KEY_E; - - der->publicKeySz = encodedSz; - } -#endif /* HAVE_NTRU */ - - der->validitySz = 0; -#ifdef CYASSL_ALT_NAMES - /* date validity copy ? */ - if (cert->beforeDateSz && cert->afterDateSz) { - der->validitySz = CopyValidity(der->validity, cert); - if (der->validitySz == 0) - return DATE_E; - } -#endif - - /* date validity */ - if (der->validitySz == 0) { - der->validitySz = SetValidity(der->validity, cert->daysValid); - if (der->validitySz == 0) - return DATE_E; - } - - /* subject name */ - der->subjectSz = SetName(der->subject, &cert->subject); - if (der->subjectSz == 0) - return SUBJECT_E; - - /* issuer name */ - der->issuerSz = SetName(der->issuer, cert->selfSigned ? - &cert->subject : &cert->issuer); - if (der->issuerSz == 0) - return ISSUER_E; - - /* CA */ - if (cert->isCA) { - der->caSz = SetCa(der->ca); - if (der->caSz == 0) - return CA_TRUE_E; - } - else - der->caSz = 0; - - /* extensions, just CA now */ - if (cert->isCA) { - der->extensionsSz = SetExtensions(der->extensions, - der->ca, der->caSz, TRUE); - if (der->extensionsSz == 0) - return EXTENSIONS_E; - } - else - der->extensionsSz = 0; - -#ifdef CYASSL_ALT_NAMES - if (der->extensionsSz == 0 && cert->altNamesSz) { - der->extensionsSz = SetExtensions(der->extensions, cert->altNames, - cert->altNamesSz, TRUE); - if (der->extensionsSz == 0) - return EXTENSIONS_E; - } -#endif - - der->total = der->versionSz + der->serialSz + der->sigAlgoSz + - der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz + - der->extensionsSz; - - return 0; -} - - -/* write DER encoded cert to buffer, size already checked */ -static int WriteCertBody(DerCert* der, byte* buffer) -{ - int idx; - - /* signed part header */ - idx = SetSequence(der->total, buffer); - /* version */ - XMEMCPY(buffer + idx, der->version, der->versionSz); - idx += der->versionSz; - /* serial */ - XMEMCPY(buffer + idx, der->serial, der->serialSz); - idx += der->serialSz; - /* sig algo */ - XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz); - idx += der->sigAlgoSz; - /* issuer */ - XMEMCPY(buffer + idx, der->issuer, der->issuerSz); - idx += der->issuerSz; - /* validity */ - XMEMCPY(buffer + idx, der->validity, der->validitySz); - idx += der->validitySz; - /* subject */ - XMEMCPY(buffer + idx, der->subject, der->subjectSz); - idx += der->subjectSz; - /* public key */ - XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); - idx += der->publicKeySz; - if (der->extensionsSz) { - /* extensions */ - XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, - sizeof(der->extensions))); - idx += der->extensionsSz; - } - - return idx; -} - - -/* Make RSA signature from buffer (sz), write to sig (sigSz) */ -static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, - RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, - int sigAlgoType) -{ - int encSigSz, digestSz, typeH = 0, ret = 0; - byte digest[SHA256_DIGEST_SIZE]; /* max size */ -#ifdef CYASSL_SMALL_STACK - byte* encSig; -#else - byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; -#endif - - (void)digest; - (void)digestSz; - (void)encSig; - (void)encSigSz; - (void)typeH; - - (void)buffer; - (void)sz; - (void)sig; - (void)sigSz; - (void)rsaKey; - (void)eccKey; - (void)rng; - - switch (sigAlgoType) { - #ifndef NO_MD5 - case CTC_MD5wRSA: - if ((ret = Md5Hash(buffer, sz, digest)) == 0) { - typeH = MD5h; - digestSz = MD5_DIGEST_SIZE; - } - break; - #endif - #ifndef NO_SHA - case CTC_SHAwRSA: - case CTC_SHAwECDSA: - if ((ret = ShaHash(buffer, sz, digest)) == 0) { - typeH = SHAh; - digestSz = SHA_DIGEST_SIZE; - } - break; - #endif - #ifndef NO_SHA256 - case CTC_SHA256wRSA: - case CTC_SHA256wECDSA: - if ((ret = Sha256Hash(buffer, sz, digest)) == 0) { - typeH = SHA256h; - digestSz = SHA256_DIGEST_SIZE; - } - break; - #endif - default: - CYASSL_MSG("MakeSignautre called with unsupported type"); - ret = ALGO_ID_E; - } - - if (ret != 0) - return ret; - -#ifdef CYASSL_SMALL_STACK - encSig = (byte*)XMALLOC(MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ, - NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (encSig == NULL) - return MEMORY_E; -#endif - - ret = ALGO_ID_E; - -#ifndef NO_RSA - if (rsaKey) { - /* signature */ - encSigSz = EncodeSignature(encSig, digest, digestSz, typeH); - ret = RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng); - } -#endif - -#ifdef HAVE_ECC - if (!rsaKey && eccKey) { - word32 outSz = sigSz; - ret = ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey); - - if (ret == 0) - ret = outSz; - } -#endif - -#ifdef CYASSL_SMALL_STACK - XFREE(encSig, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - - -/* add signature to end of buffer, size of buffer assumed checked, return - new length */ -static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz, - int sigAlgoType) -{ - byte seq[MAX_SEQ_SZ]; - int idx = bodySz, seqSz; - - /* algo */ - idx += SetAlgoID(sigAlgoType, buffer + idx, sigType, 0); - /* bit string */ - buffer[idx++] = ASN_BIT_STRING; - /* length */ - idx += SetLength(sigSz + 1, buffer + idx); - buffer[idx++] = 0; /* trailing 0 */ - /* signature */ - XMEMCPY(buffer + idx, sig, sigSz); - idx += sigSz; - - /* make room for overall header */ - seqSz = SetSequence(idx, seq); - XMEMMOVE(buffer + seqSz, buffer, idx); - XMEMCPY(buffer, seq, seqSz); - - return idx + seqSz; -} - - -/* Make an x509 Certificate v3 any key type from cert input, write to buffer */ -static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, - RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, - const byte* ntruKey, word16 ntruSz) -{ - int ret; -#ifdef CYASSL_SMALL_STACK - DerCert* der; -#else - DerCert der[1]; -#endif - - cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : NTRU_KEY); - -#ifdef CYASSL_SMALL_STACK - der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (der == NULL) - return MEMORY_E; -#endif - - ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz); - - if (ret == 0) { - if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) - ret = BUFFER_E; - else - ret = cert->bodySz = WriteCertBody(der, derBuffer); - } - -#ifdef CYASSL_SMALL_STACK - XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - - -/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */ -int MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, - ecc_key* eccKey, RNG* rng) -{ - return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0); -} - - -#ifdef HAVE_NTRU - -int MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz, - const byte* ntruKey, word16 keySz, RNG* rng) -{ - return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz); -} - -#endif /* HAVE_NTRU */ - - -#ifdef CYASSL_CERT_REQ - -static int SetReqAttrib(byte* output, char* pw, int extSz) -{ - static const byte cpOid[] = - { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x07 }; - static const byte erOid[] = - { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x0e }; - - int sz = 0; /* overall size */ - int cpSz = 0; /* Challenge Password section size */ - int cpSeqSz = 0; - int cpSetSz = 0; - int cpStrSz = 0; - int pwSz = 0; - int erSz = 0; /* Extension Request section size */ - int erSeqSz = 0; - int erSetSz = 0; - byte cpSeq[MAX_SEQ_SZ]; - byte cpSet[MAX_SET_SZ]; - byte cpStr[MAX_PRSTR_SZ]; - byte erSeq[MAX_SEQ_SZ]; - byte erSet[MAX_SET_SZ]; - - output[0] = 0xa0; - sz++; - - if (pw && pw[0]) { - pwSz = (int)XSTRLEN(pw); - cpStrSz = SetUTF8String(pwSz, cpStr); - cpSetSz = SetSet(cpStrSz + pwSz, cpSet); - cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq); - cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz; - } - - if (extSz) { - erSetSz = SetSet(extSz, erSet); - erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq); - erSz = extSz + erSetSz + erSeqSz + sizeof(erOid); - } - - /* Put the pieces together. */ - sz += SetLength(cpSz + erSz, &output[sz]); - - if (cpSz) { - XMEMCPY(&output[sz], cpSeq, cpSeqSz); - sz += cpSeqSz; - XMEMCPY(&output[sz], cpOid, sizeof(cpOid)); - sz += sizeof(cpOid); - XMEMCPY(&output[sz], cpSet, cpSetSz); - sz += cpSetSz; - XMEMCPY(&output[sz], cpStr, cpStrSz); - sz += cpStrSz; - XMEMCPY(&output[sz], pw, pwSz); - sz += pwSz; - } - - if (erSz) { - XMEMCPY(&output[sz], erSeq, erSeqSz); - sz += erSeqSz; - XMEMCPY(&output[sz], erOid, sizeof(erOid)); - sz += sizeof(erOid); - XMEMCPY(&output[sz], erSet, erSetSz); - sz += erSetSz; - /* The actual extension data will be tacked onto the output later. */ - } - - return sz; -} - - -/* encode info from cert into DER encoded format */ -static int EncodeCertReq(Cert* cert, DerCert* der, - RsaKey* rsaKey, ecc_key* eccKey) -{ - (void)eccKey; - - /* init */ - XMEMSET(der, 0, sizeof(DerCert)); - - /* version */ - der->versionSz = SetMyVersion(cert->version, der->version, FALSE); - - /* subject name */ - der->subjectSz = SetName(der->subject, &cert->subject); - if (der->subjectSz == 0) - return SUBJECT_E; - - /* public key */ - if (cert->keyType == RSA_KEY) { - if (rsaKey == NULL) - return PUBLIC_KEY_E; - der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey); - if (der->publicKeySz <= 0) - return PUBLIC_KEY_E; - } - -#ifdef HAVE_ECC - if (cert->keyType == ECC_KEY) { - if (eccKey == NULL) - return PUBLIC_KEY_E; - der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey); - if (der->publicKeySz <= 0) - return PUBLIC_KEY_E; - } -#endif /* HAVE_ECC */ - - /* CA */ - if (cert->isCA) { - der->caSz = SetCa(der->ca); - if (der->caSz == 0) - return CA_TRUE_E; - } - else - der->caSz = 0; - - /* extensions, just CA now */ - if (cert->isCA) { - der->extensionsSz = SetExtensions(der->extensions, - der->ca, der->caSz, FALSE); - if (der->extensionsSz == 0) - return EXTENSIONS_E; - } - else - der->extensionsSz = 0; - - der->attribSz = SetReqAttrib(der->attrib, - cert->challengePw, der->extensionsSz); - if (der->attribSz == 0) - return REQ_ATTRIBUTE_E; - - der->total = der->versionSz + der->subjectSz + der->publicKeySz + - der->extensionsSz + der->attribSz; - - return 0; -} - - -/* write DER encoded cert req to buffer, size already checked */ -static int WriteCertReqBody(DerCert* der, byte* buffer) -{ - int idx; - - /* signed part header */ - idx = SetSequence(der->total, buffer); - /* version */ - XMEMCPY(buffer + idx, der->version, der->versionSz); - idx += der->versionSz; - /* subject */ - XMEMCPY(buffer + idx, der->subject, der->subjectSz); - idx += der->subjectSz; - /* public key */ - XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); - idx += der->publicKeySz; - /* attributes */ - XMEMCPY(buffer + idx, der->attrib, der->attribSz); - idx += der->attribSz; - /* extensions */ - if (der->extensionsSz) { - XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, - sizeof(der->extensions))); - idx += der->extensionsSz; - } - - return idx; -} - - -int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, - RsaKey* rsaKey, ecc_key* eccKey) -{ - int ret; -#ifdef CYASSL_SMALL_STACK - DerCert* der; -#else - DerCert der[1]; -#endif - - cert->keyType = eccKey ? ECC_KEY : RSA_KEY; - -#ifdef CYASSL_SMALL_STACK - der = (DerCert*)XMALLOC(sizeof(DerCert), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (der == NULL) - return MEMORY_E; -#endif - - ret = EncodeCertReq(cert, der, rsaKey, eccKey); - - if (ret == 0) { - if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) - ret = BUFFER_E; - else - ret = cert->bodySz = WriteCertReqBody(der, derBuffer); - } - -#ifdef CYASSL_SMALL_STACK - XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - -#endif /* CYASSL_CERT_REQ */ - - -int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, - RsaKey* rsaKey, ecc_key* eccKey, RNG* rng) -{ - int sigSz; -#ifdef CYASSL_SMALL_STACK - byte* sig; -#else - byte sig[MAX_ENCODED_SIG_SZ]; -#endif - - if (requestSz < 0) - return requestSz; - -#ifdef CYASSL_SMALL_STACK - sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sig == NULL) - return MEMORY_E; -#endif - - sigSz = MakeSignature(buffer, requestSz, sig, MAX_ENCODED_SIG_SZ, rsaKey, - eccKey, rng, sType); - - if (sigSz >= 0) { - if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz) - sigSz = BUFFER_E; - else - sigSz = AddSignature(buffer, requestSz, sig, sigSz, sType); - } - -#ifdef CYASSL_SMALL_STACK - XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return sigSz; -} - - -int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) -{ - int ret = MakeCert(cert, buffer, buffSz, key, NULL, rng); - - if (ret < 0) - return ret; - - return SignCert(cert->bodySz, cert->sigType, buffer, buffSz, key, NULL,rng); -} - - -#ifdef CYASSL_ALT_NAMES - -/* Set Alt Names from der cert, return 0 on success */ -static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz) -{ - int ret; -#ifdef CYASSL_SMALL_STACK - DecodedCert* decoded; -#else - DecodedCert decoded[1]; -#endif - - if (derSz < 0) - return derSz; - -#ifdef CYASSL_SMALL_STACK - decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (decoded == NULL) - return MEMORY_E; -#endif - - InitDecodedCert(decoded, (byte*)der, derSz, 0); - ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); - - if (ret < 0) { - CYASSL_MSG("ParseCertRelative error"); - } - else if (decoded->extensions) { - byte b; - int length; - word32 maxExtensionsIdx; - - decoded->srcIdx = decoded->extensionsIdx; - b = decoded->source[decoded->srcIdx++]; - - if (b != ASN_EXTENSIONS) { - ret = ASN_PARSE_E; - } - else if (GetLength(decoded->source, &decoded->srcIdx, &length, - decoded->maxIdx) < 0) { - ret = ASN_PARSE_E; - } - else if (GetSequence(decoded->source, &decoded->srcIdx, &length, - decoded->maxIdx) < 0) { - ret = ASN_PARSE_E; - } - else { - maxExtensionsIdx = decoded->srcIdx + length; - - while (decoded->srcIdx < maxExtensionsIdx) { - word32 oid; - word32 startIdx = decoded->srcIdx; - word32 tmpIdx; - - if (GetSequence(decoded->source, &decoded->srcIdx, &length, - decoded->maxIdx) < 0) { - ret = ASN_PARSE_E; - break; - } - - tmpIdx = decoded->srcIdx; - decoded->srcIdx = startIdx; - - if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid, - decoded->maxIdx) < 0) { - ret = ASN_PARSE_E; - break; - } - - if (oid == ALT_NAMES_OID) { - cert->altNamesSz = length + (tmpIdx - startIdx); - - if (cert->altNamesSz < (int)sizeof(cert->altNames)) - XMEMCPY(cert->altNames, &decoded->source[startIdx], - cert->altNamesSz); - else { - cert->altNamesSz = 0; - CYASSL_MSG("AltNames extensions too big"); - ret = ALT_NAME_E; - break; - } - } - decoded->srcIdx = tmpIdx + length; - } - } - } - - FreeDecodedCert(decoded); -#ifdef CYASSL_SMALL_STACK - XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret < 0 ? ret : 0; -} - - -/* Set Dates from der cert, return 0 on success */ -static int SetDatesFromCert(Cert* cert, const byte* der, int derSz) -{ - int ret; -#ifdef CYASSL_SMALL_STACK - DecodedCert* decoded; -#else - DecodedCert decoded[1]; -#endif - - CYASSL_ENTER("SetDatesFromCert"); - if (derSz < 0) - return derSz; - -#ifdef CYASSL_SMALL_STACK - decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (decoded == NULL) - return MEMORY_E; -#endif - - InitDecodedCert(decoded, (byte*)der, derSz, 0); - ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); - - if (ret < 0) { - CYASSL_MSG("ParseCertRelative error"); - } - else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) { - CYASSL_MSG("Couldn't extract dates"); - ret = -1; - } - else if (decoded->beforeDateLen > MAX_DATE_SIZE || - decoded->afterDateLen > MAX_DATE_SIZE) { - CYASSL_MSG("Bad date size"); - ret = -1; - } - else { - XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen); - XMEMCPY(cert->afterDate, decoded->afterDate, decoded->afterDateLen); - - cert->beforeDateSz = decoded->beforeDateLen; - cert->afterDateSz = decoded->afterDateLen; - } - - FreeDecodedCert(decoded); - -#ifdef CYASSL_SMALL_STACK - XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret < 0 ? ret : 0; -} - - -#endif /* CYASSL_ALT_NAMES && !NO_RSA */ - - -/* Set cn name from der buffer, return 0 on success */ -static int SetNameFromCert(CertName* cn, const byte* der, int derSz) -{ - int ret, sz; -#ifdef CYASSL_SMALL_STACK - DecodedCert* decoded; -#else - DecodedCert decoded[1]; -#endif - - if (derSz < 0) - return derSz; - -#ifdef CYASSL_SMALL_STACK - decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (decoded == NULL) - return MEMORY_E; -#endif - - InitDecodedCert(decoded, (byte*)der, derSz, 0); - ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0); - - if (ret < 0) { - CYASSL_MSG("ParseCertRelative error"); - } - else { - if (decoded->subjectCN) { - sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen - : CTC_NAME_SIZE - 1; - strncpy(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE); - cn->commonName[sz] = 0; - cn->commonNameEnc = decoded->subjectCNEnc; - } - if (decoded->subjectC) { - sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen - : CTC_NAME_SIZE - 1; - strncpy(cn->country, decoded->subjectC, CTC_NAME_SIZE); - cn->country[sz] = 0; - cn->countryEnc = decoded->subjectCEnc; - } - if (decoded->subjectST) { - sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen - : CTC_NAME_SIZE - 1; - strncpy(cn->state, decoded->subjectST, CTC_NAME_SIZE); - cn->state[sz] = 0; - cn->stateEnc = decoded->subjectSTEnc; - } - if (decoded->subjectL) { - sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen - : CTC_NAME_SIZE - 1; - strncpy(cn->locality, decoded->subjectL, CTC_NAME_SIZE); - cn->locality[sz] = 0; - cn->localityEnc = decoded->subjectLEnc; - } - if (decoded->subjectO) { - sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen - : CTC_NAME_SIZE - 1; - strncpy(cn->org, decoded->subjectO, CTC_NAME_SIZE); - cn->org[sz] = 0; - cn->orgEnc = decoded->subjectOEnc; - } - if (decoded->subjectOU) { - sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen - : CTC_NAME_SIZE - 1; - strncpy(cn->unit, decoded->subjectOU, CTC_NAME_SIZE); - cn->unit[sz] = 0; - cn->unitEnc = decoded->subjectOUEnc; - } - if (decoded->subjectSN) { - sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen - : CTC_NAME_SIZE - 1; - strncpy(cn->sur, decoded->subjectSN, CTC_NAME_SIZE); - cn->sur[sz] = 0; - cn->surEnc = decoded->subjectSNEnc; - } - if (decoded->subjectEmail) { - sz = (decoded->subjectEmailLen < CTC_NAME_SIZE) - ? decoded->subjectEmailLen : CTC_NAME_SIZE - 1; - strncpy(cn->email, decoded->subjectEmail, CTC_NAME_SIZE); - cn->email[sz] = 0; - } - } - - FreeDecodedCert(decoded); - -#ifdef CYASSL_SMALL_STACK - XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret < 0 ? ret : 0; -} - - -#ifndef NO_FILESYSTEM - -/* Set cert issuer from issuerFile in PEM */ -int SetIssuer(Cert* cert, const char* issuerFile) -{ - int ret; - int derSz; - byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); - - if (der == NULL) { - CYASSL_MSG("SetIssuer OOF Problem"); - return MEMORY_E; - } - derSz = CyaSSL_PemCertToDer(issuerFile, der, EIGHTK_BUF); - cert->selfSigned = 0; - ret = SetNameFromCert(&cert->issuer, der, derSz); - XFREE(der, NULL, DYNAMIC_TYPE_CERT); - - return ret; -} - - -/* Set cert subject from subjectFile in PEM */ -int SetSubject(Cert* cert, const char* subjectFile) -{ - int ret; - int derSz; - byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); - - if (der == NULL) { - CYASSL_MSG("SetSubject OOF Problem"); - return MEMORY_E; - } - derSz = CyaSSL_PemCertToDer(subjectFile, der, EIGHTK_BUF); - ret = SetNameFromCert(&cert->subject, der, derSz); - XFREE(der, NULL, DYNAMIC_TYPE_CERT); - - return ret; -} - - -#ifdef CYASSL_ALT_NAMES - -/* Set atl names from file in PEM */ -int SetAltNames(Cert* cert, const char* file) -{ - int ret; - int derSz; - byte* der = (byte*)XMALLOC(EIGHTK_BUF, NULL, DYNAMIC_TYPE_CERT); - - if (der == NULL) { - CYASSL_MSG("SetAltNames OOF Problem"); - return MEMORY_E; - } - derSz = CyaSSL_PemCertToDer(file, der, EIGHTK_BUF); - ret = SetAltNamesFromCert(cert, der, derSz); - XFREE(der, NULL, DYNAMIC_TYPE_CERT); - - return ret; -} - -#endif /* CYASSL_ALT_NAMES */ - -#endif /* NO_FILESYSTEM */ - -/* Set cert issuer from DER buffer */ -int SetIssuerBuffer(Cert* cert, const byte* der, int derSz) -{ - cert->selfSigned = 0; - return SetNameFromCert(&cert->issuer, der, derSz); -} - - -/* Set cert subject from DER buffer */ -int SetSubjectBuffer(Cert* cert, const byte* der, int derSz) -{ - return SetNameFromCert(&cert->subject, der, derSz); -} - - -#ifdef CYASSL_ALT_NAMES - -/* Set cert alt names from DER buffer */ -int SetAltNamesBuffer(Cert* cert, const byte* der, int derSz) -{ - return SetAltNamesFromCert(cert, der, derSz); -} - -/* Set cert dates from DER buffer */ -int SetDatesBuffer(Cert* cert, const byte* der, int derSz) -{ - return SetDatesFromCert(cert, der, derSz); -} - -#endif /* CYASSL_ALT_NAMES */ - -#endif /* CYASSL_CERT_GEN */ - - -#ifdef HAVE_ECC - -/* Der Encode r & s ints into out, outLen is (in/out) size */ -int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s) -{ - word32 idx = 0; - word32 rSz; /* encoding size */ - word32 sSz; - word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */ - - /* If the leading bit on the INTEGER is a 1, add a leading zero */ - int rLeadingZero = mp_leading_bit(r); - int sLeadingZero = mp_leading_bit(s); - int rLen = mp_unsigned_bin_size(r); /* big int size */ - int sLen = mp_unsigned_bin_size(s); - int err; - - if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero + - headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */ - return BAD_FUNC_ARG; - - idx = SetSequence(rLen+rLeadingZero+sLen+sLeadingZero+headerSz, out); - - /* store r */ - out[idx++] = ASN_INTEGER; - rSz = SetLength(rLen + rLeadingZero, &out[idx]); - idx += rSz; - if (rLeadingZero) - out[idx++] = 0; - err = mp_to_unsigned_bin(r, &out[idx]); - if (err != MP_OKAY) return err; - idx += rLen; - - /* store s */ - out[idx++] = ASN_INTEGER; - sSz = SetLength(sLen + sLeadingZero, &out[idx]); - idx += sSz; - if (sLeadingZero) - out[idx++] = 0; - err = mp_to_unsigned_bin(s, &out[idx]); - if (err != MP_OKAY) return err; - idx += sLen; - - *outLen = idx; - - return 0; -} - - -/* Der Decode ECC-DSA Signautre, r & s stored as big ints */ -int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s) -{ - word32 idx = 0; - int len = 0; - - if (GetSequence(sig, &idx, &len, sigLen) < 0) - return ASN_ECC_KEY_E; - - if ((word32)len > (sigLen - idx)) - return ASN_ECC_KEY_E; - - if (GetInt(r, sig, &idx, sigLen) < 0) - return ASN_ECC_KEY_E; - - if (GetInt(s, sig, &idx, sigLen) < 0) - return ASN_ECC_KEY_E; - - return 0; -} - - -int EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, - word32 inSz) -{ - word32 oid = 0; - int version, length; - int privSz, pubSz; - byte b; - int ret = 0; -#ifdef CYASSL_SMALL_STACK - byte* priv; - byte* pub; -#else - byte priv[ECC_MAXSIZE]; - byte pub[ECC_MAXSIZE * 2 + 1]; /* public key has two parts plus header */ -#endif - - if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) - return BAD_FUNC_ARG; - - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetMyVersion(input, inOutIdx, &version) < 0) - return ASN_PARSE_E; - - b = input[*inOutIdx]; - *inOutIdx += 1; - - /* priv type */ - if (b != 4 && b != 6 && b != 7) - return ASN_PARSE_E; - - if (GetLength(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (length > ECC_MAXSIZE) - return BUFFER_E; - -#ifdef CYASSL_SMALL_STACK - priv = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (priv == NULL) - return MEMORY_E; - - pub = (byte*)XMALLOC(ECC_MAXSIZE * 2 + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (pub == NULL) { - XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - /* priv key */ - privSz = length; - XMEMCPY(priv, &input[*inOutIdx], privSz); - *inOutIdx += length; - - /* prefix 0, may have */ - b = input[*inOutIdx]; - if (b == ECC_PREFIX_0) { - *inOutIdx += 1; - - if (GetLength(input, inOutIdx, &length, inSz) < 0) - ret = ASN_PARSE_E; - else { - /* object id */ - b = input[*inOutIdx]; - *inOutIdx += 1; - - if (b != ASN_OBJECT_ID) { - ret = ASN_OBJECT_ID_E; - } - else if (GetLength(input, inOutIdx, &length, inSz) < 0) { - ret = ASN_PARSE_E; - } - else { - while(length--) { - oid += input[*inOutIdx]; - *inOutIdx += 1; - } - if (CheckCurve(oid) < 0) - ret = ECC_CURVE_OID_E; - } - } - } - - if (ret == 0) { - /* prefix 1 */ - b = input[*inOutIdx]; - *inOutIdx += 1; - - if (b != ECC_PREFIX_1) { - ret = ASN_ECC_KEY_E; - } - else if (GetLength(input, inOutIdx, &length, inSz) < 0) { - ret = ASN_PARSE_E; - } - else { - /* key header */ - b = input[*inOutIdx]; - *inOutIdx += 1; - - if (b != ASN_BIT_STRING) { - ret = ASN_BITSTR_E; - } - else if (GetLength(input, inOutIdx, &length, inSz) < 0) { - ret = ASN_PARSE_E; - } - else { - b = input[*inOutIdx]; - *inOutIdx += 1; - - if (b != 0x00) { - ret = ASN_EXPECT_0_E; - } - else { - /* pub key */ - pubSz = length - 1; /* null prefix */ - if (pubSz < (ECC_MAXSIZE*2 + 1)) { - XMEMCPY(pub, &input[*inOutIdx], pubSz); - *inOutIdx += length; - ret = ecc_import_private_key(priv, privSz, pub, pubSz, - key); - } else - ret = BUFFER_E; - } - } - } - } - -#ifdef CYASSL_SMALL_STACK - XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - - -#ifdef CYASSL_KEY_GEN - -/* Write a Private ecc key to DER format, length on success else < 0 */ -int EccKeyToDer(ecc_key* key, byte* output, word32 inLen) -{ - byte curve[MAX_ALGO_SZ]; - byte ver[MAX_VERSION_SZ]; - byte seq[MAX_SEQ_SZ]; - int ret; - int curveSz; - int verSz; - int privHdrSz = ASN_ECC_HEADER_SZ; - int pubHdrSz = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ; - int curveHdrSz = ASN_ECC_CONTEXT_SZ; - word32 seqSz; - word32 idx = 0; - word32 pubSz = ECC_BUFSIZE; - word32 privSz; - word32 totalSz; - - if (key == NULL || output == NULL || inLen == 0) - return BAD_FUNC_ARG; - - ret = ecc_export_x963(key, NULL, &pubSz); - if (ret != LENGTH_ONLY_E) { - return ret; - } - curveSz = SetCurve(key, curve); - if (curveSz < 0) { - return curveSz; - } - - privSz = key->dp->size; - - verSz = SetMyVersion(1, ver, FALSE); - if (verSz < 0) { - return verSz; - } - - totalSz = verSz + privSz + privHdrSz + curveSz + curveHdrSz + - pubSz + pubHdrSz + 1; /* plus null byte b4 public */ - seqSz = SetSequence(totalSz, seq); - totalSz += seqSz; - - if (totalSz > inLen) { - return BUFFER_E; - } - - /* write it out */ - /* seq */ - XMEMCPY(output + idx, seq, seqSz); - idx += seqSz; - - /* ver */ - XMEMCPY(output + idx, ver, verSz); - idx += verSz; - - /* private */ - output[idx++] = ASN_OCTET_STRING; - output[idx++] = (byte)privSz; - ret = ecc_export_private_only(key, output + idx, &privSz); - if (ret < 0) { - return ret; - } - idx += privSz; - - /* curve */ - output[idx++] = ECC_PREFIX_0; - output[idx++] = (byte)curveSz; - XMEMCPY(output + idx, curve, curveSz); - idx += curveSz; - - /* public */ - output[idx++] = ECC_PREFIX_1; - output[idx++] = (byte)pubSz + ASN_ECC_CONTEXT_SZ + 1; /* plus null byte */ - output[idx++] = ASN_BIT_STRING; - output[idx++] = (byte)pubSz + 1; /* plus null byte */ - output[idx++] = (byte)0; /* null byte */ - ret = ecc_export_x963(key, output + idx, &pubSz); - if (ret != 0) { - return ret; - } - /* idx += pubSz if do more later */ - - return totalSz; -} - -#endif /* CYASSL_KEY_GEN */ - -#endif /* HAVE_ECC */ - - -#if defined(HAVE_OCSP) || defined(HAVE_CRL) - -/* Get raw Date only, no processing, 0 on success */ -static int GetBasicDate(const byte* source, word32* idx, byte* date, - byte* format, int maxIdx) -{ - int length; - - CYASSL_ENTER("GetBasicDate"); - - *format = source[*idx]; - *idx += 1; - if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME) - return ASN_TIME_E; - - if (GetLength(source, idx, &length, maxIdx) < 0) - return ASN_PARSE_E; - - if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE) - return ASN_DATE_SZ_E; - - XMEMCPY(date, &source[*idx], length); - *idx += length; - - return 0; -} - -#endif - - -#ifdef HAVE_OCSP - -static int GetEnumerated(const byte* input, word32* inOutIdx, int *value) -{ - word32 idx = *inOutIdx; - word32 len; - - CYASSL_ENTER("GetEnumerated"); - - *value = 0; - - if (input[idx++] != ASN_ENUMERATED) - return ASN_PARSE_E; - - len = input[idx++]; - if (len > 4) - return ASN_PARSE_E; - - while (len--) { - *value = *value << 8 | input[idx++]; - } - - *inOutIdx = idx; - - return *value; -} - - -static int DecodeSingleResponse(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) -{ - word32 idx = *ioIndex, prevIndex, oid; - int length, wrapperSz; - CertStatus* cs = resp->status; - - CYASSL_ENTER("DecodeSingleResponse"); - - /* Outer wrapper of the SEQUENCE OF Single Responses. */ - if (GetSequence(source, &idx, &wrapperSz, size) < 0) - return ASN_PARSE_E; - - prevIndex = idx; - - /* When making a request, we only request one status on one certificate - * at a time. There should only be one SingleResponse */ - - /* Wrapper around the Single Response */ - if (GetSequence(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - /* Wrapper around the CertID */ - if (GetSequence(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - /* Skip the hash algorithm */ - if (GetAlgoId(source, &idx, &oid, size) < 0) - return ASN_PARSE_E; - /* Save reference to the hash of CN */ - if (source[idx++] != ASN_OCTET_STRING) - return ASN_PARSE_E; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - resp->issuerHash = source + idx; - idx += length; - /* Save reference to the hash of the issuer public key */ - if (source[idx++] != ASN_OCTET_STRING) - return ASN_PARSE_E; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - resp->issuerKeyHash = source + idx; - idx += length; - - /* Read the serial number, it is handled as a string, not as a - * proper number. Just XMEMCPY the data over, rather than load it - * as an mp_int. */ - if (source[idx++] != ASN_INTEGER) - return ASN_PARSE_E; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - if (length <= EXTERNAL_SERIAL_SIZE) - { - if (source[idx] == 0) - { - idx++; - length--; - } - XMEMCPY(cs->serial, source + idx, length); - cs->serialSz = length; - } - else - { - return ASN_GETINT_E; - } - idx += length; - - /* CertStatus */ - switch (source[idx++]) - { - case (ASN_CONTEXT_SPECIFIC | CERT_GOOD): - cs->status = CERT_GOOD; - idx++; - break; - case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED): - cs->status = CERT_REVOKED; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - idx += length; - break; - case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN): - cs->status = CERT_UNKNOWN; - idx++; - break; - default: - return ASN_PARSE_E; - } - - if (GetBasicDate(source, &idx, cs->thisDate, - &cs->thisDateFormat, size) < 0) - return ASN_PARSE_E; - if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE)) - return ASN_BEFORE_DATE_E; - - /* The following items are optional. Only check for them if there is more - * unprocessed data in the singleResponse wrapper. */ - - if (((int)(idx - prevIndex) < wrapperSz) && - (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))) - { - idx++; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - if (GetBasicDate(source, &idx, cs->nextDate, - &cs->nextDateFormat, size) < 0) - return ASN_PARSE_E; - } - if (((int)(idx - prevIndex) < wrapperSz) && - (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))) - { - idx++; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - idx += length; - } - - *ioIndex = idx; - - return 0; -} - -static int DecodeOcspRespExtensions(byte* source, - word32* ioIndex, OcspResponse* resp, word32 sz) -{ - word32 idx = *ioIndex; - int length; - int ext_bound; /* boundary index for the sequence of extensions */ - word32 oid; - - CYASSL_ENTER("DecodeOcspRespExtensions"); - - if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) - return ASN_PARSE_E; - - if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E; - - if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E; - - ext_bound = idx + length; - - while (idx < (word32)ext_bound) { - if (GetSequence(source, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: should be a SEQUENCE"); - return ASN_PARSE_E; - } - - oid = 0; - if (GetObjectId(source, &idx, &oid, sz) < 0) { - CYASSL_MSG("\tfail: OBJECT ID"); - return ASN_PARSE_E; - } - - /* check for critical flag */ - if (source[idx] == ASN_BOOLEAN) { - CYASSL_MSG("\tfound optional critical flag, moving past"); - idx += (ASN_BOOL_SIZE + 1); - } - - /* process the extension based on the OID */ - if (source[idx++] != ASN_OCTET_STRING) { - CYASSL_MSG("\tfail: should be an OCTET STRING"); - return ASN_PARSE_E; - } - - if (GetLength(source, &idx, &length, sz) < 0) { - CYASSL_MSG("\tfail: extension data length"); - return ASN_PARSE_E; - } - - if (oid == OCSP_NONCE_OID) { - resp->nonce = source + idx; - resp->nonceSz = length; - } - - idx += length; - } - - *ioIndex = idx; - return 0; -} - - -static int DecodeResponseData(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) -{ - word32 idx = *ioIndex, prev_idx; - int length; - int version; - word32 responderId = 0; - - CYASSL_ENTER("DecodeResponseData"); - - resp->response = source + idx; - prev_idx = idx; - if (GetSequence(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - resp->responseSz = length + idx - prev_idx; - - /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this - * item isn't an EXPLICIT[0], then set version to zero and move - * onto the next item. - */ - if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) - { - idx += 2; /* Eat the value and length */ - if (GetMyVersion(source, &idx, &version) < 0) - return ASN_PARSE_E; - } else - version = 0; - - responderId = source[idx++]; - if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) || - (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))) - { - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - idx += length; - } - else - return ASN_PARSE_E; - - /* save pointer to the producedAt time */ - if (GetBasicDate(source, &idx, resp->producedDate, - &resp->producedDateFormat, size) < 0) - return ASN_PARSE_E; - - if (DecodeSingleResponse(source, &idx, resp, size) < 0) - return ASN_PARSE_E; - - if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0) - return ASN_PARSE_E; - - *ioIndex = idx; - return 0; -} - - -static int DecodeCerts(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) -{ - word32 idx = *ioIndex; - - CYASSL_ENTER("DecodeCerts"); - - if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) - { - int length; - - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - if (GetSequence(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - resp->cert = source + idx; - resp->certSz = length; - - idx += length; - } - *ioIndex = idx; - return 0; -} - -static int DecodeBasicOcspResponse(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) -{ - int length; - word32 idx = *ioIndex; - word32 end_index; - - CYASSL_ENTER("DecodeBasicOcspResponse"); - - if (GetSequence(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - if (idx + length > size) - return ASN_INPUT_E; - end_index = idx + length; - - if (DecodeResponseData(source, &idx, resp, size) < 0) - return ASN_PARSE_E; - - /* Get the signature algorithm */ - if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0) - return ASN_PARSE_E; - - /* Obtain pointer to the start of the signature, and save the size */ - if (source[idx++] == ASN_BIT_STRING) - { - int sigLength = 0; - if (GetLength(source, &idx, &sigLength, size) < 0) - return ASN_PARSE_E; - resp->sigSz = sigLength; - resp->sig = source + idx; - idx += sigLength; - } - - /* - * Check the length of the BasicOcspResponse against the current index to - * see if there are certificates, they are optional. - */ - if (idx < end_index) - { - DecodedCert cert; - int ret; - - if (DecodeCerts(source, &idx, resp, size) < 0) - return ASN_PARSE_E; - - InitDecodedCert(&cert, resp->cert, resp->certSz, 0); - ret = ParseCertRelative(&cert, CA_TYPE, NO_VERIFY, 0); - if (ret < 0) - return ret; - - ret = ConfirmSignature(resp->response, resp->responseSz, - cert.publicKey, cert.pubKeySize, cert.keyOID, - resp->sig, resp->sigSz, resp->sigOID, NULL); - FreeDecodedCert(&cert); - - if (ret == 0) - { - CYASSL_MSG("\tOCSP Confirm signature failed"); - return ASN_OCSP_CONFIRM_E; - } - } - - *ioIndex = idx; - return 0; -} - - -void InitOcspResponse(OcspResponse* resp, CertStatus* status, - byte* source, word32 inSz) -{ - CYASSL_ENTER("InitOcspResponse"); - - resp->responseStatus = -1; - resp->response = NULL; - resp->responseSz = 0; - resp->producedDateFormat = 0; - resp->issuerHash = NULL; - resp->issuerKeyHash = NULL; - resp->sig = NULL; - resp->sigSz = 0; - resp->sigOID = 0; - resp->status = status; - resp->nonce = NULL; - resp->nonceSz = 0; - resp->source = source; - resp->maxIdx = inSz; -} - - -int OcspResponseDecode(OcspResponse* resp) -{ - int length = 0; - word32 idx = 0; - byte* source = resp->source; - word32 size = resp->maxIdx; - word32 oid; - - CYASSL_ENTER("OcspResponseDecode"); - - /* peel the outer SEQUENCE wrapper */ - if (GetSequence(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - /* First get the responseStatus, an ENUMERATED */ - if (GetEnumerated(source, &idx, &resp->responseStatus) < 0) - return ASN_PARSE_E; - - if (resp->responseStatus != OCSP_SUCCESSFUL) - return 0; - - /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */ - if (idx >= size) - return ASN_INPUT_E; - if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) - return ASN_PARSE_E; - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - /* Get the responseBytes SEQUENCE */ - if (GetSequence(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - /* Check ObjectID for the resposeBytes */ - if (GetObjectId(source, &idx, &oid, size) < 0) - return ASN_PARSE_E; - if (oid != OCSP_BASIC_OID) - return ASN_PARSE_E; - if (source[idx++] != ASN_OCTET_STRING) - return ASN_PARSE_E; - - if (GetLength(source, &idx, &length, size) < 0) - return ASN_PARSE_E; - - if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0) - return ASN_PARSE_E; - - return 0; -} - - -static word32 SetOcspReqExtensions(word32 extSz, byte* output, - const byte* nonce, word32 nonceSz) -{ - static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x30, 0x01, 0x02 }; - byte seqArray[5][MAX_SEQ_SZ]; - word32 seqSz[5], totalSz; - - CYASSL_ENTER("SetOcspReqExtensions"); - - if (nonce == NULL || nonceSz == 0) return 0; - - seqArray[0][0] = ASN_OCTET_STRING; - seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]); - - seqArray[1][0] = ASN_OBJECT_ID; - seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]); - - totalSz = seqSz[0] + seqSz[1] + nonceSz + (word32)sizeof(NonceObjId); - - seqSz[2] = SetSequence(totalSz, seqArray[2]); - totalSz += seqSz[2]; - - seqSz[3] = SetSequence(totalSz, seqArray[3]); - totalSz += seqSz[3]; - - seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2); - seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]); - totalSz += seqSz[4]; - - if (totalSz < extSz) - { - totalSz = 0; - XMEMCPY(output + totalSz, seqArray[4], seqSz[4]); - totalSz += seqSz[4]; - XMEMCPY(output + totalSz, seqArray[3], seqSz[3]); - totalSz += seqSz[3]; - XMEMCPY(output + totalSz, seqArray[2], seqSz[2]); - totalSz += seqSz[2]; - XMEMCPY(output + totalSz, seqArray[1], seqSz[1]); - totalSz += seqSz[1]; - XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId)); - totalSz += (word32)sizeof(NonceObjId); - XMEMCPY(output + totalSz, seqArray[0], seqSz[0]); - totalSz += seqSz[0]; - XMEMCPY(output + totalSz, nonce, nonceSz); - totalSz += nonceSz; - } - - return totalSz; -} - - -int EncodeOcspRequest(OcspRequest* req) -{ - byte seqArray[5][MAX_SEQ_SZ]; - /* The ASN.1 of the OCSP Request is an onion of sequences */ - byte algoArray[MAX_ALGO_SZ]; - byte issuerArray[MAX_ENCODED_DIG_SZ]; - byte issuerKeyArray[MAX_ENCODED_DIG_SZ]; - byte snArray[MAX_SN_SZ]; - byte extArray[MAX_OCSP_EXT_SZ]; - byte* output = req->dest; - word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; - int i; - - CYASSL_ENTER("EncodeOcspRequest"); - - algoSz = SetAlgoID(SHAh, algoArray, hashType, 0); - - req->issuerHash = req->cert->issuerHash; - issuerSz = SetDigest(req->cert->issuerHash, SHA_SIZE, issuerArray); - - req->issuerKeyHash = req->cert->issuerKeyHash; - issuerKeySz = SetDigest(req->cert->issuerKeyHash, SHA_SIZE, issuerKeyArray); - - req->serial = req->cert->serial; - req->serialSz = req->cert->serialSz; - snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray); - - extSz = 0; - if (req->useNonce) { - RNG rng; - if (InitRng(&rng) != 0) { - CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); - } else { - if (RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0) - CYASSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce."); - else { - req->nonceSz = MAX_OCSP_NONCE_SZ; - extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, - req->nonce, req->nonceSz); - } - } - } - - totalSz = algoSz + issuerSz + issuerKeySz + snSz; - - for (i = 4; i >= 0; i--) { - seqSz[i] = SetSequence(totalSz, seqArray[i]); - totalSz += seqSz[i]; - if (i == 2) totalSz += extSz; - } - totalSz = 0; - for (i = 0; i < 5; i++) { - XMEMCPY(output + totalSz, seqArray[i], seqSz[i]); - totalSz += seqSz[i]; - } - XMEMCPY(output + totalSz, algoArray, algoSz); - totalSz += algoSz; - XMEMCPY(output + totalSz, issuerArray, issuerSz); - totalSz += issuerSz; - XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz); - totalSz += issuerKeySz; - XMEMCPY(output + totalSz, snArray, snSz); - totalSz += snSz; - if (extSz != 0) { - XMEMCPY(output + totalSz, extArray, extSz); - totalSz += extSz; - } - - return totalSz; -} - - -void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, - byte* dest, word32 destSz) -{ - CYASSL_ENTER("InitOcspRequest"); - - req->cert = cert; - req->useNonce = useNonce; - req->nonceSz = 0; - req->issuerHash = NULL; - req->issuerKeyHash = NULL; - req->serial = NULL; - req->dest = dest; - req->destSz = destSz; -} - - -int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp) -{ - int cmp; - - CYASSL_ENTER("CompareOcspReqResp"); - - if (req == NULL) - { - CYASSL_MSG("\tReq missing"); - return -1; - } - - if (resp == NULL) - { - CYASSL_MSG("\tResp missing"); - return 1; - } - - /* Nonces are not critical. The responder may not necessarily add - * the nonce to the response. */ - if (req->useNonce && resp->nonceSz != 0) { - cmp = req->nonceSz - resp->nonceSz; - if (cmp != 0) - { - CYASSL_MSG("\tnonceSz mismatch"); - return cmp; - } - - cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz); - if (cmp != 0) - { - CYASSL_MSG("\tnonce mismatch"); - return cmp; - } - } - - cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE); - if (cmp != 0) - { - CYASSL_MSG("\tissuerHash mismatch"); - return cmp; - } - - cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, SHA_DIGEST_SIZE); - if (cmp != 0) - { - CYASSL_MSG("\tissuerKeyHash mismatch"); - return cmp; - } - - cmp = req->serialSz - resp->status->serialSz; - if (cmp != 0) - { - CYASSL_MSG("\tserialSz mismatch"); - return cmp; - } - - cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz); - if (cmp != 0) - { - CYASSL_MSG("\tserial mismatch"); - return cmp; - } - - return 0; -} - -#endif - - -/* store SHA1 hash of NAME */ -CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, - int maxIdx) -{ - Sha sha; - int length; /* length of all distinguished names */ - int ret = 0; - word32 dummy; - - CYASSL_ENTER("GetNameHash"); - - if (source[*idx] == ASN_OBJECT_ID) { - CYASSL_MSG("Trying optional prefix..."); - - if (GetLength(source, idx, &length, maxIdx) < 0) - return ASN_PARSE_E; - - *idx += length; - CYASSL_MSG("Got optional prefix"); - } - - /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be - * calculated over the entire DER encoding of the Name field, including - * the tag and length. */ - dummy = *idx; - if (GetSequence(source, idx, &length, maxIdx) < 0) - return ASN_PARSE_E; - - ret = InitSha(&sha); - if (ret != 0) - return ret; - ShaUpdate(&sha, source + dummy, length + *idx - dummy); - ShaFinal(&sha, hash); - - *idx += length; - - return 0; -} - - -#ifdef HAVE_CRL - -/* initialize decoded CRL */ -void InitDecodedCRL(DecodedCRL* dcrl) -{ - CYASSL_MSG("InitDecodedCRL"); - - dcrl->certBegin = 0; - dcrl->sigIndex = 0; - dcrl->sigLength = 0; - dcrl->signatureOID = 0; - dcrl->certs = NULL; - dcrl->totalCerts = 0; -} - - -/* free decoded CRL resources */ -void FreeDecodedCRL(DecodedCRL* dcrl) -{ - RevokedCert* tmp = dcrl->certs; - - CYASSL_MSG("FreeDecodedCRL"); - - while(tmp) { - RevokedCert* next = tmp->next; - XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED); - tmp = next; - } -} - - -/* Get Revoked Cert list, 0 on success */ -static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl, - int maxIdx) -{ - int len; - word32 end; - byte b; - RevokedCert* rc; - - CYASSL_ENTER("GetRevoked"); - - if (GetSequence(buff, idx, &len, maxIdx) < 0) - return ASN_PARSE_E; - - end = *idx + len; - - /* get serial number */ - b = buff[*idx]; - *idx += 1; - - if (b != ASN_INTEGER) { - CYASSL_MSG("Expecting Integer"); - return ASN_PARSE_E; - } - - if (GetLength(buff, idx, &len, maxIdx) < 0) - return ASN_PARSE_E; - - if (len > EXTERNAL_SERIAL_SIZE) { - CYASSL_MSG("Serial Size too big"); - return ASN_PARSE_E; - } - - rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL); - if (rc == NULL) { - CYASSL_MSG("Alloc Revoked Cert failed"); - return MEMORY_E; - } - - XMEMCPY(rc->serialNumber, &buff[*idx], len); - rc->serialSz = len; - - /* add to list */ - rc->next = dcrl->certs; - dcrl->certs = rc; - dcrl->totalCerts++; - - *idx += len; - - /* get date */ - b = buff[*idx]; - *idx += 1; - - if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME) { - CYASSL_MSG("Expecting Date"); - return ASN_PARSE_E; - } - - if (GetLength(buff, idx, &len, maxIdx) < 0) - return ASN_PARSE_E; - - /* skip for now */ - *idx += len; - - if (*idx != end) /* skip extensions */ - *idx = end; - - return 0; -} - - -/* Get CRL Signature, 0 on success */ -static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl, - int maxIdx) -{ - int length; - byte b; - - CYASSL_ENTER("GetCRL_Signature"); - - b = source[*idx]; - *idx += 1; - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; - - if (GetLength(source, idx, &length, maxIdx) < 0) - return ASN_PARSE_E; - - dcrl->sigLength = length; - - b = source[*idx]; - *idx += 1; - if (b != 0x00) - return ASN_EXPECT_0_E; - - dcrl->sigLength--; - dcrl->signature = (byte*)&source[*idx]; - - *idx += dcrl->sigLength; - - return 0; -} - - -/* prase crl buffer into decoded state, 0 on success */ -int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm) -{ - int version, len; - word32 oid, idx = 0; - Signer* ca = NULL; - - CYASSL_MSG("ParseCRL"); - - /* raw crl hash */ - /* hash here if needed for optimized comparisons - * Sha sha; - * InitSha(&sha); - * ShaUpdate(&sha, buff, sz); - * ShaFinal(&sha, dcrl->crlHash); */ - - if (GetSequence(buff, &idx, &len, sz) < 0) - return ASN_PARSE_E; - - dcrl->certBegin = idx; - - if (GetSequence(buff, &idx, &len, sz) < 0) - return ASN_PARSE_E; - dcrl->sigIndex = len + idx; - - /* may have version */ - if (buff[idx] == ASN_INTEGER) { - if (GetMyVersion(buff, &idx, &version) < 0) - return ASN_PARSE_E; - } - - if (GetAlgoId(buff, &idx, &oid, sz) < 0) - return ASN_PARSE_E; - - if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0) - return ASN_PARSE_E; - - if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0) - return ASN_PARSE_E; - - if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0) - return ASN_PARSE_E; - - if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) { - CYASSL_MSG("CRL after date is no longer valid"); - return ASN_AFTER_DATE_E; - } - - if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) { - if (GetSequence(buff, &idx, &len, sz) < 0) - return ASN_PARSE_E; - - len += idx; - - while (idx < (word32)len) { - if (GetRevoked(buff, &idx, dcrl, sz) < 0) - return ASN_PARSE_E; - } - } - - if (idx != dcrl->sigIndex) - idx = dcrl->sigIndex; /* skip extensions */ - - if (GetAlgoId(buff, &idx, &dcrl->signatureOID, sz) < 0) - return ASN_PARSE_E; - - if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0) - return ASN_PARSE_E; - - /* openssl doesn't add skid by default for CRLs cause firefox chokes - we're not assuming it's available yet */ - #if !defined(NO_SKID) && defined(CRL_SKID_READY) - if (dcrl->extAuthKeyIdSet) - ca = GetCA(cm, dcrl->extAuthKeyId); - if (ca == NULL) - ca = GetCAByName(cm, dcrl->issuerHash); - #else /* NO_SKID */ - ca = GetCA(cm, dcrl->issuerHash); - #endif /* NO_SKID */ - CYASSL_MSG("About to verify CRL signature"); - - if (ca) { - CYASSL_MSG("Found CRL issuer CA"); - /* try to confirm/verify signature */ - #ifndef IGNORE_KEY_EXTENSIONS - if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) { - CYASSL_MSG("CA cannot sign CRLs"); - return ASN_CRL_NO_SIGNER_E; - } - #endif /* IGNORE_KEY_EXTENSIONS */ - if (!ConfirmSignature(buff + dcrl->certBegin, - dcrl->sigIndex - dcrl->certBegin, - ca->publicKey, ca->pubKeySize, ca->keyOID, - dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) { - CYASSL_MSG("CRL Confirm signature failed"); - return ASN_CRL_CONFIRM_E; - } - } - else { - CYASSL_MSG("Did NOT find CRL issuer CA"); - return ASN_CRL_NO_SIGNER_E; - } - - return 0; -} - -#endif /* HAVE_CRL */ -#endif - -#ifdef CYASSL_SEP - - - -#endif /* CYASSL_SEP */ - diff --git a/ctaocrypt/src/blake2b.c b/ctaocrypt/src/blake2b.c deleted file mode 100644 index ef208b7d2..000000000 --- a/ctaocrypt/src/blake2b.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -/* blake2b.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef HAVE_BLAKE2 - -#include -#include - - -static const word64 blake2b_IV[8] = -{ - 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL -}; - -static const byte blake2b_sigma[12][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } -}; - - -static INLINE int blake2b_set_lastnode( blake2b_state *S ) -{ - S->f[1] = ~0ULL; - return 0; -} - -/* Some helper functions, not necessarily useful */ -static INLINE int blake2b_set_lastblock( blake2b_state *S ) -{ - if( S->last_node ) blake2b_set_lastnode( S ); - - S->f[0] = ~0ULL; - return 0; -} - -static INLINE int blake2b_increment_counter( blake2b_state *S, const word64 - inc ) -{ - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); - return 0; -} - -static INLINE int blake2b_init0( blake2b_state *S ) -{ - int i; - XMEMSET( S, 0, sizeof( blake2b_state ) ); - - for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; - - return 0; -} - -/* init xors IV with input parameter block */ -int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ - word32 i; - blake2b_init0( S ); - byte *p = ( byte * )( P ); - - /* IV XOR ParamBlock */ - for( i = 0; i < 8; ++i ) - S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); - - return 0; -} - - - -int blake2b_init( blake2b_state *S, const byte outlen ) -{ - blake2b_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - P->digest_length = outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store64( &P->node_offset, 0 ); - P->node_depth = 0; - P->inner_length = 0; - XMEMSET( P->reserved, 0, sizeof( P->reserved ) ); - XMEMSET( P->salt, 0, sizeof( P->salt ) ); - XMEMSET( P->personal, 0, sizeof( P->personal ) ); - return blake2b_init_param( S, P ); -} - - -int blake2b_init_key( blake2b_state *S, const byte outlen, const void *key, - const byte keylen ) -{ - blake2b_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store64( &P->node_offset, 0 ); - P->node_depth = 0; - P->inner_length = 0; - XMEMSET( P->reserved, 0, sizeof( P->reserved ) ); - XMEMSET( P->salt, 0, sizeof( P->salt ) ); - XMEMSET( P->personal, 0, sizeof( P->personal ) ); - - if( blake2b_init_param( S, P ) < 0 ) return -1; - - { -#ifdef CYASSL_SMALL_STACK - byte* block; - - block = (byte*)XMALLOC(BLAKE2B_BLOCKBYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER); - - if ( block == NULL ) return -1; -#else - byte block[BLAKE2B_BLOCKBYTES]; -#endif - - XMEMSET( block, 0, BLAKE2B_BLOCKBYTES ); - XMEMCPY( block, key, keylen ); - blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from */ - /* memory */ - -#ifdef CYASSL_SMALL_STACK - XFREE(block, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - } - return 0; -} - -static int blake2b_compress( blake2b_state *S, - const byte block[BLAKE2B_BLOCKBYTES] ) -{ - int i; - -#ifdef CYASSL_SMALL_STACK - word64* m; - word64* v; - - m = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); - - if ( m == NULL ) return -1; - - v = (word64*)XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER); - - if ( v == NULL ) - { - XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return -1; - } -#else - word64 m[16]; - word64 v[16]; -#endif - - for( i = 0; i < 16; ++i ) - m[i] = load64( block + i * sizeof( m[i] ) ); - - for( i = 0; i < 8; ++i ) - v[i] = S->h[i]; - - v[ 8] = blake2b_IV[0]; - v[ 9] = blake2b_IV[1]; - v[10] = blake2b_IV[2]; - v[11] = blake2b_IV[3]; - v[12] = S->t[0] ^ blake2b_IV[4]; - v[13] = S->t[1] ^ blake2b_IV[5]; - v[14] = S->f[0] ^ blake2b_IV[6]; - v[15] = S->f[1] ^ blake2b_IV[7]; -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2*i+0]]; \ - d = rotr64(d ^ a, 32); \ - c = c + d; \ - b = rotr64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2*i+1]]; \ - d = rotr64(d ^ a, 16); \ - c = c + d; \ - b = rotr64(b ^ c, 63); \ - } while(0) -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - ROUND( 10 ); - ROUND( 11 ); - - for( i = 0; i < 8; ++i ) - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - -#undef G -#undef ROUND - -#ifdef CYASSL_SMALL_STACK - XFREE(m, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return 0; -} - -/* inlen now in bytes */ -int blake2b_update( blake2b_state *S, const byte *in, word64 inlen ) -{ - while( inlen > 0 ) - { - word64 left = S->buflen; - word64 fill = 2 * BLAKE2B_BLOCKBYTES - left; - - if( inlen > fill ) - { - XMEMCPY( S->buf + left, in, (cyassl_word)fill ); /* Fill buffer */ - S->buflen += fill; - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - - if ( blake2b_compress( S, S->buf ) < 0 ) return -1; /* Compress */ - - XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); - /* Shift buffer left */ - S->buflen -= BLAKE2B_BLOCKBYTES; - in += fill; - inlen -= fill; - } - else /* inlen <= fill */ - { - XMEMCPY( S->buf + left, in, (cyassl_word)inlen ); - S->buflen += inlen; /* Be lazy, do not compress */ - in += inlen; - inlen -= inlen; - } - } - - return 0; -} - -/* Is this correct? */ -int blake2b_final( blake2b_state *S, byte *out, byte outlen ) -{ - byte buffer[BLAKE2B_OUTBYTES]; - int i; - - if( S->buflen > BLAKE2B_BLOCKBYTES ) - { - blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - - if ( blake2b_compress( S, S->buf ) < 0 ) return -1; - - S->buflen -= BLAKE2B_BLOCKBYTES; - XMEMCPY( S->buf, S->buf + BLAKE2B_BLOCKBYTES, (cyassl_word)S->buflen ); - } - - blake2b_increment_counter( S, S->buflen ); - blake2b_set_lastblock( S ); - XMEMSET( S->buf + S->buflen, 0, (cyassl_word)(2 * BLAKE2B_BLOCKBYTES - S->buflen) ); - /* Padding */ - if ( blake2b_compress( S, S->buf ) < 0 ) return -1; - - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - - XMEMCPY( out, buffer, outlen ); - return 0; -} - -/* inlen, at least, should be word64. Others can be size_t. */ -int blake2b( byte *out, const void *in, const void *key, const byte outlen, - const word64 inlen, byte keylen ) -{ - blake2b_state S[1]; - - /* Verify parameters */ - if ( NULL == in ) return -1; - - if ( NULL == out ) return -1; - - if( NULL == key ) keylen = 0; - - if( keylen > 0 ) - { - if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; - } - else - { - if( blake2b_init( S, outlen ) < 0 ) return -1; - } - - if ( blake2b_update( S, ( byte * )in, inlen ) < 0) return -1; - - return blake2b_final( S, out, outlen ); -} - -#if defined(BLAKE2B_SELFTEST) -#include -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - byte key[BLAKE2B_KEYBYTES]; - byte buf[KAT_LENGTH]; - - for( word32 i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( byte )i; - - for( word32 i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( byte )i; - - for( word32 i = 0; i < KAT_LENGTH; ++i ) - { - byte hash[BLAKE2B_OUTBYTES]; - if ( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 ) - { - puts( "error" ); - return -1; - } - - if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} -#endif - - -/* CTaoCrypt API */ - -/* Init Blake2b digest, track size incase final doesn't want to "remember" */ -int InitBlake2b(Blake2b* b2b, word32 digestSz) -{ - b2b->digestSz = digestSz; - - return blake2b_init(b2b->S, (byte)digestSz); -} - - -/* Blake2b Update */ -int Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz) -{ - return blake2b_update(b2b->S, data, sz); -} - - -/* Blake2b Final, if pass in zero size we use init digestSz */ -int Blake2bFinal(Blake2b* b2b, byte* final, word32 requestSz) -{ - word32 sz = requestSz ? requestSz : b2b->digestSz; - - return blake2b_final(b2b->S, final, (byte)sz); -} - - -/* end CTaoCrypt API */ - -#endif /* HAVE_BLAKE2 */ - diff --git a/ctaocrypt/src/coding.c b/ctaocrypt/src/coding.c deleted file mode 100644 index 1d0acd52c..000000000 --- a/ctaocrypt/src/coding.c +++ /dev/null @@ -1,399 +0,0 @@ -/* coding.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifndef NO_CODING - -#include -#include -#include - - -enum { - BAD = 0xFF, /* invalid encoding */ - PAD = '=', - PEM_LINE_SZ = 64 -}; - - -static -const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - BAD, BAD, BAD, BAD, BAD, BAD, BAD, - 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, - BAD, BAD, BAD, BAD, BAD, BAD, - 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 - }; - - -int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) -{ - word32 i = 0; - word32 j = 0; - word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ ); - const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1; - - plainSz = (plainSz * 3 + 3) / 4; - if (plainSz > *outLen) return BAD_FUNC_ARG; - - while (inLen > 3) { - byte b1, b2, b3; - byte e1 = in[j++]; - byte e2 = in[j++]; - byte e3 = in[j++]; - byte e4 = in[j++]; - - int pad3 = 0; - int pad4 = 0; - - if (e1 == 0) /* end file 0's */ - break; - if (e3 == PAD) - pad3 = 1; - if (e4 == PAD) - pad4 = 1; - - if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) { - CYASSL_MSG("Bad Base64 Decode data, too small"); - return ASN_INPUT_E; - } - - if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) { - CYASSL_MSG("Bad Base64 Decode data, too big"); - return ASN_INPUT_E; - } - - e1 = base64Decode[e1 - 0x2B]; - e2 = base64Decode[e2 - 0x2B]; - e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B]; - e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B]; - - b1 = (byte)((e1 << 2) | (e2 >> 4)); - b2 = (byte)(((e2 & 0xF) << 4) | (e3 >> 2)); - b3 = (byte)(((e3 & 0x3) << 6) | e4); - - out[i++] = b1; - if (!pad3) - out[i++] = b2; - if (!pad4) - out[i++] = b3; - else - break; - - inLen -= 4; - if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) { - byte endLine = in[j++]; - inLen--; - while (inLen && endLine == ' ') { /* allow trailing whitespace */ - endLine = in[j++]; - inLen--; - } - if (endLine == '\r') { - if (inLen) { - endLine = in[j++]; - inLen--; - } - } - if (endLine != '\n') { - CYASSL_MSG("Bad end of line in Base64 Decode"); - return ASN_INPUT_E; - } - } - } - *outLen = i; - - return 0; -} - - -#if defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) - -static -const byte base64Encode[] = { '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', - '+', '/' - }; - - -/* make sure *i (idx) won't exceed max, store and possibly escape to out, - * raw means use e w/o decode, 0 on success */ -static int CEscape(int escaped, byte e, byte* out, word32* i, word32 max, - int raw) -{ - int doEscape = 0; - word32 needed = 1; - word32 idx = *i; - - byte basic; - byte plus = 0; - byte equals = 0; - byte newline = 0; - - if (raw) - basic = e; - else - basic = base64Encode[e]; - - /* check whether to escape */ - if (escaped) { - switch ((char)basic) { - case '+' : - plus = 1; - doEscape = 1; - needed += 2; - break; - case '=' : - equals = 1; - doEscape = 1; - needed += 2; - break; - case '\n' : - newline = 1; - doEscape = 1; - needed += 2; - break; - default: - /* do nothing */ - break; - } - } - - /* check size */ - if ( (idx+needed) > max) { - CYASSL_MSG("Escape buffer max too small"); - return BUFFER_E; - } - - /* store it */ - if (doEscape == 0) { - out[idx++] = basic; - } - else { - out[idx++] = '%'; /* start escape */ - - if (plus) { - out[idx++] = '2'; - out[idx++] = 'B'; - } - else if (equals) { - out[idx++] = '3'; - out[idx++] = 'D'; - } - else if (newline) { - out[idx++] = '0'; - out[idx++] = 'A'; - } - - } - *i = idx; - - return 0; -} - - -/* internal worker, handles both escaped and normal line endings */ -static int DoBase64_Encode(const byte* in, word32 inLen, byte* out, - word32* outLen, int escaped) -{ - int ret = 0; - word32 i = 0, - j = 0, - n = 0; /* new line counter */ - - word32 outSz = (inLen + 3 - 1) / 3 * 4; - word32 addSz = (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */ - - if (escaped) - addSz *= 3; /* instead of just \n, we're doing %0A triplet */ - - outSz += addSz; - - /* if escaped we can't predetermine size for one pass encoding, but - * make sure we have enough if no escapes are in input */ - if (outSz > *outLen) return BAD_FUNC_ARG; - - while (inLen > 2) { - byte b1 = in[j++]; - byte b2 = in[j++]; - byte b3 = in[j++]; - - /* encoded idx */ - byte e1 = b1 >> 2; - byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4)); - byte e3 = (byte)(((b2 & 0xF) << 2) | (b3 >> 6)); - byte e4 = b3 & 0x3F; - - /* store */ - ret = CEscape(escaped, e1, out, &i, *outLen, 0); - if (ret != 0) break; - ret = CEscape(escaped, e2, out, &i, *outLen, 0); - if (ret != 0) break; - ret = CEscape(escaped, e3, out, &i, *outLen, 0); - if (ret != 0) break; - ret = CEscape(escaped, e4, out, &i, *outLen, 0); - if (ret != 0) break; - - inLen -= 3; - - if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) { - ret = CEscape(escaped, '\n', out, &i, *outLen, 1); - if (ret != 0) break; - } - } - - /* last integral */ - if (inLen && ret == 0) { - int twoBytes = (inLen == 2); - - byte b1 = in[j++]; - byte b2 = (twoBytes) ? in[j++] : 0; - - byte e1 = b1 >> 2; - byte e2 = (byte)(((b1 & 0x3) << 4) | (b2 >> 4)); - byte e3 = (byte)((b2 & 0xF) << 2); - - ret = CEscape(escaped, e1, out, &i, *outLen, 0); - if (ret == 0) - ret = CEscape(escaped, e2, out, &i, *outLen, 0); - if (ret == 0) { - /* third */ - if (twoBytes) - ret = CEscape(escaped, e3, out, &i, *outLen, 0); - else - ret = CEscape(escaped, '=', out, &i, *outLen, 1); - } - /* fourth always pad */ - if (ret == 0) - ret = CEscape(escaped, '=', out, &i, *outLen, 1); - } - - if (ret == 0) - ret = CEscape(escaped, '\n', out, &i, *outLen, 1); - - if (i != outSz && escaped == 0 && ret == 0) - return ASN_INPUT_E; - - *outLen = i; - return ret; -} - - -/* Base64 Encode, PEM style, with \n line endings */ -int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) -{ - return DoBase64_Encode(in, inLen, out, outLen, 0); -} - - -/* Base64 Encode, with %0A esacped line endings instead of \n */ -int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, word32* outLen) -{ - return DoBase64_Encode(in, inLen, out, outLen, 1); -} - - -#endif /* defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) */ - - -#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) - -static -const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - BAD, BAD, BAD, BAD, BAD, BAD, BAD, - 10, 11, 12, 13, 14, 15, /* upper case A-F */ - BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, - BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, - BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, - BAD, BAD, /* G - ` */ - 10, 11, 12, 13, 14, 15 /* lower case a-f */ - }; /* A starts at 0x41 not 0x3A */ - -int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) -{ - word32 inIdx = 0; - word32 outIdx = 0; - - if (inLen == 1 && *outLen && in) { - byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ - - /* sanity check */ - if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) - return ASN_INPUT_E; - - b = hexDecode[b]; - - if (b == BAD) - return ASN_INPUT_E; - - out[outIdx++] = b; - - *outLen = outIdx; - return 0; - } - - if (inLen % 2) - return BAD_FUNC_ARG; - - if (*outLen < (inLen / 2)) - return BAD_FUNC_ARG; - - while (inLen) { - byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ - byte b2 = in[inIdx++] - 0x30; - - /* sanity checks */ - if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) - return ASN_INPUT_E; - if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0])) - return ASN_INPUT_E; - - b = hexDecode[b]; - b2 = hexDecode[b2]; - - if (b == BAD || b2 == BAD) - return ASN_INPUT_E; - - out[outIdx++] = (byte)((b << 4) | b2); - inLen -= 2; - } - - *outLen = outIdx; - return 0; -} - - -#endif /* (OPENSSL_EXTRA) || (HAVE_WEBSERVER) || (HAVE_FIPS) */ - -#endif /* NO_CODING */ diff --git a/ctaocrypt/src/compress.c b/ctaocrypt/src/compress.c deleted file mode 100644 index 0845bf40d..000000000 --- a/ctaocrypt/src/compress.c +++ /dev/null @@ -1,169 +0,0 @@ -/* compress.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef HAVE_LIBZ - - -#include -#include -#include -#ifdef NO_INLINE - #include -#else - #include -#endif - -#include - - -/* alloc user allocs to work with zlib */ -static void* myAlloc(void* opaque, unsigned int item, unsigned int size) -{ - (void)opaque; - return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ); -} - - -static void myFree(void* opaque, void* memory) -{ - (void)opaque; - XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ); -} - - -#ifdef HAVE_MCAPI - #define DEFLATE_DEFAULT_WINDOWBITS 11 - #define DEFLATE_DEFAULT_MEMLEVEL 1 -#else - #define DEFLATE_DEFAULT_WINDOWBITS 15 - #define DEFLATE_DEFAULT_MEMLEVEL 8 -#endif - - -int Compress(byte* out, word32 outSz, const byte* in, word32 inSz, word32 flags) -/* - * out - pointer to destination buffer - * outSz - size of destination buffer - * in - pointer to source buffer to compress - * inSz - size of source to compress - * flags - flags to control how compress operates - * - * return: - * negative - error code - * positive - bytes stored in out buffer - * - * Note, the output buffer still needs to be larger than the input buffer. - * The right chunk of data won't compress at all, and the lookup table will - * add to the size of the output. The libz code says the compressed - * buffer should be srcSz + 0.1% + 12. - */ -{ - z_stream stream; - int result = 0; - - stream.next_in = (Bytef*)in; - stream.avail_in = (uInt)inSz; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != inSz) return COMPRESS_INIT_E; -#endif - stream.next_out = out; - stream.avail_out = (uInt)outSz; - if ((uLong)stream.avail_out != outSz) return COMPRESS_INIT_E; - - stream.zalloc = (alloc_func)myAlloc; - stream.zfree = (free_func)myFree; - stream.opaque = (voidpf)0; - - if (deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, - DEFLATE_DEFAULT_WINDOWBITS, DEFLATE_DEFAULT_MEMLEVEL, - flags ? Z_FIXED : Z_DEFAULT_STRATEGY) != Z_OK) - return COMPRESS_INIT_E; - - if (deflate(&stream, Z_FINISH) != Z_STREAM_END) { - deflateEnd(&stream); - return COMPRESS_E; - } - - result = (int)stream.total_out; - - if (deflateEnd(&stream) != Z_OK) - result = COMPRESS_E; - - return result; -} - - -int DeCompress(byte* out, word32 outSz, const byte* in, word32 inSz) -/* - * out - pointer to destination buffer - * outSz - size of destination buffer - * in - pointer to source buffer to compress - * inSz - size of source to compress - * flags - flags to control how compress operates - * - * return: - * negative - error code - * positive - bytes stored in out buffer - */ -{ - z_stream stream; - int result = 0; - - stream.next_in = (Bytef*)in; - stream.avail_in = (uInt)inSz; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != inSz) return DECOMPRESS_INIT_E; - - stream.next_out = out; - stream.avail_out = (uInt)outSz; - if ((uLong)stream.avail_out != outSz) return DECOMPRESS_INIT_E; - - stream.zalloc = (alloc_func)myAlloc; - stream.zfree = (free_func)myFree; - stream.opaque = (voidpf)0; - - if (inflateInit2(&stream, DEFLATE_DEFAULT_WINDOWBITS) != Z_OK) - return DECOMPRESS_INIT_E; - - if (inflate(&stream, Z_FINISH) != Z_STREAM_END) { - inflateEnd(&stream); - return DECOMPRESS_E; - } - - result = (int)stream.total_out; - - if (inflateEnd(&stream) != Z_OK) - result = DECOMPRESS_E; - - return result; -} - - -#endif /* HAVE_LIBZ */ - diff --git a/ctaocrypt/src/include.am b/ctaocrypt/src/include.am deleted file mode 100644 index 6664dab22..000000000 --- a/ctaocrypt/src/include.am +++ /dev/null @@ -1,40 +0,0 @@ -# vim:ft=automake -# All paths should be given relative to the root - -EXTRA_DIST += ctaocrypt/src/misc.c -EXTRA_DIST += ctaocrypt/src/asm.c -EXTRA_DIST += ctaocrypt/src/aes_asm.asm - -EXTRA_DIST += \ - ctaocrypt/src/ecc_fp.c \ - ctaocrypt/src/fp_mont_small.i \ - ctaocrypt/src/fp_mul_comba_12.i \ - ctaocrypt/src/fp_mul_comba_17.i \ - ctaocrypt/src/fp_mul_comba_20.i \ - ctaocrypt/src/fp_mul_comba_24.i \ - ctaocrypt/src/fp_mul_comba_28.i \ - ctaocrypt/src/fp_mul_comba_32.i \ - ctaocrypt/src/fp_mul_comba_3.i \ - ctaocrypt/src/fp_mul_comba_48.i \ - ctaocrypt/src/fp_mul_comba_4.i \ - ctaocrypt/src/fp_mul_comba_64.i \ - ctaocrypt/src/fp_mul_comba_6.i \ - ctaocrypt/src/fp_mul_comba_7.i \ - ctaocrypt/src/fp_mul_comba_8.i \ - ctaocrypt/src/fp_mul_comba_9.i \ - ctaocrypt/src/fp_mul_comba_small_set.i \ - ctaocrypt/src/fp_sqr_comba_12.i \ - ctaocrypt/src/fp_sqr_comba_17.i \ - ctaocrypt/src/fp_sqr_comba_20.i \ - ctaocrypt/src/fp_sqr_comba_24.i \ - ctaocrypt/src/fp_sqr_comba_28.i \ - ctaocrypt/src/fp_sqr_comba_32.i \ - ctaocrypt/src/fp_sqr_comba_3.i \ - ctaocrypt/src/fp_sqr_comba_48.i \ - ctaocrypt/src/fp_sqr_comba_4.i \ - ctaocrypt/src/fp_sqr_comba_64.i \ - ctaocrypt/src/fp_sqr_comba_6.i \ - ctaocrypt/src/fp_sqr_comba_7.i \ - ctaocrypt/src/fp_sqr_comba_8.i \ - ctaocrypt/src/fp_sqr_comba_9.i \ - ctaocrypt/src/fp_sqr_comba_small_set.i diff --git a/ctaocrypt/src/integer.c b/ctaocrypt/src/integer.c deleted file mode 100644 index b5618eeac..000000000 --- a/ctaocrypt/src/integer.c +++ /dev/null @@ -1,4492 +0,0 @@ -/* integer.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - - -/* - * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca, - * http://math.libtomcrypt.com - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set USE_FAST_MATH there */ -#include - -#ifndef NO_BIG_INT - -#ifndef USE_FAST_MATH - -#include - -#ifndef NO_CYASSL_SMALL_STACK - #ifndef CYASSL_SMALL_STACK - #define CYASSL_SMALL_STACK - #endif -#endif - -static void bn_reverse (unsigned char *s, int len); - -/* math settings check */ -word32 CheckRunTimeSettings(void) -{ - return CTC_SETTINGS; -} - - -/* handle up to 6 inits */ -int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, - mp_int* f) -{ - int res = MP_OKAY; - - if (a && ((res = mp_init(a)) != MP_OKAY)) - return res; - - if (b && ((res = mp_init(b)) != MP_OKAY)) { - mp_clear(a); - return res; - } - - if (c && ((res = mp_init(c)) != MP_OKAY)) { - mp_clear(a); mp_clear(b); - return res; - } - - if (d && ((res = mp_init(d)) != MP_OKAY)) { - mp_clear(a); mp_clear(b); mp_clear(c); - return res; - } - - if (e && ((res = mp_init(e)) != MP_OKAY)) { - mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); - return res; - } - - if (f && ((res = mp_init(f)) != MP_OKAY)) { - mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e); - return res; - } - - return res; -} - - -/* init a new mp_int */ -int mp_init (mp_int * a) -{ - int i; - - /* allocate memory required and clear it */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC, 0, - DYNAMIC_TYPE_BIGINT); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; -} - - -/* clear one (frees) */ -void -mp_clear (mp_int * a) -{ - int i; - - if (a == NULL) - return; - - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - for (i = 0; i < a->used; i++) { - a->dp[i] = 0; - } - - /* free ram */ - XFREE(a->dp, 0, DYNAMIC_TYPE_BIGINT); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } -} - - -/* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) -{ - int size = mp_count_bits (a); - return (size / 8 + ((size & 7) != 0 ? 1 : 0)); -} - - -/* returns the number of bits in an int */ -int -mp_count_bits (mp_int * a) -{ - int r; - mp_digit q; - - /* shortcut */ - if (a->used == 0) { - return 0; - } - - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { - ++r; - q >>= ((mp_digit) 1); - } - return r; -} - - -int mp_leading_bit (mp_int * a) -{ - int bit = 0; - mp_int t; - - if (mp_init_copy(&t, a) != MP_OKAY) - return 0; - - while (mp_iszero(&t) == 0) { -#ifndef MP_8BIT - bit = (t.dp[0] & 0x80) != 0; -#else - bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0; -#endif - if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY) - break; - } - mp_clear(&t); - return bit; -} - - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin (mp_int * a, unsigned char *b) -{ - int x, res; - mp_int t; - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - x = 0; - while (mp_iszero (&t) == 0) { -#ifndef MP_8BIT - b[x++] = (unsigned char) (t.dp[0] & 255); -#else - b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); -#endif - if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - bn_reverse (b, x); - mp_clear (&t); - return MP_OKAY; -} - - -/* creates "a" then copies b into it */ -int mp_init_copy (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_init (a)) != MP_OKAY) { - return res; - } - return mp_copy (b, a); -} - - -/* copy, b = a */ -int -mp_copy (mp_int * a, mp_int * b) -{ - int res, n; - - /* if dst == src do nothing */ - if (a == b) { - return MP_OKAY; - } - - /* grow dest */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - /* zero b and copy the parameters over */ - { - register mp_digit *tmpa, *tmpb; - - /* pointer aliases */ - - /* source */ - tmpa = a->dp; - - /* destination */ - tmpb = b->dp; - - /* copy all the digits */ - for (n = 0; n < a->used; n++) { - *tmpb++ = *tmpa++; - } - - /* clear high digits */ - for (; n < b->used; n++) { - *tmpb++ = 0; - } - } - - /* copy used count and sign */ - b->used = a->used; - b->sign = a->sign; - return MP_OKAY; -} - - -/* grow as required */ -int mp_grow (mp_int * a, int size) -{ - int i; - mp_digit *tmp; - - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size, 0, - DYNAMIC_TYPE_BIGINT); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } - - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; -} - - -/* reverse an array, used for radix code */ -void -bn_reverse (unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} - - -/* shift right by a certain bit count (store quotient in c, optional - remainder in d) */ -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) -{ - int D, res; - mp_int t; - - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (b % DIGIT_BIT); - if (D != 0) { - mp_rshb(c, D); - } - mp_clamp (c); - if (d != NULL) { - mp_exch (&t, d); - } - mp_clear (&t); - return MP_OKAY; -} - - -/* set to zero */ -void mp_zero (mp_int * a) -{ - int n; - mp_digit *tmp; - - a->sign = MP_ZPOS; - a->used = 0; - - tmp = a->dp; - for (n = 0; n < a->alloc; n++) { - *tmp++ = 0; - } -} - - -/* trim unused digits - * - * This is used to ensure that leading zero digits are - * trimed and the leading "used" digit will be non-zero - * Typically very fast. Also fixes the sign if there - * are no more leading digits - */ -void -mp_clamp (mp_int * a) -{ - /* decrease used while the most significant digit is - * zero. - */ - while (a->used > 0 && a->dp[a->used - 1] == 0) { - --(a->used); - } - - /* reset the sign flag if used == 0 */ - if (a->used == 0) { - a->sign = MP_ZPOS; - } -} - - -/* swap the elements of two integers, for cases where you can't simply swap the - * mp_int pointers around - */ -void -mp_exch (mp_int * a, mp_int * b) -{ - mp_int t; - - t = *a; - *a = *b; - *b = t; -} - - -/* shift right a certain number of bits */ -void mp_rshb (mp_int *c, int x) -{ - register mp_digit *tmpc, mask, shift; - mp_digit r, rr; - mp_digit D = x; - - /* mask */ - mask = (((mp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } -} - - -/* shift right a certain amount of digits */ -void mp_rshd (mp_int * a, int b) -{ - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return; - } - - { - register mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } - - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; -} - - -/* calc a value mod 2**b */ -int -mp_mod_2d (mp_int * a, int b, mp_int * c) -{ - int x, res; - - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } - - /* if the modulus is larger than the value than return */ - if (b >= (int) (a->used * DIGIT_BIT)) { - res = mp_copy (a, c); - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) << - (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); - mp_clamp (c); - return MP_OKAY; -} - - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* make sure there are at least two digits */ - if (a->alloc < 2) { - if ((res = mp_grow(a, 2)) != MP_OKAY) { - return res; - } - } - - /* zero the int */ - mp_zero (a); - - /* read the bytes in */ - while (c-- > 0) { - if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { - return res; - } - -#ifndef MP_8BIT - a->dp[0] |= *b++; - a->used += 1; -#else - a->dp[0] = (*b & MP_MASK); - a->dp[1] |= ((*b++ >> 7U) & 1); - a->used += 2; -#endif - } - mp_clamp (a); - return MP_OKAY; -} - - -/* shift left by a certain bit count */ -int mp_mul_2d (mp_int * a, int b, mp_int * c) -{ - mp_digit d; - int res; - - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } - - if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { - if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } - - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - register mp_digit *tmpc, shift, mask, r, rr; - register int x; - - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; - - /* shift for msbs */ - shift = DIGIT_BIT - d; - - /* alias */ - tmpc = c->dp; - - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; - - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; - - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; -} - - -/* shift left a certain amount of digits */ -int mp_lshd (mp_int * a, int b) -{ - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < a->used + b) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - register mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = a->dp + a->used - 1 - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } - - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; -} - - -/* this is a shell function that calls either the normal or Montgomery - * exptmod functions. Originally the call to the montgomery code was - * embedded in the normal function but that wasted alot of stack space - * for nothing (since 99% of the time the Montgomery code would be called) - */ -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -{ - int dr; - - /* modulus P must be positive */ - if (P->sign == MP_NEG) { - return MP_VAL; - } - - /* if exponent X is negative we have to recurse */ - if (X->sign == MP_NEG) { -#ifdef BN_MP_INVMOD_C - mp_int tmpG, tmpX; - int err; - - /* first compute 1/G mod P */ - if ((err = mp_init(&tmpG)) != MP_OKAY) { - return err; - } - if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - - /* now get |X| */ - if ((err = mp_init(&tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - mp_clear(&tmpX); - return err; - } - - /* and now compute (1/G)**|X| instead of G**X [X < 0] */ - err = mp_exptmod(&tmpG, &tmpX, P, Y); - mp_clear(&tmpG); - mp_clear(&tmpX); - return err; -#else - /* no invmod */ - return MP_VAL; -#endif - } - -/* modified diminished radix reduction */ -#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && \ - defined(BN_S_MP_EXPTMOD_C) - if (mp_reduce_is_2k_l(P) == MP_YES) { - return s_mp_exptmod(G, X, P, Y, 1); - } -#endif - -#ifdef BN_MP_DR_IS_MODULUS_C - /* is it a DR modulus? */ - dr = mp_dr_is_modulus(P); -#else - /* default to no */ - dr = 0; -#endif - -#ifdef BN_MP_REDUCE_IS_2K_C - /* if not, is it a unrestricted DR modulus? */ - if (dr == 0) { - dr = mp_reduce_is_2k(P) << 1; - } -#endif - - /* if the modulus is odd or dr != 0 use the montgomery method */ -#ifdef BN_MP_EXPTMOD_FAST_C - if (mp_isodd (P) == 1 || dr != 0) { - return mp_exptmod_fast (G, X, P, Y, dr); - } else { -#endif -#ifdef BN_S_MP_EXPTMOD_C - /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y, 0); -#else - /* no exptmod for evens */ - return MP_VAL; -#endif -#ifdef BN_MP_EXPTMOD_FAST_C - } -#endif -} - - -/* b = |a| - * - * Simple function copies the input and fixes the sign to positive - */ -int -mp_abs (mp_int * a, mp_int * b) -{ - int res; - - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - /* force the sign of b to positive */ - b->sign = MP_ZPOS; - - return MP_OKAY; -} - - -/* hac 14.61, pp608 */ -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - -#ifdef BN_FAST_MP_INVMOD_C - /* if the modulus is odd we can use a faster routine instead */ - if (mp_isodd (b) == 1) { - return fast_mp_invmod (a, b, c); - } -#endif - -#ifdef BN_MP_INVMOD_SLOW_C - return mp_invmod_slow(a, b, c); -#endif -} - - -/* computes the modular inverse via binary extended euclidean algorithm, - * that is c = 1/a mod b - * - * Based on slow invmod except this is optimized for the case where b is - * odd as per HAC Note 14.64 on pp. 610 - */ -int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, B, D; - int res, neg; - - /* 2. [modified] b must be odd */ - if (mp_iseven (b) == 1) { - return MP_VAL; - } - - /* init all our temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D)) != MP_OKAY) { - return res; - } - - /* x == modulus, y == value to invert */ - if ((res = mp_copy (b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - - /* we need y = |a| */ - if ((res = mp_mod (a, b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if B is odd then */ - if (mp_isodd (&B) == 1) { - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* B = B/2 */ - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if D is odd then */ - if (mp_isodd (&D) == 1) { - /* D = (D-x)/2 */ - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* D = D/2 */ - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == MP_NEG) { - if ((res = mp_add (&D, b, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_exch (&D, c); - c->sign = neg; - res = MP_OKAY; - -LBL_ERR:mp_clear(&x); - mp_clear(&y); - mp_clear(&u); - mp_clear(&v); - mp_clear(&B); - mp_clear(&D); - return res; -} - - -/* hac 14.61, pp608 */ -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - - /* init temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, - &A, &B)) != MP_OKAY) { - return res; - } - - /* init rest of tmps temps */ - if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) { - return res; - } - - /* x = a, y = b */ - if ((res = mp_mod(a, b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 2. [modified] if x,y are both even then return an error! */ - if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { - res = MP_VAL; - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&A, 1); - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if A or B is odd then */ - if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { - /* A = (A+y)/2, B = (B-x)/2 */ - if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* A = A/2, B = B/2 */ - if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if C or D is odd then */ - if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { - /* C = (C+y)/2, D = (D-x)/2 */ - if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* C = C/2, D = D/2 */ - if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, A = A - C, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, C = C - A, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { - if ((res = mp_add(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* too big */ - while (mp_cmp_mag(&C, b) != MP_LT) { - if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* C is now the inverse */ - mp_exch (&C, c); - res = MP_OKAY; -LBL_ERR:mp_clear(&x); - mp_clear(&y); - mp_clear(&u); - mp_clear(&v); - mp_clear(&A); - mp_clear(&B); - mp_clear(&C); - mp_clear(&D); - return res; -} - - -/* compare maginitude of two ints (unsigned) */ -int mp_cmp_mag (mp_int * a, mp_int * b) -{ - int n; - mp_digit *tmpa, *tmpb; - - /* compare based on # of non-zero digits */ - if (a->used > b->used) { - return MP_GT; - } - - if (a->used < b->used) { - return MP_LT; - } - - /* alias for a */ - tmpa = a->dp + (a->used - 1); - - /* alias for b */ - tmpb = b->dp + (a->used - 1); - - /* compare based on digits */ - for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { - if (*tmpa > *tmpb) { - return MP_GT; - } - - if (*tmpa < *tmpb) { - return MP_LT; - } - } - return MP_EQ; -} - - -/* compare two ints (signed)*/ -int -mp_cmp (mp_int * a, mp_int * b) -{ - /* compare based on sign */ - if (a->sign != b->sign) { - if (a->sign == MP_NEG) { - return MP_LT; - } else { - return MP_GT; - } - } - - /* compare digits */ - if (a->sign == MP_NEG) { - /* if negative compare opposite direction */ - return mp_cmp_mag(b, a); - } else { - return mp_cmp_mag(a, b); - } -} - - -/* compare a digit */ -int mp_cmp_d(mp_int * a, mp_digit b) -{ - /* compare based on sign */ - if (a->sign == MP_NEG) { - return MP_LT; - } - - /* compare based on magnitude */ - if (a->used > 1) { - return MP_GT; - } - - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return MP_GT; - } else if (a->dp[0] < b) { - return MP_LT; - } else { - return MP_EQ; - } -} - - -/* set to a digit */ -void mp_set (mp_int * a, mp_digit b) -{ - mp_zero (a); - a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; -} - - -/* c = a mod b, 0 <= c < b */ -int -mp_mod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int t; - int res; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - if (t.sign != b->sign) { - res = mp_add (b, &t, c); - } else { - res = MP_OKAY; - mp_exch (&t, c); - } - - mp_clear (&t); - return res; -} - - -/* slower bit-bang division... also smaller */ -int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int ta, tb, tq, q; - int res, n, n2; - - /* is divisor zero ? */ - if (mp_iszero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, 0, 0)) != MP_OKAY) { - return res; - } - - - mp_set(&tq, 1); - n = mp_count_bits(a) - mp_count_bits(b); - if (((res = mp_abs(a, &ta)) != MP_OKAY) || - ((res = mp_abs(b, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { - goto LBL_ERR; - } - - while (n-- >= 0) { - if (mp_cmp(&tb, &ta) != MP_GT) { - if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { - goto LBL_ERR; - } - } - if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { - goto LBL_ERR; - } - } - - /* now q == quotient and ta == remainder */ - n = a->sign; - n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); - if (c != NULL) { - mp_exch(c, &q); - c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; - } - if (d != NULL) { - mp_exch(d, &ta); - d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; - } -LBL_ERR: - mp_clear(&ta); - mp_clear(&tb); - mp_clear(&tq); - mp_clear(&q); - return res; -} - - -/* b = a/2 */ -int mp_div_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; -} - - -/* high level addition (handles signs) */ -int mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; - - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (mp_cmp_mag (a, b) == MP_LT) { - c->sign = sb; - res = s_mp_sub (b, a, c); - } else { - c->sign = sa; - res = s_mp_sub (a, b, c); - } - } - return res; -} - - -/* low level addition, based on HAC pp.594, Algorithm 14.7 */ -int -s_mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int *x; - int olduse, res, min, max; - - /* find sizes, we let |a| <= |b| which means we have to sort - * them. "x" will point to the input with the most digits - */ - if (a->used > b->used) { - min = b->used; - max = a->used; - x = a; - } else { - min = a->used; - max = b->used; - x = b; - } - - /* init result */ - if (c->alloc < max + 1) { - if ((res = mp_grow (c, max + 1)) != MP_OKAY) { - return res; - } - } - - /* get old used digit count and set new one */ - olduse = c->used; - c->used = max + 1; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - - /* first input */ - tmpa = a->dp; - - /* second input */ - tmpb = b->dp; - - /* destination */ - tmpc = c->dp; - - /* zero the carry */ - u = 0; - for (i = 0; i < min; i++) { - /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ - *tmpc = *tmpa++ + *tmpb++ + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, that is in A+B - * if A or B has more digits add those in - */ - if (min != max) { - for (; i < max; i++) { - /* T[i] = X[i] + U */ - *tmpc = x->dp[i] + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - } - - /* add carry */ - *tmpc++ = u; - - /* clear digits above oldused */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - - -/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -int -s_mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int olduse, res, min, max; - - /* find sizes */ - min = b->used; - max = a->used; - - /* init result */ - if (c->alloc < max) { - if ((res = mp_grow (c, max)) != MP_OKAY) { - return res; - } - } - olduse = c->used; - c->used = max; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - tmpa = a->dp; - tmpb = b->dp; - tmpc = c->dp; - - /* set carry to zero */ - u = 0; - for (i = 0; i < min; i++) { - /* T[i] = A[i] - B[i] - U */ - *tmpc = *tmpa++ - *tmpb++ - u; - - /* U = carry bit of T[i] - * Note this saves performing an AND operation since - * if a carry does occur it will propagate all the way to the - * MSB. As a result a single shift is enough to get the carry - */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, e.g. if A has more digits than B */ - for (; i < max; i++) { - /* T[i] = A[i] - U */ - *tmpc = *tmpa++ - u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* clear digits above used (since we may not have grown result above) */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - - -/* high level subtraction (handles signs) */ -int -mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (mp_cmp_mag (a, b) != MP_LT) { - /* Copy the sign from the first */ - c->sign = sa; - /* The first has a larger or equal magnitude */ - res = s_mp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; - /* The second has a larger magnitude */ - res = s_mp_sub (b, a, c); - } - } - return res; -} - - -/* determines if reduce_2k_l can be used */ -int mp_reduce_is_2k_l(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - /* if more than half of the digits are -1 we're sold */ - for (iy = ix = 0; ix < a->used; ix++) { - if (a->dp[ix] == MP_MASK) { - ++iy; - } - } - return (iy >= (a->used/2)) ? MP_YES : MP_NO; - - } - return MP_NO; -} - - -/* determines if mp_reduce_2k can be used */ -int mp_reduce_is_2k(mp_int *a) -{ - int ix, iy, iw; - mp_digit iz; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - iy = mp_count_bits(a); - iz = 1; - iw = 1; - - /* Test every bit from the second digit up, must be 1 */ - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { - return MP_NO; - } - iz <<= 1; - if (iz > (mp_digit)MP_MASK) { - ++iw; - iz = 1; - } - } - } - return MP_YES; -} - - -/* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - /* must be of the form b**k - a [a <= b] so all - * but the first digit must be equal to -1 (mod b). - */ - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - - -/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 - * - * Uses a left-to-right k-ary sliding window to compute the modular - * exponentiation. - * The value of k changes based on the size of the exponent. - * - * Uses Montgomery or Diminished Radix reduction [whichever appropriate] - */ - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, - int redmode) -{ - mp_int M[TAB_SIZE], res; - mp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* use a pointer to the reduction algorithm. This allows us to use - * one of many reduction algorithms without modding the guts of - * the code with if statements everywhere. - */ - int (*redux)(mp_int*,mp_int*,mp_digit); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* determine and setup reduction code */ - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_SETUP_C - /* now setup montgomery */ - if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { - goto LBL_M; - } -#else - err = MP_VAL; - goto LBL_M; -#endif - - /* automatically pick the comba one if available (saves quite a few - calls/ifs) */ -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C - if (((P->used * 2 + 1) < MP_WARRAY) && - P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - redux = fast_mp_montgomery_reduce; - } else -#endif - { -#ifdef BN_MP_MONTGOMERY_REDUCE_C - /* use slower baseline Montgomery method */ - redux = mp_montgomery_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - } else if (redmode == 1) { -#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) - /* setup DR reduction for moduli of the form B**k - b */ - mp_dr_setup(P, &mp); - redux = mp_dr_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } else { -#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) - /* setup DR reduction for moduli of the form 2**k - b */ - if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { - goto LBL_M; - } - redux = mp_reduce_2k; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_M; - } - - /* create M table - * - - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - /* now we need R mod m */ - if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { - goto LBL_RES; - } -#else - err = MP_VAL; - goto LBL_RES; -#endif - - /* now set M[1] to G * R mod m */ - if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } else { - mp_set(&res, 1); - if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/ - if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { - goto LBL_RES; - } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[x], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (int)(buf >> (DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - if (redmode == 0) { - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - if ((err = redux(&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* swap res with Y */ - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} - - -/* setups the montgomery reduction stuff */ -int -mp_montgomery_setup (mp_int * n, mp_digit * rho) -{ - mp_digit x, b; - -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = n->dp[0]; - - if ((b & 1) == 0) { - return MP_VAL; - } - - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - b * x; /* here x*a==1 mod 2**8 */ -#if !defined(MP_8BIT) - x *= 2 - b * x; /* here x*a==1 mod 2**16 */ -#endif -#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) - x *= 2 - b * x; /* here x*a==1 mod 2**32 */ -#endif -#ifdef MP_64BIT - x *= 2 - b * x; /* here x*a==1 mod 2**64 */ -#endif - - /* rho = -1/m mod b */ - /* TAO, switched mp_word casts to mp_digit to shut up compiler */ - *rho = (((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK; - - return MP_OKAY; -} - - -/* computes xR**-1 == x (mod N) via Montgomery Reduction - * - * This is an optimized implementation of montgomery_reduce - * which uses the comba method to quickly calculate the columns of the - * reduction. - * - * Based on Algorithm 14.32 on pp.601 of HAC. -*/ -int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, olduse; -#ifdef CYASSL_SMALL_STACK - mp_word* W; /* uses dynamic memory and slower */ -#else - mp_word W[MP_WARRAY]; -#endif - - /* get old used count */ - olduse = x->used; - - /* grow a as required */ - if (x->alloc < n->used + 1) { - if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { - return res; - } - } - -#ifdef CYASSL_SMALL_STACK - W = (mp_word*)XMALLOC(sizeof(mp_word) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT); - if (W == NULL) - return MP_MEM; -#endif - - /* first we have to get the digits of the input into - * an array of double precision words W[...] - */ - { - register mp_word *_W; - register mp_digit *tmpx; - - /* alias for the W[] array */ - _W = W; - - /* alias for the digits of x*/ - tmpx = x->dp; - - /* copy the digits of a into W[0..a->used-1] */ - for (ix = 0; ix < x->used; ix++) { - *_W++ = *tmpx++; - } - - /* zero the high words of W[a->used..m->used*2] */ - for (; ix < n->used * 2 + 1; ix++) { - *_W++ = 0; - } - } - - /* now we proceed to zero successive digits - * from the least significant upwards - */ - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b - * - * We avoid a double precision multiplication (which isn't required) - * by casting the value down to a mp_digit. Note this requires - * that W[ix-1] have the carry cleared (see after the inner loop) - */ - register mp_digit mu; - mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); - - /* a = a + mu * m * b**i - * - * This is computed in place and on the fly. The multiplication - * by b**i is handled by offseting which columns the results - * are added to. - * - * Note the comba method normally doesn't handle carries in the - * inner loop In this case we fix the carry from the previous - * column since the Montgomery reduction requires digits of the - * result (so far) [see above] to work. This is - * handled by fixing up one carry after the inner loop. The - * carry fixups are done in order so after these loops the - * first m->used words of W[] have the carries fixed - */ - { - register int iy; - register mp_digit *tmpn; - register mp_word *_W; - - /* alias for the digits of the modulus */ - tmpn = n->dp; - - /* Alias for the columns set by an offset of ix */ - _W = W + ix; - - /* inner loop */ - for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); - } - } - - /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); - } - - /* now we have to propagate the carries and - * shift the words downward [all those least - * significant digits we zeroed]. - */ - { - register mp_digit *tmpx; - register mp_word *_W, *_W1; - - /* nox fix rest of carries */ - - /* alias for current word */ - _W1 = W + ix; - - /* alias for next word, where the carry goes */ - _W = W + ++ix; - - for (; ix <= n->used * 2 + 1; ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); - } - - /* copy out, A = A/b**n - * - * The result is A/b**n but instead of converting from an - * array of mp_word to mp_digit than calling mp_rshd - * we just copy them in the right order - */ - - /* alias for destination word */ - tmpx = x->dp; - - /* alias for shifted double precision result */ - _W = W + n->used; - - for (ix = 0; ix < n->used + 1; ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); - } - - /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits - */ - for (; ix < olduse; ix++) { - *tmpx++ = 0; - } - } - - /* set the max used and clamp */ - x->used = n->used + 1; - mp_clamp (x); - -#ifdef CYASSL_SMALL_STACK - XFREE(W, 0, DYNAMIC_TYPE_BIGINT); -#endif - - /* if A >= m then A = A - m */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - return MP_OKAY; -} - - -/* computes xR**-1 == x (mod N) via Montgomery Reduction */ -int -mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, digs; - mp_digit mu; - - /* can the fast reduction [comba] method be used? - * - * Note that unlike in mul you're safely allowed *less* - * than the available columns [255 per default] since carries - * are fixed up in the inner loop. - */ - digs = n->used * 2 + 1; - if ((digs < MP_WARRAY) && - n->used < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_mp_montgomery_reduce (x, n, rho); - } - - /* grow the input as required */ - if (x->alloc < digs) { - if ((res = mp_grow (x, digs)) != MP_OKAY) { - return res; - } - } - x->used = digs; - - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * rho mod b - * - * The value of rho must be precalculated via - * montgomery_setup() such that - * it equals -1/n0 mod b this allows the - * following inner loop to reduce the - * input one digit at a time - */ - mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); - - /* a = a + mu * m * b**i */ - { - register int iy; - register mp_digit *tmpn, *tmpx, u; - register mp_word r; - - /* alias for digits of the modulus */ - tmpn = n->dp; - - /* alias for the digits of x [the input] */ - tmpx = x->dp + ix; - - /* set the carry to zero */ - u = 0; - - /* Multiply and add in place */ - for (iy = 0; iy < n->used; iy++) { - /* compute product and sum */ - r = ((mp_word)mu) * ((mp_word)*tmpn++) + - ((mp_word) u) + ((mp_word) * tmpx); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); - } - /* At this point the ix'th digit of x should be zero */ - - - /* propagate carries upwards as required*/ - while (u) { - *tmpx += u; - u = *tmpx >> DIGIT_BIT; - *tmpx++ &= MP_MASK; - } - } - } - - /* at this point the n.used'th least - * significant digits of x are all zero - * which means we can shift x to the - * right by n.used digits and the - * residue is unchanged. - */ - - /* x = x/b**n.used */ - mp_clamp(x); - mp_rshd (x, n->used); - - /* if x >= n then x = x - n */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - - return MP_OKAY; -} - - -/* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - - -/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. - * - * Based on algorithm from the paper - * - * "Generating Efficient Primes for Discrete Log Cryptosystems" - * Chae Hoon Lim, Pil Joong Lee, - * POSTECH Information Research Laboratories - * - * The modulus must be of a special format [see manual] - * - * Has been modified to use algorithm 7.10 from the LTM book instead - * - * Input x must be in the range 0 <= x <= (n-1)**2 - */ -int -mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) -{ - int err, i, m; - mp_word r; - mp_digit mu, *tmpx1, *tmpx2; - - /* m = digits in modulus */ - m = n->used; - - /* ensure that "x" has at least 2m digits */ - if (x->alloc < m + m) { - if ((err = mp_grow (x, m + m)) != MP_OKAY) { - return err; - } - } - -/* top of loop, this is where the code resumes if - * another reduction pass is required. - */ -top: - /* aliases for digits */ - /* alias for lower half of x */ - tmpx1 = x->dp; - - /* alias for upper half of x, or x/B**m */ - tmpx2 = x->dp + m; - - /* set carry to zero */ - mu = 0; - - /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ - for (i = 0; i < m; i++) { - r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; - *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); - } - - /* set final carry */ - *tmpx1++ = mu; - - /* zero words above m */ - for (i = m + 1; i < x->used; i++) { - *tmpx1++ = 0; - } - - /* clamp, sub and return */ - mp_clamp (x); - - /* if x >= n then subtract and reduce again - * Each successive "recursion" makes the input smaller and smaller. - */ - if (mp_cmp_mag (x, n) != MP_LT) { - s_mp_sub(x, n, x); - goto top; - } - return MP_OKAY; -} - - -/* reduces a modulo n where n is of the form 2**p - d */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (d != 1) { - /* q = q * d */ - if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - - -/* determines the setup value */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} - - -/* computes a = 2**b - * - * Simple algorithm which zeroes the int, grows it then just sets one bit - * as required. - */ -int -mp_2expt (mp_int * a, int b) -{ - int res; - - /* zero a as per default */ - mp_zero (a); - - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - - /* set the used count of where the bit will go */ - a->used = b / DIGIT_BIT + 1; - - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} - - -/* multiply by a digit */ -int -mp_mul_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; - - /* make sure c is big enough to hold a*b */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* get the original destinations used count */ - olduse = c->used; - - /* set the sign */ - c->sign = a->sign; - - /* alias for a->dp [source] */ - tmpa = a->dp; - - /* alias for c->dp [dest] */ - tmpc = c->dp; - - /* zero carry */ - u = 0; - - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); - - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - - /* store final carry [if any] and increment ix offset */ - *tmpc++ = u; - ++ix; - - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } - - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); - - return MP_OKAY; -} - - -/* d = a * b (mod c) */ -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} - - -/* computes b = a*a */ -int -mp_sqr (mp_int * a, mp_int * b) -{ - int res; - - { -#ifdef BN_FAST_S_MP_SQR_C - /* can we use the fast comba multiplier? */ - if ((a->used * 2 + 1) < MP_WARRAY && - a->used < - (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { - res = fast_s_mp_sqr (a, b); - } else -#endif -#ifdef BN_S_MP_SQR_C - res = s_mp_sqr (a, b); -#else - res = MP_VAL; -#endif - } - b->sign = MP_ZPOS; - return res; -} - - -/* high level multiplication (handles sign) */ -int mp_mul (mp_int * a, mp_int * b, mp_int * c) -{ - int res, neg; - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - - { - /* can we use the fast multiplier? - * - * The fast multiplier can be used if the output will - * have less than MP_WARRAY digits and the number of - * digits won't affect carry propagation - */ - int digs = a->used + b->used + 1; - -#ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < MP_WARRAY) && - MIN(a->used, b->used) <= - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - res = fast_s_mp_mul_digs (a, b, c, digs); - } else -#endif -#ifdef BN_S_MP_MUL_DIGS_C - res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ -#else - res = MP_VAL; -#endif - - } - c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; -} - - -/* b = a*2 */ -int mp_mul_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* grow to accomodate result */ - if (b->alloc < a->used + 1) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; -} - - -/* divide by three (based on routine from MPI and the GMP manual) */ -int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) -{ - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } - - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - - -/* init an mp_init for a given size */ -int mp_init_size (mp_int * a, int size) -{ - int x; - - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size, 0, - DYNAMIC_TYPE_BIGINT); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; - - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; -} - - -/* the jist of squaring... - * you do like mult except the offset of the tmpx [one that - * starts closer to zero] can't equal the offset of tmpy. - * So basically you set up iy like before then you min it with - * (ty-tx) so that it never happens. You double all those - * you add in the inner loop - -After that loop you do the squares and add them in. -*/ - -int fast_s_mp_sqr (mp_int * a, mp_int * b) -{ - int olduse, res, pa, ix, iz; -#ifdef CYASSL_SMALL_STACK - mp_digit* W; /* uses dynamic memory and slower */ -#else - mp_digit W[MP_WARRAY]; -#endif - mp_digit *tmpx; - mp_word W1; - - /* grow the destination as required */ - pa = a->used + a->used; - if (b->alloc < pa) { - if ((res = mp_grow (b, pa)) != MP_OKAY) { - return res; - } - } - - if (pa > MP_WARRAY) - return MP_RANGE; /* TAO range check */ - -#ifdef CYASSL_SMALL_STACK - W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT); - if (W == NULL) - return MP_MEM; -#endif - - /* number of output digits to produce */ - W1 = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - mp_word _W; - mp_digit *tmpy; - - /* clear counter */ - _W = 0; - - /* get offsets into the two bignums */ - ty = MIN(a->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = a->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach at a rate of 2x - * and we have to round because odd cases need to be executed - */ - iy = MIN(iy, (ty-tx+1)>>1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* double the inner product and add carry */ - _W = _W + _W + W1; - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); - } - - /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); - - /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = b->used; - b->used = a->used+a->used; - - { - mp_digit *tmpb; - tmpb = b->dp; - for (ix = 0; ix < pa; ix++) { - *tmpb++ = W[ix] & MP_MASK; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpb++ = 0; - } - } - mp_clamp (b); - -#ifdef CYASSL_SMALL_STACK - XFREE(W, 0, DYNAMIC_TYPE_BIGINT); -#endif - - return MP_OKAY; -} - - -/* Fast (comba) multiplier - * - * This is the fast column-array [comba] multiplier. It is - * designed to compute the columns of the product first - * then handle the carries afterwards. This has the effect - * of making the nested loops that compute the columns very - * simple and schedulable on super-scalar processors. - * - * This has been modified to produce a variable number of - * digits of output so if say only a half-product is required - * you don't have to compute the upper half (a feature - * required for fast Barrett reduction). - * - * Based on Algorithm 14.12 on pp.595 of HAC. - * - */ -int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; -#ifdef CYASSL_SMALL_STACK - mp_digit* W; /* uses dynamic memory and slower */ -#else - mp_digit W[MP_WARRAY]; -#endif - register mp_word _W; - - /* grow the destination as required */ - if (c->alloc < digs) { - if ((res = mp_grow (c, digs)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = MIN(digs, a->used + b->used); - if (pa > MP_WARRAY) - return MP_RANGE; /* TAO range check */ - -#ifdef CYASSL_SMALL_STACK - W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT); - if (W == NULL) - return MP_MEM; -#endif - - /* clear the carry */ - _W = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty; - int iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - tmpc = c->dp; - for (ix = 0; ix < pa+1; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - -#ifdef CYASSL_SMALL_STACK - XFREE(W, 0, DYNAMIC_TYPE_BIGINT); -#endif - - return MP_OKAY; -} - - -/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -int s_mp_sqr (mp_int * a, mp_int * b) -{ - mp_int t; - int res, ix, iy, pa; - mp_word r; - mp_digit u, tmpx, *tmpt; - - pa = a->used; - if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { - return res; - } - - /* default used is maximum possible size */ - t.used = 2*pa + 1; - - for (ix = 0; ix < pa; ix++) { - /* first calculate the digit at 2*ix */ - /* calculate double precision result */ - r = ((mp_word) t.dp[2*ix]) + - ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); - - /* store lower part in result */ - t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* left hand side of A[ix] * A[iy] */ - tmpx = a->dp[ix]; - - /* alias for where to store the results */ - tmpt = t.dp + (2*ix + 1); - - for (iy = ix + 1; iy < pa; iy++) { - /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); - - /* now calculate the double precision result, note we use - * addition instead of *2 since it's easier to optimize - */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); - - /* store lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - } - - mp_clamp (&t); - mp_exch (&t, b); - mp_clear (&t); - return MP_OKAY; -} - - -/* multiplies |a| * |b| and only computes upto digs digits of result - * HAC pp. 595, Algorithm 14.12 Modified so you can control how - * many digits of output are created. - */ -int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ - if (((digs) < MP_WARRAY) && - MIN (a->used, b->used) < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_digs (a, b, c, digs); - } - - if ((res = mp_init_size (&t, digs)) != MP_OKAY) { - return res; - } - t.used = digs; - - /* compute the digits of the product directly */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* set the carry to zero */ - u = 0; - - /* limit ourselves to making digs digits of output */ - pb = MIN (b->used, digs - ix); - - /* setup some aliases */ - /* copy of the digit from a used within the nested loop */ - tmpx = a->dp[ix]; - - /* an alias for the destination shifted ix places */ - tmpt = t.dp + ix; - - /* an alias for the digits of b */ - tmpy = b->dp; - - /* compute the columns of the output and propagate the carry */ - for (iy = 0; iy < pb; iy++) { - /* compute the column as a mp_word */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry word from the result */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - /* set carry if it is placed below digs */ - if (ix + iy < digs) { - *tmpt = u; - } - } - - mp_clamp (&t); - mp_exch (&t, c); - - mp_clear (&t); - return MP_OKAY; -} - - -/* - * shifts with subtractions when the result is greater than b. - * - * The method is slightly modified to shift B unconditionally upto just under - * the leading bit of b. This saves alot of multiple precision shifting. - */ -int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) -{ - int x, bits, res; - - /* how many bits of last digit does b use */ - bits = mp_count_bits (b) % DIGIT_BIT; - - if (b->used > 1) { - if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { - return res; - } - } else { - mp_set(a, 1); - bits = 1; - } - - - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - if ((res = mp_mul_2 (a, a)) != MP_OKAY) { - return res; - } - if (mp_cmp_mag (a, b) != MP_LT) { - if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { - return res; - } - } - } - - return MP_OKAY; -} - - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res, mu; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int*,mp_int*,mp_int*); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* create mu, used for Barrett reduction */ - if ((err = mp_init (&mu)) != MP_OKAY) { - goto LBL_M; - } - - if (redmode == 0) { - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce; - } else { - if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce_2k_l; - } - - /* create M table - * - * The M table contains powers of the base, - * e.g. M[x] = G**x mod P - * - * The first half of the table is not - * computed though accept for M[0] and M[1] - */ - if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { - goto LBL_MU; - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { - goto LBL_MU; - } - - for (x = 0; x < (winsize - 1); x++) { - /* square it */ - if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))], - &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) { - goto LBL_MU; - } - - /* reduce modulo P */ - if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) - * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) - */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_MU; - } - if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_MU; - } - mp_set (&res, 1); - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits */ - if (digidx == -1) { - break; - } - /* read next digit and reset the bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (int)(buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_MU:mp_clear (&mu); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} - - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -int mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); -} - - -/* reduces x mod m, assumes 0 < x < m**2, mu is - * precomputed via mp_reduce_setup. - * From HAC pp.604 Algorithm 14.42 - */ -int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) -{ - mp_int q; - int res, um = m->used; - - /* q = x */ - if ((res = mp_init_copy (&q, x)) != MP_OKAY) { - return res; - } - - /* q1 = x / b**(k-1) */ - mp_rshd (&q, um - 1); - - /* according to HAC this optimization is ok */ - if (((mp_word) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { - if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { - goto CLEANUP; - } - } else { -#ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#else - { - res = MP_VAL; - goto CLEANUP; - } -#endif - } - - /* q3 = q2 / b**(k+1) */ - mp_rshd (&q, um + 1); - - /* x = x mod b**(k+1), quick (no division) */ - if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { - goto CLEANUP; - } - - /* q = q * m mod b**(k+1), quick (no division) */ - if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { - goto CLEANUP; - } - - /* x = x - q */ - if ((res = mp_sub (x, &q, x)) != MP_OKAY) { - goto CLEANUP; - } - - /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d (x, 0) == MP_LT) { - mp_set (&q, 1); - if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if ((res = mp_add (x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while (mp_cmp (x, m) != MP_LT) { - if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { - goto CLEANUP; - } - } - -CLEANUP: - mp_clear (&q); - - return res; -} - - -/* reduces a modulo n where n is of the form 2**p - d - This differs from reduce_2k since "d" can be larger - than a single digit. -*/ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - /* q = q * d */ - if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - - -/* determines the setup value */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) -{ - int res; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { - goto ERR; - } - - if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear(&tmp); - return res; -} - - -/* multiplies |a| * |b| and does not compute the lower digs digits - * [meant to get the higher part of the product] - */ -int -s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C - if (((a->used + b->used + 1) < MP_WARRAY) - && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_high_digs (a, b, c, digs); - } -#endif - - if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { - return res; - } - t.used = a->used + b->used + 1; - - pa = a->used; - pb = b->used; - for (ix = 0; ix < pa; ix++) { - /* clear the carry */ - u = 0; - - /* left hand side of A[ix] * B[iy] */ - tmpx = a->dp[ix]; - - /* alias to the address of where the digits will be stored */ - tmpt = &(t.dp[digs]); - - /* alias for where to read the right hand side from */ - tmpy = b->dp + (digs - ix); - - for (iy = digs - ix; iy < pb; iy++) { - /* calculate the double precision result */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* get the lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* carry the carry */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - *tmpt = u; - } - mp_clamp (&t); - mp_exch (&t, c); - mp_clear (&t); - return MP_OKAY; -} - - -/* this is a modified version of fast_s_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mul_digs - * to see how it works. - * - * This is used in the Barrett reduction since for one of the multiplications - * only the higher digits were needed. This essentially halves the work. - * - * Based on Algorithm 14.12 on pp.595 of HAC. - */ -int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; -#ifdef CYASSL_SMALL_STACK - mp_digit* W; /* uses dynamic memory and slower */ -#else - mp_digit W[MP_WARRAY]; -#endif - mp_word _W; - - /* grow the destination as required */ - pa = a->used + b->used; - if (c->alloc < pa) { - if ((res = mp_grow (c, pa)) != MP_OKAY) { - return res; - } - } - - if (pa > MP_WARRAY) - return MP_RANGE; /* TAO range check */ - -#ifdef CYASSL_SMALL_STACK - W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT); - if (W == NULL) - return MP_MEM; -#endif - - /* number of output digits to produce */ - pa = a->used + b->used; - _W = 0; - for (ix = digs; ix < pa; ix++) { - int tx, ty, iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - - tmpc = c->dp + digs; - for (ix = digs; ix <= pa; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - -#ifdef CYASSL_SMALL_STACK - XFREE(W, 0, DYNAMIC_TYPE_BIGINT); -#endif - - return MP_OKAY; -} - - -/* set a 32-bit const */ -int mp_set_int (mp_int * a, unsigned long b) -{ - int x, res; - - mp_zero (a); - - /* set four bits at a time */ - for (x = 0; x < 8; x++) { - /* shift the number up four bits */ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { - return res; - } - - /* OR in the top four bits of the source */ - a->dp[0] |= (b >> 28) & 15; - - /* shift the source up to the next four bits */ - b <<= 4; - - /* ensure that digits are not clamped off */ - a->used += 1; - } - mp_clamp (a); - return MP_OKAY; -} - - -#if defined(CYASSL_KEY_GEN) || defined(HAVE_ECC) - -/* c = a * a (mod b) */ -int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sqr (a, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, b, c); - mp_clear (&t); - return res; -} - -#endif - - -#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(CYASSL_SNIFFER) || defined(CYASSL_HAVE_WOLFSCEP) || defined(CYASSL_KEY_GEN) - -/* single digit addition */ -int mp_add_d (mp_int* a, mp_digit b, mp_int* c) -{ - int res, ix, oldused; - mp_digit *tmpa, *tmpc, mu; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative and |a| >= b, call c = |a| - b */ - if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { - /* temporarily fix sign of a */ - a->sign = MP_ZPOS; - - /* c = |a| - b */ - res = mp_sub_d(a, b, c); - - /* fix sign */ - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* old number of used digits in c */ - oldused = c->used; - - /* sign always positive */ - c->sign = MP_ZPOS; - - /* source alias */ - tmpa = a->dp; - - /* destination alias */ - tmpc = c->dp; - - /* if a is positive */ - if (a->sign == MP_ZPOS) { - /* add digit, after this we're propagating - * the carry. - */ - *tmpc = *tmpa++ + b; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - - /* now handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ + mu; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - } - /* set final carry */ - if (mu != 0 && ix < c->alloc) { - ix++; - *tmpc++ = mu; - } - - /* setup size */ - c->used = a->used + 1; - } else { - /* a was negative and |a| < b */ - c->used = 1; - - /* the result is a single digit */ - if (a->used == 1) { - *tmpc++ = b - a->dp[0]; - } else { - *tmpc++ = b; - } - - /* setup count so the clearing of oldused - * can fall through correctly - */ - ix = 1; - } - - /* now zero to oldused */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - - return MP_OKAY; -} - - -/* single digit subtraction */ -int mp_sub_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; - - /* if a <= b simply fix the single digit */ - if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; - - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; - - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - } - } - - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; -} - -#endif /* defined(HAVE_ECC) || !defined(NO_PWDBASED) */ - - -#if defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY) - -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a) -{ - int x; - mp_digit q, qq; - - /* easy out */ - if (mp_iszero(a) == 1) { - return 0; - } - - /* scan lower digits until non-zero */ - for (x = 0; x < a->used && a->dp[x] == 0; x++); - q = a->dp[x]; - x *= DIGIT_BIT; - - /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { - do { - qq = q & 15; - x += lnz[qq]; - q >>= 4; - } while (qq == 0); - } - return x; -} - - - - -static int s_is_power_of_two(mp_digit b, int *p) -{ - int x; - - /* fast return if no power of two */ - if ((b==0) || (b & (b-1))) { - return 0; - } - - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= b) { - t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - if (d != NULL) { - *d = (mp_digit)w; - } - - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - - -int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) -{ - return mp_div_d(a, b, NULL, c); -} - -#endif /* defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY) */ - -#ifdef CYASSL_KEY_GEN - -const mp_digit ltm_prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, -#ifndef MP_8BIT - 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 -#endif -}; - - -/* Miller-Rabin test of "a" to the base of "b" as described in - * HAC pp. 139 Algorithm 4.24 - * - * Sets result to 0 if definitely composite or 1 if probably prime. - * Randomly the chance of error is no more than 1/4 and often - * very much lower. - */ -static int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) -{ - mp_int n1, y, r; - int s, j, err; - - /* default */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* get n1 = a - 1 */ - if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { - return err; - } - if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* set 2**s * r = n1 */ - if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* count the number of least significant bits - * which are zero - */ - s = mp_cnt_lsb(&r); - - /* now divide n - 1 by 2**s */ - if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { - goto LBL_R; - } - - /* compute y = b**r mod a */ - if ((err = mp_init (&y)) != MP_OKAY) { - goto LBL_R; - } - if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y != 1 and y != n1 do */ - if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { - if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y == 1 then composite */ - if (mp_cmp_d (&y, 1) == MP_EQ) { - goto LBL_Y; - } - - ++j; - } - - /* if y != n1 then composite */ - if (mp_cmp (&y, &n1) != MP_EQ) { - goto LBL_Y; - } - } - - /* probably prime now */ - *result = MP_YES; -LBL_Y:mp_clear (&y); -LBL_R:mp_clear (&r); -LBL_N1:mp_clear (&n1); - return err; -} - - -/* determines if an integers is divisible by one - * of the first PRIME_SIZE primes or not - * - * sets result to 0 if not, 1 if yes - */ -static int mp_prime_is_divisible (mp_int * a, int *result) -{ - int err, ix; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < PRIME_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} - - -/* - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime (mp_int * a, int t, int *result) -{ - mp_int b; - int ix, err, res; - - /* default to no */ - *result = MP_NO; - - /* valid value of t? */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIME_SIZE; ix++) { - if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { - *result = 1; - return MP_OKAY; - } - } - - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } - - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } - - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } - - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, ltm_prime_tab[ix]); - - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto LBL_B; - } - - if (res == MP_NO) { - goto LBL_B; - } - } - - /* passed the test */ - *result = MP_YES; -LBL_B:mp_clear (&b); - return err; -} - - -/* computes least common multiple as |a*b|/(a, b) */ -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t1, t2; - - - if ((res = mp_init_multi (&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { - return res; - } - - /* t1 = get the GCD of the two inputs */ - if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { - goto LBL_T; - } - - /* divide the smallest by the GCD */ - if (mp_cmp_mag(a, b) == MP_LT) { - /* store quotient in t2 such that t2 * b is the LCM */ - if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(b, &t2, c); - } else { - /* store quotient in t2 such that t2 * a is the LCM */ - if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(a, &t2, c); - } - - /* fix the sign to positive */ - c->sign = MP_ZPOS; - -LBL_T: - mp_clear(&t1); - mp_clear(&t2); - return res; -} - - - -/* Greatest Common Divisor using the binary method */ -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int u, v; - int k, u_lsb, v_lsb, res; - - /* either zero than gcd is the largest */ - if (mp_iszero (a) == MP_YES) { - return mp_abs (b, c); - } - if (mp_iszero (b) == MP_YES) { - return mp_abs (a, c); - } - - /* get copies of a and b we can modify */ - if ((res = mp_init_copy (&u, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init_copy (&v, b)) != MP_OKAY) { - goto LBL_U; - } - - /* must be positive for the remainder of the algorithm */ - u.sign = v.sign = MP_ZPOS; - - /* B1. Find the common power of two for u and v */ - u_lsb = mp_cnt_lsb(&u); - v_lsb = mp_cnt_lsb(&v); - k = MIN(u_lsb, v_lsb); - - if (k > 0) { - /* divide the power of two out */ - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* divide any remaining factors of two out */ - if (u_lsb != k) { - if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - if (v_lsb != k) { - if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - while (mp_iszero(&v) == 0) { - /* make sure v is the largest */ - if (mp_cmp_mag(&u, &v) == MP_GT) { - /* swap u and v to make sure v is >= u */ - mp_exch(&u, &v); - } - - /* subtract smallest from largest */ - if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { - goto LBL_V; - } - - /* Divide out all factors of two */ - if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* multiply by 2**k which we divided out at the beginning */ - if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto LBL_V; - } - c->sign = MP_ZPOS; - res = MP_OKAY; -LBL_V:mp_clear (&u); -LBL_U:mp_clear (&v); - return res; -} - - - -#endif /* CYASSL_KEY_GEN */ - - -#ifdef HAVE_ECC - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; - -/* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, const char *str, int radix) -{ - int y, res, neg; - char ch; - - /* zero the digit bignum */ - mp_zero(a); - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? XTOUPPER(*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != 1) { - a->sign = neg; - } - return MP_OKAY; -} - -#endif /* HAVE_ECC */ - -#endif /* USE_FAST_MATH */ - -#endif /* NO_BIG_INT */ diff --git a/ctaocrypt/src/logging.c b/ctaocrypt/src/logging.c deleted file mode 100644 index e53d9e162..000000000 --- a/ctaocrypt/src/logging.c +++ /dev/null @@ -1,162 +0,0 @@ -/* logging.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -/* submitted by eof */ - -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - CYASSL_API int CyaSSL_Debugging_ON(void); - CYASSL_API void CyaSSL_Debugging_OFF(void); -#ifdef __cplusplus - } -#endif - - -#ifdef DEBUG_CYASSL - -/* Set these to default values initially. */ -static CyaSSL_Logging_cb log_function = 0; -static int loggingEnabled = 0; - -#endif /* DEBUG_CYASSL */ - - -int CyaSSL_SetLoggingCb(CyaSSL_Logging_cb f) -{ -#ifdef DEBUG_CYASSL - int res = 0; - - if (f) - log_function = f; - else - res = BAD_FUNC_ARG; - - return res; -#else - (void)f; - return NOT_COMPILED_IN; -#endif -} - - -int CyaSSL_Debugging_ON(void) -{ -#ifdef DEBUG_CYASSL - loggingEnabled = 1; - return 0; -#else - return NOT_COMPILED_IN; -#endif -} - - -void CyaSSL_Debugging_OFF(void) -{ -#ifdef DEBUG_CYASSL - loggingEnabled = 0; -#endif -} - - -#ifdef DEBUG_CYASSL - -#ifdef FREESCALE_MQX - #include -#else - #include /* for default printf stuff */ -#endif - -#ifdef THREADX - int dc_log_printf(char*, ...); -#endif - -static void cyassl_log(const int logLevel, const char *const logMessage) -{ - if (log_function) - log_function(logLevel, logMessage); - else { - if (loggingEnabled) { -#ifdef THREADX - dc_log_printf("%s\n", logMessage); -#elif defined(MICRIUM) - #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED) - NetSecure_TraceOut((CPU_CHAR *)logMessage); - #endif -#elif defined(CYASSL_MDK_ARM) - fflush(stdout) ; - printf("%s\n", logMessage); - fflush(stdout) ; -#else - fprintf(stderr, "%s\n", logMessage); -#endif - } - } -} - - -void CYASSL_MSG(const char* msg) -{ - if (loggingEnabled) - cyassl_log(INFO_LOG , msg); -} - - -void CYASSL_ENTER(const char* msg) -{ - if (loggingEnabled) { - char buffer[80]; - sprintf(buffer, "CyaSSL Entering %s", msg); - cyassl_log(ENTER_LOG , buffer); - } -} - - -void CYASSL_LEAVE(const char* msg, int ret) -{ - if (loggingEnabled) { - char buffer[80]; - sprintf(buffer, "CyaSSL Leaving %s, return %d", msg, ret); - cyassl_log(LEAVE_LOG , buffer); - } -} - - -void CYASSL_ERROR(int error) -{ - if (loggingEnabled) { - char buffer[80]; - sprintf(buffer, "CyaSSL error occured, error = %d", error); - cyassl_log(ERROR_LOG , buffer); - } -} - -#endif /* DEBUG_CYASSL */ diff --git a/ctaocrypt/src/md2.c b/ctaocrypt/src/md2.c deleted file mode 100644 index 8cc25b672..000000000 --- a/ctaocrypt/src/md2.c +++ /dev/null @@ -1,159 +0,0 @@ -/* md2.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - - -//#ifdef HAVE_CONFIG_H -// #include -//#endif -// -//#include -// -//#ifdef CYASSL_MD2 -// -//#include -//#include -// -//#ifdef NO_INLINE -// #include -//#else -// #include -//#endif -// -// -//void InitMd2(Md2* md2) -//{ -// XMEMSET(md2->X, 0, MD2_X_SIZE); -// XMEMSET(md2->C, 0, MD2_BLOCK_SIZE); -// XMEMSET(md2->buffer, 0, MD2_BLOCK_SIZE); -// md2->count = 0; -//} -// -// -//void Md2Update(Md2* md2, const byte* data, word32 len) -//{ -// static const byte S[256] = -// { -// 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, -// 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, -// 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, -// 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, -// 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, -// 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, -// 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, -// 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, -// 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, -// 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, -// 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, -// 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, -// 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, -// 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, -// 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, -// 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, -// 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, -// 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 -// }; -// -// while (len) { -// word32 L = (MD2_PAD_SIZE - md2->count) < len ? -// (MD2_PAD_SIZE - md2->count) : len; -// XMEMCPY(md2->buffer + md2->count, data, L); -// md2->count += L; -// data += L; -// len -= L; -// -// if (md2->count == MD2_PAD_SIZE) { -// int i; -// byte t; -// -// md2->count = 0; -// XMEMCPY(md2->X + MD2_PAD_SIZE, md2->buffer, MD2_PAD_SIZE); -// t = md2->C[15]; -// -// for(i = 0; i < MD2_PAD_SIZE; i++) { -// md2->X[32 + i] = md2->X[MD2_PAD_SIZE + i] ^ md2->X[i]; -// t = md2->C[i] ^= S[md2->buffer[i] ^ t]; -// } -// -// t=0; -// for(i = 0; i < 18; i++) { -// int j; -// for(j = 0; j < MD2_X_SIZE; j += 8) { -// t = md2->X[j+0] ^= S[t]; -// t = md2->X[j+1] ^= S[t]; -// t = md2->X[j+2] ^= S[t]; -// t = md2->X[j+3] ^= S[t]; -// t = md2->X[j+4] ^= S[t]; -// t = md2->X[j+5] ^= S[t]; -// t = md2->X[j+6] ^= S[t]; -// t = md2->X[j+7] ^= S[t]; -// } -// t = (t + i) & 0xFF; -// } -// } -// } -//} -// -// -//void Md2Final(Md2* md2, byte* hash) -//{ -// byte padding[MD2_BLOCK_SIZE]; -// word32 padLen = MD2_PAD_SIZE - md2->count; -// word32 i; -// -// for (i = 0; i < padLen; i++) -// padding[i] = (byte)padLen; -// -// Md2Update(md2, padding, padLen); -// Md2Update(md2, md2->C, MD2_BLOCK_SIZE); -// -// XMEMCPY(hash, md2->X, MD2_DIGEST_SIZE); -// -// InitMd2(md2); -//} -// -// -//int Md2Hash(const byte* data, word32 len, byte* hash) -//{ -//#ifdef CYASSL_SMALL_STACK -// Md2* md2; -//#else -// Md2 md2[1]; -//#endif -// -//#ifdef CYASSL_SMALL_STACK -// md2 = (Md2*)XMALLOC(sizeof(Md2), NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (md2 == NULL) -// return MEMORY_E; -//#endif -// -// InitMd2(md2); -// Md2Update(md2, data, len); -// Md2Final(md2, hash); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(md2, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// return 0; -//} -// -// -//#endif /* CYASSL_MD2 */ diff --git a/ctaocrypt/src/md4.c b/ctaocrypt/src/md4.c deleted file mode 100644 index ef0cd80ce..000000000 --- a/ctaocrypt/src/md4.c +++ /dev/null @@ -1,219 +0,0 @@ -/* md4.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - -//#ifdef HAVE_CONFIG_H -// #include -//#endif -// -//#include -// -//#ifndef NO_MD4 -// -//#include -//#ifdef NO_INLINE -// #include -//#else -// #include -//#endif -// -// -//#ifndef min -// -// static INLINE word32 min(word32 a, word32 b) -// { -// return a > b ? b : a; -// } -// -//#endif /* min */ -// -// -//void InitMd4(Md4* md4) -//{ -// md4->digest[0] = 0x67452301L; -// md4->digest[1] = 0xefcdab89L; -// md4->digest[2] = 0x98badcfeL; -// md4->digest[3] = 0x10325476L; -// -// md4->buffLen = 0; -// md4->loLen = 0; -// md4->hiLen = 0; -//} -// -// -//static void Transform(Md4* md4) -//{ -//#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -//#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -//#define H(x, y, z) ((x) ^ (y) ^ (z)) -// -// /* Copy context->state[] to working vars */ -// word32 A = md4->digest[0]; -// word32 B = md4->digest[1]; -// word32 C = md4->digest[2]; -// word32 D = md4->digest[3]; -// -//#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s); -// function(A,B,C,D, 0, 3); -// function(D,A,B,C, 1, 7); -// function(C,D,A,B, 2,11); -// function(B,C,D,A, 3,19); -// function(A,B,C,D, 4, 3); -// function(D,A,B,C, 5, 7); -// function(C,D,A,B, 6,11); -// function(B,C,D,A, 7,19); -// function(A,B,C,D, 8, 3); -// function(D,A,B,C, 9, 7); -// function(C,D,A,B,10,11); -// function(B,C,D,A,11,19); -// function(A,B,C,D,12, 3); -// function(D,A,B,C,13, 7); -// function(C,D,A,B,14,11); -// function(B,C,D,A,15,19); -// -//#undef function -//#define function(a,b,c,d,k,s) \ -// a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s); -// -// function(A,B,C,D, 0, 3); -// function(D,A,B,C, 4, 5); -// function(C,D,A,B, 8, 9); -// function(B,C,D,A,12,13); -// function(A,B,C,D, 1, 3); -// function(D,A,B,C, 5, 5); -// function(C,D,A,B, 9, 9); -// function(B,C,D,A,13,13); -// function(A,B,C,D, 2, 3); -// function(D,A,B,C, 6, 5); -// function(C,D,A,B,10, 9); -// function(B,C,D,A,14,13); -// function(A,B,C,D, 3, 3); -// function(D,A,B,C, 7, 5); -// function(C,D,A,B,11, 9); -// function(B,C,D,A,15,13); -// -//#undef function -//#define function(a,b,c,d,k,s) \ -// a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s); -// -// function(A,B,C,D, 0, 3); -// function(D,A,B,C, 8, 9); -// function(C,D,A,B, 4,11); -// function(B,C,D,A,12,15); -// function(A,B,C,D, 2, 3); -// function(D,A,B,C,10, 9); -// function(C,D,A,B, 6,11); -// function(B,C,D,A,14,15); -// function(A,B,C,D, 1, 3); -// function(D,A,B,C, 9, 9); -// function(C,D,A,B, 5,11); -// function(B,C,D,A,13,15); -// function(A,B,C,D, 3, 3); -// function(D,A,B,C,11, 9); -// function(C,D,A,B, 7,11); -// function(B,C,D,A,15,15); -// -// /* Add the working vars back into digest state[] */ -// md4->digest[0] += A; -// md4->digest[1] += B; -// md4->digest[2] += C; -// md4->digest[3] += D; -//} -// -// -//static INLINE void AddLength(Md4* md4, word32 len) -//{ -// word32 tmp = md4->loLen; -// if ( (md4->loLen += len) < tmp) -// md4->hiLen++; /* carry low to high */ -//} -// -// -//void Md4Update(Md4* md4, const byte* data, word32 len) -//{ -// /* do block size increments */ -// byte* local = (byte*)md4->buffer; -// -// while (len) { -// word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen); -// XMEMCPY(&local[md4->buffLen], data, add); -// -// md4->buffLen += add; -// data += add; -// len -= add; -// -// if (md4->buffLen == MD4_BLOCK_SIZE) { -// #ifdef BIG_ENDIAN_ORDER -// ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE); -// #endif -// Transform(md4); -// AddLength(md4, MD4_BLOCK_SIZE); -// md4->buffLen = 0; -// } -// } -//} -// -// -//void Md4Final(Md4* md4, byte* hash) -//{ -// byte* local = (byte*)md4->buffer; -// -// AddLength(md4, md4->buffLen); /* before adding pads */ -// -// local[md4->buffLen++] = 0x80; /* add 1 */ -// -// /* pad with zeros */ -// if (md4->buffLen > MD4_PAD_SIZE) { -// XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen); -// md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen; -// -// #ifdef BIG_ENDIAN_ORDER -// ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE); -// #endif -// Transform(md4); -// md4->buffLen = 0; -// } -// XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen); -// -// /* put lengths in bits */ -// md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) + -// (md4->hiLen << 3); -// md4->loLen = md4->loLen << 3; -// -// /* store lengths */ -// #ifdef BIG_ENDIAN_ORDER -// ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE); -// #endif -// /* ! length ordering dependent on digest endian type ! */ -// XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32)); -// XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32)); -// -// Transform(md4); -// #ifdef BIG_ENDIAN_ORDER -// ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE); -// #endif -// XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE); -// -// InitMd4(md4); /* reset state */ -//} -// -// -//#endif /* NO_MD4 */ -// diff --git a/ctaocrypt/src/md5.c b/ctaocrypt/src/md5.c deleted file mode 100644 index b31339b2a..000000000 --- a/ctaocrypt/src/md5.c +++ /dev/null @@ -1,391 +0,0 @@ -/* md5.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#if !defined(NO_MD5) - -#ifdef CYASSL_PIC32MZ_HASH -#define InitMd5 InitMd5_sw -#define Md5Update Md5Update_sw -#define Md5Final Md5Final_sw -#endif - -#include -#include - -#ifdef NO_INLINE - #include -#else - #include -#endif - -#ifdef FREESCALE_MMCAU - #include "cau_api.h" - #define XTRANSFORM(S,B) cau_md5_hash_n((B), 1, (unsigned char*)(S)->digest) -#else - #define XTRANSFORM(S,B) Transform((S)) -#endif - - -#ifdef STM32F2_HASH - /* - * STM32F2 hardware MD5 support through the STM32F2 standard peripheral - * library. Documentation located in STM32F2xx Standard Peripheral Library - * document (See note in README). - */ - #include "stm32f2xx.h" - - void InitMd5(Md5* md5) - { - /* STM32F2 struct notes: - * md5->buffer = first 4 bytes used to hold partial block if needed - * md5->buffLen = num bytes currently stored in md5->buffer - * md5->loLen = num bytes that have been written to STM32 FIFO - */ - XMEMSET(md5->buffer, 0, MD5_REG_SIZE); - - md5->buffLen = 0; - md5->loLen = 0; - - /* initialize HASH peripheral */ - HASH_DeInit(); - - /* configure algo used, algo mode, datatype */ - HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); - HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH - | HASH_DataType_8b); - - /* reset HASH processor */ - HASH->CR |= HASH_CR_INIT; - } - - void Md5Update(Md5* md5, const byte* data, word32 len) - { - word32 i = 0; - word32 fill = 0; - word32 diff = 0; - - /* if saved partial block is available */ - if (md5->buffLen > 0) { - fill = 4 - md5->buffLen; - - /* if enough data to fill, fill and push to FIFO */ - if (fill <= len) { - XMEMCPY((byte*)md5->buffer + md5->buffLen, data, fill); - HASH_DataIn(*(uint32_t*)md5->buffer); - - data += fill; - len -= fill; - md5->loLen += 4; - md5->buffLen = 0; - } else { - /* append partial to existing stored block */ - XMEMCPY((byte*)md5->buffer + md5->buffLen, data, len); - md5->buffLen += len; - return; - } - } - - /* write input block in the IN FIFO */ - for (i = 0; i < len; i += 4) - { - diff = len - i; - if (diff < 4) { - /* store incomplete last block, not yet in FIFO */ - XMEMSET(md5->buffer, 0, MD5_REG_SIZE); - XMEMCPY((byte*)md5->buffer, data, diff); - md5->buffLen = diff; - } else { - HASH_DataIn(*(uint32_t*)data); - data+=4; - } - } - - /* keep track of total data length thus far */ - md5->loLen += (len - md5->buffLen); - } - - void Md5Final(Md5* md5, byte* hash) - { - __IO uint16_t nbvalidbitsdata = 0; - - /* finish reading any trailing bytes into FIFO */ - if (md5->buffLen > 0) { - HASH_DataIn(*(uint32_t*)md5->buffer); - md5->loLen += md5->buffLen; - } - - /* calculate number of valid bits in last word of input data */ - nbvalidbitsdata = 8 * (md5->loLen % MD5_REG_SIZE); - - /* configure number of valid bits in last word of the data */ - HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); - - /* start HASH processor */ - HASH_StartDigest(); - - /* wait until Busy flag == RESET */ - while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} - - /* read message digest */ - md5->digest[0] = HASH->HR[0]; - md5->digest[1] = HASH->HR[1]; - md5->digest[2] = HASH->HR[2]; - md5->digest[3] = HASH->HR[3]; - - ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE); - - XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE); - - InitMd5(md5); /* reset state */ - } - -#else /* CTaoCrypt software implementation */ - -#ifndef min - - static INLINE word32 min(word32 a, word32 b) - { - return a > b ? b : a; - } - -#endif /* min */ - - -void InitMd5(Md5* md5) -{ - md5->digest[0] = 0x67452301L; - md5->digest[1] = 0xefcdab89L; - md5->digest[2] = 0x98badcfeL; - md5->digest[3] = 0x10325476L; - - md5->buffLen = 0; - md5->loLen = 0; - md5->hiLen = 0; -} - -#ifndef FREESCALE_MMCAU - -static void Transform(Md5* md5) -{ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -#define MD5STEP(f, w, x, y, z, data, s) \ - w = rotlFixed(w + f(x, y, z) + data, s) + x - - /* Copy context->state[] to working vars */ - word32 a = md5->digest[0]; - word32 b = md5->digest[1]; - word32 c = md5->digest[2]; - word32 d = md5->digest[3]; - - MD5STEP(F1, a, b, c, d, md5->buffer[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, md5->buffer[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, md5->buffer[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, md5->buffer[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, md5->buffer[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, md5->buffer[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, md5->buffer[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, md5->buffer[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, md5->buffer[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, md5->buffer[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, md5->buffer[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, md5->buffer[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, md5->buffer[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, md5->buffer[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, md5->buffer[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, md5->buffer[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, md5->buffer[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, md5->buffer[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, md5->buffer[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, md5->buffer[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, md5->buffer[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, md5->buffer[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, md5->buffer[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, md5->buffer[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, md5->buffer[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, md5->buffer[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, md5->buffer[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, md5->buffer[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, md5->buffer[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, md5->buffer[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, md5->buffer[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, md5->buffer[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, md5->buffer[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, md5->buffer[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, md5->buffer[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, md5->buffer[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, md5->buffer[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, md5->buffer[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, md5->buffer[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, md5->buffer[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, md5->buffer[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, md5->buffer[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, md5->buffer[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, md5->buffer[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, md5->buffer[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, md5->buffer[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, md5->buffer[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, md5->buffer[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, md5->buffer[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, md5->buffer[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, md5->buffer[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, md5->buffer[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, md5->buffer[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, md5->buffer[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, md5->buffer[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, md5->buffer[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, md5->buffer[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, md5->buffer[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, md5->buffer[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, md5->buffer[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, md5->buffer[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, md5->buffer[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, md5->buffer[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, md5->buffer[9] + 0xeb86d391, 21); - - /* Add the working vars back into digest state[] */ - md5->digest[0] += a; - md5->digest[1] += b; - md5->digest[2] += c; - md5->digest[3] += d; -} - -#endif /* FREESCALE_MMCAU */ - - -static INLINE void AddLength(Md5* md5, word32 len) -{ - word32 tmp = md5->loLen; - if ( (md5->loLen += len) < tmp) - md5->hiLen++; /* carry low to high */ -} - - -void Md5Update(Md5* md5, const byte* data, word32 len) -{ - /* do block size increments */ - byte* local = (byte*)md5->buffer; - - while (len) { - word32 add = min(len, MD5_BLOCK_SIZE - md5->buffLen); - XMEMCPY(&local[md5->buffLen], data, add); - - md5->buffLen += add; - data += add; - len -= add; - - if (md5->buffLen == MD5_BLOCK_SIZE) { - #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) - ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); - #endif - XTRANSFORM(md5, local); - AddLength(md5, MD5_BLOCK_SIZE); - md5->buffLen = 0; - } - } -} - - -void Md5Final(Md5* md5, byte* hash) -{ - byte* local = (byte*)md5->buffer; - - AddLength(md5, md5->buffLen); /* before adding pads */ - - local[md5->buffLen++] = 0x80; /* add 1 */ - - /* pad with zeros */ - if (md5->buffLen > MD5_PAD_SIZE) { - XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen); - md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen; - - #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) - ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); - #endif - XTRANSFORM(md5, local); - md5->buffLen = 0; - } - XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen); - - /* put lengths in bits */ - md5->hiLen = (md5->loLen >> (8*sizeof(md5->loLen) - 3)) + - (md5->hiLen << 3); - md5->loLen = md5->loLen << 3; - - /* store lengths */ - #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) - ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); - #endif - /* ! length ordering dependent on digest endian type ! */ - XMEMCPY(&local[MD5_PAD_SIZE], &md5->loLen, sizeof(word32)); - XMEMCPY(&local[MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32)); - - XTRANSFORM(md5, local); - #ifdef BIG_ENDIAN_ORDER - ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE); - #endif - XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE); - - InitMd5(md5); /* reset state */ -} - -#endif /* STM32F2_HASH */ - - -int Md5Hash(const byte* data, word32 len, byte* hash) -{ -#ifdef CYASSL_SMALL_STACK - Md5* md5; -#else - Md5 md5[1]; -#endif - -#ifdef CYASSL_SMALL_STACK - md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (md5 == NULL) - return MEMORY_E; -#endif - - InitMd5(md5); - Md5Update(md5, data, len); - Md5Final(md5, hash); - -#ifdef CYASSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return 0; -} - -#endif /* NO_MD5 */ diff --git a/ctaocrypt/src/memory.c b/ctaocrypt/src/memory.c deleted file mode 100644 index 64932d18f..000000000 --- a/ctaocrypt/src/memory.c +++ /dev/null @@ -1,183 +0,0 @@ -/* memory.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef USE_CYASSL_MEMORY - -#include -#include - -#ifdef CYASSL_MALLOC_CHECK - #include -#endif - -/* Set these to default values initially. */ -static CyaSSL_Malloc_cb malloc_function = 0; -static CyaSSL_Free_cb free_function = 0; -static CyaSSL_Realloc_cb realloc_function = 0; - -int CyaSSL_SetAllocators(CyaSSL_Malloc_cb mf, - CyaSSL_Free_cb ff, - CyaSSL_Realloc_cb rf) -{ - int res = 0; - - if (mf) - malloc_function = mf; - else - res = BAD_FUNC_ARG; - - if (ff) - free_function = ff; - else - res = BAD_FUNC_ARG; - - if (rf) - realloc_function = rf; - else - res = BAD_FUNC_ARG; - - return res; -} - - -void* CyaSSL_Malloc(size_t size) -{ - void* res = 0; - - if (malloc_function) - res = malloc_function(size); - else - res = malloc(size); - - #ifdef CYASSL_MALLOC_CHECK - if (res == NULL) - puts("CyaSSL_malloc failed"); - #endif - - return res; -} - -void CyaSSL_Free(void *ptr) -{ - if (free_function) - free_function(ptr); - else - free(ptr); -} - -void* CyaSSL_Realloc(void *ptr, size_t size) -{ - void* res = 0; - - if (realloc_function) - res = realloc_function(ptr, size); - else - res = realloc(ptr, size); - - return res; -} - -#endif /* USE_CYASSL_MEMORY */ - - -#ifdef HAVE_IO_POOL - -/* Example for user io pool, shared build may need definitions in lib proper */ - -#include -#include - -#ifndef HAVE_THREAD_LS - #error "Oops, simple I/O pool example needs thread local storage" -#endif - - -/* allow simple per thread in and out pools */ -/* use 17k size sense max record size is 16k plus overhead */ -static THREAD_LS_T byte pool_in[17*1024]; -static THREAD_LS_T byte pool_out[17*1024]; - - -void* XMALLOC(size_t n, void* heap, int type) -{ - (void)heap; - - if (type == DYNAMIC_TYPE_IN_BUFFER) { - if (n < sizeof(pool_in)) - return pool_in; - else - return NULL; - } - - if (type == DYNAMIC_TYPE_OUT_BUFFER) { - if (n < sizeof(pool_out)) - return pool_out; - else - return NULL; - } - - return malloc(n); -} - -void* XREALLOC(void *p, size_t n, void* heap, int type) -{ - (void)heap; - - if (type == DYNAMIC_TYPE_IN_BUFFER) { - if (n < sizeof(pool_in)) - return pool_in; - else - return NULL; - } - - if (type == DYNAMIC_TYPE_OUT_BUFFER) { - if (n < sizeof(pool_out)) - return pool_out; - else - return NULL; - } - - return realloc(p, n); -} - - -/* unit api calls, let's make sure visisble with CYASSL_API */ -CYASSL_API void XFREE(void *p, void* heap, int type) -{ - (void)heap; - - if (type == DYNAMIC_TYPE_IN_BUFFER) - return; /* do nothing, static pool */ - - if (type == DYNAMIC_TYPE_OUT_BUFFER) - return; /* do nothing, static pool */ - - free(p); -} - -#endif /* HAVE_IO_POOL */ - diff --git a/ctaocrypt/src/misc.c b/ctaocrypt/src/misc.c index 7ac9cb16c..319445b72 100644 --- a/ctaocrypt/src/misc.c +++ b/ctaocrypt/src/misc.c @@ -19,155 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#include - -/* inlining these functions is a huge speed increase and a small size decrease, - because the functions are smaller than function call setup/cleanup, e.g., - md5 benchmark is twice as fast with inline. If you don't want it, then - define NO_INLINE and compile this file into cyassl, otherwise it's used as - a source header - */ - #ifdef NO_INLINE - #define STATIC + #include #else - #define STATIC static + #include #endif - - -#ifdef INTEL_INTRINSICS - - #include /* get intrinsic definitions */ - - /* for non visual studio probably need no long version, 32 bit only - * i.e., _rotl and _rotr */ - #pragma intrinsic(_lrotl, _lrotr) - - STATIC INLINE word32 rotlFixed(word32 x, word32 y) - { - return y ? _lrotl(x, y) : x; - } - - STATIC INLINE word32 rotrFixed(word32 x, word32 y) - { - return y ? _lrotr(x, y) : x; - } - -#else /* generic */ - - STATIC INLINE word32 rotlFixed(word32 x, word32 y) - { - return (x << y) | (x >> (sizeof(y) * 8 - y)); - } - - - STATIC INLINE word32 rotrFixed(word32 x, word32 y) - { - return (x >> y) | (x << (sizeof(y) * 8 - y)); - } - -#endif - - -STATIC INLINE word32 ByteReverseWord32(word32 value) -{ -#ifdef PPC_INTRINSICS - /* PPC: load reverse indexed instruction */ - return (word32)__lwbrx(&value,0); -#elif defined(KEIL_INTRINSICS) - return (word32)__rev(value); -#elif defined(FAST_ROTATE) - /* 5 instructions with rotate instruction, 9 without */ - return (rotrFixed(value, 8U) & 0xff00ff00) | - (rotlFixed(value, 8U) & 0x00ff00ff); -#else - /* 6 instructions with rotate instruction, 8 without */ - value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); - return rotlFixed(value, 16U); -#endif -} - - -STATIC INLINE void ByteReverseWords(word32* out, const word32* in, - word32 byteCount) -{ - word32 count = byteCount/(word32)sizeof(word32), i; - - for (i = 0; i < count; i++) - out[i] = ByteReverseWord32(in[i]); - -} - - -#ifdef WORD64_AVAILABLE - - -STATIC INLINE word64 rotlFixed64(word64 x, word64 y) -{ - return (x << y) | (x >> (sizeof(y) * 8 - y)); -} - - -STATIC INLINE word64 rotrFixed64(word64 x, word64 y) -{ - return (x >> y) | (x << (sizeof(y) * 8 - y)); -} - - -STATIC INLINE word64 ByteReverseWord64(word64 value) -{ -#ifdef CTAOCRYPT_SLOW_WORD64 - return (word64)(ByteReverseWord32((word32)value)) << 32 | - ByteReverseWord32((word32)(value>>32)); -#else - value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | - ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); - value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | - ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); - return rotlFixed64(value, 32U); -#endif -} - - -STATIC INLINE void ByteReverseWords64(word64* out, const word64* in, - word32 byteCount) -{ - word32 count = byteCount/(word32)sizeof(word64), i; - - for (i = 0; i < count; i++) - out[i] = ByteReverseWord64(in[i]); - -} - -#endif /* WORD64_AVAILABLE */ - - -STATIC INLINE void XorWords(cyassl_word* r, const cyassl_word* a, word32 n) -{ - word32 i; - - for (i = 0; i < n; i++) r[i] ^= a[i]; -} - - -STATIC INLINE void xorbuf(void* buf, const void* mask, word32 count) -{ - if (((cyassl_word)buf | (cyassl_word)mask | count) % CYASSL_WORD_SIZE == 0) - XorWords( (cyassl_word*)buf, - (const cyassl_word*)mask, count / CYASSL_WORD_SIZE); - else { - word32 i; - byte* b = (byte*)buf; - const byte* m = (const byte*)mask; - - for (i = 0; i < count; i++) b[i] ^= m[i]; - } -} -#undef STATIC - diff --git a/ctaocrypt/src/pkcs7.c b/ctaocrypt/src/pkcs7.c deleted file mode 100644 index ffa5a4440..000000000 --- a/ctaocrypt/src/pkcs7.c +++ /dev/null @@ -1,1849 +0,0 @@ -/* pkcs7.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - -//#ifdef HAVE_CONFIG_H -// #include -//#endif -// -//#include -// -//#ifdef HAVE_PKCS7 -// -//#include -//#include -//#include -// -//#ifndef min -// static INLINE word32 min(word32 a, word32 b) -// { -// return a > b ? b : a; -// } -//#endif -// -// -///* placed ASN.1 contentType OID into *output, return idx on success, -// * 0 upon failure */ -//CYASSL_LOCAL int SetContentType(int pkcs7TypeOID, byte* output) -//{ -// /* PKCS#7 content types, RFC 2315, section 14 */ -// static const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, -// 0x0D, 0x01, 0x07 }; -// static const byte data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, -// 0x0D, 0x01, 0x07, 0x01 }; -// static const byte signedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, -// 0x0D, 0x01, 0x07, 0x02}; -// static const byte envelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, -// 0x0D, 0x01, 0x07, 0x03 }; -// static const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, -// 0x0D, 0x01, 0x07, 0x04 }; -// static const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, -// 0x0D, 0x01, 0x07, 0x05 }; -// static const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, -// 0x0D, 0x01, 0x07, 0x06 }; -// -// int idSz; -// int typeSz = 0, idx = 0; -// const byte* typeName = 0; -// byte ID_Length[MAX_LENGTH_SZ]; -// -// switch (pkcs7TypeOID) { -// case PKCS7_MSG: -// typeSz = sizeof(pkcs7); -// typeName = pkcs7; -// break; -// -// case DATA: -// typeSz = sizeof(data); -// typeName = data; -// break; -// -// case SIGNED_DATA: -// typeSz = sizeof(signedData); -// typeName = signedData; -// break; -// -// case ENVELOPED_DATA: -// typeSz = sizeof(envelopedData); -// typeName = envelopedData; -// break; -// -// case SIGNED_AND_ENVELOPED_DATA: -// typeSz = sizeof(signedAndEnveloped); -// typeName = signedAndEnveloped; -// break; -// -// case DIGESTED_DATA: -// typeSz = sizeof(digestedData); -// typeName = digestedData; -// break; -// -// case ENCRYPTED_DATA: -// typeSz = sizeof(encryptedData); -// typeName = encryptedData; -// break; -// -// default: -// CYASSL_MSG("Unknown PKCS#7 Type"); -// return 0; -// }; -// -// idSz = SetLength(typeSz, ID_Length); -// output[idx++] = ASN_OBJECT_ID; -// XMEMCPY(output + idx, ID_Length, idSz); -// idx += idSz; -// XMEMCPY(output + idx, typeName, typeSz); -// idx += typeSz; -// -// return idx; -// -//} -// -// -///* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */ -//int GetContentType(const byte* input, word32* inOutIdx, word32* oid, -// word32 maxIdx) -//{ -// int length; -// word32 i = *inOutIdx; -// byte b; -// *oid = 0; -// -// CYASSL_ENTER("GetContentType"); -// -// b = input[i++]; -// if (b != ASN_OBJECT_ID) -// return ASN_OBJECT_ID_E; -// -// if (GetLength(input, &i, &length, maxIdx) < 0) -// return ASN_PARSE_E; -// -// while(length--) { -// *oid += input[i]; -// i++; -// } -// -// *inOutIdx = i; -// -// return 0; -//} -// -// -///* init PKCS7 struct with recipient cert, decode into DecodedCert */ -//int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz) -//{ -// int ret = 0; -// -// XMEMSET(pkcs7, 0, sizeof(PKCS7)); -// if (cert != NULL && certSz > 0) { -//#ifdef CYASSL_SMALL_STACK -// DecodedCert* dCert; -// -// dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// if (dCert == NULL) -// return MEMORY_E; -//#else -// DecodedCert stack_dCert; -// DecodedCert* dCert = &stack_dCert; -//#endif -// -// pkcs7->singleCert = cert; -// pkcs7->singleCertSz = certSz; -// InitDecodedCert(dCert, cert, certSz, 0); -// -// ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0); -// if (ret < 0) { -// FreeDecodedCert(dCert); -//#ifdef CYASSL_SMALL_STACK -// XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// -// XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize); -// pkcs7->publicKeySz = dCert->pubKeySize; -// XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, SHA_SIZE); -// pkcs7->issuer = dCert->issuerRaw; -// pkcs7->issuerSz = dCert->issuerRawLen; -// XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz); -// pkcs7->issuerSnSz = dCert->serialSz; -// FreeDecodedCert(dCert); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// } -// -// return ret; -//} -// -// -///* releases any memory allocated by a PKCS7 initializer */ -//void PKCS7_Free(PKCS7* pkcs7) -//{ -// (void)pkcs7; -//} -// -// -///* build PKCS#7 data content type */ -//int PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz) -//{ -// static const byte oid[] = -// { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, -// 0x07, 0x01 }; -// byte seq[MAX_SEQ_SZ]; -// byte octetStr[MAX_OCTET_STR_SZ]; -// word32 seqSz; -// word32 octetStrSz; -// word32 oidSz = (word32)sizeof(oid); -// int idx = 0; -// -// octetStrSz = SetOctetString(pkcs7->contentSz, octetStr); -// seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq); -// -// if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz) -// return BUFFER_E; -// -// XMEMCPY(output, seq, seqSz); -// idx += seqSz; -// XMEMCPY(output + idx, oid, oidSz); -// idx += oidSz; -// XMEMCPY(output + idx, octetStr, octetStrSz); -// idx += octetStrSz; -// XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); -// idx += pkcs7->contentSz; -// -// return idx; -//} -// -// -//typedef struct EncodedAttrib { -// byte valueSeq[MAX_SEQ_SZ]; -// const byte* oid; -// byte valueSet[MAX_SET_SZ]; -// const byte* value; -// word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz; -//} EncodedAttrib; -// -// -//typedef struct ESD { -// Sha sha; -// byte contentDigest[SHA_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */ -// byte contentAttribsDigest[SHA_DIGEST_SIZE]; -// byte encContentDigest[512]; -// -// byte outerSeq[MAX_SEQ_SZ]; -// byte outerContent[MAX_EXP_SZ]; -// byte innerSeq[MAX_SEQ_SZ]; -// byte version[MAX_VERSION_SZ]; -// byte digAlgoIdSet[MAX_SET_SZ]; -// byte singleDigAlgoId[MAX_ALGO_SZ]; -// -// byte contentInfoSeq[MAX_SEQ_SZ]; -// byte innerContSeq[MAX_EXP_SZ]; -// byte innerOctets[MAX_OCTET_STR_SZ]; -// -// byte certsSet[MAX_SET_SZ]; -// -// byte signerInfoSet[MAX_SET_SZ]; -// byte signerInfoSeq[MAX_SEQ_SZ]; -// byte signerVersion[MAX_VERSION_SZ]; -// byte issuerSnSeq[MAX_SEQ_SZ]; -// byte issuerName[MAX_SEQ_SZ]; -// byte issuerSn[MAX_SN_SZ]; -// byte signerDigAlgoId[MAX_ALGO_SZ]; -// byte digEncAlgoId[MAX_ALGO_SZ]; -// byte signedAttribSet[MAX_SET_SZ]; -// EncodedAttrib signedAttribs[6]; -// byte signerDigest[MAX_OCTET_STR_SZ]; -// word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz; -// word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz, -// singleDigAlgoIdSz, certsSetSz; -// word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz, -// issuerSnSeqSz, issuerNameSz, issuerSnSz, -// signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz; -// word32 encContentDigestSz, signedAttribsSz, signedAttribsCount, -// signedAttribSetSz; -//} ESD; -// -// -//static int EncodeAttributes(EncodedAttrib* ea, int eaSz, -// PKCS7Attrib* attribs, int attribsSz) -//{ -// int i; -// int maxSz = min(eaSz, attribsSz); -// int allAttribsSz = 0; -// -// for (i = 0; i < maxSz; i++) -// { -// int attribSz = 0; -// -// ea[i].value = attribs[i].value; -// ea[i].valueSz = attribs[i].valueSz; -// attribSz += ea[i].valueSz; -// ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet); -// attribSz += ea[i].valueSetSz; -// ea[i].oid = attribs[i].oid; -// ea[i].oidSz = attribs[i].oidSz; -// attribSz += ea[i].oidSz; -// ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq); -// attribSz += ea[i].valueSeqSz; -// ea[i].totalSz = attribSz; -// -// allAttribsSz += attribSz; -// } -// return allAttribsSz; -//} -// -// -//static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz) -//{ -// int i, idx; -// -// idx = 0; -// for (i = 0; i < eaSz; i++) { -// XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz); -// idx += ea[i].valueSeqSz; -// XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz); -// idx += ea[i].oidSz; -// XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz); -// idx += ea[i].valueSetSz; -// XMEMCPY(output + idx, ea[i].value, ea[i].valueSz); -// idx += ea[i].valueSz; -// } -// return 0; -//} -// -// -///* build PKCS#7 signedData content type */ -//int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) -//{ -// static const byte outerOid[] = -// { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, -// 0x07, 0x02 }; -// static const byte innerOid[] = -// { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, -// 0x07, 0x01 }; -// -//#ifdef CYASSL_SMALL_STACK -// ESD* esd = NULL; -//#else -// ESD stack_esd; -// ESD* esd = &stack_esd; -//#endif -// -// word32 signerInfoSz = 0; -// word32 totalSz = 0; -// int idx = 0, ret = 0; -// byte* flatSignedAttribs = NULL; -// word32 flatSignedAttribsSz = 0; -// word32 innerOidSz = sizeof(innerOid); -// word32 outerOidSz = sizeof(outerOid); -// -// if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 || -// pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 || -// pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 || -// pkcs7->privateKey == NULL || pkcs7->privateKeySz == 0 || -// output == NULL || outputSz == 0) -// return BAD_FUNC_ARG; -// -//#ifdef CYASSL_SMALL_STACK -// esd = (ESD*)XMALLOC(sizeof(ESD), NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (esd == NULL) -// return MEMORY_E; -//#endif -// -// XMEMSET(esd, 0, sizeof(ESD)); -// ret = InitSha(&esd->sha); -// if (ret != 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// -// if (pkcs7->contentSz != 0) -// { -// ShaUpdate(&esd->sha, pkcs7->content, pkcs7->contentSz); -// esd->contentDigest[0] = ASN_OCTET_STRING; -// esd->contentDigest[1] = SHA_DIGEST_SIZE; -// ShaFinal(&esd->sha, &esd->contentDigest[2]); -// } -// -// esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets); -// esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz, -// esd->innerContSeq); -// esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd->innerOctetsSz + -// innerOidSz + esd->innerContSeqSz, -// esd->contentInfoSeq); -// -// esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, -// esd->issuerSn); -// signerInfoSz += esd->issuerSnSz; -// esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName); -// signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz; -// esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq); -// signerInfoSz += esd->issuerSnSeqSz; -// esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0); -// signerInfoSz += esd->signerVersionSz; -// esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId, -// hashType, 0); -// signerInfoSz += esd->signerDigAlgoIdSz; -// esd->digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd->digEncAlgoId, -// keyType, 0); -// signerInfoSz += esd->digEncAlgoIdSz; -// -// if (pkcs7->signedAttribsSz != 0) { -// byte contentTypeOid[] = -// { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, -// 0x09, 0x03 }; -// byte contentType[] = -// { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, -// 0x07, 0x01 }; -// byte messageDigestOid[] = -// { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, -// 0x09, 0x04 }; -// -// PKCS7Attrib cannedAttribs[2] = -// { -// { contentTypeOid, sizeof(contentTypeOid), -// contentType, sizeof(contentType) }, -// { messageDigestOid, sizeof(messageDigestOid), -// esd->contentDigest, sizeof(esd->contentDigest) } -// }; -// word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); -// -// esd->signedAttribsCount += cannedAttribsCount; -// esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2, -// cannedAttribs, cannedAttribsCount); -// -// esd->signedAttribsCount += pkcs7->signedAttribsSz; -// esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4, -// pkcs7->signedAttribs, pkcs7->signedAttribsSz); -// -// flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, 0, NULL); -// flatSignedAttribsSz = esd->signedAttribsSz; -// if (flatSignedAttribs == NULL) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return MEMORY_E; -// } -// FlattenAttributes(flatSignedAttribs, -// esd->signedAttribs, esd->signedAttribsCount); -// esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz, -// esd->signedAttribSet); -// } -// /* Calculate the final hash and encrypt it. */ -// { -// int result; -// word32 scratch = 0; -// -//#ifdef CYASSL_SMALL_STACK -// byte* digestInfo; -// RsaKey* privKey; -//#else -// RsaKey stack_privKey; -// RsaKey* privKey = &stack_privKey; -// byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ + -// MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE]; -//#endif -// byte digestInfoSeq[MAX_SEQ_SZ]; -// byte digestStr[MAX_OCTET_STR_SZ]; -// word32 digestInfoSeqSz, digestStrSz; -// int digIdx = 0; -// -// if (pkcs7->signedAttribsSz != 0) { -// byte attribSet[MAX_SET_SZ]; -// word32 attribSetSz; -// -// attribSetSz = SetSet(flatSignedAttribsSz, attribSet); -// -// ret = InitSha(&esd->sha); -// if (ret < 0) { -// XFREE(flatSignedAttribs, 0, NULL); -//#ifdef CYASSL_SMALL_STACK -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// ShaUpdate(&esd->sha, attribSet, attribSetSz); -// ShaUpdate(&esd->sha, flatSignedAttribs, flatSignedAttribsSz); -// } -// ShaFinal(&esd->sha, esd->contentAttribsDigest); -// -// digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr); -// digestInfoSeqSz = SetSequence(esd->signerDigAlgoIdSz + -// digestStrSz + SHA_DIGEST_SIZE, -// digestInfoSeq); -// -//#ifdef CYASSL_SMALL_STACK -// digestInfo = (byte*)XMALLOC(MAX_SEQ_SZ + MAX_ALGO_SZ + -// MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE, -// NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (digestInfo == NULL) { -// if (pkcs7->signedAttribsSz != 0) -// XFREE(flatSignedAttribs, 0, NULL); -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// return MEMORY_E; -// } -//#endif -// -// XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz); -// digIdx += digestInfoSeqSz; -// XMEMCPY(digestInfo + digIdx, -// esd->signerDigAlgoId, esd->signerDigAlgoIdSz); -// digIdx += esd->signerDigAlgoIdSz; -// XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz); -// digIdx += digestStrSz; -// XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, -// SHA_DIGEST_SIZE); -// digIdx += SHA_DIGEST_SIZE; -// -//#ifdef CYASSL_SMALL_STACK -// privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// if (privKey == NULL) { -// if (pkcs7->signedAttribsSz != 0) -// XFREE(flatSignedAttribs, 0, NULL); -// XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// return MEMORY_E; -// } -//#endif -// -// result = InitRsaKey(privKey, NULL); -// if (result == 0) -// result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, privKey, -// pkcs7->privateKeySz); -// if (result < 0) { -// if (pkcs7->signedAttribsSz != 0) -// XFREE(flatSignedAttribs, 0, NULL); -//#ifdef CYASSL_SMALL_STACK -// XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return PUBLIC_KEY_E; -// } -// -// result = RsaSSL_Sign(digestInfo, digIdx, -// esd->encContentDigest, -// sizeof(esd->encContentDigest), -// privKey, pkcs7->rng); -// -// FreeRsaKey(privKey); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// if (result < 0) { -// if (pkcs7->signedAttribsSz != 0) -// XFREE(flatSignedAttribs, 0, NULL); -//#ifdef CYASSL_SMALL_STACK -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return result; -// } -// esd->encContentDigestSz = (word32)result; -// } -// signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz; -// -// esd->signerDigestSz = SetOctetString(esd->encContentDigestSz, -// esd->signerDigest); -// signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz; -// -// esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq); -// signerInfoSz += esd->signerInfoSeqSz; -// esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet); -// signerInfoSz += esd->signerInfoSetSz; -// -// esd->certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz, -// esd->certsSet); -// -// esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId, -// hashType, 0); -// esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet); -// -// -// esd->versionSz = SetMyVersion(1, esd->version, 0); -// -// totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz + -// esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz + -// esd->innerOctetsSz + esd->innerContSeqSz + -// innerOidSz + pkcs7->contentSz + -// signerInfoSz; -// esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq); -// totalSz += esd->innerSeqSz; -// esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent); -// totalSz += esd->outerContentSz + outerOidSz; -// esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq); -// totalSz += esd->outerSeqSz; -// -// if (outputSz < totalSz) { -// if (pkcs7->signedAttribsSz != 0) -// XFREE(flatSignedAttribs, 0, NULL); -//#ifdef CYASSL_SMALL_STACK -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return BUFFER_E; -// } -// -// idx = 0; -// XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz); -// idx += esd->outerSeqSz; -// XMEMCPY(output + idx, outerOid, outerOidSz); -// idx += outerOidSz; -// XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz); -// idx += esd->outerContentSz; -// XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz); -// idx += esd->innerSeqSz; -// XMEMCPY(output + idx, esd->version, esd->versionSz); -// idx += esd->versionSz; -// XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz); -// idx += esd->digAlgoIdSetSz; -// XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz); -// idx += esd->singleDigAlgoIdSz; -// XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz); -// idx += esd->contentInfoSeqSz; -// XMEMCPY(output + idx, innerOid, innerOidSz); -// idx += innerOidSz; -// XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz); -// idx += esd->innerContSeqSz; -// XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz); -// idx += esd->innerOctetsSz; -// XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz); -// idx += pkcs7->contentSz; -// XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz); -// idx += esd->certsSetSz; -// XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz); -// idx += pkcs7->singleCertSz; -// XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz); -// idx += esd->signerInfoSetSz; -// XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz); -// idx += esd->signerInfoSeqSz; -// XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz); -// idx += esd->signerVersionSz; -// XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz); -// idx += esd->issuerSnSeqSz; -// XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz); -// idx += esd->issuerNameSz; -// XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz); -// idx += pkcs7->issuerSz; -// XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz); -// idx += esd->issuerSnSz; -// XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz); -// idx += esd->signerDigAlgoIdSz; -// -// /* SignerInfo:Attributes */ -// if (pkcs7->signedAttribsSz != 0) { -// XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz); -// idx += esd->signedAttribSetSz; -// XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz); -// idx += flatSignedAttribsSz; -// XFREE(flatSignedAttribs, 0, NULL); -// } -// -// XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz); -// idx += esd->digEncAlgoIdSz; -// XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz); -// idx += esd->signerDigestSz; -// XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz); -// idx += esd->encContentDigestSz; -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// return idx; -//} -// -// -///* Finds the certificates in the message and saves it. */ -//int PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz) -//{ -// word32 idx, contentType; -// int length, version, ret; -// byte* content = NULL; -// byte* sig = NULL; -// byte* cert = NULL; -// int contentSz = 0, sigSz = 0, certSz = 0; -// -// if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0) -// return BAD_FUNC_ARG; -// -// idx = 0; -// -// /* Get the contentInfo sequence */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Get the contentInfo contentType */ -// if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (contentType != SIGNED_DATA) { -// CYASSL_MSG("PKCS#7 input not of type SignedData"); -// return PKCS7_OID_E; -// } -// -// /* get the ContentInfo content */ -// if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) -// return ASN_PARSE_E; -// -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Get the signedData sequence */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Get the version */ -// if (GetMyVersion(pkiMsg, &idx, &version) < 0) -// return ASN_PARSE_E; -// -// if (version != 1) { -// CYASSL_MSG("PKCS#7 signedData needs to be of version 1"); -// return ASN_VERSION_E; -// } -// -// /* Get the set of DigestAlgorithmIdentifiers */ -// if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Skip the set. */ -// idx += length; -// -// /* Get the inner ContentInfo sequence */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Get the inner ContentInfo contentType */ -// if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (contentType != DATA) { -// CYASSL_MSG("PKCS#7 inner input not of type Data"); -// return PKCS7_OID_E; -// } -// -// if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) -// return ASN_PARSE_E; -// -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (pkiMsg[idx++] != ASN_OCTET_STRING) -// return ASN_PARSE_E; -// -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Save the inner data as the content. */ -// if (length > 0) { -// /* Local pointer for calculating hashes later */ -// pkcs7->content = content = &pkiMsg[idx]; -// pkcs7->contentSz = contentSz = length; -// idx += length; -// } -// -// /* Get the implicit[0] set of certificates */ -// if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { -// idx++; -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (length > 0) { -// /* At this point, idx is at the first certificate in -// * a set of certificates. There may be more than one, -// * or none, or they may be a PKCS 6 extended -// * certificate. We want to save the first cert if it -// * is X.509. */ -// -// word32 certIdx = idx; -// -// if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) { -// if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// cert = &pkiMsg[idx]; -// certSz += (certIdx - idx); -// } -// PKCS7_InitWithCert(pkcs7, cert, certSz); -// } -// idx += length; -// } -// -// /* Get the implicit[1] set of crls */ -// if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { -// idx++; -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Skip the set */ -// idx += length; -// } -// -// /* Get the set of signerInfos */ -// if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (length > 0) { -// /* Get the sequence of the first signerInfo */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Get the version */ -// if (GetMyVersion(pkiMsg, &idx, &version) < 0) -// return ASN_PARSE_E; -// -// if (version != 1) { -// CYASSL_MSG("PKCS#7 signerInfo needs to be of version 1"); -// return ASN_VERSION_E; -// } -// -// /* Get the sequence of IssuerAndSerialNumber */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Skip it */ -// idx += length; -// -// /* Get the sequence of digestAlgorithm */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Skip it */ -// idx += length; -// -// /* Get the IMPLICIT[0] SET OF signedAttributes */ -// if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { -// idx++; -// -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// idx += length; -// } -// -// /* Get the sequence of digestEncryptionAlgorithm */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* Skip it */ -// idx += length; -// -// /* Get the signature */ -// if (pkiMsg[idx] == ASN_OCTET_STRING) { -// idx++; -// -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* save pointer and length */ -// sig = &pkiMsg[idx]; -// sigSz = length; -// -// idx += length; -// } -// -// pkcs7->content = content; -// pkcs7->contentSz = contentSz; -// -// { -// word32 scratch = 0; -// int plainSz = 0; -// int digestSz = MAX_SEQ_SZ + MAX_ALGO_SZ + -// MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE; -// -//#ifdef CYASSL_SMALL_STACK -// byte* digest; -// RsaKey* key; -// -// digest = (byte*)XMALLOC(digestSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// -// if (digest == NULL) -// return MEMORY_E; -// -// key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// if (key == NULL) { -// XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// return MEMORY_E; -// } -//#else -// byte digest[digestSz]; -// RsaKey stack_key; -// RsaKey* key = &stack_key; -//#endif -// -// XMEMSET(digest, 0, digestSz); -// -// ret = InitRsaKey(key, NULL); -// if (ret != 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// if (RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key, -// pkcs7->publicKeySz) < 0) { -// CYASSL_MSG("ASN RSA key decode error"); -//#ifdef CYASSL_SMALL_STACK -// XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return PUBLIC_KEY_E; -// } -// -// plainSz = RsaSSL_Verify(sig, sigSz, digest, digestSz, key); -// FreeRsaKey(key); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// if (plainSz < 0) -// return plainSz; -// } -// } -// -// return 0; -//} -// -// -///* create ASN.1 fomatted RecipientInfo structure, returns sequence size */ -//CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz, -// int keyEncAlgo, int blockKeySz, -// RNG* rng, byte* contentKeyPlain, -// byte* contentKeyEnc, -// int* keyEncSz, byte* out, word32 outSz) -//{ -// word32 idx = 0; -// int ret = 0, totalSz = 0; -// int verSz, issuerSz, snSz, keyEncAlgSz; -// int issuerSeqSz, recipSeqSz, issuerSerialSeqSz; -// int encKeyOctetStrSz; -// -// byte ver[MAX_VERSION_SZ]; -// byte issuerSerialSeq[MAX_SEQ_SZ]; -// byte recipSeq[MAX_SEQ_SZ]; -// byte issuerSeq[MAX_SEQ_SZ]; -// byte encKeyOctetStr[MAX_OCTET_STR_SZ]; -// -//#ifdef CYASSL_SMALL_STACK -// byte *serial; -// byte *keyAlgArray; -// -// RsaKey* pubKey; -// DecodedCert* decoded; -// -// serial = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// -// if (decoded == NULL || serial == NULL || keyAlgArray == NULL) { -// if (serial) XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (keyAlgArray) XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (decoded) XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// return MEMORY_E; -// } -// -//#else -// byte serial[MAX_SN_SZ]; -// byte keyAlgArray[MAX_ALGO_SZ]; -// -// RsaKey stack_pubKey; -// RsaKey* pubKey = &stack_pubKey; -// DecodedCert stack_decoded; -// DecodedCert* decoded = &stack_decoded; -//#endif -// -// InitDecodedCert(decoded, (byte*)cert, certSz, 0); -// ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0); -// if (ret < 0) { -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// -// /* version */ -// verSz = SetMyVersion(0, ver, 0); -// -// /* IssuerAndSerialNumber */ -// if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) { -// CYASSL_MSG("DecodedCert lacks raw issuer pointer and length"); -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return -1; -// } -// issuerSz = decoded->issuerRawLen; -// issuerSeqSz = SetSequence(issuerSz, issuerSeq); -// -// if (decoded->serial == NULL || decoded->serialSz == 0) { -// CYASSL_MSG("DecodedCert missing serial number"); -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return -1; -// } -// snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial); -// -// issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz, -// issuerSerialSeq); -// -// /* KeyEncryptionAlgorithmIdentifier, only support RSA now */ -// if (keyEncAlgo != RSAk) { -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ALGO_ID_E; -// } -// -// keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0); -// if (keyEncAlgSz == 0) { -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return BAD_FUNC_ARG; -// } -// -//#ifdef CYASSL_SMALL_STACK -// pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (pubKey == NULL) { -// FreeDecodedCert(decoded); -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// return MEMORY_E; -// } -//#endif -// -// /* EncryptedKey */ -// ret = InitRsaKey(pubKey, 0); -// if (ret != 0) { -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// -// if (RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey, -// decoded->pubKeySize) < 0) { -// CYASSL_MSG("ASN RSA key decode error"); -// FreeRsaKey(pubKey); -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return PUBLIC_KEY_E; -// } -// -// *keyEncSz = RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc, -// MAX_ENCRYPTED_KEY_SZ, pubKey, rng); -// FreeRsaKey(pubKey); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// if (*keyEncSz < 0) { -// CYASSL_MSG("RSA Public Encrypt failed"); -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return *keyEncSz; -// } -// -// encKeyOctetStrSz = SetOctetString(*keyEncSz, encKeyOctetStr); -// -// /* RecipientInfo */ -// recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz + -// issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz + -// *keyEncSz, recipSeq); -// -// if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz + -// keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) { -// CYASSL_MSG("RecipientInfo output buffer too small"); -// FreeDecodedCert(decoded); -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return BUFFER_E; -// } -// -// XMEMCPY(out + totalSz, recipSeq, recipSeqSz); -// totalSz += recipSeqSz; -// XMEMCPY(out + totalSz, ver, verSz); -// totalSz += verSz; -// XMEMCPY(out + totalSz, issuerSerialSeq, issuerSerialSeqSz); -// totalSz += issuerSerialSeqSz; -// XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz); -// totalSz += issuerSeqSz; -// XMEMCPY(out + totalSz, decoded->issuerRaw, issuerSz); -// totalSz += issuerSz; -// XMEMCPY(out + totalSz, serial, snSz); -// totalSz += snSz; -// XMEMCPY(out + totalSz, keyAlgArray, keyEncAlgSz); -// totalSz += keyEncAlgSz; -// XMEMCPY(out + totalSz, encKeyOctetStr, encKeyOctetStrSz); -// totalSz += encKeyOctetStrSz; -// XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz); -// totalSz += *keyEncSz; -// -// FreeDecodedCert(decoded); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// return totalSz; -//} -// -// -///* build PKCS#7 envelopedData content type, return enveloped size */ -//int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) -//{ -// int i, ret = 0, idx = 0; -// int totalSz = 0, padSz = 0, desOutSz = 0; -// -// int contentInfoSeqSz, outerContentTypeSz, outerContentSz; -// byte contentInfoSeq[MAX_SEQ_SZ]; -// byte outerContentType[MAX_ALGO_SZ]; -// byte outerContent[MAX_SEQ_SZ]; -// -// int envDataSeqSz, verSz; -// byte envDataSeq[MAX_SEQ_SZ]; -// byte ver[MAX_VERSION_SZ]; -// -// RNG rng; -// int contentKeyEncSz, blockKeySz; -// int dynamicFlag = 0; -// byte contentKeyPlain[MAX_CONTENT_KEY_LEN]; -//#ifdef CYASSL_SMALL_STACK -// byte* contentKeyEnc; -//#else -// byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ]; -//#endif -// byte* plain; -// byte* encryptedContent; -// -// int recipSz, recipSetSz; -//#ifdef CYASSL_SMALL_STACK -// byte* recip; -//#else -// byte recip[MAX_RECIP_SZ]; -//#endif -// byte recipSet[MAX_SET_SZ]; -// -// int encContentOctetSz, encContentSeqSz, contentTypeSz; -// int contentEncAlgoSz, ivOctetStringSz; -// byte encContentSeq[MAX_SEQ_SZ]; -// byte contentType[MAX_ALGO_SZ]; -// byte contentEncAlgo[MAX_ALGO_SZ]; -// byte tmpIv[DES_BLOCK_SIZE]; -// byte ivOctetString[MAX_OCTET_STR_SZ]; -// byte encContentOctet[MAX_OCTET_STR_SZ]; -// -// if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 || -// pkcs7->encryptOID == 0 || pkcs7->singleCert == NULL) -// return BAD_FUNC_ARG; -// -// if (output == NULL || outputSz == 0) -// return BAD_FUNC_ARG; -// -// /* PKCS#7 only supports DES, 3DES for now */ -// switch (pkcs7->encryptOID) { -// case DESb: -// blockKeySz = DES_KEYLEN; -// break; -// -// case DES3b: -// blockKeySz = DES3_KEYLEN; -// break; -// -// default: -// CYASSL_MSG("Unsupported content cipher type"); -// return ALGO_ID_E; -// }; -// -// /* outer content type */ -// outerContentTypeSz = SetContentType(ENVELOPED_DATA, outerContentType); -// -// /* version, defined as 0 in RFC 2315 */ -// verSz = SetMyVersion(0, ver, 0); -// -// /* generate random content encryption key */ -// ret = InitRng(&rng); -// if (ret != 0) -// return ret; -// -// ret = RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz); -// if (ret != 0) -// return ret; -// -//#ifdef CYASSL_SMALL_STACK -// recip = (byte*)XMALLOC(MAX_RECIP_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// contentKeyEnc = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// if (contentKeyEnc == NULL || recip == NULL) { -// if (recip) XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (contentKeyEnc) XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// return MEMORY_E; -// } -// -//#endif -// -// /* build RecipientInfo, only handle 1 for now */ -// recipSz = CreateRecipientInfo(pkcs7->singleCert, pkcs7->singleCertSz, RSAk, -// blockKeySz, &rng, contentKeyPlain, -// contentKeyEnc, &contentKeyEncSz, recip, -// MAX_RECIP_SZ); -// -// XMEMSET(contentKeyEnc, 0, MAX_ENCRYPTED_KEY_SZ); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// if (recipSz < 0) { -// CYASSL_MSG("Failed to create RecipientInfo"); -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return recipSz; -// } -// recipSetSz = SetSet(recipSz, recipSet); -// -// /* generate IV for block cipher */ -// ret = RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE); -// if (ret != 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// -// /* EncryptedContentInfo */ -// contentTypeSz = SetContentType(pkcs7->contentOID, contentType); -// if (contentTypeSz == 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return BAD_FUNC_ARG; -// } -// -// /* allocate encrypted content buffer, pad if necessary, PKCS#7 padding */ -// padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE); -// desOutSz = pkcs7->contentSz + padSz; -// -// if (padSz != 0) { -// plain = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (plain == NULL) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return MEMORY_E; -// } -// XMEMCPY(plain, pkcs7->content, pkcs7->contentSz); -// dynamicFlag = 1; -// -// for (i = 0; i < padSz; i++) { -// plain[pkcs7->contentSz + i] = padSz; -// } -// -// } else { -// plain = pkcs7->content; -// desOutSz = pkcs7->contentSz; -// } -// -// encryptedContent = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (encryptedContent == NULL) { -// if (dynamicFlag) -// XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return MEMORY_E; -// } -// -// /* put together IV OCTET STRING */ -// ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString); -// -// /* build up our ContentEncryptionAlgorithmIdentifier sequence, -// * adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */ -// contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo, -// blkType, ivOctetStringSz + DES_BLOCK_SIZE); -// -// if (contentEncAlgoSz == 0) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (dynamicFlag) -// XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return BAD_FUNC_ARG; -// } -// -// /* encrypt content */ -// if (pkcs7->encryptOID == DESb) { -// Des des; -// -// ret = Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION); -// -// if (ret == 0) -// Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz); -// -// if (ret != 0) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (dynamicFlag) -// XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// } -// else if (pkcs7->encryptOID == DES3b) { -// Des3 des3; -// -// ret = Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION); -// -// if (ret == 0) -// ret = Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz); -// -// if (ret != 0) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (dynamicFlag) -// XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// } -// -// encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, -// desOutSz, encContentOctet); -// -// encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz + -// ivOctetStringSz + DES_BLOCK_SIZE + -// encContentOctetSz + desOutSz, encContentSeq); -// -// /* keep track of sizes for outer wrapper layering */ -// totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz + -// contentEncAlgoSz + ivOctetStringSz + DES_BLOCK_SIZE + -// encContentOctetSz + desOutSz; -// -// /* EnvelopedData */ -// envDataSeqSz = SetSequence(totalSz, envDataSeq); -// totalSz += envDataSeqSz; -// -// /* outer content */ -// outerContentSz = SetExplicit(0, totalSz, outerContent); -// totalSz += outerContentTypeSz; -// totalSz += outerContentSz; -// -// /* ContentInfo */ -// contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq); -// totalSz += contentInfoSeqSz; -// -// if (totalSz > (int)outputSz) { -// CYASSL_MSG("Pkcs7_encrypt output buffer too small"); -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (dynamicFlag) -// XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// return BUFFER_E; -// } -// -// XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz); -// idx += contentInfoSeqSz; -// XMEMCPY(output + idx, outerContentType, outerContentTypeSz); -// idx += outerContentTypeSz; -// XMEMCPY(output + idx, outerContent, outerContentSz); -// idx += outerContentSz; -// XMEMCPY(output + idx, envDataSeq, envDataSeqSz); -// idx += envDataSeqSz; -// XMEMCPY(output + idx, ver, verSz); -// idx += verSz; -// XMEMCPY(output + idx, recipSet, recipSetSz); -// idx += recipSetSz; -// XMEMCPY(output + idx, recip, recipSz); -// idx += recipSz; -// XMEMCPY(output + idx, encContentSeq, encContentSeqSz); -// idx += encContentSeqSz; -// XMEMCPY(output + idx, contentType, contentTypeSz); -// idx += contentTypeSz; -// XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz); -// idx += contentEncAlgoSz; -// XMEMCPY(output + idx, ivOctetString, ivOctetStringSz); -// idx += ivOctetStringSz; -// XMEMCPY(output + idx, tmpIv, DES_BLOCK_SIZE); -// idx += DES_BLOCK_SIZE; -// XMEMCPY(output + idx, encContentOctet, encContentOctetSz); -// idx += encContentOctetSz; -// XMEMCPY(output + idx, encryptedContent, desOutSz); -// idx += desOutSz; -// -//#if defined(HAVE_HASHDRBG) || defined(NO_RC4) -// FreeRng(&rng); -//#endif -// -// XMEMSET(contentKeyPlain, 0, MAX_CONTENT_KEY_LEN); -// -// if (dynamicFlag) -// XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER); -//#endif -// -// return idx; -//} -// -///* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */ -//CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg, -// word32 pkiMsgSz, byte* output, -// word32 outputSz) -//{ -// int recipFound = 0; -// int ret, version, length; -// word32 savedIdx = 0, idx = 0; -// word32 contentType, encOID; -// byte issuerHash[SHA_DIGEST_SIZE]; -// -// int encryptedKeySz, keySz; -// byte tmpIv[DES_BLOCK_SIZE]; -// byte* decryptedKey = NULL; -// -//#ifdef CYASSL_SMALL_STACK -// mp_int* serialNum; -// byte* encryptedKey; -// RsaKey* privKey; -//#else -// mp_int stack_serialNum; -// mp_int* serialNum = &stack_serialNum; -// byte encryptedKey[MAX_ENCRYPTED_KEY_SZ]; -// -// RsaKey stack_privKey; -// RsaKey* privKey = &stack_privKey; -//#endif -// int encryptedContentSz; -// byte padLen; -// byte* encryptedContent = NULL; -// -// if (pkcs7 == NULL || pkcs7->singleCert == NULL || -// pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL || -// pkcs7->privateKeySz == 0) -// return BAD_FUNC_ARG; -// -// if (pkiMsg == NULL || pkiMsgSz == 0 || -// output == NULL || outputSz == 0) -// return BAD_FUNC_ARG; -// -// /* read past ContentInfo, verify type is envelopedData */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (contentType != ENVELOPED_DATA) { -// CYASSL_MSG("PKCS#7 input not of type EnvelopedData"); -// return PKCS7_OID_E; -// } -// -// if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) -// return ASN_PARSE_E; -// -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// /* remove EnvelopedData and version */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -// if (GetMyVersion(pkiMsg, &idx, &version) < 0) -// return ASN_PARSE_E; -// -// if (version != 0) { -// CYASSL_MSG("PKCS#7 envelopedData needs to be of version 0"); -// return ASN_VERSION_E; -// } -// -// /* walk through RecipientInfo set, find correct recipient */ -// if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) -// return ASN_PARSE_E; -// -//#ifdef CYASSL_SMALL_STACK -// encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// if (encryptedKey == NULL) -// return MEMORY_E; -//#endif -// -// savedIdx = idx; -// recipFound = 0; -// -// /* when looking for next recipient, use first sequence and version to -// * indicate there is another, if not, move on */ -// while(recipFound == 0) { -// -// /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to -// * last good saved one */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { -// idx = savedIdx; -// break; -// } -// -// if (GetMyVersion(pkiMsg, &idx, &version) < 0) { -// idx = savedIdx; -// break; -// } -// -// if (version != 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_VERSION_E; -// } -// -// /* remove IssuerAndSerialNumber */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// /* if we found correct recipient, issuer hashes will match */ -// if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) { -// recipFound = 1; -// } -// -//#ifdef CYASSL_SMALL_STACK -// serialNum = (mp_int*)XMALLOC(sizeof(mp_int), NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// if (serialNum == NULL) { -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// return MEMORY_E; -// } -//#endif -// -// if (GetInt(serialNum, pkiMsg, &idx, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// mp_clear(serialNum); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// /* key encryption algorithm must be RSA for now */ -// if (encOID != RSAk) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ALGO_ID_E; -// } -// -// /* read encryptedKey */ -// if (pkiMsg[idx++] != ASN_OCTET_STRING) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (recipFound == 1) -// XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz); -// idx += encryptedKeySz; -// -// /* update good idx */ -// savedIdx = idx; -// } -// -// if (recipFound == 0) { -// CYASSL_MSG("No recipient found in envelopedData that matches input"); -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return PKCS7_RECIP_E; -// } -// -// /* remove EncryptedContentInfo */ -// if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */ -// if (pkiMsg[idx++] != ASN_OCTET_STRING) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (length != DES_BLOCK_SIZE) { -// CYASSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE"); -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// XMEMCPY(tmpIv, &pkiMsg[idx], length); -// idx += length; -// -// /* read encryptedContent, cont[0] */ -// if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ASN_PARSE_E; -// } -// -// encryptedContent = (byte*)XMALLOC(encryptedContentSz, NULL, -// DYNAMIC_TYPE_TMP_BUFFER); -// if (encryptedContent == NULL) { -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return MEMORY_E; -// } -// -// XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz); -// -// /* load private key */ -//#ifdef CYASSL_SMALL_STACK -// privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); -// if (privKey == NULL) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; -// } -//#endif -// -// ret = InitRsaKey(privKey, 0); -// if (ret != 0) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// -// idx = 0; -// -// ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey, -// pkcs7->privateKeySz); -// if (ret != 0) { -// CYASSL_MSG("Failed to decode RSA private key"); -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// -// /* decrypt encryptedKey */ -// keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz, -// &decryptedKey, privKey); -// FreeRsaKey(privKey); -// -//#ifdef CYASSL_SMALL_STACK -// XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// if (keySz <= 0) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return keySz; -// } -// -// /* decrypt encryptedContent */ -// if (encOID == DESb) { -// Des des; -// ret = Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION); -// -// if (ret == 0) -// Des_CbcDecrypt(&des, encryptedContent, encryptedContent, -// encryptedContentSz); -// -// if (ret != 0) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// } -// else if (encOID == DES3b) { -// Des3 des; -// ret = Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION); -// if (ret == 0) -// ret = Des3_CbcDecrypt(&des, encryptedContent, encryptedContent, -// encryptedContentSz); -// -// if (ret != 0) { -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ret; -// } -// } else { -// CYASSL_MSG("Unsupported content encryption OID type"); -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// return ALGO_ID_E; -// } -// -// padLen = encryptedContent[encryptedContentSz-1]; -// -// /* copy plaintext to output */ -// XMEMCPY(output, encryptedContent, encryptedContentSz - padLen); -// -// /* free memory, zero out keys */ -// XMEMSET(encryptedKey, 0, MAX_ENCRYPTED_KEY_SZ); -// XMEMSET(encryptedContent, 0, encryptedContentSz); -// XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#ifdef CYASSL_SMALL_STACK -// XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); -//#endif -// -// return encryptedContentSz - padLen; -//} -// -// -//#else /* HAVE_PKCS7 */ -// -// -//#ifdef _MSC_VER -// /* 4206 warning for blank file */ -// #pragma warning(disable: 4206) -//#endif -// -// -//#endif /* HAVE_PKCS7 */ -// diff --git a/ctaocrypt/src/pwdbased.c b/ctaocrypt/src/pwdbased.c deleted file mode 100644 index ca96a40f1..000000000 --- a/ctaocrypt/src/pwdbased.c +++ /dev/null @@ -1,474 +0,0 @@ -/* pwdbased.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifndef NO_PWDBASED - -#ifdef CYASSL_PIC32MZ_HASH - -#define InitMd5 InitMd5_sw -#define Md5Update Md5Update_sw -#define Md5Final Md5Final_sw - -#define InitSha InitSha_sw -#define ShaUpdate ShaUpdate_sw -#define ShaFinal ShaFinal_sw - -#define InitSha256 InitSha256_sw -#define Sha256Update Sha256Update_sw -#define Sha256Final Sha256Final_sw - -#endif - -#include -#include -#include -#include -#if defined(CYASSL_SHA512) || defined(CYASSL_SHA384) - #include -#endif - -#ifdef NO_INLINE - #include -#else - #include -#endif - - -#ifndef min - - static INLINE word32 min(word32 a, word32 b) - { - return a > b ? b : a; - } - -#endif /* min */ - - -int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, - int sLen, int iterations, int kLen, int hashType) -{ - Md5 md5; - Sha sha; - int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE; - int i, ret = 0; - byte buffer[SHA_DIGEST_SIZE]; /* max size */ - - if (hashType != MD5 && hashType != SHA) - return BAD_FUNC_ARG; - - if (kLen > hLen) - return BAD_FUNC_ARG; - - if (iterations < 1) - return BAD_FUNC_ARG; - - if (hashType == MD5) { - InitMd5(&md5); - Md5Update(&md5, passwd, pLen); - Md5Update(&md5, salt, sLen); - Md5Final(&md5, buffer); - } - else { - ret = InitSha(&sha); - if (ret != 0) - return ret; - ShaUpdate(&sha, passwd, pLen); - ShaUpdate(&sha, salt, sLen); - ShaFinal(&sha, buffer); - } - - for (i = 1; i < iterations; i++) { - if (hashType == MD5) { - Md5Update(&md5, buffer, hLen); - Md5Final(&md5, buffer); - } - else { - ShaUpdate(&sha, buffer, hLen); - ShaFinal(&sha, buffer); - } - } - XMEMCPY(output, buffer, kLen); - - return 0; -} - - -int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, - int sLen, int iterations, int kLen, int hashType) -{ - word32 i = 1; - int hLen; - int j, ret; - Hmac hmac; -#ifdef CYASSL_SMALL_STACK - byte* buffer; -#else - byte buffer[MAX_DIGEST_SIZE]; -#endif - - if (hashType == MD5) { - hLen = MD5_DIGEST_SIZE; - } - else if (hashType == SHA) { - hLen = SHA_DIGEST_SIZE; - } -#ifndef NO_SHA256 - else if (hashType == SHA256) { - hLen = SHA256_DIGEST_SIZE; - } -#endif -#ifdef CYASSL_SHA512 - else if (hashType == SHA512) { - hLen = SHA512_DIGEST_SIZE; - } -#endif - else - return BAD_FUNC_ARG; - -#ifdef CYASSL_SMALL_STACK - buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (buffer == NULL) - return MEMORY_E; -#endif - - ret = HmacSetKey(&hmac, hashType, passwd, pLen); - - if (ret == 0) { - while (kLen) { - int currentLen; - - ret = HmacUpdate(&hmac, salt, sLen); - if (ret != 0) - break; - - /* encode i */ - for (j = 0; j < 4; j++) { - byte b = (byte)(i >> ((3-j) * 8)); - - ret = HmacUpdate(&hmac, &b, 1); - if (ret != 0) - break; - } - - /* check ret from inside for loop */ - if (ret != 0) - break; - - ret = HmacFinal(&hmac, buffer); - if (ret != 0) - break; - - currentLen = min(kLen, hLen); - XMEMCPY(output, buffer, currentLen); - - for (j = 1; j < iterations; j++) { - ret = HmacUpdate(&hmac, buffer, hLen); - if (ret != 0) - break; - ret = HmacFinal(&hmac, buffer); - if (ret != 0) - break; - xorbuf(output, buffer, currentLen); - } - - /* check ret from inside for loop */ - if (ret != 0) - break; - - output += currentLen; - kLen -= currentLen; - i++; - } - } - -#ifdef CYASSL_SMALL_STACK - XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - -#ifdef CYASSL_SHA512 -#define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE -#elif !defined(NO_SHA256) -#define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE -#else -#define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE -#endif - -int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, - int saltLen, int iterations, int kLen, int hashType, int id) -{ - /* all in bytes instead of bits */ - word32 u, v, dLen, pLen, iLen, sLen, totalLen; - int dynamic = 0; - int ret = 0; - int i; - byte *D, *S, *P, *I; -#ifdef CYASSL_SMALL_STACK - byte staticBuffer[1]; /* force dynamic usage */ -#else - byte staticBuffer[1024]; -#endif - byte* buffer = staticBuffer; - -#ifdef CYASSL_SMALL_STACK - byte* Ai; - byte* B; -#else - byte Ai[PBKDF_DIGEST_SIZE]; - byte B[PBKDF_DIGEST_SIZE]; -#endif - - if (!iterations) - iterations = 1; - - if (hashType == MD5) { - v = MD5_BLOCK_SIZE; - u = MD5_DIGEST_SIZE; - } - else if (hashType == SHA) { - v = SHA_BLOCK_SIZE; - u = SHA_DIGEST_SIZE; - } -#ifndef NO_SHA256 - else if (hashType == SHA256) { - v = SHA256_BLOCK_SIZE; - u = SHA256_DIGEST_SIZE; - } -#endif -#ifdef CYASSL_SHA512 - else if (hashType == SHA512) { - v = SHA512_BLOCK_SIZE; - u = SHA512_DIGEST_SIZE; - } -#endif - else - return BAD_FUNC_ARG; - -#ifdef CYASSL_SMALL_STACK - Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (Ai == NULL) - return MEMORY_E; - - B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (B == NULL) { - XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - dLen = v; - sLen = v * ((saltLen + v - 1) / v); - if (passLen) - pLen = v * ((passLen + v - 1) / v); - else - pLen = 0; - iLen = sLen + pLen; - - totalLen = dLen + sLen + pLen; - - if (totalLen > sizeof(staticBuffer)) { - buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY); - if (buffer == NULL) { -#ifdef CYASSL_SMALL_STACK - XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - return MEMORY_E; - } - dynamic = 1; - } - - D = buffer; - S = D + dLen; - P = S + sLen; - I = S; - - XMEMSET(D, id, dLen); - - for (i = 0; i < (int)sLen; i++) - S[i] = salt[i % saltLen]; - for (i = 0; i < (int)pLen; i++) - P[i] = passwd[i % passLen]; - - while (kLen > 0) { - word32 currentLen; - mp_int B1; - - if (hashType == MD5) { - Md5 md5; - - InitMd5(&md5); - Md5Update(&md5, buffer, totalLen); - Md5Final(&md5, Ai); - - for (i = 1; i < iterations; i++) { - Md5Update(&md5, Ai, u); - Md5Final(&md5, Ai); - } - } - else if (hashType == SHA) { - Sha sha; - - ret = InitSha(&sha); - if (ret != 0) - break; - ShaUpdate(&sha, buffer, totalLen); - ShaFinal(&sha, Ai); - - for (i = 1; i < iterations; i++) { - ShaUpdate(&sha, Ai, u); - ShaFinal(&sha, Ai); - } - } -#ifndef NO_SHA256 - else if (hashType == SHA256) { - Sha256 sha256; - - ret = InitSha256(&sha256); - if (ret != 0) - break; - - ret = Sha256Update(&sha256, buffer, totalLen); - if (ret != 0) - break; - - ret = Sha256Final(&sha256, Ai); - if (ret != 0) - break; - - for (i = 1; i < iterations; i++) { - ret = Sha256Update(&sha256, Ai, u); - if (ret != 0) - break; - - ret = Sha256Final(&sha256, Ai); - if (ret != 0) - break; - } - } -#endif -#ifdef CYASSL_SHA512 - else if (hashType == SHA512) { - Sha512 sha512; - - ret = InitSha512(&sha512); - if (ret != 0) - break; - - ret = Sha512Update(&sha512, buffer, totalLen); - if (ret != 0) - break; - - ret = Sha512Final(&sha512, Ai); - if (ret != 0) - break; - - for (i = 1; i < iterations; i++) { - ret = Sha512Update(&sha512, Ai, u); - if (ret != 0) - break; - - ret = Sha512Final(&sha512, Ai); - if (ret != 0) - break; - } - } -#endif - - for (i = 0; i < (int)v; i++) - B[i] = Ai[i % u]; - - if (mp_init(&B1) != MP_OKAY) - ret = MP_INIT_E; - else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY) - ret = MP_READ_E; - else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY) - ret = MP_ADD_E; - - if (ret != 0) { - mp_clear(&B1); - break; - } - - for (i = 0; i < (int)iLen; i += v) { - int outSz; - mp_int i1; - mp_int res; - - if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) { - ret = MP_INIT_E; - break; - } - if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY) - ret = MP_READ_E; - else if (mp_add(&i1, &B1, &res) != MP_OKAY) - ret = MP_ADD_E; - else if ( (outSz = mp_unsigned_bin_size(&res)) < 0) - ret = MP_TO_E; - else { - if (outSz > (int)v) { - /* take off MSB */ - byte tmp[129]; - ret = mp_to_unsigned_bin(&res, tmp); - XMEMCPY(I + i, tmp + 1, v); - } - else if (outSz < (int)v) { - XMEMSET(I + i, 0, v - outSz); - ret = mp_to_unsigned_bin(&res, I + i + v - outSz); - } - else - ret = mp_to_unsigned_bin(&res, I + i); - } - - mp_clear(&i1); - mp_clear(&res); - if (ret < 0) break; - } - - currentLen = min(kLen, (int)u); - XMEMCPY(output, Ai, currentLen); - output += currentLen; - kLen -= currentLen; - mp_clear(&B1); - } - - if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY); - -#ifdef CYASSL_SMALL_STACK - XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - -#undef PBKDF_DIGEST_SIZE - -#endif /* NO_PWDBASED */ - diff --git a/ctaocrypt/src/tfm.c b/ctaocrypt/src/tfm.c deleted file mode 100644 index 50b0ffffa..000000000 --- a/ctaocrypt/src/tfm.c +++ /dev/null @@ -1,2538 +0,0 @@ -/* tfm.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL 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. - * - * wolfSSL 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 - */ - - -/* - * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca, - * http://math.libtomcrypt.com - */ - -/** - * Edited by Moisés Guimarães (moisesguimaraesm@gmail.com) - * to fit CyaSSL's needs. - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set USE_FAST_MATH there */ -#include - -#ifdef USE_FAST_MATH - -#include -#include /* will define asm MACROS or C ones */ - - -/* math settings check */ -word32 CheckRunTimeSettings(void) -{ - return CTC_SETTINGS; -} - - -/* math settings size check */ -word32 CheckRunTimeFastMath(void) -{ - return FP_SIZE; -} - - -/* Functions */ - -void fp_add(fp_int *a, fp_int *b, fp_int *c) -{ - int sa, sb; - - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; - - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - s_fp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (fp_cmp_mag (a, b) == FP_LT) { - c->sign = sb; - s_fp_sub (b, a, c); - } else { - c->sign = sa; - s_fp_sub (a, b, c); - } - } -} - -/* unsigned addition */ -void s_fp_add(fp_int *a, fp_int *b, fp_int *c) -{ - int x, y, oldused; - register fp_word t; - - y = MAX(a->used, b->used); - oldused = MIN(c->used, FP_SIZE); /* help static analysis w/ largest size */ - c->used = y; - - t = 0; - for (x = 0; x < y; x++) { - t += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]); - c->dp[x] = (fp_digit)t; - t >>= DIGIT_BIT; - } - if (t != 0 && x < FP_SIZE) { - c->dp[c->used++] = (fp_digit)t; - ++x; - } - - c->used = x; - for (; x < oldused; x++) { - c->dp[x] = 0; - } - fp_clamp(c); -} - -/* c = a - b */ -void fp_sub(fp_int *a, fp_int *b, fp_int *c) -{ - int sa, sb; - - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - s_fp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (fp_cmp_mag (a, b) != FP_LT) { - /* Copy the sign from the first */ - c->sign = sa; - /* The first has a larger or equal magnitude */ - s_fp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == FP_ZPOS) ? FP_NEG : FP_ZPOS; - /* The second has a larger magnitude */ - s_fp_sub (b, a, c); - } - } -} - -/* unsigned subtraction ||a|| >= ||b|| ALWAYS! */ -void s_fp_sub(fp_int *a, fp_int *b, fp_int *c) -{ - int x, oldbused, oldused; - fp_word t; - - oldused = c->used; - oldbused = b->used; - c->used = a->used; - t = 0; - for (x = 0; x < oldbused; x++) { - t = ((fp_word)a->dp[x]) - (((fp_word)b->dp[x]) + t); - c->dp[x] = (fp_digit)t; - t = (t >> DIGIT_BIT)&1; - } - for (; x < a->used; x++) { - t = ((fp_word)a->dp[x]) - t; - c->dp[x] = (fp_digit)t; - t = (t >> DIGIT_BIT)&1; - } - for (; x < oldused; x++) { - c->dp[x] = 0; - } - fp_clamp(c); -} - -/* c = a * b */ -void fp_mul(fp_int *A, fp_int *B, fp_int *C) -{ - int y, yy; - - y = MAX(A->used, B->used); - yy = MIN(A->used, B->used); - - /* call generic if we're out of range */ - if (y + yy > FP_SIZE) { - fp_mul_comba(A, B, C); - return ; - } - - /* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size - of the largest input. We also want to avoid doing excess mults if the - inputs are not close to the next power of two. That is, for example, - if say y=17 then we would do (32-17)^2 = 225 unneeded multiplications - */ - -#ifdef TFM_MUL3 - if (y <= 3) { - fp_mul_comba3(A,B,C); - return; - } -#endif -#ifdef TFM_MUL4 - if (y == 4) { - fp_mul_comba4(A,B,C); - return; - } -#endif -#ifdef TFM_MUL6 - if (y <= 6) { - fp_mul_comba6(A,B,C); - return; - } -#endif -#ifdef TFM_MUL7 - if (y == 7) { - fp_mul_comba7(A,B,C); - return; - } -#endif -#ifdef TFM_MUL8 - if (y == 8) { - fp_mul_comba8(A,B,C); - return; - } -#endif -#ifdef TFM_MUL9 - if (y == 9) { - fp_mul_comba9(A,B,C); - return; - } -#endif -#ifdef TFM_MUL12 - if (y <= 12) { - fp_mul_comba12(A,B,C); - return; - } -#endif -#ifdef TFM_MUL17 - if (y <= 17) { - fp_mul_comba17(A,B,C); - return; - } -#endif - -#ifdef TFM_SMALL_SET - if (y <= 16) { - fp_mul_comba_small(A,B,C); - return; - } -#endif -#if defined(TFM_MUL20) - if (y <= 20) { - fp_mul_comba20(A,B,C); - return; - } -#endif -#if defined(TFM_MUL24) - if (yy >= 16 && y <= 24) { - fp_mul_comba24(A,B,C); - return; - } -#endif -#if defined(TFM_MUL28) - if (yy >= 20 && y <= 28) { - fp_mul_comba28(A,B,C); - return; - } -#endif -#if defined(TFM_MUL32) - if (yy >= 24 && y <= 32) { - fp_mul_comba32(A,B,C); - return; - } -#endif -#if defined(TFM_MUL48) - if (yy >= 40 && y <= 48) { - fp_mul_comba48(A,B,C); - return; - } -#endif -#if defined(TFM_MUL64) - if (yy >= 56 && y <= 64) { - fp_mul_comba64(A,B,C); - return; - } -#endif - fp_mul_comba(A,B,C); -} - -void fp_mul_2(fp_int * a, fp_int * b) -{ - int x, oldused; - - oldused = b->used; - b->used = a->used; - - { - register fp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((fp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((fp_digit)1)) | r); - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0 && b->used != (FP_SIZE-1)) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; -} - -/* c = a * b */ -void fp_mul_d(fp_int *a, fp_digit b, fp_int *c) -{ - fp_word w; - int x, oldused; - - oldused = c->used; - c->used = a->used; - c->sign = a->sign; - w = 0; - for (x = 0; x < a->used; x++) { - w = ((fp_word)a->dp[x]) * ((fp_word)b) + w; - c->dp[x] = (fp_digit)w; - w = w >> DIGIT_BIT; - } - if (w != 0 && (a->used != FP_SIZE)) { - c->dp[c->used++] = (fp_digit) w; - ++x; - } - for (; x < oldused; x++) { - c->dp[x] = 0; - } - fp_clamp(c); -} - -/* c = a * 2**d */ -void fp_mul_2d(fp_int *a, int b, fp_int *c) -{ - fp_digit carry, carrytmp, shift; - int x; - - /* copy it */ - fp_copy(a, c); - - /* handle whole digits */ - if (b >= DIGIT_BIT) { - fp_lshd(c, b/DIGIT_BIT); - } - b %= DIGIT_BIT; - - /* shift the digits */ - if (b != 0) { - carry = 0; - shift = DIGIT_BIT - b; - for (x = 0; x < c->used; x++) { - carrytmp = c->dp[x] >> shift; - c->dp[x] = (c->dp[x] << b) + carry; - carry = carrytmp; - } - /* store last carry if room */ - if (carry && x < FP_SIZE) { - c->dp[c->used++] = carry; - } - } - fp_clamp(c); -} - -/* generic PxQ multiplier */ -void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) -{ - int ix, iy, iz, tx, ty, pa; - fp_digit c0, c1, c2, *tmpx, *tmpy; - fp_int tmp, *dst; - - COMBA_START; - COMBA_CLEAR; - - /* get size of output and trim */ - pa = A->used + B->used; - if (pa >= FP_SIZE) { - pa = FP_SIZE-1; - } - - if (A == C || B == C) { - fp_zero(&tmp); - dst = &tmp; - } else { - fp_zero(C); - dst = C; - } - - for (ix = 0; ix < pa; ix++) { - /* get offsets into the two bignums */ - ty = MIN(ix, B->used-1); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = A->dp + tx; - tmpy = B->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(A->used-tx, ty+1); - - /* execute loop */ - COMBA_FORWARD; - for (iz = 0; iz < iy; ++iz) { - /* TAO change COMBA_ADD back to MULADD */ - MULADD(*tmpx++, *tmpy--); - } - - /* store term */ - COMBA_STORE(dst->dp[ix]); - } - COMBA_FINI; - - dst->used = pa; - dst->sign = A->sign ^ B->sign; - fp_clamp(dst); - fp_copy(dst, C); -} - -/* a/b => cb + d == a */ -int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d) -{ - fp_int q, x, y, t1, t2; - int n, t, i, norm, neg; - - /* is divisor zero ? */ - if (fp_iszero (b) == 1) { - return FP_VAL; - } - - /* if a < b then q=0, r = a */ - if (fp_cmp_mag (a, b) == FP_LT) { - if (d != NULL) { - fp_copy (a, d); - } - if (c != NULL) { - fp_zero (c); - } - return FP_OKAY; - } - - fp_init(&q); - q.used = a->used + 2; - - fp_init(&t1); - fp_init(&t2); - fp_init_copy(&x, a); - fp_init_copy(&y, b); - - /* fix the sign */ - neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG; - x.sign = y.sign = FP_ZPOS; - - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = fp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; - fp_mul_2d (&x, norm, &x); - fp_mul_2d (&y, norm, &y); - } else { - norm = 0; - } - - /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ - n = x.used - 1; - t = y.used - 1; - - /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - fp_lshd (&y, n - t); /* y = y*b**{n-t} */ - - while (fp_cmp (&x, &y) != FP_LT) { - ++(q.dp[n - t]); - fp_sub (&x, &y, &x); - } - - /* reset y by shifting it back down */ - fp_rshd (&y, n - t); - - /* step 3. for i from n down to (t + 1) */ - for (i = n; i >= (t + 1); i--) { - if (i > x.used) { - continue; - } - - /* step 3.1 if xi == yt then set q{i-t-1} to b-1, - * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ - if (x.dp[i] == y.dp[t]) { - q.dp[i - t - 1] = (fp_digit) ((((fp_word)1) << DIGIT_BIT) - 1); - } else { - fp_word tmp; - tmp = ((fp_word) x.dp[i]) << ((fp_word) DIGIT_BIT); - tmp |= ((fp_word) x.dp[i - 1]); - tmp /= ((fp_word)y.dp[t]); - q.dp[i - t - 1] = (fp_digit) (tmp); - } - - /* while (q{i-t-1} * (yt * b + y{t-1})) > - xi * b**2 + xi-1 * b + xi-2 - - do q{i-t-1} -= 1; - */ - q.dp[i - t - 1] = (q.dp[i - t - 1] + 1); - do { - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1); - - /* find left hand */ - fp_zero (&t1); - t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; - t1.dp[1] = y.dp[t]; - t1.used = 2; - fp_mul_d (&t1, q.dp[i - t - 1], &t1); - - /* find right hand */ - t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; - t2.dp[2] = x.dp[i]; - t2.used = 3; - } while (fp_cmp_mag(&t1, &t2) == FP_GT); - - /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - fp_mul_d (&y, q.dp[i - t - 1], &t1); - fp_lshd (&t1, i - t - 1); - fp_sub (&x, &t1, &x); - - /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ - if (x.sign == FP_NEG) { - fp_copy (&y, &t1); - fp_lshd (&t1, i - t - 1); - fp_add (&x, &t1, &x); - q.dp[i - t - 1] = q.dp[i - t - 1] - 1; - } - } - - /* now q is the quotient and x is the remainder - * [which we have to normalize] - */ - - /* get sign before writing to c */ - x.sign = x.used == 0 ? FP_ZPOS : a->sign; - - if (c != NULL) { - fp_clamp (&q); - fp_copy (&q, c); - c->sign = neg; - } - - if (d != NULL) { - fp_div_2d (&x, norm, &x, NULL); - -/* the following is a kludge, essentially we were seeing the right remainder but - with excess digits that should have been zero - */ - for (i = b->used; i < x.used; i++) { - x.dp[i] = 0; - } - fp_clamp(&x); - fp_copy (&x, d); - } - - return FP_OKAY; -} - -/* b = a/2 */ -void fp_div_2(fp_int * a, fp_int * b) -{ - int x, oldused; - - oldused = b->used; - b->used = a->used; - { - register fp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - fp_clamp (b); -} - -/* c = a / 2**b */ -void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d) -{ - int D; - fp_int t; - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - fp_copy (a, c); - if (d != NULL) { - fp_zero (d); - } - return; - } - - fp_init(&t); - - /* get the remainder */ - if (d != NULL) { - fp_mod_2d (a, b, &t); - } - - /* copy */ - fp_copy(a, c); - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - fp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (b % DIGIT_BIT); - if (D != 0) { - fp_rshb(c, D); - } - fp_clamp (c); - if (d != NULL) { - fp_copy (&t, d); - } -} - -/* c = a mod b, 0 <= c < b */ -int fp_mod(fp_int *a, fp_int *b, fp_int *c) -{ - fp_int t; - int err; - - fp_zero(&t); - if ((err = fp_div(a, b, NULL, &t)) != FP_OKAY) { - return err; - } - if (t.sign != b->sign) { - fp_add(&t, b, c); - } else { - fp_copy(&t, c); - } - return FP_OKAY; -} - -/* c = a mod 2**d */ -void fp_mod_2d(fp_int *a, int b, fp_int *c) -{ - int x; - - /* zero if count less than or equal to zero */ - if (b <= 0) { - fp_zero(c); - return; - } - - /* get copy of input */ - fp_copy(a, c); - - /* if 2**d is larger than we just return */ - if (b >= (DIGIT_BIT * a->used)) { - return; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= ~((fp_digit)0) >> (DIGIT_BIT - b); - fp_clamp (c); -} - -static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c) -{ - fp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if (b->sign == FP_NEG || fp_iszero(b) == 1) { - return FP_VAL; - } - - /* init temps */ - fp_init(&x); fp_init(&y); - fp_init(&u); fp_init(&v); - fp_init(&A); fp_init(&B); - fp_init(&C); fp_init(&D); - - /* x = a, y = b */ - if ((res = fp_mod(a, b, &x)) != FP_OKAY) { - return res; - } - fp_copy(b, &y); - - /* 2. [modified] if x,y are both even then return an error! */ - if (fp_iseven (&x) == 1 && fp_iseven (&y) == 1) { - return FP_VAL; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - fp_copy (&x, &u); - fp_copy (&y, &v); - fp_set (&A, 1); - fp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (fp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - fp_div_2 (&u, &u); - - /* 4.2 if A or B is odd then */ - if (fp_isodd (&A) == 1 || fp_isodd (&B) == 1) { - /* A = (A+y)/2, B = (B-x)/2 */ - fp_add (&A, &y, &A); - fp_sub (&B, &x, &B); - } - /* A = A/2, B = B/2 */ - fp_div_2 (&A, &A); - fp_div_2 (&B, &B); - } - - /* 5. while v is even do */ - while (fp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - fp_div_2 (&v, &v); - - /* 5.2 if C or D is odd then */ - if (fp_isodd (&C) == 1 || fp_isodd (&D) == 1) { - /* C = (C+y)/2, D = (D-x)/2 */ - fp_add (&C, &y, &C); - fp_sub (&D, &x, &D); - } - /* C = C/2, D = D/2 */ - fp_div_2 (&C, &C); - fp_div_2 (&D, &D); - } - - /* 6. if u >= v then */ - if (fp_cmp (&u, &v) != FP_LT) { - /* u = u - v, A = A - C, B = B - D */ - fp_sub (&u, &v, &u); - fp_sub (&A, &C, &A); - fp_sub (&B, &D, &B); - } else { - /* v - v - u, C = C - A, D = D - B */ - fp_sub (&v, &u, &v); - fp_sub (&C, &A, &C); - fp_sub (&D, &B, &D); - } - - /* if not zero goto step 4 */ - if (fp_iszero (&u) == 0) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (fp_cmp_d (&v, 1) != FP_EQ) { - return FP_VAL; - } - - /* if its too low */ - while (fp_cmp_d(&C, 0) == FP_LT) { - fp_add(&C, b, &C); - } - - /* too big */ - while (fp_cmp_mag(&C, b) != FP_LT) { - fp_sub(&C, b, &C); - } - - /* C is now the inverse */ - fp_copy(&C, c); - return FP_OKAY; -} - -/* c = 1/a (mod b) for odd b only */ -int fp_invmod(fp_int *a, fp_int *b, fp_int *c) -{ - fp_int x, y, u, v, B, D; - int neg; - - /* 2. [modified] b must be odd */ - if (fp_iseven (b) == FP_YES) { - return fp_invmod_slow(a,b,c); - } - - /* init all our temps */ - fp_init(&x); fp_init(&y); - fp_init(&u); fp_init(&v); - fp_init(&B); fp_init(&D); - - /* x == modulus, y == value to invert */ - fp_copy(b, &x); - - /* we need y = |a| */ - fp_abs(a, &y); - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - fp_copy(&x, &u); - fp_copy(&y, &v); - fp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (fp_iseven (&u) == FP_YES) { - /* 4.1 u = u/2 */ - fp_div_2 (&u, &u); - - /* 4.2 if B is odd then */ - if (fp_isodd (&B) == FP_YES) { - fp_sub (&B, &x, &B); - } - /* B = B/2 */ - fp_div_2 (&B, &B); - } - - /* 5. while v is even do */ - while (fp_iseven (&v) == FP_YES) { - /* 5.1 v = v/2 */ - fp_div_2 (&v, &v); - - /* 5.2 if D is odd then */ - if (fp_isodd (&D) == FP_YES) { - /* D = (D-x)/2 */ - fp_sub (&D, &x, &D); - } - /* D = D/2 */ - fp_div_2 (&D, &D); - } - - /* 6. if u >= v then */ - if (fp_cmp (&u, &v) != FP_LT) { - /* u = u - v, B = B - D */ - fp_sub (&u, &v, &u); - fp_sub (&B, &D, &B); - } else { - /* v - v - u, D = D - B */ - fp_sub (&v, &u, &v); - fp_sub (&D, &B, &D); - } - - /* if not zero goto step 4 */ - if (fp_iszero (&u) == FP_NO) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (fp_cmp_d (&v, 1) != FP_EQ) { - return FP_VAL; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == FP_NEG) { - fp_add (&D, b, &D); - } - fp_copy (&D, c); - c->sign = neg; - return FP_OKAY; -} - -/* d = a * b (mod c) */ -int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) -{ - fp_int tmp; - fp_zero(&tmp); - fp_mul(a, b, &tmp); - return fp_mod(&tmp, c, d); -} - -#ifdef TFM_TIMING_RESISTANT - -/* timing resistant montgomery ladder based exptmod - - Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder", Cryptographic Hardware and Embedded Systems, CHES 2002 -*/ -static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) -{ - fp_int R[2]; - fp_digit buf, mp; - int err, bitcnt, digidx, y; - - /* now setup montgomery */ - if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) { - return err; - } - - fp_init(&R[0]); - fp_init(&R[1]); - - /* now we need R mod m */ - fp_montgomery_calc_normalization (&R[0], P); - - /* now set R[0][1] to G * R mod m */ - if (fp_cmp_mag(P, G) != FP_GT) { - /* G > P so we reduce it first */ - fp_mod(G, P, &R[1]); - } else { - fp_copy(G, &R[1]); - } - fp_mulmod (&R[1], &R[0], P, &R[1]); - - /* for j = t-1 downto 0 do - r_!k = R0*R1; r_k = r_k^2 - */ - - /* set initial mode and bit cnt */ - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (int)(buf >> (DIGIT_BIT - 1)) & 1; - buf <<= (fp_digit)1; - - /* do ops */ - fp_mul(&R[0], &R[1], &R[y^1]); fp_montgomery_reduce(&R[y^1], P, mp); - fp_sqr(&R[y], &R[y]); fp_montgomery_reduce(&R[y], P, mp); - } - - fp_montgomery_reduce(&R[0], P, mp); - fp_copy(&R[0], Y); - return FP_OKAY; -} - -#else - -/* y = g**x (mod b) - * Some restrictions... x must be positive and < b - */ -static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) -{ - fp_int M[64], res; - fp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* find window size */ - x = fp_count_bits (X); - if (x <= 21) { - winsize = 1; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else { - winsize = 6; - } - - /* init M array */ - XMEMSET(M, 0, sizeof(M)); - - /* now setup montgomery */ - if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) { - return err; - } - - /* setup result */ - fp_init(&res); - - /* create M table - * - * The M table contains powers of the input base, e.g. M[x] = G^x mod P - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - /* now we need R mod m */ - fp_montgomery_calc_normalization (&res, P); - - /* now set M[1] to G * R mod m */ - if (fp_cmp_mag(P, G) != FP_GT) { - /* G > P so we reduce it first */ - fp_mod(G, P, &M[1]); - } else { - fp_copy(G, &M[1]); - } - fp_mulmod (&M[1], &res, P, &M[1]); - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ - fp_copy (&M[1], &M[1 << (winsize - 1)]); - for (x = 0; x < (winsize - 1); x++) { - fp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)]); - fp_montgomery_reduce (&M[1 << (winsize - 1)], P, mp); - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - fp_mul(&M[x - 1], &M[1], &M[x]); - fp_montgomery_reduce(&M[x], P, mp); - } - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (int)(buf >> (DIGIT_BIT - 1)) & 1; - buf <<= (fp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - fp_sqr(&res, &res); - fp_montgomery_reduce(&res, P, mp); - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - fp_sqr(&res, &res); - fp_montgomery_reduce(&res, P, mp); - } - - /* then multiply */ - fp_mul(&res, &M[bitbuf], &res); - fp_montgomery_reduce(&res, P, mp); - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - fp_sqr(&res, &res); - fp_montgomery_reduce(&res, P, mp); - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - fp_mul(&res, &M[1], &res); - fp_montgomery_reduce(&res, P, mp); - } - } - } - - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - fp_montgomery_reduce(&res, P, mp); - - /* swap res with Y */ - fp_copy (&res, Y); - return FP_OKAY; -} - -#endif - -int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) -{ - /* prevent overflows */ - if (P->used > (FP_SIZE/2)) { - return FP_VAL; - } - - if (X->sign == FP_NEG) { -#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ - int err; - fp_int tmp; - - /* yes, copy G and invmod it */ - fp_copy(G, &tmp); - if ((err = fp_invmod(&tmp, P, &tmp)) != FP_OKAY) { - return err; - } - X->sign = FP_ZPOS; - err = _fp_exptmod(&tmp, X, P, Y); - if (X != Y) { - X->sign = FP_NEG; - } - return err; -#else - return FP_VAL; -#endif - } - else { - /* Positive exponent so just exptmod */ - return _fp_exptmod(G, X, P, Y); - } -} - -/* computes a = 2**b */ -void fp_2expt(fp_int *a, int b) -{ - int z; - - /* zero a as per default */ - fp_zero (a); - - if (b < 0) { - return; - } - - z = b / DIGIT_BIT; - if (z >= FP_SIZE) { - return; - } - - /* set the used count of where the bit will go */ - a->used = z + 1; - - /* put the single bit in its place */ - a->dp[z] = ((fp_digit)1) << (b % DIGIT_BIT); -} - -/* b = a*a */ -void fp_sqr(fp_int *A, fp_int *B) -{ - int y = A->used; - - /* call generic if we're out of range */ - if (y + y > FP_SIZE) { - fp_sqr_comba(A, B); - return ; - } - -#if defined(TFM_SQR3) - if (y <= 3) { - fp_sqr_comba3(A,B); - return; - } -#endif -#if defined(TFM_SQR4) - if (y == 4) { - fp_sqr_comba4(A,B); - return; - } -#endif -#if defined(TFM_SQR6) - if (y <= 6) { - fp_sqr_comba6(A,B); - return; - } -#endif -#if defined(TFM_SQR7) - if (y == 7) { - fp_sqr_comba7(A,B); - return; - } -#endif -#if defined(TFM_SQR8) - if (y == 8) { - fp_sqr_comba8(A,B); - return; - } -#endif -#if defined(TFM_SQR9) - if (y == 9) { - fp_sqr_comba9(A,B); - return; - } -#endif -#if defined(TFM_SQR12) - if (y <= 12) { - fp_sqr_comba12(A,B); - return; - } -#endif -#if defined(TFM_SQR17) - if (y <= 17) { - fp_sqr_comba17(A,B); - return; - } -#endif -#if defined(TFM_SMALL_SET) - if (y <= 16) { - fp_sqr_comba_small(A,B); - return; - } -#endif -#if defined(TFM_SQR20) - if (y <= 20) { - fp_sqr_comba20(A,B); - return; - } -#endif -#if defined(TFM_SQR24) - if (y <= 24) { - fp_sqr_comba24(A,B); - return; - } -#endif -#if defined(TFM_SQR28) - if (y <= 28) { - fp_sqr_comba28(A,B); - return; - } -#endif -#if defined(TFM_SQR32) - if (y <= 32) { - fp_sqr_comba32(A,B); - return; - } -#endif -#if defined(TFM_SQR48) - if (y <= 48) { - fp_sqr_comba48(A,B); - return; - } -#endif -#if defined(TFM_SQR64) - if (y <= 64) { - fp_sqr_comba64(A,B); - return; - } -#endif - fp_sqr_comba(A, B); -} - -/* generic comba squarer */ -void fp_sqr_comba(fp_int *A, fp_int *B) -{ - int pa, ix, iz; - fp_digit c0, c1, c2; - fp_int tmp, *dst; -#ifdef TFM_ISO - fp_word tt; -#endif - - /* get size of output and trim */ - pa = A->used + A->used; - if (pa >= FP_SIZE) { - pa = FP_SIZE-1; - } - - /* number of output digits to produce */ - COMBA_START; - COMBA_CLEAR; - - if (A == B) { - fp_zero(&tmp); - dst = &tmp; - } else { - fp_zero(B); - dst = B; - } - - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - fp_digit *tmpy, *tmpx; - - /* get offsets into the two bignums */ - ty = MIN(A->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = A->dp + tx; - tmpy = A->dp + ty; - - /* this is the number of times the loop will iterrate, - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(A->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach - * at a rate of 2x and we have to round because - * odd cases need to be executed - */ - iy = MIN(iy, (ty-tx+1)>>1); - - /* forward carries */ - COMBA_FORWARD; - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - SQRADD2(*tmpx++, *tmpy--); - } - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - /* TAO change COMBA_ADD back to SQRADD */ - SQRADD(A->dp[ix>>1], A->dp[ix>>1]); - } - - /* store it */ - COMBA_STORE(dst->dp[ix]); - } - - COMBA_FINI; - - /* setup dest */ - dst->used = pa; - fp_clamp (dst); - if (dst != B) { - fp_copy(dst, B); - } -} - -int fp_cmp(fp_int *a, fp_int *b) -{ - if (a->sign == FP_NEG && b->sign == FP_ZPOS) { - return FP_LT; - } else if (a->sign == FP_ZPOS && b->sign == FP_NEG) { - return FP_GT; - } else { - /* compare digits */ - if (a->sign == FP_NEG) { - /* if negative compare opposite direction */ - return fp_cmp_mag(b, a); - } else { - return fp_cmp_mag(a, b); - } - } -} - -/* compare against a single digit */ -int fp_cmp_d(fp_int *a, fp_digit b) -{ - /* compare based on sign */ - if ((b && a->used == 0) || a->sign == FP_NEG) { - return FP_LT; - } - - /* compare based on magnitude */ - if (a->used > 1) { - return FP_GT; - } - - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return FP_GT; - } else if (a->dp[0] < b) { - return FP_LT; - } else { - return FP_EQ; - } - -} - -int fp_cmp_mag(fp_int *a, fp_int *b) -{ - int x; - - if (a->used > b->used) { - return FP_GT; - } else if (a->used < b->used) { - return FP_LT; - } else { - for (x = a->used - 1; x >= 0; x--) { - if (a->dp[x] > b->dp[x]) { - return FP_GT; - } else if (a->dp[x] < b->dp[x]) { - return FP_LT; - } - } - } - return FP_EQ; -} - -/* setups the montgomery reduction */ -int fp_montgomery_setup(fp_int *a, fp_digit *rho) -{ - fp_digit x, b; - -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = a->dp[0]; - - if ((b & 1) == 0) { - return FP_VAL; - } - - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - b * x; /* here x*a==1 mod 2**8 */ - x *= 2 - b * x; /* here x*a==1 mod 2**16 */ - x *= 2 - b * x; /* here x*a==1 mod 2**32 */ -#ifdef FP_64BIT - x *= 2 - b * x; /* here x*a==1 mod 2**64 */ -#endif - - /* rho = -1/m mod b */ - *rho = (fp_digit) (((fp_word) 1 << ((fp_word) DIGIT_BIT)) - ((fp_word)x)); - - return FP_OKAY; -} - -/* computes a = B**n mod b without division or multiplication useful for - * normalizing numbers in a Montgomery system. - */ -void fp_montgomery_calc_normalization(fp_int *a, fp_int *b) -{ - int x, bits; - - /* how many bits of last digit does b use */ - bits = fp_count_bits (b) % DIGIT_BIT; - if (!bits) bits = DIGIT_BIT; - - /* compute A = B^(n-1) * 2^(bits-1) */ - if (b->used > 1) { - fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1); - } else { - fp_set(a, 1); - bits = 1; - } - - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - fp_mul_2 (a, a); - if (fp_cmp_mag (a, b) != FP_LT) { - s_fp_sub (a, b, a); - } - } -} - - -#ifdef TFM_SMALL_MONT_SET - #include "fp_mont_small.i" -#endif - -/* computes x/R == x (mod N) via Montgomery Reduction */ -void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) -{ - fp_digit c[FP_SIZE], *_c, *tmpm, mu = 0; - int oldused, x, y, pa; - - /* bail if too large */ - if (m->used > (FP_SIZE/2)) { - (void)mu; /* shut up compiler */ - return; - } - -#ifdef TFM_SMALL_MONT_SET - if (m->used <= 16) { - fp_montgomery_reduce_small(a, m, mp); - return; - } -#endif - - - /* now zero the buff */ - XMEMSET(c, 0, sizeof c); - pa = m->used; - - /* copy the input */ - oldused = a->used; - for (x = 0; x < oldused; x++) { - c[x] = a->dp[x]; - } - MONT_START; - - for (x = 0; x < pa; x++) { - fp_digit cy = 0; - /* get Mu for this round */ - LOOP_START; - _c = c + x; - tmpm = m->dp; - y = 0; - #if (defined(TFM_SSE2) || defined(TFM_X86_64)) - for (; y < (pa & ~7); y += 8) { - INNERMUL8; - _c += 8; - tmpm += 8; - } - #endif - - for (; y < pa; y++) { - INNERMUL; - ++_c; - } - LOOP_END; - while (cy) { - PROPCARRY; - ++_c; - } - } - - /* now copy out */ - _c = c + pa; - tmpm = a->dp; - for (x = 0; x < pa+1; x++) { - *tmpm++ = *_c++; - } - - for (; x < oldused; x++) { - *tmpm++ = 0; - } - - MONT_FINI; - - a->used = pa+1; - fp_clamp(a); - - /* if A >= m then A = A - m */ - if (fp_cmp_mag (a, m) != FP_LT) { - s_fp_sub (a, m, a); - } -} - -void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c) -{ - /* zero the int */ - fp_zero (a); - - /* If we know the endianness of this architecture, and we're using - 32-bit fp_digits, we can optimize this */ -#if (defined(LITTLE_ENDIAN_ORDER) || defined(BIG_ENDIAN_ORDER)) && defined(FP_32BIT) - /* But not for both simultaneously */ -#if defined(LITTLE_ENDIAN_ORDER) && defined(BIG_ENDIAN_ORDER) -#error Both LITTLE_ENDIAN_ORDER and BIG_ENDIAN_ORDER defined. -#endif - { - unsigned char *pd = (unsigned char *)a->dp; - - if ((unsigned)c > (FP_SIZE * sizeof(fp_digit))) { - int excess = c - (FP_SIZE * sizeof(fp_digit)); - c -= excess; - b += excess; - } - a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit); - /* read the bytes in */ -#ifdef BIG_ENDIAN_ORDER - { - /* Use Duff's device to unroll the loop. */ - int idx = (c - 1) & ~3; - switch (c % 4) { - case 0: do { pd[idx+0] = *b++; - case 3: pd[idx+1] = *b++; - case 2: pd[idx+2] = *b++; - case 1: pd[idx+3] = *b++; - idx -= 4; - } while ((c -= 4) > 0); - } - } -#else - for (c -= 1; c >= 0; c -= 1) { - pd[c] = *b++; - } -#endif - } -#else - /* read the bytes in */ - for (; c > 0; c--) { - fp_mul_2d (a, 8, a); - a->dp[0] |= *b++; - a->used += 1; - } -#endif - fp_clamp (a); -} - -void fp_to_unsigned_bin(fp_int *a, unsigned char *b) -{ - int x; - fp_int t; - - fp_init_copy(&t, a); - - x = 0; - while (fp_iszero (&t) == FP_NO) { - b[x++] = (unsigned char) (t.dp[0] & 255); - fp_div_2d (&t, 8, &t, NULL); - } - fp_reverse (b, x); -} - -int fp_unsigned_bin_size(fp_int *a) -{ - int size = fp_count_bits (a); - return (size / 8 + ((size & 7) != 0 ? 1 : 0)); -} - -void fp_set(fp_int *a, fp_digit b) -{ - fp_zero(a); - a->dp[0] = b; - a->used = a->dp[0] ? 1 : 0; -} - -int fp_count_bits (fp_int * a) -{ - int r; - fp_digit q; - - /* shortcut */ - if (a->used == 0) { - return 0; - } - - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((fp_digit) 0)) { - ++r; - q >>= ((fp_digit) 1); - } - return r; -} - -int fp_leading_bit(fp_int *a) -{ - int bit = 0; - - if (a->used != 0) { - fp_digit q = a->dp[a->used - 1]; - int qSz = sizeof(fp_digit); - - while (qSz > 0) { - if ((unsigned char)q != 0) - bit = (q & 0x80) != 0; - q >>= 8; - qSz--; - } - } - - return bit; -} - -void fp_lshd(fp_int *a, int x) -{ - int y; - - /* move up and truncate as required */ - y = MIN(a->used + x - 1, (int)(FP_SIZE-1)); - - /* store new size */ - a->used = y + 1; - - /* move digits */ - for (; y >= x; y--) { - a->dp[y] = a->dp[y-x]; - } - - /* zero lower digits */ - for (; y >= 0; y--) { - a->dp[y] = 0; - } - - /* clamp digits */ - fp_clamp(a); -} - - -/* right shift by bit count */ -void fp_rshb(fp_int *c, int x) -{ - register fp_digit *tmpc, mask, shift; - fp_digit r, rr; - fp_digit D = x; - - /* mask */ - mask = (((fp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } -} - - -void fp_rshd(fp_int *a, int x) -{ - int y; - - /* too many digits just zero and return */ - if (x >= a->used) { - fp_zero(a); - return; - } - - /* shift */ - for (y = 0; y < a->used - x; y++) { - a->dp[y] = a->dp[y+x]; - } - - /* zero rest */ - for (; y < a->used; y++) { - a->dp[y] = 0; - } - - /* decrement count */ - a->used -= x; - fp_clamp(a); -} - -/* reverse an array, used for radix code */ -void fp_reverse (unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} - - -/* c = a - b */ -void fp_sub_d(fp_int *a, fp_digit b, fp_int *c) -{ - fp_int tmp; - fp_set(&tmp, b); - fp_sub(a, &tmp, c); -} - - -/* CyaSSL callers from normal lib */ - -/* init a new mp_int */ -int mp_init (mp_int * a) -{ - if (a) - fp_init(a); - return MP_OKAY; -} - -/* clear one (frees) */ -void mp_clear (mp_int * a) -{ - fp_zero(a); -} - -/* handle up to 6 inits */ -int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, mp_int* f) -{ - if (a) - fp_init(a); - if (b) - fp_init(b); - if (c) - fp_init(c); - if (d) - fp_init(d); - if (e) - fp_init(e); - if (f) - fp_init(f); - - return MP_OKAY; -} - -/* high level addition (handles signs) */ -int mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - fp_add(a, b, c); - return MP_OKAY; -} - -/* high level subtraction (handles signs) */ -int mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - fp_sub(a, b, c); - return MP_OKAY; -} - -/* high level multiplication (handles sign) */ -int mp_mul (mp_int * a, mp_int * b, mp_int * c) -{ - fp_mul(a, b, c); - return MP_OKAY; -} - -/* d = a * b (mod c) */ -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - return fp_mulmod(a, b, c, d); -} - -/* c = a mod b, 0 <= c < b */ -int mp_mod (mp_int * a, mp_int * b, mp_int * c) -{ - return fp_mod (a, b, c); -} - -/* hac 14.61, pp608 */ -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - return fp_invmod(a, b, c); -} - -/* this is a shell function that calls either the normal or Montgomery - * exptmod functions. Originally the call to the montgomery code was - * embedded in the normal function but that wasted alot of stack space - * for nothing (since 99% of the time the Montgomery code would be called) - */ -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -{ - return fp_exptmod(G, X, P, Y); -} - -/* compare two ints (signed)*/ -int mp_cmp (mp_int * a, mp_int * b) -{ - return fp_cmp(a, b); -} - -/* compare a digit */ -int mp_cmp_d(mp_int * a, mp_digit b) -{ - return fp_cmp_d(a, b); -} - -/* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) -{ - return fp_unsigned_bin_size(a); -} - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin (mp_int * a, unsigned char *b) -{ - fp_to_unsigned_bin(a,b); - return MP_OKAY; -} - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) -{ - fp_read_unsigned_bin(a, (unsigned char *)b, c); - return MP_OKAY; -} - - -int mp_sub_d(fp_int *a, fp_digit b, fp_int *c) -{ - fp_sub_d(a, b, c); - return MP_OKAY; -} - - -/* fast math conversion */ -int mp_copy(fp_int* a, fp_int* b) -{ - fp_copy(a, b); - return MP_OKAY; -} - - -/* fast math conversion */ -int mp_isodd(mp_int* a) -{ - return fp_isodd(a); -} - - -/* fast math conversion */ -int mp_iszero(mp_int* a) -{ - return fp_iszero(a); -} - - -/* fast math conversion */ -int mp_count_bits (mp_int* a) -{ - return fp_count_bits(a); -} - - -int mp_leading_bit (mp_int* a) -{ - return fp_leading_bit(a); -} - - -/* fast math conversion */ -void mp_rshb (mp_int* a, int x) -{ - fp_rshb(a, x); -} - - -/* fast math wrappers */ -int mp_set_int(fp_int *a, fp_digit b) -{ - fp_set(a, b); - return MP_OKAY; -} - - -#if defined(CYASSL_KEY_GEN) || defined (HAVE_ECC) - -/* c = a * a (mod b) */ -int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c) -{ - fp_int tmp; - fp_zero(&tmp); - fp_sqr(a, &tmp); - return fp_mod(&tmp, b, c); -} - -/* fast math conversion */ -int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c) -{ - return fp_sqrmod(a, b, c); -} - -/* fast math conversion */ -int mp_montgomery_calc_normalization(mp_int *a, mp_int *b) -{ - fp_montgomery_calc_normalization(a, b); - return MP_OKAY; -} - -#endif /* CYASSL_KEYGEN || HAVE_ECC */ - - -#if defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY) - -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Counts the number of lsbs which are zero before the first zero bit */ -int fp_cnt_lsb(fp_int *a) -{ - int x; - fp_digit q, qq; - - /* easy out */ - if (fp_iszero(a) == 1) { - return 0; - } - - /* scan lower digits until non-zero */ - for (x = 0; x < a->used && a->dp[x] == 0; x++); - q = a->dp[x]; - x *= DIGIT_BIT; - - /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { - do { - qq = q & 15; - x += lnz[qq]; - q >>= 4; - } while (qq == 0); - } - return x; -} - - - - -static int s_is_power_of_two(fp_digit b, int *p) -{ - int x; - - /* fast return if no power of two */ - if ((b==0) || (b & (b-1))) { - return 0; - } - - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((fp_digit)1)< cb + d == a */ -static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d) -{ - fp_int q; - fp_word w; - fp_digit t; - int ix; - - /* cannot divide by zero */ - if (b == 0) { - return FP_VAL; - } - - /* quick outs */ - if (b == 1 || fp_iszero(a) == 1) { - if (d != NULL) { - *d = 0; - } - if (c != NULL) { - fp_copy(a, c); - } - return FP_OKAY; - } - - /* power of two ? */ - if (s_is_power_of_two(b, &ix) == 1) { - if (d != NULL) { - *d = a->dp[0] & ((((fp_digit)1)<used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]); - - if (w >= b) { - t = (fp_digit)(w / b); - w -= ((fp_word)t) * ((fp_word)b); - } else { - t = 0; - } - q.dp[ix] = (fp_digit)t; - } - - if (d != NULL) { - *d = (fp_digit)w; - } - - if (c != NULL) { - fp_clamp(&q); - fp_copy(&q, c); - } - - return FP_OKAY; -} - - -/* c = a mod b, 0 <= c < b */ -static int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c) -{ - return fp_div_d(a, b, NULL, c); -} - -int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c) -{ - return fp_mod_d(a, b, c); -} - -#endif /* defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY) */ - -#ifdef CYASSL_KEY_GEN - -void fp_gcd(fp_int *a, fp_int *b, fp_int *c); -void fp_lcm(fp_int *a, fp_int *b, fp_int *c); -int fp_isprime(fp_int *a); - -int mp_gcd(fp_int *a, fp_int *b, fp_int *c) -{ - fp_gcd(a, b, c); - return MP_OKAY; -} - - -int mp_lcm(fp_int *a, fp_int *b, fp_int *c) -{ - fp_lcm(a, b, c); - return MP_OKAY; -} - - -int mp_prime_is_prime(mp_int* a, int t, int* result) -{ - (void)t; - *result = fp_isprime(a); - return MP_OKAY; -} - -/* Miller-Rabin test of "a" to the base of "b" as described in - * HAC pp. 139 Algorithm 4.24 - * - * Sets result to 0 if definitely composite or 1 if probably prime. - * Randomly the chance of error is no more than 1/4 and often - * very much lower. - */ -static void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result) -{ - fp_int n1, y, r; - int s, j; - - /* default */ - *result = FP_NO; - - /* ensure b > 1 */ - if (fp_cmp_d(b, 1) != FP_GT) { - return; - } - - /* get n1 = a - 1 */ - fp_init_copy(&n1, a); - fp_sub_d(&n1, 1, &n1); - - /* set 2**s * r = n1 */ - fp_init_copy(&r, &n1); - - /* count the number of least significant bits - * which are zero - */ - s = fp_cnt_lsb(&r); - - /* now divide n - 1 by 2**s */ - fp_div_2d (&r, s, &r, NULL); - - /* compute y = b**r mod a */ - fp_init(&y); - fp_exptmod(b, &r, a, &y); - - /* if y != 1 and y != n1 do */ - if (fp_cmp_d (&y, 1) != FP_EQ && fp_cmp (&y, &n1) != FP_EQ) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && fp_cmp (&y, &n1) != FP_EQ) { - fp_sqrmod (&y, a, &y); - - /* if y == 1 then composite */ - if (fp_cmp_d (&y, 1) == FP_EQ) { - return; - } - ++j; - } - - /* if y != n1 then composite */ - if (fp_cmp (&y, &n1) != FP_EQ) { - return; - } - } - - /* probably prime now */ - *result = FP_YES; -} - - -/* a few primes */ -static const fp_digit primes[256] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 -}; - -int fp_isprime(fp_int *a) -{ - fp_int b; - fp_digit d = 0; - int r, res; - - /* do trial division */ - for (r = 0; r < 256; r++) { - fp_mod_d(a, primes[r], &d); - if (d == 0) { - return FP_NO; - } - } - - /* now do 8 miller rabins */ - fp_init(&b); - for (r = 0; r < 8; r++) { - fp_set(&b, primes[r]); - fp_prime_miller_rabin(a, &b, &res); - if (res == FP_NO) { - return FP_NO; - } - } - return FP_YES; -} - - -/* c = [a, b] */ -void fp_lcm(fp_int *a, fp_int *b, fp_int *c) -{ - fp_int t1, t2; - - fp_init(&t1); - fp_init(&t2); - fp_gcd(a, b, &t1); - if (fp_cmp_mag(a, b) == FP_GT) { - fp_div(a, &t1, &t2, NULL); - fp_mul(b, &t2, c); - } else { - fp_div(b, &t1, &t2, NULL); - fp_mul(a, &t2, c); - } -} - - - -/* c = (a, b) */ -void fp_gcd(fp_int *a, fp_int *b, fp_int *c) -{ - fp_int u, v, r; - - /* either zero than gcd is the largest */ - if (fp_iszero (a) == 1 && fp_iszero (b) == 0) { - fp_abs (b, c); - return; - } - if (fp_iszero (a) == 0 && fp_iszero (b) == 1) { - fp_abs (a, c); - return; - } - - /* optimized. At this point if a == 0 then - * b must equal zero too - */ - if (fp_iszero (a) == 1) { - fp_zero(c); - return; - } - - /* sort inputs */ - if (fp_cmp_mag(a, b) != FP_LT) { - fp_init_copy(&u, a); - fp_init_copy(&v, b); - } else { - fp_init_copy(&u, b); - fp_init_copy(&v, a); - } - - fp_zero(&r); - while (fp_iszero(&v) == FP_NO) { - fp_mod(&u, &v, &r); - fp_copy(&v, &u); - fp_copy(&r, &v); - } - fp_copy(&u, c); -} - -#endif /* CYASSL_KEY_GEN */ - - -#if defined(HAVE_ECC) || !defined(NO_PWDBASED) -/* c = a + b */ -void fp_add_d(fp_int *a, fp_digit b, fp_int *c) -{ - fp_int tmp; - fp_set(&tmp, b); - fp_add(a,&tmp,c); -} - -/* external compatibility */ -int mp_add_d(fp_int *a, fp_digit b, fp_int *c) -{ - fp_add_d(a, b, c); - return MP_OKAY; -} - -#endif /* HAVE_ECC || !NO_PWDBASED */ - - -#ifdef HAVE_ECC - -/* chars used in radix conversions */ -static const char *fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; - -static int fp_read_radix(fp_int *a, const char *str, int radix) -{ - int y, neg; - char ch; - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return FP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = FP_NEG; - } else { - neg = FP_ZPOS; - } - - /* set the integer to the default of zero */ - fp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? XTOUPPER(*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == fp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - fp_mul_d (a, (fp_digit) radix, a); - fp_add_d (a, (fp_digit) y, a); - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (fp_iszero(a) != FP_YES) { - a->sign = neg; - } - return FP_OKAY; -} - -/* fast math conversion */ -int mp_read_radix(mp_int *a, const char *str, int radix) -{ - return fp_read_radix(a, str, radix); -} - -/* fast math conversion */ -int mp_set(fp_int *a, fp_digit b) -{ - fp_set(a,b); - return MP_OKAY; -} - -/* fast math conversion */ -int mp_sqr(fp_int *A, fp_int *B) -{ - fp_sqr(A, B); - return MP_OKAY; -} - -/* fast math conversion */ -int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp) -{ - fp_montgomery_reduce(a, m, mp); - return MP_OKAY; -} - - -/* fast math conversion */ -int mp_montgomery_setup(fp_int *a, fp_digit *rho) -{ - return fp_montgomery_setup(a, rho); -} - -int mp_div_2(fp_int * a, fp_int * b) -{ - fp_div_2(a, b); - return MP_OKAY; -} - - -int mp_init_copy(fp_int * a, fp_int * b) -{ - fp_init_copy(a, b); - return MP_OKAY; -} - - -#ifdef HAVE_COMP_KEY - -int mp_cnt_lsb(fp_int* a) -{ - fp_cnt_lsb(a); - return MP_OKAY; -} - -int mp_div_2d(fp_int* a, int b, fp_int* c, fp_int* d) -{ - fp_div_2d(a, b, c, d); - return MP_OKAY; -} - -#endif /* HAVE_COMP_KEY */ - - -#endif /* HAVE_ECC */ - -#endif /* USE_FAST_MATH */ diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 40c2cce9f..bd85b20e7 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -24,696 +24,13 @@ #ifndef CTAO_CRYPT_ASN_H #define CTAO_CRYPT_ASN_H -#include -#include -#include -#include -#include -#include -#include /* public interface */ -#ifdef HAVE_ECC - #include -#endif - -#ifdef __cplusplus - extern "C" { -#endif - - -enum { - ISSUER = 0, - SUBJECT = 1, - - EXTERNAL_SERIAL_SIZE = 32, - - BEFORE = 0, - AFTER = 1 -}; - -/* ASN Tags */ -enum ASN_Tags { - ASN_BOOLEAN = 0x01, - ASN_INTEGER = 0x02, - ASN_BIT_STRING = 0x03, - ASN_OCTET_STRING = 0x04, - ASN_TAG_NULL = 0x05, - ASN_OBJECT_ID = 0x06, - ASN_ENUMERATED = 0x0a, - ASN_UTF8STRING = 0x0c, - ASN_SEQUENCE = 0x10, - ASN_SET = 0x11, - ASN_UTC_TIME = 0x17, - ASN_OTHER_TYPE = 0x00, - ASN_RFC822_TYPE = 0x01, - ASN_DNS_TYPE = 0x02, - ASN_DIR_TYPE = 0x04, - ASN_GENERALIZED_TIME = 0x18, - CRL_EXTENSIONS = 0xa0, - ASN_EXTENSIONS = 0xa3, - ASN_LONG_LENGTH = 0x80 -}; - -enum ASN_Flags{ - ASN_CONSTRUCTED = 0x20, - ASN_CONTEXT_SPECIFIC = 0x80 -}; - -enum DN_Tags { - ASN_COMMON_NAME = 0x03, /* CN */ - ASN_SUR_NAME = 0x04, /* SN */ - ASN_SERIAL_NUMBER = 0x05, /* serialNumber */ - ASN_COUNTRY_NAME = 0x06, /* C */ - ASN_LOCALITY_NAME = 0x07, /* L */ - ASN_STATE_NAME = 0x08, /* ST */ - ASN_ORG_NAME = 0x0a, /* O */ - ASN_ORGUNIT_NAME = 0x0b /* OU */ -}; - -enum PBES { - PBE_MD5_DES = 0, - PBE_SHA1_DES = 1, - PBE_SHA1_DES3 = 2, - PBE_SHA1_RC4_128 = 3, - PBES2 = 13 /* algo ID */ -}; - -enum ENCRYPTION_TYPES { - DES_TYPE = 0, - DES3_TYPE = 1, - RC4_TYPE = 2 -}; - -enum ECC_TYPES { - ECC_PREFIX_0 = 160, - ECC_PREFIX_1 = 161 -}; - -enum Misc_ASN { - ASN_NAME_MAX = 256, - MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */ - MAX_IV_SIZE = 64, /* MAX PKCS Iv length */ - MAX_KEY_SIZE = 64, /* MAX PKCS Key length */ - PKCS5 = 5, /* PKCS oid tag */ - PKCS5v2 = 6, /* PKCS #5 v2.0 */ - PKCS12 = 12, /* PKCS #12 */ - MAX_UNICODE_SZ = 256, - ASN_BOOL_SIZE = 2, /* including type */ - ASN_ECC_HEADER_SZ = 2, /* String type + 1 byte len */ - ASN_ECC_CONTEXT_SZ = 2, /* Content specific type + 1 byte len */ - SHA_SIZE = 20, - RSA_INTS = 8, /* RSA ints in private key */ - MIN_DATE_SIZE = 13, - MAX_DATE_SIZE = 32, - ASN_GEN_TIME_SZ = 15, /* 7 numbers * 2 + Zulu tag */ - MAX_ENCODED_SIG_SZ = 512, - MAX_SIG_SZ = 256, - MAX_ALGO_SZ = 20, - MAX_SEQ_SZ = 5, /* enum(seq | con) + length(4) */ - MAX_SET_SZ = 5, /* enum(set | con) + length(4) */ - MAX_OCTET_STR_SZ = 5, /* enum(set | con) + length(4) */ - MAX_EXP_SZ = 5, /* enum(contextspec|con|exp) + length(4) */ - MAX_PRSTR_SZ = 5, /* enum(prstr) + length(4) */ - MAX_VERSION_SZ = 5, /* enum + id + version(byte) + (header(2))*/ - MAX_ENCODED_DIG_SZ = 73, /* sha512 + enum(bit or octet) + legnth(4) */ - MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */ - MAX_NTRU_KEY_SZ = 610, /* NTRU 112 bit public key */ - MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */ - MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */ - MAX_RSA_E_SZ = 16, /* Max RSA public e size */ - MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */ - MAX_SN_SZ = 35, /* Max encoded serial number (INT) length */ -#ifdef CYASSL_CERT_GEN - #ifdef CYASSL_CERT_REQ - /* Max encoded cert req attributes length */ - MAX_ATTRIB_SZ = MAX_SEQ_SZ * 3 + (11 + MAX_SEQ_SZ) * 2 + - MAX_PRSTR_SZ + CTC_NAME_SIZE, /* 11 is the OID size */ - #endif - #ifdef CYASSL_ALT_NAMES - MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + CTC_MAX_ALT_SIZE, - #else - MAX_EXTENSIONS_SZ = 1 + MAX_LENGTH_SZ + MAX_CA_SZ, - #endif - /* Max total extensions, id + len + others */ -#endif - MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */ - MAX_OCSP_NONCE_SZ = 18, /* OCSP Nonce size */ - EIGHTK_BUF = 8192, /* Tmp buffer size */ - MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2 - /* use bigger NTRU size */ -}; - - -enum Oid_Types { - hashType = 0, - sigType = 1, - keyType = 2, - curveType = 3, - blkType = 4 -}; - - -enum Hash_Sum { - MD2h = 646, - MD5h = 649, - SHAh = 88, - SHA256h = 414, - SHA384h = 415, - SHA512h = 416 -}; - - -enum Block_Sum { - DESb = 69, - DES3b = 652 -}; - - -enum Key_Sum { - DSAk = 515, - RSAk = 645, - NTRUk = 274, - ECDSAk = 518 -}; - - -enum Ecc_Sum { - ECC_256R1 = 526, - ECC_384R1 = 210, - ECC_521R1 = 211, - ECC_160R1 = 184, - ECC_192R1 = 520, - ECC_224R1 = 209, - CURVE25519_OID = 212 //TODO value to be determined -}; - - -enum KDF_Sum { - PBKDF2_OID = 660 -}; - - -enum Extensions_Sum { - BASIC_CA_OID = 133, - ALT_NAMES_OID = 131, - CRL_DIST_OID = 145, - AUTH_INFO_OID = 69, - CA_ISSUER_OID = 117, - AUTH_KEY_OID = 149, - SUBJ_KEY_OID = 128, - CERT_POLICY_OID = 146, - KEY_USAGE_OID = 129, /* 2.5.29.15 */ - INHIBIT_ANY_OID = 168, /* 2.5.29.54 */ - EXT_KEY_USAGE_OID = 151, /* 2.5.29.37 */ - NAME_CONS_OID = 144 /* 2.5.29.30 */ -}; - -enum CertificatePolicy_Sum { - CP_ANY_OID = 146 /* id-ce 32 0 */ -}; - -enum SepHardwareName_Sum { - HW_NAME_OID = 79 /* 1.3.6.1.5.5.7.8.4 from RFC 4108*/ -}; - -enum AuthInfo_Sum { - AIA_OCSP_OID = 116, /* 1.3.6.1.5.5.7.48.1 */ - AIA_CA_ISSUER_OID = 117 /* 1.3.6.1.5.5.7.48.2 */ -}; - -enum ExtKeyUsage_Sum { /* From RFC 5280 */ - EKU_ANY_OID = 151, /* 2.5.29.37.0, anyExtendedKeyUsage */ - EKU_SERVER_AUTH_OID = 71, /* 1.3.6.1.5.5.7.3.1, id-kp-serverAuth */ - EKU_CLIENT_AUTH_OID = 72, /* 1.3.6.1.5.5.7.3.2, id-kp-clientAuth */ - EKU_OCSP_SIGN_OID = 79 /* 1.3.6.1.5.5.7.3.9, OCSPSigning */ -}; - - -enum VerifyType { - NO_VERIFY = 0, - VERIFY = 1 -}; - - -/* Key usage extension bits */ -#define KEYUSE_DIGITAL_SIG 0x0100 -#define KEYUSE_CONTENT_COMMIT 0x0080 -#define KEYUSE_KEY_ENCIPHER 0x0040 -#define KEYUSE_DATA_ENCIPHER 0x0020 -#define KEYUSE_KEY_AGREE 0x0010 -#define KEYUSE_KEY_CERT_SIGN 0x0008 -#define KEYUSE_CRL_SIGN 0x0004 -#define KEYUSE_ENCIPHER_ONLY 0x0002 -#define KEYUSE_DECIPHER_ONLY 0x0001 - -#define EXTKEYUSE_ANY 0x08 -#define EXTKEYUSE_OCSP_SIGN 0x04 -#define EXTKEYUSE_CLIENT_AUTH 0x02 -#define EXTKEYUSE_SERVER_AUTH 0x01 - -typedef struct DNS_entry DNS_entry; - -struct DNS_entry { - DNS_entry* next; /* next on DNS list */ - char* name; /* actual DNS name */ -}; - - -typedef struct Base_entry Base_entry; - -struct Base_entry { - Base_entry* next; /* next on name base list */ - char* name; /* actual name base */ - int nameSz; /* name length */ - byte type; /* Name base type (DNS or RFC822) */ -}; - - -struct DecodedName { - char* fullName; - int fullNameLen; - int entryCount; - int cnIdx; - int cnLen; - int snIdx; - int snLen; - int cIdx; - int cLen; - int lIdx; - int lLen; - int stIdx; - int stLen; - int oIdx; - int oLen; - int ouIdx; - int ouLen; - int emailIdx; - int emailLen; - int uidIdx; - int uidLen; - int serialIdx; - int serialLen; -}; - - -typedef struct DecodedCert DecodedCert; -typedef struct DecodedName DecodedName; -typedef struct Signer Signer; - - -struct DecodedCert { - byte* publicKey; - word32 pubKeySize; - int pubKeyStored; - word32 certBegin; /* offset to start of cert */ - word32 sigIndex; /* offset to start of signature */ - word32 sigLength; /* length of signature */ - word32 signatureOID; /* sum of algorithm object id */ - word32 keyOID; /* sum of key algo object id */ - int version; /* cert version, 1 or 3 */ - DNS_entry* altNames; /* alt names list of dns entries */ -#ifndef IGNORE_NAME_CONSTRAINTS - DNS_entry* altEmailNames; /* alt names list of RFC822 entries */ - Base_entry* permittedNames; /* Permitted name bases */ - Base_entry* excludedNames; /* Excluded name bases */ -#endif /* IGNORE_NAME_CONSTRAINTS */ - byte subjectHash[SHA_SIZE]; /* hash of all Names */ - byte issuerHash[SHA_SIZE]; /* hash of all Names */ -#ifdef HAVE_OCSP - byte issuerKeyHash[SHA_SIZE]; /* hash of the public Key */ -#endif /* HAVE_OCSP */ - byte* signature; /* not owned, points into raw cert */ - char* subjectCN; /* CommonName */ - int subjectCNLen; /* CommonName Length */ - char subjectCNEnc; /* CommonName Encoding */ - int subjectCNStored; /* have we saved a copy we own */ - char issuer[ASN_NAME_MAX]; /* full name including common name */ - char subject[ASN_NAME_MAX]; /* full name including common name */ - int verify; /* Default to yes, but could be off */ - byte* source; /* byte buffer holder cert, NOT owner */ - word32 srcIdx; /* current offset into buffer */ - word32 maxIdx; /* max offset based on init size */ - void* heap; /* for user memory overrides */ - byte serial[EXTERNAL_SERIAL_SIZE]; /* raw serial number */ - int serialSz; /* raw serial bytes stored */ - byte* extensions; /* not owned, points into raw cert */ - int extensionsSz; /* length of cert extensions */ - word32 extensionsIdx; /* if want to go back and parse later */ - byte* extAuthInfo; /* Authority Information Access URI */ - int extAuthInfoSz; /* length of the URI */ - byte* extCrlInfo; /* CRL Distribution Points */ - int extCrlInfoSz; /* length of the URI */ - byte extSubjKeyId[SHA_SIZE]; /* Subject Key ID */ - byte extSubjKeyIdSet; /* Set when the SKID was read from cert */ - byte extAuthKeyId[SHA_SIZE]; /* Authority Key ID */ - byte extAuthKeyIdSet; /* Set when the AKID was read from cert */ -#ifndef IGNORE_NAME_CONSTRAINTS - byte extNameConstraintSet; -#endif /* IGNORE_NAME_CONSTRAINTS */ - byte isCA; /* CA basic constraint true */ - byte extKeyUsageSet; - word16 extKeyUsage; /* Key usage bitfield */ - byte extExtKeyUsageSet; /* Extended Key Usage */ - byte extExtKeyUsage; /* Extended Key usage bitfield */ -#ifdef OPENSSL_EXTRA - byte extBasicConstSet; - byte extBasicConstCrit; - byte extBasicConstPlSet; - word32 pathLength; /* CA basic constraint path length, opt */ - byte extSubjAltNameSet; - byte extSubjAltNameCrit; - byte extAuthKeyIdCrit; -#ifndef IGNORE_NAME_CONSTRAINTS - byte extNameConstraintCrit; -#endif /* IGNORE_NAME_CONSTRAINTS */ - byte extSubjKeyIdCrit; - byte extKeyUsageCrit; - byte extExtKeyUsageCrit; - byte* extExtKeyUsageSrc; - word32 extExtKeyUsageSz; - word32 extExtKeyUsageCount; - byte* extAuthKeyIdSrc; - word32 extAuthKeyIdSz; - byte* extSubjKeyIdSrc; - word32 extSubjKeyIdSz; -#endif -#ifdef HAVE_ECC - word32 pkCurveOID; /* Public Key's curve OID */ -#endif /* HAVE_ECC */ - byte* beforeDate; - int beforeDateLen; - byte* afterDate; - int afterDateLen; -#ifdef HAVE_PKCS7 - byte* issuerRaw; /* pointer to issuer inside source */ - int issuerRawLen; -#endif -#ifndef IGNORE_NAME_CONSTRAINT - byte* subjectRaw; /* pointer to subject inside source */ - int subjectRawLen; -#endif -#if defined(CYASSL_CERT_GEN) - /* easy access to subject info for other sign */ - char* subjectSN; - int subjectSNLen; - char subjectSNEnc; - char* subjectC; - int subjectCLen; - char subjectCEnc; - char* subjectL; - int subjectLLen; - char subjectLEnc; - char* subjectST; - int subjectSTLen; - char subjectSTEnc; - char* subjectO; - int subjectOLen; - char subjectOEnc; - char* subjectOU; - int subjectOULen; - char subjectOUEnc; - char* subjectEmail; - int subjectEmailLen; -#endif /* CYASSL_CERT_GEN */ -#ifdef OPENSSL_EXTRA - DecodedName issuerName; - DecodedName subjectName; -#endif /* OPENSSL_EXTRA */ -#ifdef CYASSL_SEP - int deviceTypeSz; - byte* deviceType; - int hwTypeSz; - byte* hwType; - int hwSerialNumSz; - byte* hwSerialNum; - #ifdef OPENSSL_EXTRA - byte extCertPolicySet; - byte extCertPolicyCrit; - #endif /* OPENSSL_EXTRA */ -#endif /* CYASSL_SEP */ -}; - - -#ifdef SHA_DIGEST_SIZE - #define SIGNER_DIGEST_SIZE SHA_DIGEST_SIZE -#else - #define SIGNER_DIGEST_SIZE 20 -#endif - -/* CA Signers */ -/* if change layout change PERSIST_CERT_CACHE functions too */ -struct Signer { - word32 pubKeySize; - word32 keyOID; /* key type */ - word16 keyUsage; - byte* publicKey; - int nameLen; - char* name; /* common name */ -#ifndef IGNORE_NAME_CONSTRAINTS - Base_entry* permittedNames; - Base_entry* excludedNames; -#endif /* IGNORE_NAME_CONSTRAINTS */ - byte subjectNameHash[SIGNER_DIGEST_SIZE]; - /* sha hash of names in certificate */ - #ifndef NO_SKID - byte subjectKeyIdHash[SIGNER_DIGEST_SIZE]; - /* sha hash of names in certificate */ - #endif - Signer* next; -}; - - -/* not for public consumption but may use for testing sometimes */ -#ifdef CYASSL_TEST_CERT - #define CYASSL_TEST_API CYASSL_API -#else - #define CYASSL_TEST_API CYASSL_LOCAL -#endif - -CYASSL_TEST_API void FreeAltNames(DNS_entry*, void*); -#ifndef IGNORE_NAME_CONSTRAINTS - CYASSL_TEST_API void FreeNameSubtrees(Base_entry*, void*); -#endif /* IGNORE_NAME_CONSTRAINTS */ -CYASSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*); -CYASSL_TEST_API void FreeDecodedCert(DecodedCert*); -CYASSL_TEST_API int ParseCert(DecodedCert*, int type, int verify, void* cm); - -CYASSL_LOCAL int ParseCertRelative(DecodedCert*, int type, int verify,void* cm); -CYASSL_LOCAL int DecodeToKey(DecodedCert*, int verify); - -CYASSL_LOCAL Signer* MakeSigner(void*); -CYASSL_LOCAL void FreeSigner(Signer*, void*); -CYASSL_LOCAL void FreeSignerTable(Signer**, int, void*); - - -CYASSL_LOCAL int ToTraditional(byte* buffer, word32 length); -CYASSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*, int); - -CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType); - -/* ASN.1 helper functions */ -CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, - word32 maxIdx); -CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len, - word32 maxIdx); -CYASSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len, - word32 maxIdx); -CYASSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, - int* version); -CYASSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, - word32 maxIdx); -CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, - word32 maxIdx); -CYASSL_LOCAL word32 SetLength(word32 length, byte* output); -CYASSL_LOCAL word32 SetSequence(word32 len, byte* output); -CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output); -CYASSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len,byte* output); -CYASSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output); -CYASSL_LOCAL word32 SetSet(word32 len, byte* output); -CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz); -CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header); -CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output); -CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, - int maxIdx); - -#ifdef HAVE_ECC - /* ASN sig helpers */ - CYASSL_LOCAL int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, - mp_int* s); - CYASSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, - mp_int* r, mp_int* s); -#endif - -#ifdef CYASSL_CERT_GEN - -enum cert_enums { - NAME_ENTRIES = 8, - JOINT_LEN = 2, - EMAIL_JOINT_LEN = 9, - RSA_KEY = 10, - NTRU_KEY = 11, - ECC_KEY = 12 -}; - -#ifndef CYASSL_PEMCERT_TODER_DEFINED +#include +#ifndef WOLFSSL_PEMCERT_TODER_DEFINED #ifndef NO_FILESYSTEM -/* forward from CyaSSL */ -CYASSL_API -int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz); -#define CYASSL_PEMCERT_TODER_DEFINED + #define CyaSSL_PemCertToDer wolfSSL_PemCertToDer #endif #endif -#endif /* CYASSL_CERT_GEN */ - - - -/* for pointer use */ -typedef struct CertStatus CertStatus; - -#ifdef HAVE_OCSP - -enum Ocsp_Response_Status { - OCSP_SUCCESSFUL = 0, /* Response has valid confirmations */ - OCSP_MALFORMED_REQUEST = 1, /* Illegal confirmation request */ - OCSP_INTERNAL_ERROR = 2, /* Internal error in issuer */ - OCSP_TRY_LATER = 3, /* Try again later */ - OCSP_SIG_REQUIRED = 5, /* Must sign the request (4 is skipped) */ - OCSP_UNAUTHROIZED = 6 /* Request unauthorized */ -}; - - -enum Ocsp_Cert_Status { - CERT_GOOD = 0, - CERT_REVOKED = 1, - CERT_UNKNOWN = 2 -}; - - -enum Ocsp_Sums { - OCSP_BASIC_OID = 117, - OCSP_NONCE_OID = 118 -}; - - -typedef struct OcspRequest OcspRequest; -typedef struct OcspResponse OcspResponse; - - -struct CertStatus { - CertStatus* next; - - byte serial[EXTERNAL_SERIAL_SIZE]; - int serialSz; - - int status; - - byte thisDate[MAX_DATE_SIZE]; - byte nextDate[MAX_DATE_SIZE]; - byte thisDateFormat; - byte nextDateFormat; -}; - - -struct OcspResponse { - int responseStatus; /* return code from Responder */ - - byte* response; /* Pointer to beginning of OCSP Response */ - word32 responseSz; /* length of the OCSP Response */ - - byte producedDate[MAX_DATE_SIZE]; - /* Date at which this response was signed */ - byte producedDateFormat; /* format of the producedDate */ - byte* issuerHash; - byte* issuerKeyHash; - - byte* cert; - word32 certSz; - - byte* sig; /* Pointer to sig in source */ - word32 sigSz; /* Length in octets for the sig */ - word32 sigOID; /* OID for hash used for sig */ - - CertStatus* status; /* certificate status to fill out */ - - byte* nonce; /* pointer to nonce inside ASN.1 response */ - int nonceSz; /* length of the nonce string */ - - byte* source; /* pointer to source buffer, not owned */ - word32 maxIdx; /* max offset based on init size */ -}; - - -struct OcspRequest { - DecodedCert* cert; - - byte useNonce; - byte nonce[MAX_OCSP_NONCE_SZ]; - int nonceSz; - - byte* issuerHash; /* pointer to issuerHash in source cert */ - byte* issuerKeyHash; /* pointer to issuerKeyHash in source cert */ - byte* serial; /* pointer to serial number in source cert */ - int serialSz; /* length of the serial number */ - - byte* dest; /* pointer to the destination ASN.1 buffer */ - word32 destSz; /* length of the destination buffer */ -}; - - -CYASSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32); -CYASSL_LOCAL int OcspResponseDecode(OcspResponse*); - -CYASSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*, - byte, byte*, word32); -CYASSL_LOCAL int EncodeOcspRequest(OcspRequest*); - -CYASSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*); - - -#endif /* HAVE_OCSP */ - - -/* for pointer use */ -typedef struct RevokedCert RevokedCert; - -#ifdef HAVE_CRL - -struct RevokedCert { - byte serialNumber[EXTERNAL_SERIAL_SIZE]; - int serialSz; - RevokedCert* next; -}; - -typedef struct DecodedCRL DecodedCRL; - -struct DecodedCRL { - word32 certBegin; /* offset to start of cert */ - word32 sigIndex; /* offset to start of signature */ - word32 sigLength; /* length of signature */ - word32 signatureOID; /* sum of algorithm object id */ - byte* signature; /* pointer into raw source, not owned */ - byte issuerHash[SHA_DIGEST_SIZE]; /* issuer hash */ - byte crlHash[SHA_DIGEST_SIZE]; /* raw crl data hash */ - byte lastDate[MAX_DATE_SIZE]; /* last date updated */ - byte nextDate[MAX_DATE_SIZE]; /* next update date */ - byte lastDateFormat; /* format of last date */ - byte nextDateFormat; /* format of next date */ - RevokedCert* certs; /* revoked cert list */ - int totalCerts; /* number on list */ -}; - -CYASSL_LOCAL void InitDecodedCRL(DecodedCRL*); -CYASSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, word32 sz, void* cm); -CYASSL_LOCAL void FreeDecodedCRL(DecodedCRL*); - - -#endif /* HAVE_CRL */ - - -#ifdef __cplusplus - } /* extern "C" */ -#endif - #endif /* CTAO_CRYPT_ASN_H */ #endif /* !NO_ASN */ diff --git a/cyassl/ctaocrypt/blake2.h b/cyassl/ctaocrypt/blake2.h index 8f5cfa126..250ef1640 100644 --- a/cyassl/ctaocrypt/blake2.h +++ b/cyassl/ctaocrypt/blake2.h @@ -32,7 +32,12 @@ #define InitBlake2b wc_InitBlake2b #define Blake2bUpdate wc_Blake2bUpdate #define Blake2bFinal wc_Blake2bFinal -#endif +#else + /* name for when fips hmac calls blake */ + #define wc_InitBlake2b InitBlake2b + #define wc_Blake2bUpdate Blake2bUpdate + #define wc_Blake2bFinal Blake2bFinal +#endif /* HAVE_FIPS */ #endif /* CTAOCRYPT_BLAKE2_H */ #endif /* HAVE_BLAKE2 */ diff --git a/cyassl/ctaocrypt/coding.h b/cyassl/ctaocrypt/coding.h index d2ca0d62b..c63b26a16 100644 --- a/cyassl/ctaocrypt/coding.h +++ b/cyassl/ctaocrypt/coding.h @@ -23,41 +23,7 @@ #ifndef CTAO_CRYPT_CODING_H #define CTAO_CRYPT_CODING_H -#ifndef HAVE_FIPS - #include -#else +#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - -/* decode needed by CyaSSL */ -CYASSL_LOCAL int Base64_Decode(const byte* in, word32 inLen, byte* out, - word32* outLen); - -#if defined(OPENSSL_EXTRA) || defined(SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) - /* encode isn't */ - CYASSL_API - int Base64_Encode(const byte* in, word32 inLen, byte* out, - word32* outLen); - CYASSL_API - int Base64_EncodeEsc(const byte* in, word32 inLen, byte* out, - word32* outLen); -#endif - -#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) - CYASSL_API - int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen); -#endif - - -#ifdef __cplusplus - } /* extern "C" */ -#endif - -#endif /* HAVE_FIPS */ #endif /* CTAO_CRYPT_CODING_H */ diff --git a/cyassl/ctaocrypt/compress.h b/cyassl/ctaocrypt/compress.h index f64578351..e2c3aee80 100644 --- a/cyassl/ctaocrypt/compress.h +++ b/cyassl/ctaocrypt/compress.h @@ -31,26 +31,6 @@ #define Compress wc_Compress #define DeCompress wc_DeCompress -//#include -// -// -//#ifdef __cplusplus -// extern "C" { -//#endif -// -// -//#define COMPRESS_FIXED 1 -// -// -//CYASSL_API int Compress(byte*, word32, const byte*, word32, word32); -//CYASSL_API int DeCompress(byte*, word32, const byte*, word32); -// -// -//#ifdef __cplusplus -// } /* extern "C" */ -//#endif -// -// #endif /* CTAO_CRYPT_COMPRESS_H */ #endif /* HAVE_LIBZ */ diff --git a/cyassl/ctaocrypt/integer.h b/cyassl/ctaocrypt/integer.h index 8357274ae..1e6691b2e 100644 --- a/cyassl/ctaocrypt/integer.h +++ b/cyassl/ctaocrypt/integer.h @@ -28,301 +28,7 @@ #ifndef CTAO_CRYPT_INTEGER_H #define CTAO_CRYPT_INTEGER_H -#ifndef HAVE_FIPS - #include -#else -/* may optionally use fast math instead, not yet supported on all platforms and - may not be faster on all -*/ -#include /* will set MP_xxBIT if not default */ -#ifdef USE_FAST_MATH - #include -#else +#include -#ifndef CHAR_BIT - #include -#endif - -#include - -#ifndef MIN - #define MIN(x,y) ((x)<(y)?(x):(y)) -#endif - -#ifndef MAX - #define MAX(x,y) ((x)>(y)?(x):(y)) -#endif - -#ifdef __cplusplus -extern "C" { - -/* C++ compilers don't like assigning void * to mp_digit * */ -#define OPT_CAST(x) (x *) - -#else - -/* C on the other hand doesn't care */ -#define OPT_CAST(x) - -#endif - - -/* detect 64-bit mode if possible */ -#if defined(__x86_64__) - #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) - #define MP_64BIT - #endif -#endif -/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */ -#if defined(MP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T) - #undef MP_64BIT -#endif - -/* some default configurations. - * - * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits - * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits - * - * At the very least a mp_digit must be able to hold 7 bits - * [any size beyond that is ok provided it doesn't overflow the data type] - */ -#ifdef MP_8BIT - typedef unsigned char mp_digit; - typedef unsigned short mp_word; -#elif defined(MP_16BIT) || defined(NO_64BIT) - typedef unsigned short mp_digit; - typedef unsigned int mp_word; -#elif defined(MP_64BIT) - /* for GCC only on supported platforms */ - typedef unsigned long long mp_digit; /* 64 bit type, 128 uses mode(TI) */ - typedef unsigned long mp_word __attribute__ ((mode(TI))); - - #define DIGIT_BIT 60 -#else - /* this is the default case, 28-bit digits */ - - #if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 ulong64; - #else - typedef unsigned long long ulong64; - #endif - - typedef unsigned int mp_digit; /* long could be 64 now, changed TAO */ - typedef ulong64 mp_word; - -#ifdef MP_31BIT - /* this is an extension that uses 31-bit digits */ - #define DIGIT_BIT 31 -#else - /* default case is 28-bit digits, defines MP_28BIT as a handy test macro */ - #define DIGIT_BIT 28 - #define MP_28BIT -#endif -#endif - - -/* otherwise the bits per digit is calculated automatically from the size of - a mp_digit */ -#ifndef DIGIT_BIT - #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) - /* bits per digit */ -#endif - -#define MP_DIGIT_BIT DIGIT_BIT -#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) -#define MP_DIGIT_MAX MP_MASK - -/* equalities */ -#define MP_LT -1 /* less than */ -#define MP_EQ 0 /* equal to */ -#define MP_GT 1 /* greater than */ - -#define MP_ZPOS 0 /* positive integer */ -#define MP_NEG 1 /* negative */ - -#define MP_OKAY 0 /* ok result */ -#define MP_MEM -2 /* out of mem */ -#define MP_VAL -3 /* invalid input */ -#define MP_RANGE MP_VAL - -#define MP_YES 1 /* yes response */ -#define MP_NO 0 /* no response */ - -/* Primality generation flags */ -#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ -#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ -#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ - -typedef int mp_err; - -/* define this to use lower memory usage routines (exptmods mostly) */ -#define MP_LOW_MEM - -/* default precision */ -#ifndef MP_PREC - #ifndef MP_LOW_MEM - #define MP_PREC 32 /* default digits of precision */ - #else - #define MP_PREC 1 /* default digits of precision */ - #endif -#endif - -/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - - BITS_PER_DIGIT*2) */ -#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) - -/* the infamous mp_int structure */ -typedef struct { - int used, alloc, sign; - mp_digit *dp; -} mp_int; - -/* callback for mp_prime_random, should fill dst with random bytes and return - how many read [upto len] */ -typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); - - -#define USED(m) ((m)->used) -#define DIGIT(m,k) ((m)->dp[(k)]) -#define SIGN(m) ((m)->sign) - - -/* ---> Basic Manipulations <--- */ -#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) -#define mp_iseven(a) \ - (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) -#define mp_isodd(a) \ - (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) - - -/* number of primes */ -#ifdef MP_8BIT - #define PRIME_SIZE 31 -#else - #define PRIME_SIZE 256 -#endif - -#define mp_prime_random(a, t, size, bbs, cb, dat) \ - mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) - -#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) -#define mp_raw_size(mp) mp_signed_bin_size(mp) -#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) -#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) -#define mp_mag_size(mp) mp_unsigned_bin_size(mp) -#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) - -#define mp_tobinary(M, S) mp_toradix((M), (S), 2) -#define mp_tooctal(M, S) mp_toradix((M), (S), 8) -#define mp_todecimal(M, S) mp_toradix((M), (S), 10) -#define mp_tohex(M, S) mp_toradix((M), (S), 16) - -#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) - -extern const char *mp_s_rmap; - -/* 6 functions needed by Rsa */ -int mp_init (mp_int * a); -void mp_clear (mp_int * a); -int mp_unsigned_bin_size(mp_int * a); -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); -int mp_to_unsigned_bin (mp_int * a, unsigned char *b); -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); -/* end functions needed by Rsa */ - -/* functions added to support above needed, removed TOOM and KARATSUBA */ -int mp_count_bits (mp_int * a); -int mp_leading_bit (mp_int * a); -int mp_init_copy (mp_int * a, mp_int * b); -int mp_copy (mp_int * a, mp_int * b); -int mp_grow (mp_int * a, int size); -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); -void mp_zero (mp_int * a); -void mp_clamp (mp_int * a); -void mp_exch (mp_int * a, mp_int * b); -void mp_rshd (mp_int * a, int b); -void mp_rshb (mp_int * a, int b); -int mp_mod_2d (mp_int * a, int b, mp_int * c); -int mp_mul_2d (mp_int * a, int b, mp_int * c); -int mp_lshd (mp_int * a, int b); -int mp_abs (mp_int * a, mp_int * b); -int mp_invmod (mp_int * a, mp_int * b, mp_int * c); -int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c); -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); -int mp_cmp_mag (mp_int * a, mp_int * b); -int mp_cmp (mp_int * a, mp_int * b); -int mp_cmp_d(mp_int * a, mp_digit b); -void mp_set (mp_int * a, mp_digit b); -int mp_mod (mp_int * a, mp_int * b, mp_int * c); -int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); -int mp_div_2(mp_int * a, mp_int * b); -int mp_add (mp_int * a, mp_int * b, mp_int * c); -int s_mp_add (mp_int * a, mp_int * b, mp_int * c); -int s_mp_sub (mp_int * a, mp_int * b, mp_int * c); -int mp_sub (mp_int * a, mp_int * b, mp_int * c); -int mp_reduce_is_2k_l(mp_int *a); -int mp_reduce_is_2k(mp_int *a); -int mp_dr_is_modulus(mp_int *a); -int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int); -int mp_montgomery_setup (mp_int * n, mp_digit * rho); -int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); -int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); -void mp_dr_setup(mp_int *a, mp_digit *d); -int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k); -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); -int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); -int s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); -int mp_reduce (mp_int * x, mp_int * m, mp_int * mu); -int mp_reduce_setup (mp_int * a, mp_int * b); -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); -int mp_montgomery_calc_normalization (mp_int * a, mp_int * b); -int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); -int s_mp_sqr (mp_int * a, mp_int * b); -int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); -int fast_s_mp_sqr (mp_int * a, mp_int * b); -int mp_init_size (mp_int * a, int size); -int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d); -int mp_mul_2(mp_int * a, mp_int * b); -int mp_mul (mp_int * a, mp_int * b, mp_int * c); -int mp_sqr (mp_int * a, mp_int * b); -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d); -int mp_mul_d (mp_int * a, mp_digit b, mp_int * c); -int mp_2expt (mp_int * a, int b); -int mp_reduce_2k_setup(mp_int *a, mp_digit *d); -int mp_add_d (mp_int* a, mp_digit b, mp_int* c); -int mp_set_int (mp_int * a, unsigned long b); -int mp_sub_d (mp_int * a, mp_digit b, mp_int * c); -/* end support added functions */ - -/* added */ -int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, - mp_int* f); - -#if defined(HAVE_ECC) || defined(CYASSL_KEY_GEN) - int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); -#endif -#ifdef HAVE_ECC - int mp_read_radix(mp_int* a, const char* str, int radix); -#endif - -#ifdef CYASSL_KEY_GEN - int mp_prime_is_prime (mp_int * a, int t, int *result); - int mp_gcd (mp_int * a, mp_int * b, mp_int * c); - int mp_lcm (mp_int * a, mp_int * b, mp_int * c); -#endif - -int mp_cnt_lsb(mp_int *a); -int mp_mod_d(mp_int* a, mp_digit b, mp_digit* c); - -#ifdef __cplusplus - } -#endif - - -#endif /* USE_FAST_MATH */ - -#endif /* HAVE_FIPS */ #endif /* CTAO_CRYPT_INTEGER_H */ diff --git a/cyassl/ctaocrypt/logging.h b/cyassl/ctaocrypt/logging.h index af5d60daf..4f45f52e1 100644 --- a/cyassl/ctaocrypt/logging.h +++ b/cyassl/ctaocrypt/logging.h @@ -26,57 +26,15 @@ #define CYASSL_LOGGING_H /* for fips compatibility @wc_fips */ -#ifndef HAVE_FIPS - #include - #define CYASSL_LEAVE WOLFSSL_LEAVE - #define CYASSL_ERROR WOLFSSL_ERROR - #define CYASSL_ENTER WOLFSSL_ENTER - #define CYASSL_MSG WOLFSSL_MSG - /* check old macros possibly declared */ - #if defined(CYASSL_DEBUG) && !defined(DEBUG_WOLFSSL) - #define DEBUG_WOLFSSL - #endif -#else - #ifdef __cplusplus - extern "C" { - #endif - - - enum CYA_Log_Levels { - ERROR_LOG = 0, - INFO_LOG, - ENTER_LOG, - LEAVE_LOG, - OTHER_LOG - }; - - typedef void (*CyaSSL_Logging_cb)(const int logLevel, - const char *const logMessage); - - CYASSL_API int CyaSSL_SetLoggingCb(CyaSSL_Logging_cb log_function); - - - #ifdef DEBUG_CYASSL - - void CYASSL_ENTER(const char* msg); - void CYASSL_LEAVE(const char* msg, int ret); - - void CYASSL_ERROR(int); - void CYASSL_MSG(const char* msg); - - #else /* DEBUG_CYASSL */ - - #define CYASSL_ENTER(m) - #define CYASSL_LEAVE(m, r) - - #define CYASSL_ERROR(e) - #define CYASSL_MSG(m) - - #endif /* DEBUG_CYASSL */ - - #ifdef __cplusplus - } - #endif -#endif /* HAVE_FIPS*/ -#endif /* CYASSL_MEMORY_H */ +#include +#define CYASSL_LEAVE WOLFSSL_LEAVE +#define CYASSL_ERROR WOLFSSL_ERROR +#define CYASSL_ENTER WOLFSSL_ENTER +#define CYASSL_MSG WOLFSSL_MSG +/* check old macros possibly declared */ +#if defined(CYASSL_DEBUG) && !defined(DEBUG_WOLFSSL) + #define DEBUG_WOLFSSL +#endif + +#endif /* CYASSL_LOGGING_H */ diff --git a/cyassl/ctaocrypt/md5.h b/cyassl/ctaocrypt/md5.h index 755924978..f5bc5bd8e 100644 --- a/cyassl/ctaocrypt/md5.h +++ b/cyassl/ctaocrypt/md5.h @@ -25,7 +25,6 @@ #define CTAO_CRYPT_MD5_H #include -#include #ifndef HAVE_FIPS #define InitMd5 wc_InitMd5 diff --git a/cyassl/ctaocrypt/memory.h b/cyassl/ctaocrypt/memory.h index d8d8e3c77..bc22c5391 100644 --- a/cyassl/ctaocrypt/memory.h +++ b/cyassl/ctaocrypt/memory.h @@ -25,38 +25,17 @@ #ifndef CYASSL_MEMORY_H #define CYASSL_MEMORY_H -#include -/* for fips compatibility @wc_fips */ -#ifndef HAVE_FIPS #include -#else - -#ifdef __cplusplus - extern "C" { -#endif - - -typedef void *(*CyaSSL_Malloc_cb)(size_t size); -typedef void (*CyaSSL_Free_cb)(void *ptr); -typedef void *(*CyaSSL_Realloc_cb)(void *ptr, size_t size); - - -/* Public set function */ -CYASSL_API int CyaSSL_SetAllocators(CyaSSL_Malloc_cb malloc_function, - CyaSSL_Free_cb free_function, - CyaSSL_Realloc_cb realloc_function); +#define CyaSSL_Malloc_cb wolfSSL_Malloc_cb +#define CyaSSL_Free_cb wolfSSL_Free_cb +#define CyaSSL_Realloc_cb wolfSSL_Realloc_cb +#define CyaSSL_SetAllocators wolfSSL_SetAllocators /* Public in case user app wants to use XMALLOC/XFREE */ -CYASSL_API void* CyaSSL_Malloc(size_t size); -CYASSL_API void CyaSSL_Free(void *ptr); -CYASSL_API void* CyaSSL_Realloc(void *ptr, size_t size); +#define CyaSSL_Malloc wolfSSL_Malloc +#define CyaSSL_Free wolfSSL_Free +#define CyaSSL_Realloc wolfSSL_Realloc - -#ifdef __cplusplus -} -#endif - -#endif /* HAVE_FIPS */ #endif /* CYASSL_MEMORY_H */ diff --git a/cyassl/ctaocrypt/misc.h b/cyassl/ctaocrypt/misc.h index f6f1149a4..13e5a4b31 100644 --- a/cyassl/ctaocrypt/misc.h +++ b/cyassl/ctaocrypt/misc.h @@ -23,54 +23,7 @@ #ifndef CTAO_CRYPT_MISC_H #define CTAO_CRYPT_MISC_H -#include +#include -#ifndef HAVE_FIPS - #include -#else - - -#ifdef __cplusplus - extern "C" { -#endif - - -#ifdef NO_INLINE -CYASSL_LOCAL -word32 rotlFixed(word32, word32); -CYASSL_LOCAL -word32 rotrFixed(word32, word32); - -CYASSL_LOCAL -word32 ByteReverseWord32(word32); -CYASSL_LOCAL -void ByteReverseWords(word32*, const word32*, word32); - -CYASSL_LOCAL -void XorWords(word*, const word*, word32); -CYASSL_LOCAL -void xorbuf(void*, const void*, word32); - -#ifdef WORD64_AVAILABLE -CYASSL_LOCAL -word64 rotlFixed64(word64, word64); -CYASSL_LOCAL -word64 rotrFixed64(word64, word64); - -CYASSL_LOCAL -word64 ByteReverseWord64(word64); -CYASSL_LOCAL -void ByteReverseWords64(word64*, const word64*, word32); -#endif /* WORD64_AVAILABLE */ - -#endif /* NO_INLINE */ - - -#ifdef __cplusplus - } /* extern "C" */ -#endif - - -#endif /* HAVE_FIPS */ #endif /* CTAO_CRYPT_MISC_H */ diff --git a/cyassl/ctaocrypt/pkcs7.h b/cyassl/ctaocrypt/pkcs7.h index 241344e9e..c4939ce91 100644 --- a/cyassl/ctaocrypt/pkcs7.h +++ b/cyassl/ctaocrypt/pkcs7.h @@ -9,7 +9,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * wolfSSL is distributed in the hope that it will be useful, + * wolfSSL 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. diff --git a/cyassl/ctaocrypt/pwdbased.h b/cyassl/ctaocrypt/pwdbased.h index cd89acf00..4d9dee21f 100644 --- a/cyassl/ctaocrypt/pwdbased.h +++ b/cyassl/ctaocrypt/pwdbased.h @@ -25,29 +25,11 @@ #ifndef CTAO_CRYPT_PWDBASED_H #define CTAO_CRYPT_PWDBASED_H -#include -#include /* for hash type */ -#include - -#ifdef __cplusplus - extern "C" { -#endif - - -CYASSL_API int PBKDF1(byte* output, const byte* passwd, int pLen, - const byte* salt, int sLen, int iterations, int kLen, - int hashType); -CYASSL_API int PBKDF2(byte* output, const byte* passwd, int pLen, - const byte* salt, int sLen, int iterations, int kLen, - int hashType); -CYASSL_API int PKCS12_PBKDF(byte* output, const byte* passwd, int pLen, - const byte* salt, int sLen, int iterations, - int kLen, int hashType, int purpose); - - -#ifdef __cplusplus - } /* extern "C" */ -#endif +/* for pwdbased reverse compatibility */ +#include +#define PBKDF1 wc_PBKDF1 +#define PBKDF2 wc_PBKDF2 +#define PKCS12_PBKDF wc_PKCS12_PBKDF #endif /* CTAO_CRYPT_PWDBASED_H */ #endif /* NO_PWDBASED */ diff --git a/cyassl/ctaocrypt/settings.h b/cyassl/ctaocrypt/settings.h index b17fdd83c..ca2fe9987 100644 --- a/cyassl/ctaocrypt/settings.h +++ b/cyassl/ctaocrypt/settings.h @@ -28,12 +28,6 @@ /* for reverse compatibility after name change */ #include -#if defined(WOLFSSL_LEANPSK) && !defined(CYASSL_LEANPSK) - #define CYASSL_LEANPSK -#endif -#if defined(NO_WOLFSSL_MEMORY) && !defined(NO_CYASSL_MEMORY) - #define NO_CYASSL_MEMORY -#endif #ifdef __cplusplus extern "C" { diff --git a/cyassl/ctaocrypt/settings_comp.h b/cyassl/ctaocrypt/settings_comp.h index c7f469338..9fa1c2734 100644 --- a/cyassl/ctaocrypt/settings_comp.h +++ b/cyassl/ctaocrypt/settings_comp.h @@ -23,12 +23,23 @@ #define CTAO_CRYPT_SETTINGS_C_H /* Macro redefinitions for compatibility */ -#ifdef WOLFSSL_SHA512 - #define CYASSL_SHA512 WOLFSSL_SHA512 +#if defined(WOLFSSL_SHA512) && !defined(CYASSL_SHA512) + #define CYASSL_SHA512 #endif -#ifdef WOLFSSL_SHA384 - #define CYASSL_SHA384 WOLFSSL_SHA384 +#if defined(WOLFSSL_SHA384) && !defined(CYASSL_SHA384) + #define CYASSL_SHA384 #endif +#if defined(WOLFSSL_LEANPSK) && !defined(CYASSL_LEANPSK) + #define CYASSL_LEANPSK +#endif +#if defined(NO_WOLFSSL_MEMORY) && !defined(NO_CYASSL_MEMORY) + #define NO_CYASSL_MEMORY +#endif + +/* asn.c compatibility */ +#define RsaPrivateKeyDecode wc_RsaPrivateKeyDecode +#define RsaPublicKeyDecode wc_RsaPublicKeyDecode +#define RsaPublicKeyDecodeRaw wc_RsaPublicKeyDecodeRaw /* These are compatibility from fips protected headers * When using non-fips mode and including old headers this allows for @@ -94,10 +105,7 @@ #define RsaSSL_VerifyInline wc_RsaSSL_VerifyInline #define RsaSSL_Verify wc_RsaSSL_Verify #define RsaEncryptSize wc_RsaEncryptSize - #define RsaPrivateKeyDecode wc_RsaPrivateKeyDecode - #define RsaPublicKeyDecode wc_RsaPublicKeyDecode - #define RsaPublicKeyDecodeRaw wc_RsaPublicKeyDecodeRaw - #define RsaFlattenPublicKey wc_RsaFlattenPublicKey + #define RsaFlattenPublicKey wc_RsaFlattenPublicKey #ifdef WOLFSSL_KEY_GEN #define MakeRsaKey wc_MakeRsaKey diff --git a/cyassl/ctaocrypt/tfm.h b/cyassl/ctaocrypt/tfm.h index 1fb19aeae..47d6d48d8 100644 --- a/cyassl/ctaocrypt/tfm.h +++ b/cyassl/ctaocrypt/tfm.h @@ -35,673 +35,7 @@ #ifndef CTAO_CRYPT_TFM_H #define CTAO_CRYPT_TFM_H -#include -#ifndef CHAR_BIT - #include -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef MIN - #define MIN(x,y) ((x)<(y)?(x):(y)) -#endif - -#ifndef MAX - #define MAX(x,y) ((x)>(y)?(x):(y)) -#endif - - -#ifndef NO_64BIT -/* autodetect x86-64 and make sure we are using 64-bit digits with x86-64 asm */ -#if defined(__x86_64__) - #if defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) - #error x86-64 detected, x86-32/SSE2/ARM optimizations are not valid! - #endif - #if !defined(TFM_X86_64) && !defined(TFM_NO_ASM) - #define TFM_X86_64 - #endif -#endif -#if defined(TFM_X86_64) - #if !defined(FP_64BIT) - #define FP_64BIT - #endif -#endif -/* use 64-bit digit even if not using asm on x86_64 */ -#if defined(__x86_64__) && !defined(FP_64BIT) - #define FP_64BIT -#endif -/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */ -#if defined(FP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T) - #undef FP_64BIT - #undef TFM_X86_64 -#endif -#endif /* NO_64BIT */ - -/* try to detect x86-32 */ -#if defined(__i386__) && !defined(TFM_SSE2) - #if defined(TFM_X86_64) || defined(TFM_ARM) - #error x86-32 detected, x86-64/ARM optimizations are not valid! - #endif - #if !defined(TFM_X86) && !defined(TFM_NO_ASM) - #define TFM_X86 - #endif -#endif - -/* make sure we're 32-bit for x86-32/sse/arm/ppc32 */ -#if (defined(TFM_X86) || defined(TFM_SSE2) || defined(TFM_ARM) || defined(TFM_PPC32)) && defined(FP_64BIT) - #warning x86-32, SSE2 and ARM, PPC32 optimizations require 32-bit digits (undefining) - #undef FP_64BIT -#endif - -/* multi asms? */ -#ifdef TFM_X86 - #define TFM_ASM -#endif -#ifdef TFM_X86_64 - #ifdef TFM_ASM - #error TFM_ASM already defined! - #endif - #define TFM_ASM -#endif -#ifdef TFM_SSE2 - #ifdef TFM_ASM - #error TFM_ASM already defined! - #endif - #define TFM_ASM -#endif -#ifdef TFM_ARM - #ifdef TFM_ASM - #error TFM_ASM already defined! - #endif - #define TFM_ASM -#endif -#ifdef TFM_PPC32 - #ifdef TFM_ASM - #error TFM_ASM already defined! - #endif - #define TFM_ASM -#endif -#ifdef TFM_PPC64 - #ifdef TFM_ASM - #error TFM_ASM already defined! - #endif - #define TFM_ASM -#endif -#ifdef TFM_AVR32 - #ifdef TFM_ASM - #error TFM_ASM already defined! - #endif - #define TFM_ASM -#endif - -/* we want no asm? */ -#ifdef TFM_NO_ASM - #undef TFM_X86 - #undef TFM_X86_64 - #undef TFM_SSE2 - #undef TFM_ARM - #undef TFM_PPC32 - #undef TFM_PPC64 - #undef TFM_AVR32 - #undef TFM_ASM -#endif - -/* ECC helpers */ -#ifdef TFM_ECC192 - #ifdef FP_64BIT - #define TFM_MUL3 - #define TFM_SQR3 - #else - #define TFM_MUL6 - #define TFM_SQR6 - #endif -#endif - -#ifdef TFM_ECC224 - #ifdef FP_64BIT - #define TFM_MUL4 - #define TFM_SQR4 - #else - #define TFM_MUL7 - #define TFM_SQR7 - #endif -#endif - -#ifdef TFM_ECC256 - #ifdef FP_64BIT - #define TFM_MUL4 - #define TFM_SQR4 - #else - #define TFM_MUL8 - #define TFM_SQR8 - #endif -#endif - -#ifdef TFM_ECC384 - #ifdef FP_64BIT - #define TFM_MUL6 - #define TFM_SQR6 - #else - #define TFM_MUL12 - #define TFM_SQR12 - #endif -#endif - -#ifdef TFM_ECC521 - #ifdef FP_64BIT - #define TFM_MUL9 - #define TFM_SQR9 - #else - #define TFM_MUL17 - #define TFM_SQR17 - #endif -#endif - - -/* some default configurations. - */ -#if defined(FP_64BIT) - /* for GCC only on supported platforms */ - typedef unsigned long long fp_digit; /* 64bit, 128 uses mode(TI) below */ - typedef unsigned long fp_word __attribute__ ((mode(TI))); -#else - #if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 ulong64; - #else - typedef unsigned long long ulong64; - #endif - - #ifndef NO_64BIT - typedef unsigned int fp_digit; - typedef ulong64 fp_word; - #define FP_32BIT - #else - /* some procs like coldfire prefer not to place multiply into 64bit type - even though it exists */ - typedef unsigned short fp_digit; - typedef unsigned int fp_word; - #endif -#endif - -/* # of digits this is */ -#define DIGIT_BIT (int)((CHAR_BIT) * sizeof(fp_digit)) - -/* Max size of any number in bits. Basically the largest size you will be - * multiplying should be half [or smaller] of FP_MAX_SIZE-four_digit - * - * It defaults to 4096-bits [allowing multiplications upto 2048x2048 bits ] - */ -#ifndef FP_MAX_BITS - #define FP_MAX_BITS 4096 -#endif -#define FP_MAX_SIZE (FP_MAX_BITS+(8*DIGIT_BIT)) - -/* will this lib work? */ -#if (CHAR_BIT & 7) - #error CHAR_BIT must be a multiple of eight. -#endif -#if FP_MAX_BITS % CHAR_BIT - #error FP_MAX_BITS must be a multiple of CHAR_BIT -#endif - -#define FP_MASK (fp_digit)(-1) -#define FP_SIZE (FP_MAX_SIZE/DIGIT_BIT) - -/* signs */ -#define FP_ZPOS 0 -#define FP_NEG 1 - -/* return codes */ -#define FP_OKAY 0 -#define FP_VAL 1 -#define FP_MEM 2 - -/* equalities */ -#define FP_LT -1 /* less than */ -#define FP_EQ 0 /* equal to */ -#define FP_GT 1 /* greater than */ - -/* replies */ -#define FP_YES 1 /* yes response */ -#define FP_NO 0 /* no response */ - -/* a FP type */ -typedef struct { - fp_digit dp[FP_SIZE]; - int used, - sign; -} fp_int; - -/* externally define this symbol to ignore the default settings, useful for changing the build from the make process */ -#ifndef TFM_ALREADY_SET - -/* do we want the large set of small multiplications ? - Enable these if you are going to be doing a lot of small (<= 16 digit) multiplications say in ECC - Or if you're on a 64-bit machine doing RSA as a 1024-bit integer == 16 digits ;-) - */ -/* need to refactor the function */ -/*#define TFM_SMALL_SET */ - -/* do we want huge code - Enable these if you are doing 20, 24, 28, 32, 48, 64 digit multiplications (useful for RSA) - Less important on 64-bit machines as 32 digits == 2048 bits - */ -#if 0 -#define TFM_MUL3 -#define TFM_MUL4 -#define TFM_MUL6 -#define TFM_MUL7 -#define TFM_MUL8 -#define TFM_MUL9 -#define TFM_MUL12 -#define TFM_MUL17 -#endif -#ifdef TFM_HUGE_SET -#define TFM_MUL20 -#define TFM_MUL24 -#define TFM_MUL28 -#define TFM_MUL32 -#if (FP_MAX_BITS >= 6144) && defined(FP_64BIT) - #define TFM_MUL48 -#endif -#if (FP_MAX_BITS >= 8192) && defined(FP_64BIT) - #define TFM_MUL64 -#endif -#endif - -#if 0 -#define TFM_SQR3 -#define TFM_SQR4 -#define TFM_SQR6 -#define TFM_SQR7 -#define TFM_SQR8 -#define TFM_SQR9 -#define TFM_SQR12 -#define TFM_SQR17 -#endif -#ifdef TFM_HUGE_SET -#define TFM_SQR20 -#define TFM_SQR24 -#define TFM_SQR28 -#define TFM_SQR32 -#define TFM_SQR48 -#define TFM_SQR64 -#endif - -/* do we want some overflow checks - Not required if you make sure your numbers are within range (e.g. by default a modulus for fp_exptmod() can only be upto 2048 bits long) - */ -/* #define TFM_CHECK */ - -/* Is the target a P4 Prescott - */ -/* #define TFM_PRESCOTT */ - -/* Do we want timing resistant fp_exptmod() ? - * This makes it slower but also timing invariant with respect to the exponent - */ -/* #define TFM_TIMING_RESISTANT */ - -#endif /* TFM_ALREADY_SET */ - -/* functions */ - -/* returns a TFM ident string useful for debugging... */ -/*const char *fp_ident(void);*/ - -/* initialize [or zero] an fp int */ -#define fp_init(a) (void)XMEMSET((a), 0, sizeof(fp_int)) -#define fp_zero(a) fp_init(a) - -/* zero/even/odd ? */ -#define fp_iszero(a) (((a)->used == 0) ? FP_YES : FP_NO) -#define fp_iseven(a) (((a)->used >= 0 && (((a)->dp[0] & 1) == 0)) ? FP_YES : FP_NO) -#define fp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? FP_YES : FP_NO) - -/* set to a small digit */ -void fp_set(fp_int *a, fp_digit b); - -/* copy from a to b */ -#define fp_copy(a, b) (void)(((a) != (b)) ? ((void)XMEMCPY((b), (a), sizeof(fp_int))) : (void)0) -#define fp_init_copy(a, b) fp_copy(b, a) - -/* clamp digits */ -#define fp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : FP_ZPOS; } - -/* negate and absolute */ -#define fp_neg(a, b) { fp_copy(a, b); (b)->sign ^= 1; fp_clamp(b); } -#define fp_abs(a, b) { fp_copy(a, b); (b)->sign = 0; } - -/* right shift x digits */ -void fp_rshd(fp_int *a, int x); - -/* right shift x bits */ -void fp_rshb(fp_int *a, int x); - -/* left shift x digits */ -void fp_lshd(fp_int *a, int x); - -/* signed comparison */ -int fp_cmp(fp_int *a, fp_int *b); - -/* unsigned comparison */ -int fp_cmp_mag(fp_int *a, fp_int *b); - -/* power of 2 operations */ -void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d); -void fp_mod_2d(fp_int *a, int b, fp_int *c); -void fp_mul_2d(fp_int *a, int b, fp_int *c); -void fp_2expt (fp_int *a, int b); -void fp_mul_2(fp_int *a, fp_int *c); -void fp_div_2(fp_int *a, fp_int *c); - -/* Counts the number of lsbs which are zero before the first zero bit */ -int fp_cnt_lsb(fp_int *a); - -/* c = a + b */ -void fp_add(fp_int *a, fp_int *b, fp_int *c); - -/* c = a - b */ -void fp_sub(fp_int *a, fp_int *b, fp_int *c); - -/* c = a * b */ -void fp_mul(fp_int *a, fp_int *b, fp_int *c); - -/* b = a*a */ -void fp_sqr(fp_int *a, fp_int *b); - -/* a/b => cb + d == a */ -int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d); - -/* c = a mod b, 0 <= c < b */ -int fp_mod(fp_int *a, fp_int *b, fp_int *c); - -/* compare against a single digit */ -int fp_cmp_d(fp_int *a, fp_digit b); - -/* c = a + b */ -void fp_add_d(fp_int *a, fp_digit b, fp_int *c); - -/* c = a - b */ -void fp_sub_d(fp_int *a, fp_digit b, fp_int *c); - -/* c = a * b */ -void fp_mul_d(fp_int *a, fp_digit b, fp_int *c); - -/* a/b => cb + d == a */ -/*int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d);*/ - -/* c = a mod b, 0 <= c < b */ -/*int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c);*/ - -/* ---> number theory <--- */ -/* d = a + b (mod c) */ -/*int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/ - -/* d = a - b (mod c) */ -/*int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d);*/ - -/* d = a * b (mod c) */ -int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); - -/* c = a * a (mod b) */ -int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c); - -/* c = 1/a (mod b) */ -int fp_invmod(fp_int *a, fp_int *b, fp_int *c); - -/* c = (a, b) */ -/*void fp_gcd(fp_int *a, fp_int *b, fp_int *c);*/ - -/* c = [a, b] */ -/*void fp_lcm(fp_int *a, fp_int *b, fp_int *c);*/ - -/* setups the montgomery reduction */ -int fp_montgomery_setup(fp_int *a, fp_digit *mp); - -/* computes a = B**n mod b without division or multiplication useful for - * normalizing numbers in a Montgomery system. - */ -void fp_montgomery_calc_normalization(fp_int *a, fp_int *b); - -/* computes x/R == x (mod N) via Montgomery Reduction */ -void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); - -/* d = a**b (mod c) */ -int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); - -/* primality stuff */ - -/* perform a Miller-Rabin test of a to the base b and store result in "result" */ -/*void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result);*/ - -/* 256 trial divisions + 8 Miller-Rabins, returns FP_YES if probable prime */ -/*int fp_isprime(fp_int *a);*/ - -/* Primality generation flags */ -/*#define TFM_PRIME_BBS 0x0001 */ /* BBS style prime */ -/*#define TFM_PRIME_SAFE 0x0002 */ /* Safe prime (p-1)/2 == prime */ -/*#define TFM_PRIME_2MSB_OFF 0x0004 */ /* force 2nd MSB to 0 */ -/*#define TFM_PRIME_2MSB_ON 0x0008 */ /* force 2nd MSB to 1 */ - -/* callback for fp_prime_random, should fill dst with random bytes and return how many read [upto len] */ -/*typedef int tfm_prime_callback(unsigned char *dst, int len, void *dat);*/ - -/*#define fp_prime_random(a, t, size, bbs, cb, dat) fp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?TFM_PRIME_BBS:0, cb, dat)*/ - -/*int fp_prime_random_ex(fp_int *a, int t, int size, int flags, tfm_prime_callback cb, void *dat);*/ - -/* radix conersions */ -int fp_count_bits(fp_int *a); -int fp_leading_bit(fp_int *a); - -int fp_unsigned_bin_size(fp_int *a); -void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c); -void fp_to_unsigned_bin(fp_int *a, unsigned char *b); - -/*int fp_signed_bin_size(fp_int *a);*/ -/*void fp_read_signed_bin(fp_int *a, unsigned char *b, int c);*/ -/*void fp_to_signed_bin(fp_int *a, unsigned char *b);*/ - -/*int fp_read_radix(fp_int *a, char *str, int radix);*/ -/*int fp_toradix(fp_int *a, char *str, int radix);*/ -/*int fp_toradix_n(fp_int * a, char *str, int radix, int maxlen);*/ - - -/* VARIOUS LOW LEVEL STUFFS */ -void s_fp_add(fp_int *a, fp_int *b, fp_int *c); -void s_fp_sub(fp_int *a, fp_int *b, fp_int *c); -void fp_reverse(unsigned char *s, int len); - -void fp_mul_comba(fp_int *a, fp_int *b, fp_int *c); - -#ifdef TFM_SMALL_SET -void fp_mul_comba_small(fp_int *a, fp_int *b, fp_int *c); -#endif - -#ifdef TFM_MUL3 -void fp_mul_comba3(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL4 -void fp_mul_comba4(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL6 -void fp_mul_comba6(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL7 -void fp_mul_comba7(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL8 -void fp_mul_comba8(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL9 -void fp_mul_comba9(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL12 -void fp_mul_comba12(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL17 -void fp_mul_comba17(fp_int *a, fp_int *b, fp_int *c); -#endif - -#ifdef TFM_MUL20 -void fp_mul_comba20(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL24 -void fp_mul_comba24(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL28 -void fp_mul_comba28(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL32 -void fp_mul_comba32(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL48 -void fp_mul_comba48(fp_int *a, fp_int *b, fp_int *c); -#endif -#ifdef TFM_MUL64 -void fp_mul_comba64(fp_int *a, fp_int *b, fp_int *c); -#endif - -void fp_sqr_comba(fp_int *a, fp_int *b); - -#ifdef TFM_SMALL_SET -void fp_sqr_comba_small(fp_int *a, fp_int *b); -#endif - -#ifdef TFM_SQR3 -void fp_sqr_comba3(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR4 -void fp_sqr_comba4(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR6 -void fp_sqr_comba6(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR7 -void fp_sqr_comba7(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR8 -void fp_sqr_comba8(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR9 -void fp_sqr_comba9(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR12 -void fp_sqr_comba12(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR17 -void fp_sqr_comba17(fp_int *a, fp_int *b); -#endif - -#ifdef TFM_SQR20 -void fp_sqr_comba20(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR24 -void fp_sqr_comba24(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR28 -void fp_sqr_comba28(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR32 -void fp_sqr_comba32(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR48 -void fp_sqr_comba48(fp_int *a, fp_int *b); -#endif -#ifdef TFM_SQR64 -void fp_sqr_comba64(fp_int *a, fp_int *b); -#endif -/*extern const char *fp_s_rmap;*/ - - -/** - * Used by CyaSSL - */ - -/* Types */ - typedef fp_digit mp_digit; - typedef fp_word mp_word; - typedef fp_int mp_int; - -/* Constants */ - #define MP_LT FP_LT /* less than */ - #define MP_EQ FP_EQ /* equal to */ - #define MP_GT FP_GT /* greater than */ - #define MP_VAL FP_VAL /* invalid */ - #define MP_OKAY FP_OKAY /* ok result */ - #define MP_NO FP_NO /* yes/no result */ - #define MP_YES FP_YES /* yes/no result */ - -/* Prototypes */ -#define mp_zero(a) fp_zero(a) -#define mp_iseven(a) fp_iseven(a) -int mp_init (mp_int * a); -void mp_clear (mp_int * a); -int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, mp_int* f); - -int mp_add (mp_int * a, mp_int * b, mp_int * c); -int mp_sub (mp_int * a, mp_int * b, mp_int * c); -int mp_add_d (mp_int * a, mp_digit b, mp_int * c); - -int mp_mul (mp_int * a, mp_int * b, mp_int * c); -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d); -int mp_mod(mp_int *a, mp_int *b, mp_int *c); -int mp_invmod(mp_int *a, mp_int *b, mp_int *c); -int mp_exptmod (mp_int * g, mp_int * x, mp_int * p, mp_int * y); - -int mp_cmp(mp_int *a, mp_int *b); -int mp_cmp_d(mp_int *a, mp_digit b); - -int mp_unsigned_bin_size(mp_int * a); -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); -int mp_to_unsigned_bin (mp_int * a, unsigned char *b); - -int mp_sub_d(fp_int *a, fp_digit b, fp_int *c); -int mp_copy(fp_int* a, fp_int* b); -int mp_isodd(mp_int* a); -int mp_iszero(mp_int* a); -int mp_count_bits(mp_int *a); -int mp_leading_bit(mp_int *a); -int mp_set_int(fp_int *a, fp_digit b); -void mp_rshb(mp_int *a, int x); - -#ifdef HAVE_ECC - int mp_read_radix(mp_int* a, const char* str, int radix); - int mp_set(fp_int *a, fp_digit b); - int mp_sqr(fp_int *a, fp_int *b); - int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); - int mp_montgomery_setup(fp_int *a, fp_digit *rho); - int mp_div_2(fp_int * a, fp_int * b); - int mp_init_copy(fp_int * a, fp_int * b); -#endif - -#if defined(HAVE_ECC) || defined(CYASSL_KEY_GEN) - int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); - int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); -#endif - -#ifdef CYASSL_KEY_GEN -int mp_gcd(fp_int *a, fp_int *b, fp_int *c); -int mp_lcm(fp_int *a, fp_int *b, fp_int *c); -int mp_prime_is_prime(mp_int* a, int t, int* result); -#endif /* CYASSL_KEY_GEN */ - -int mp_cnt_lsb(fp_int *a); -int mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d); -int mp_mod_d(fp_int* a, fp_digit b, fp_digit* c); - -CYASSL_API word32 CheckRunTimeFastMath(void); - -/* If user uses RSA, DH, DSA, or ECC math lib directly then fast math FP_SIZE - must match, return 1 if a match otherwise 0 */ -#define CheckFastMathSettings() (FP_SIZE == CheckRunTimeFastMath()) -#ifdef __cplusplus - } -#endif - +#include #endif /* CTAO_CRYPT_TFM_H */ + diff --git a/cyassl/ctaocrypt/types.h b/cyassl/ctaocrypt/types.h index 56241fb97..6932aa325 100644 --- a/cyassl/ctaocrypt/types.h +++ b/cyassl/ctaocrypt/types.h @@ -23,7 +23,8 @@ #ifndef CTAO_CRYPT_TYPES_H #define CTAO_CRYPT_TYPES_H -#ifndef HAVE_FIPS +#include +#include #include /* compatibility macros */ #define CYASSL_WORD_SIZE WOLFSSL_WORD_SIZE @@ -31,309 +32,30 @@ #define CYASSL_MAX_16BIT WOLFSSL_MAX_16BIT #define CYASSL_MAX_ERROR_SZ WOLFSSL_MAX_ERROR_SZ #define cyassl_word wolfssl_word -#else - -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - -#if defined(WORDS_BIGENDIAN) - #define BIG_ENDIAN_ORDER -#endif - -#ifndef BIG_ENDIAN_ORDER - #define LITTLE_ENDIAN_ORDER -#endif - -#ifndef CYASSL_TYPES - #ifndef byte - typedef unsigned char byte; - #endif - typedef unsigned short word16; - typedef unsigned int word32; -#endif - - -/* try to set SIZEOF_LONG or LONG_LONG if user didn't */ -#if !defined(_MSC_VER) && !defined(__BCPLUSPLUS__) - #if !defined(SIZEOF_LONG_LONG) && !defined(SIZEOF_LONG) - #if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) \ - || defined(__mips64) || defined(__x86_64__)) - /* long should be 64bit */ - #define SIZEOF_LONG 8 - #elif defined(__i386__) || defined(__CORTEX_M3__) - /* long long should be 64bit */ - #define SIZEOF_LONG_LONG 8 - #endif - #endif -#endif - - -#if defined(_MSC_VER) || defined(__BCPLUSPLUS__) - #define WORD64_AVAILABLE - #define W64LIT(x) x##ui64 - typedef unsigned __int64 word64; -#elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8 - #define WORD64_AVAILABLE - #define W64LIT(x) x##LL - typedef unsigned long word64; -#elif defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8 - #define WORD64_AVAILABLE - #define W64LIT(x) x##LL - typedef unsigned long long word64; -#elif defined(__SIZEOF_LONG_LONG__) && __SIZEOF_LONG_LONG__ == 8 - #define WORD64_AVAILABLE - #define W64LIT(x) x##LL - typedef unsigned long long word64; -#else - #define MP_16BIT /* for mp_int, mp_word needs to be twice as big as - mp_digit, no 64 bit type so make mp_digit 16 bit */ -#endif - - -/* These platforms have 64-bit CPU registers. */ -#if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \ - defined(__mips64) || defined(__x86_64__) || defined(_M_X64)) - typedef word64 cyassl_word; -#else - typedef word32 cyassl_word; - #ifdef WORD64_AVAILABLE - #define CTAOCRYPT_SLOW_WORD64 - #endif -#endif - - -enum { - CYASSL_WORD_SIZE = sizeof(cyassl_word), - CYASSL_BIT_SIZE = 8, - CYASSL_WORD_BITS = CYASSL_WORD_SIZE * CYASSL_BIT_SIZE -}; - -#define CYASSL_MAX_16BIT 0xffffU - -/* use inlining if compiler allows */ -#ifndef INLINE -#ifndef NO_INLINE - #ifdef _MSC_VER - #define INLINE __inline - #elif defined(__GNUC__) - #define INLINE inline - #elif defined(__IAR_SYSTEMS_ICC__) - #define INLINE inline - #elif defined(THREADX) - #define INLINE _Inline - #else - #define INLINE - #endif -#else - #define INLINE -#endif -#endif - - -/* set up rotate style */ -#if defined(_MSC_VER) || defined(__BCPLUSPLUS__) - #define INTEL_INTRINSICS - #define FAST_ROTATE -#elif defined(__MWERKS__) && TARGET_CPU_PPC - #define PPC_INTRINSICS - #define FAST_ROTATE -#elif defined(__GNUC__) && defined(__i386__) - /* GCC does peephole optimizations which should result in using rotate - instructions */ - #define FAST_ROTATE -#endif - - -/* set up thread local storage if available */ -#ifdef HAVE_THREAD_LS - #if defined(_MSC_VER) - #define THREAD_LS_T __declspec(thread) - #else - #define THREAD_LS_T __thread - #endif -#else - #define THREAD_LS_T -#endif - - -/* Micrium will use Visual Studio for compilation but not the Win32 API */ -#if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) \ - && !defined(EBSNET) - #define USE_WINDOWS_API -#endif - - -/* idea to add global alloc override by Moisés Guimarães */ -/* default to libc stuff */ -/* XREALLOC is used once in normal math lib, not in fast math lib */ -/* XFREE on some embeded systems doesn't like free(0) so test */ -#if defined(XMALLOC_USER) - /* prototypes for user heap override functions */ - #include /* for size_t */ - extern void *XMALLOC(size_t n, void* heap, int type); - extern void *XREALLOC(void *p, size_t n, void* heap, int type); - extern void XFREE(void *p, void* heap, int type); -#elif defined(NO_CYASSL_MEMORY) - /* just use plain C stdlib stuff if desired */ - #include - #define XMALLOC(s, h, t) ((void)h, (void)t, malloc((s))) - #define XFREE(p, h, t) {void* xp = (p); if((xp)) free((xp));} - #define XREALLOC(p, n, h, t) realloc((p), (n)) -#elif !defined(MICRIUM_MALLOC) && !defined(EBSNET) \ - && !defined(CYASSL_SAFERTOS) && !defined(FREESCALE_MQX) \ - && !defined(CYASSL_LEANPSK) - /* default C runtime, can install different routines at runtime via cbs */ - #include - #define XMALLOC(s, h, t) ((void)h, (void)t, CyaSSL_Malloc((s))) - #define XFREE(p, h, t) {void* xp = (p); if((xp)) CyaSSL_Free((xp));} - #define XREALLOC(p, n, h, t) CyaSSL_Realloc((p), (n)) -#endif - -#ifndef STRING_USER - #include - char* mystrnstr(const char* s1, const char* s2, unsigned int n); - - #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) - #define XMEMSET(b,c,l) memset((b),(c),(l)) - #define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) - #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) - - #define XSTRLEN(s1) strlen((s1)) - #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) - /* strstr, strncmp, and strncat only used by CyaSSL proper, not required for - CTaoCrypt only */ - #define XSTRSTR(s1,s2) strstr((s1),(s2)) - #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) - #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) - #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) - #ifndef USE_WINDOWS_API - #define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n)) - #define XSNPRINTF snprintf - #else - #define XSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) - #define XSNPRINTF _snprintf - #endif -#endif - -#ifndef CTYPE_USER - #include - #if defined(HAVE_ECC) || defined(HAVE_OCSP) - #define XTOUPPER(c) toupper((c)) - #define XISALPHA(c) isalpha((c)) - #endif - /* needed by CyaSSL_check_domain_name() */ - #ifdef __CYGWIN__ - /* Cygwin uses a macro version of tolower() by default, use the - * function version. */ - #undef tolower - #endif - #define XTOLOWER(c) tolower((c)) -#endif - - -/* memory allocation types for user hints */ -enum { - DYNAMIC_TYPE_CA = 1, - DYNAMIC_TYPE_CERT = 2, - DYNAMIC_TYPE_KEY = 3, - DYNAMIC_TYPE_FILE = 4, - DYNAMIC_TYPE_SUBJECT_CN = 5, - DYNAMIC_TYPE_PUBLIC_KEY = 6, - DYNAMIC_TYPE_SIGNER = 7, - DYNAMIC_TYPE_NONE = 8, - DYNAMIC_TYPE_BIGINT = 9, - DYNAMIC_TYPE_RSA = 10, - DYNAMIC_TYPE_METHOD = 11, - DYNAMIC_TYPE_OUT_BUFFER = 12, - DYNAMIC_TYPE_IN_BUFFER = 13, - DYNAMIC_TYPE_INFO = 14, - DYNAMIC_TYPE_DH = 15, - DYNAMIC_TYPE_DOMAIN = 16, - DYNAMIC_TYPE_SSL = 17, - DYNAMIC_TYPE_CTX = 18, - DYNAMIC_TYPE_WRITEV = 19, - DYNAMIC_TYPE_OPENSSL = 20, - DYNAMIC_TYPE_DSA = 21, - DYNAMIC_TYPE_CRL = 22, - DYNAMIC_TYPE_REVOKED = 23, - DYNAMIC_TYPE_CRL_ENTRY = 24, - DYNAMIC_TYPE_CERT_MANAGER = 25, - DYNAMIC_TYPE_CRL_MONITOR = 26, - DYNAMIC_TYPE_OCSP_STATUS = 27, - DYNAMIC_TYPE_OCSP_ENTRY = 28, - DYNAMIC_TYPE_ALTNAME = 29, - DYNAMIC_TYPE_SUITES = 30, - DYNAMIC_TYPE_CIPHER = 31, - DYNAMIC_TYPE_RNG = 32, - DYNAMIC_TYPE_ARRAYS = 33, - DYNAMIC_TYPE_DTLS_POOL = 34, - DYNAMIC_TYPE_SOCKADDR = 35, - DYNAMIC_TYPE_LIBZ = 36, - DYNAMIC_TYPE_ECC = 37, - DYNAMIC_TYPE_TMP_BUFFER = 38, - DYNAMIC_TYPE_DTLS_MSG = 39, - DYNAMIC_TYPE_CAVIUM_TMP = 40, - DYNAMIC_TYPE_CAVIUM_RSA = 41, - DYNAMIC_TYPE_X509 = 42, - DYNAMIC_TYPE_TLSX = 43, - DYNAMIC_TYPE_OCSP = 44, - DYNAMIC_TYPE_SIGNATURE = 45 -}; - -/* max error buffer string size */ -enum { - CYASSL_MAX_ERROR_SZ = 80 -}; - -/* stack protection */ -enum { - MIN_STACK_BUFFER = 8 -}; - - - -/* settings detection for compile vs runtime math incombatibilities */ -enum { -#if !defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG) - CTC_SETTINGS = 0x0 -#elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8) - CTC_SETTINGS = 0x1 -#elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8) - CTC_SETTINGS = 0x2 -#elif !defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4) - CTC_SETTINGS = 0x4 -#elif defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG) - CTC_SETTINGS = 0x8 -#elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG) && (SIZEOF_LONG == 8) - CTC_SETTINGS = 0x10 -#elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8) - CTC_SETTINGS = 0x20 -#elif defined(USE_FAST_MATH) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 4) - CTC_SETTINGS = 0x40 -#else - #error "bad math long / long long settings" -#endif -}; - - -CYASSL_API word32 CheckRunTimeSettings(void); - -/* If user uses RSA, DH, DSA, or ECC math lib directly then fast math and long - types need to match at compile time and run time, CheckCtcSettings will - return 1 if a match otherwise 0 */ -#define CheckCtcSettings() (CTC_SETTINGS == CheckRunTimeSettings()) - - -#ifdef __cplusplus - } /* extern "C" */ -#endif - - -#endif /* HAVE_FIPS */ +// /* set old macros since this is often called for visibility also */ +// #ifndef WOLFSSL_API +// #define WOLFSSL_API CYASSL_API +// #endif +// #ifndef WOLFSSL_LOCAL +// #define WOLFSSL_LOCAL CYASSL_LOCAL +// #endif +// #define WOLFSSL_MAX_ERROR_SZ CYASSL_MAX_ERROR_SZ +// +// #define WOLFSSL_WORD_SIZE CYASSL_WORD_SIZE +// #define WOLFSSL_BIT_SIZE CYASSL_BIT_SIZE +// #define WOLFSSL_MAX_16BIT CYASSL_MAX_16BIT +// #define WOLFSSL_MAX_ERROR_SZ CYASSL_MAX_ERROR_SZ +// #define wolfssl_word cyassl_word +///* memory macros */ +// /* when using fips map wolfSSL to CyaSSL*/ +// #define wolfSSL_Malloc_cb CyaSSL_Malloc_cb +// #define wolfSSL_Free_cb CyaSSL_Free_cb +// #define wolfSSL_Realloc_cb CyaSSL_Realloc_cb +// #define wolfSSL_SetAllocators CyaSSL_SetAllocators +// +// /* Public in case user app wants to use XMALLOC/XFREE */ +// #define wolfSSL_Malloc CyaSSL_Malloc +// #define wolfSSL_Free CyaSSL_Free +// #define wolfSSL_Realloc CyaSSL_Realloc #endif /* CTAO_CRYPT_TYPES_H */ diff --git a/cyassl/ctaocrypt/visibility.h b/cyassl/ctaocrypt/visibility.h index 6ab9b444f..ea9a52bb3 100644 --- a/cyassl/ctaocrypt/visibility.h +++ b/cyassl/ctaocrypt/visibility.h @@ -24,56 +24,14 @@ #ifndef CTAO_CRYPT_VISIBILITY_H #define CTAO_CRYPT_VISIBILITY_H +#include /* fips compatibility @wc_fips */ -#ifndef HAVE_FIPS - #ifndef CYASSL_API - #define CYASSL_API WOLFSSL_API - #endif - #ifndef CYASSL_LOCAL - #define CYASSL_LOCAL WOLFSSL_LOCAL - #endif - #include -#else -#define BUILDING_CYASSL -/* CYASSL_API is used for the public API symbols. - It either imports or exports (or does nothing for static builds) - - CYASSL_LOCAL is used for non-API symbols (private). -*/ - -#if defined(BUILDING_CYASSL) - #if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY - #define CYASSL_API __attribute__ ((visibility("default"))) - #define CYASSL_LOCAL __attribute__ ((visibility("hidden"))) - #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) - #define CYASSL_API __global - #define CYASSL_LOCAL __hidden - #elif defined(_MSC_VER) - #ifdef CYASSL_DLL - #define CYASSL_API extern __declspec(dllexport) - #else - #define CYASSL_API - #endif - #define CYASSL_LOCAL - #else - #define CYASSL_API - #define CYASSL_LOCAL - #endif /* HAVE_VISIBILITY */ -#else /* BUILDING_CYASSL */ - #if defined(_MSC_VER) - #ifdef CYASSL_DLL - #define CYASSL_API extern __declspec(dllimport) - #else - #define CYASSL_API - #endif - #define CYASSL_LOCAL - #else - #define CYASSL_API - #define CYASSL_LOCAL - #endif -#endif /* BUILDING_CYASSL */ - - -#endif /* HAVE_FIPS */ +//#ifdef HAVE_FIPS +// #define WOLFSSL_API CYASSL_API +// #define WOLFSSL_LOCAL CYASSL_LOCAL +//#else + #define CYASSL_API WOLFSSL_API + #define CYASSL_LOCAL WOLFSSL_LOCAL +//#endif /* HAVE_FIPS */ #endif /* CTAO_CRYPT_VISIBILITY_H */ diff --git a/cyassl/ctaocrypt/wc_port.h b/cyassl/ctaocrypt/wc_port.h index af52032ee..a6901faef 100644 --- a/cyassl/ctaocrypt/wc_port.h +++ b/cyassl/ctaocrypt/wc_port.h @@ -23,178 +23,8 @@ #ifndef CTAO_CRYPT_PORT_H #define CTAO_CRYPT_PORT_H - -#ifdef __cplusplus - extern "C" { -#endif - - -#ifdef USE_WINDOWS_API - #ifdef CYASSL_GAME_BUILD - #include "system/xtl.h" - #else - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN) - /* On WinCE winsock2.h must be included before windows.h */ - #include - #endif - #include - #endif -#elif defined(THREADX) - #ifndef SINGLE_THREADED - #include "tx_api.h" - #endif -#elif defined(MICRIUM) - /* do nothing, just don't pick Unix */ -#elif defined(FREERTOS) || defined(CYASSL_SAFERTOS) - /* do nothing */ -#elif defined(EBSNET) - /* do nothing */ -#elif defined(FREESCALE_MQX) - /* do nothing */ -#elif defined(CYASSL_MDK_ARM) - #if defined(CYASSL_MDK5) - #include "cmsis_os.h" - #else - #include - #endif -#elif defined(CYASSL_CMSIS_RTOS) - #include "cmsis_os.h" -#elif defined(CYASSL_TIRTOS) - #include - #include -#else - #ifndef SINGLE_THREADED - #define CYASSL_PTHREADS - #include - #endif - #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS) - #include /* for close of BIO */ - #endif -#endif - - -#ifdef SINGLE_THREADED - typedef int CyaSSL_Mutex; -#else /* MULTI_THREADED */ - /* FREERTOS comes first to enable use of FreeRTOS Windows simulator only */ - #ifdef FREERTOS - typedef xSemaphoreHandle CyaSSL_Mutex; - #elif defined(CYASSL_SAFERTOS) - typedef struct CyaSSL_Mutex { - signed char mutexBuffer[portQUEUE_OVERHEAD_BYTES]; - xSemaphoreHandle mutex; - } CyaSSL_Mutex; - #elif defined(USE_WINDOWS_API) - typedef CRITICAL_SECTION CyaSSL_Mutex; - #elif defined(CYASSL_PTHREADS) - typedef pthread_mutex_t CyaSSL_Mutex; - #elif defined(THREADX) - typedef TX_MUTEX CyaSSL_Mutex; - #elif defined(MICRIUM) - typedef OS_MUTEX CyaSSL_Mutex; - #elif defined(EBSNET) - typedef RTP_MUTEX CyaSSL_Mutex; - #elif defined(FREESCALE_MQX) - typedef MUTEX_STRUCT CyaSSL_Mutex; - #elif defined(CYASSL_MDK_ARM) - #if defined(CYASSL_CMSIS_RTOS) - typedef osMutexId CyaSSL_Mutex; - #else - typedef OS_MUT CyaSSL_Mutex; - #endif - #elif defined(CYASSL_CMSIS_RTOS) - typedef osMutexId CyaSSL_Mutex; - #elif defined(CYASSL_TIRTOS) - typedef ti_sysbios_knl_Semaphore_Handle CyaSSL_Mutex; - #else - #error Need a mutex type in multithreaded mode - #endif /* USE_WINDOWS_API */ -#endif /* SINGLE_THREADED */ - -CYASSL_LOCAL int InitMutex(CyaSSL_Mutex*); -CYASSL_LOCAL int FreeMutex(CyaSSL_Mutex*); -CYASSL_LOCAL int LockMutex(CyaSSL_Mutex*); -CYASSL_LOCAL int UnLockMutex(CyaSSL_Mutex*); - - -/* filesystem abstraction layer, used by ssl.c */ -#ifndef NO_FILESYSTEM - -#if defined(EBSNET) - #define XFILE int - #define XFOPEN(NAME, MODE) vf_open((const char *)NAME, VO_RDONLY, 0); - #define XFSEEK vf_lseek - #define XFTELL vf_tell - #define XREWIND vf_rewind - #define XFREAD(BUF, SZ, AMT, FD) vf_read(FD, BUF, SZ*AMT) - #define XFWRITE(BUF, SZ, AMT, FD) vf_write(FD, BUF, SZ*AMT) - #define XFCLOSE vf_close - #define XSEEK_END VSEEK_END - #define XBADFILE -1 -#elif defined(LSR_FS) - #include - #define XFILE struct fs_file* - #define XFOPEN(NAME, MODE) fs_open((char*)NAME); - #define XFSEEK(F, O, W) (void)F - #define XFTELL(F) (F)->len - #define XREWIND(F) (void)F - #define XFREAD(BUF, SZ, AMT, F) fs_read(F, (char*)BUF, SZ*AMT) - #define XFWRITE(BUF, SZ, AMT, F) fs_write(F, (char*)BUF, SZ*AMT) - #define XFCLOSE fs_close - #define XSEEK_END 0 - #define XBADFILE NULL -#elif defined(FREESCALE_MQX) - #define XFILE MQX_FILE_PTR - #define XFOPEN fopen - #define XFSEEK fseek - #define XFTELL ftell - #define XREWIND(F) fseek(F, 0, IO_SEEK_SET) - #define XFREAD fread - #define XFWRITE fwrite - #define XFCLOSE fclose - #define XSEEK_END IO_SEEK_END - #define XBADFILE NULL -#elif defined(MICRIUM) - #include - #define XFILE FS_FILE* - #define XFOPEN fs_fopen - #define XFSEEK fs_fseek - #define XFTELL fs_ftell - #define XREWIND fs_rewind - #define XFREAD fs_fread - #define XFWRITE fs_fwrite - #define XFCLOSE fs_fclose - #define XSEEK_END FS_SEEK_END - #define XBADFILE NULL -#else - /* stdio, default case */ - #define XFILE FILE* - #if defined(CYASSL_MDK_ARM) - #include - extern FILE * CyaSSL_fopen(const char *name, const char *mode) ; - #define XFOPEN CyaSSL_fopen - #else - #define XFOPEN fopen - #endif - #define XFSEEK fseek - #define XFTELL ftell - #define XREWIND rewind - #define XFREAD fread - #define XFWRITE fwrite - #define XFCLOSE fclose - #define XSEEK_END SEEK_END - #define XBADFILE NULL -#endif - -#endif /* NO_FILESYSTEM */ - - -#ifdef __cplusplus - } /* extern "C" */ -#endif +#include +#define CyaSSL_Mutex wolfSSL_Mutex #endif /* CTAO_CRYPT_PORT_H */ diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 5195e5f68..3430dbdab 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -404,12 +404,6 @@ */ #define NO_WOLFSSL_ALLOC_ALIGN NO_CYASSL_ALLOC_ALIGN /* @TODO */ -/* for pwdbased reverse compatibility */ -#ifndef NO_PWDBASED - #define PBKDF1 wc_PBKDF1 - #define PBKDF2 wc_PBKDF2 - #define PKCS12_PBKDF wc_PKCS12_PBKDF -#endif /* examples/client/client.h */ #define CYASSL_THREAD WOLFSSL_THREAD diff --git a/src/include.am b/src/include.am index ec4cf4531..3d7f7e010 100644 --- a/src/include.am +++ b/src/include.am @@ -13,7 +13,6 @@ src_libwolfssl_la_CPPFLAGS = -DBUILDING_WOLFSSL $(AM_CPPFLAGS) # fips first file if BUILD_FIPS src_libwolfssl_la_SOURCES += ctaocrypt/src/wolfcrypt_first.c -#endif src_libwolfssl_la_SOURCES += \ ctaocrypt/src/hmac.c \ @@ -40,13 +39,10 @@ if BUILD_SHA512 src_libwolfssl_la_SOURCES += ctaocrypt/src/sha512.c endif -#if BUILD_FIPS src_libwolfssl_la_SOURCES += ctaocrypt/src/fips.c src_libwolfssl_la_SOURCES += ctaocrypt/src/fips_test.c -#endif # fips last file -#if BUILD_FIPS src_libwolfssl_la_SOURCES += ctaocrypt/src/wolfcrypt_last.c endif @@ -75,45 +71,26 @@ if BUILD_SHA512 src_libwolfssl_la_SOURCES += wolfcrypt/src/sha512.c endif -if BUILD_FIPS -src_libwolfssl_la_SOURCES += \ - ctaocrypt/src/logging.c \ - ctaocrypt/src/wc_port.c \ - wolfcrypt/src/error.c -else src_libwolfssl_la_SOURCES += \ wolfcrypt/src/logging.c \ wolfcrypt/src/wc_port.c \ wolfcrypt/src/error.c -endif if BUILD_MEMORY -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/memory.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/memory.c endif -endif if BUILD_DH src_libwolfssl_la_SOURCES += wolfcrypt/src/dh.c endif if BUILD_ASN -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/asn.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/asn.c endif -endif if BUILD_CODING -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/coding.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/coding.c endif -endif if BUILD_POLY1305 src_libwolfssl_la_SOURCES += wolfcrypt/src/poly1305.c @@ -128,32 +105,20 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/md4.c endif if BUILD_MD5 -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/md5.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/md5.c endif -endif if BUILD_PWDBASED -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/pwdbased.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/pwdbased.c endif -endif if BUILD_DSA src_libwolfssl_la_SOURCES += wolfcrypt/src/dsa.c endif if BUILD_AESNI -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/aes_asm.s -else src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_asm.s endif -endif if BUILD_CAMELLIA src_libwolfssl_la_SOURCES += wolfcrypt/src/camellia.c @@ -168,12 +133,8 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/ripemd.c endif if BUILD_BLAKE2 -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/blake2b.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/blake2b.c endif -endif if BUILD_HC128 src_libwolfssl_la_SOURCES += wolfcrypt/src/hc128.c @@ -188,48 +149,28 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/chacha.c endif if !BUILD_INLINE -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/misc.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/misc.c endif -endif if BUILD_FASTMATH -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/tfm.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/tfm.c endif -endif if BUILD_SLOWMATH -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/integer.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/integer.c endif -endif if BUILD_ECC src_libwolfssl_la_SOURCES += wolfcrypt/src/ecc.c endif if BUILD_LIBZ -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/compress.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/compress.c endif -endif if BUILD_PKCS7 -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/pkcs7.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/pkcs7.c endif -endif # ssl files src_libwolfssl_la_SOURCES += \ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 930d7690e..b640b414b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -775,7 +775,7 @@ int ToTraditional(byte* input, word32 sz) if (GetMyVersion(input, &inOutIdx, &version) < 0) return ASN_PARSE_E; - + if (GetAlgoId(input, &inOutIdx, &oid, sz) < 0) return ASN_PARSE_E; @@ -786,13 +786,13 @@ int ToTraditional(byte* input, word32 sz) return ASN_PARSE_E; inOutIdx += length; /* over sub id, key input will verify */ } - + if (input[inOutIdx++] != ASN_OCTET_STRING) return ASN_PARSE_E; - + if (GetLength(input, &inOutIdx, &length, sz) < 0) return ASN_PARSE_E; - + XMEMMOVE(input, input + inOutIdx, length); return length; diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 2296e922f..521a91023 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -89,28 +89,6 @@ int wc_RsaEncryptSize(RsaKey* key) } -int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, - word32 sz) -{ - return RsaPrivateKeyDecode(input, inOutIdx, key, sz); -} - - -int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, - word32 sz) -{ - return RsaPublicKeyDecode(input, inOutIdx, key, sz); -} - - - -int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, - word32 eSz, RsaKey* key) -{ - return RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key); -} - - int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, word32* bSz) { diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 0f60a36de..7adc974e9 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -43,7 +43,47 @@ #include #endif -#ifndef HAVE_FIPS +/* fips wrapper calls, user can call direct */ +#ifdef HAVE_FIPS + int wc_InitSha(Sha* sha) + { + return InitSha_fips(sha); + } + + + int wc_ShaUpdate(Sha* sha, const byte* data, word32 len) + { + return ShaUpdate_fips(sha, data, len); + } + + + int wc_ShaFinal(Sha* sha, byte* out) + { + return ShaFinal_fips(sha,out); + } + + int wc_ShaHash(const byte* data, word32 sz, byte* out) + { + return ShaHash(data, sz, out); + } + + + int wc_InitSha_fips(Sha* sha) + { + return InitSha_fips(sha); + } + + int wc_ShaUpdate_fips(Sha* sha, const byte* data, word32 sz) + { + return ShaUpdate_fips(sha, data, sz); + } + + int wc_ShaFinal_fips(Sha* sha, byte* out) + { + return ShaFinal_fips(sha, out); + } + +#else #ifdef FREESCALE_MMCAU #include "cau_api.h" @@ -370,20 +410,20 @@ int wc_ShaFinal(Sha* sha, byte* hash) /* ! length ordering dependent on digest endian type ! */ XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); - + #ifdef FREESCALE_MMCAU /* Kinetis requires only these bytes reversed */ ByteReverseWords(&sha->buffer[SHA_PAD_SIZE/sizeof(word32)], &sha->buffer[SHA_PAD_SIZE/sizeof(word32)], 2 * sizeof(word32)); #endif - + XTRANSFORM(sha, local); #ifdef LITTLE_ENDIAN_ORDER ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); #endif XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE); - + return wc_InitSha(sha); /* reset state */ } @@ -420,26 +460,6 @@ int wc_ShaHash(const byte* data, word32 len, byte* hash) return ret; } -#endif /* not defined HAVE_FIPS */ - -/* fips wrapper calls, user can call direct */ -#ifdef HAVE_FIPS - int wc_InitSha_fips(Sha* sha) - { - return InitSha_fips(sha); - } - - - int wc_ShaUpdate_fips(Sha* sha, const byte* data, word32 len) - { - return ShaUpdate_fips(sha, data, len); - } - - - int wc_ShaFinal_fips(Sha* sha, byte* out) - { - return ShaFinal_fips(sha,out); - } #endif /* HAVE_FIPS */ #endif /* NO_SHA */ diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 4be9bac23..a0c72b871 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -34,9 +34,6 @@ #include #endif -/* if using fips than the tfm.c from ctaocrypt is used @wc_fips */ -#ifndef HAVE_FIPS - /* in case user set USE_FAST_MATH there */ #include @@ -2540,5 +2537,3 @@ int mp_div_2d(fp_int* a, int b, fp_int* c, fp_int* d) #endif /* USE_FAST_MATH */ -#endif /* HAVE_FIPS */ - diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 9b04d4a28..737e1a6b9 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -26,6 +26,12 @@ #include #include + +/* fips declare of RsaPrivateKeyDecode @wc_fips */ +#ifdef HAVE_FIPS + #include +#endif + #include #include #include diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index d9cd7e648..7c47e36f6 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -28,10 +28,6 @@ #ifndef WOLF_CRYPT_INTEGER_H #define WOLF_CRYPT_INTEGER_H -/* for fips compatibility @wc_fips */ -#ifdef HAVE_FIPS - #include -#else /* may optionally use fast math instead, not yet supported on all platforms and may not be faster on all */ @@ -324,6 +320,5 @@ int mp_mod_d(mp_int* a, mp_digit b, mp_digit* c); #endif /* USE_FAST_MATH */ -#endif /* HAVE_FIPS */ #endif /* WOLF_CRYPT_INTEGER_H */ diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index f95e8e7e0..d70b53ad9 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -25,55 +25,46 @@ #ifndef WOLFSSL_LOGGING_H #define WOLFSSL_LOGGING_H -/* for reverse compatibility @wc_fips */ -#ifndef HAVE_FIPS - #include +#include - #ifdef __cplusplus - extern "C" { - #endif +#ifdef __cplusplus + extern "C" { +#endif - enum CYA_Log_Levels { - ERROR_LOG = 0, - INFO_LOG, - ENTER_LOG, - LEAVE_LOG, - OTHER_LOG - }; +enum CYA_Log_Levels { + ERROR_LOG = 0, + INFO_LOG, + ENTER_LOG, + LEAVE_LOG, + OTHER_LOG +}; - typedef void (*wolfSSL_Logging_cb)(const int logLevel, - const char *const logMessage); +typedef void (*wolfSSL_Logging_cb)(const int logLevel, + const char *const logMessage); - WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); +WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); - #ifdef DEBUG_WOLFSSL +#ifdef DEBUG_WOLFSSL - void WOLFSSL_ENTER(const char* msg); - void WOLFSSL_LEAVE(const char* msg, int ret); + void WOLFSSL_ENTER(const char* msg); + void WOLFSSL_LEAVE(const char* msg, int ret); - void WOLFSSL_ERROR(int); - void WOLFSSL_MSG(const char* msg); + void WOLFSSL_ERROR(int); + void WOLFSSL_MSG(const char* msg); - #else /* DEBUG_WOLFSSL */ +#else /* DEBUG_WOLFSSL */ - #define WOLFSSL_ENTER(m) - #define WOLFSSL_LEAVE(m, r) + #define WOLFSSL_ENTER(m) + #define WOLFSSL_LEAVE(m, r) - #define WOLFSSL_ERROR(e) - #define WOLFSSL_MSG(m) + #define WOLFSSL_ERROR(e) + #define WOLFSSL_MSG(m) - #endif /* DEBUG_WOLFSSL */ +#endif /* DEBUG_WOLFSSL */ - #ifdef __cplusplus - } - #endif -#else /* if using fips use old logging file */ - #include - #define WOLFSSL_LEAVE CYASSL_LEAVE - #define WOLFSSL_ERROR CYASSL_ERROR - #define WOLFSSL_ENTER CYASSL_ENTER - #define WOLFSSL_MSG CYASSL_MSG +#ifdef __cplusplus +} #endif #endif /* WOLFSSL_LOGGING_H */ diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index c0f61794e..1b0fe9e41 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -26,48 +26,22 @@ #define WOLFSSL_MEMORY_H #include +#include -/* compatibility and fips @wc_fips */ -#ifndef HAVE_FIPS - #include - #define CyaSSL_Malloc_cb wolfSSL_Malloc_cb - #define CyaSSL_Free_cb wolfSSL_Free_cb - #define CyaSSL_Realloc_cb wolfSSL_Realloc_cb - #define CyaSSL_SetAllocators wolfSSL_SetAllocators - - /* Public in case user app wants to use XMALLOC/XFREE */ - #define CyaSSL_Malloc wolfSSL_Malloc - #define CyaSSL_Free wolfSSL_Free - #define CyaSSL_Realloc wolfSSL_Realloc +typedef void *(*wolfSSL_Malloc_cb)(size_t size); +typedef void (*wolfSSL_Free_cb)(void *ptr); +typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size); - typedef void *(*wolfSSL_Malloc_cb)(size_t size); - typedef void (*wolfSSL_Free_cb)(void *ptr); - typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size); - - - /* Public set function */ - WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function, - wolfSSL_Free_cb free_function, - wolfSSL_Realloc_cb realloc_function); - - /* Public in case user app wants to use XMALLOC/XFREE */ - WOLFSSL_API void* wolfSSL_Malloc(size_t size); - WOLFSSL_API void wolfSSL_Free(void *ptr); - WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size); -#else - #include - /* when using fips map wolfSSL to CyaSSL*/ - #define wolfSSL_Malloc_cb CyaSSL_Malloc_cb - #define wolfSSL_Free_cb CyaSSL_Free_cb - #define wolfSSL_Realloc_cb CyaSSL_Realloc_cb - #define wolfSSL_SetAllocators CyaSSL_SetAllocators - - /* Public in case user app wants to use XMALLOC/XFREE */ - #define wolfSSL_Malloc CyaSSL_Malloc - #define wolfSSL_Free CyaSSL_Free - #define wolfSSL_Realloc CyaSSL_Realloc -#endif +/* Public set function */ +WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb malloc_function, + wolfSSL_Free_cb free_function, + wolfSSL_Realloc_cb realloc_function); + +/* Public in case user app wants to use XMALLOC/XFREE */ +WOLFSSL_API void* wolfSSL_Malloc(size_t size); +WOLFSSL_API void wolfSSL_Free(void *ptr); +WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size); #endif /* WOLFSSL_MEMORY_H */ diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index b653436cf..53267502d 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -90,12 +90,14 @@ WOLFSSL_API int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key); WOLFSSL_API int wc_RsaEncryptSize(RsaKey* key); +#ifndef HAVE_FIPS /* to avoid asn duplicate symbols @wc_fips */ WOLFSSL_API int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32); WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32); WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, word32 eSz, RsaKey* key); +#endif /* HAVE_FIPS*/ WOLFSSL_API int wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*, word32*); diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 4f89db69e..eb17d8f63 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -29,7 +29,11 @@ /* since using old code turn on old macros @wc_fips */ /* for fips */ #ifdef HAVE_FIPS -#include + #define CYASSL_SHA512 + #if defined(WOLFSSL_SHA384) + #define CYASSL_SHA384 + #endif + #include #endif #ifdef __cplusplus @@ -71,7 +75,7 @@ enum { SHA384 = 5, /* hash type unique */ SHA384_BLOCK_SIZE = 128, SHA384_DIGEST_SIZE = 48, - SHA384_PAD_SIZE = 112 + SHA384_PAD_SIZE = 112 }; @@ -98,9 +102,9 @@ WOLFSSL_API int wc_Sha384Hash(const byte*, word32, byte*); WOLFSSL_API int wc_Sha512Final_fips(Sha512*, byte*); #ifndef FIPS_NO_WRAPPERS /* if not impl or fips.c impl wrapper force fips calls if fips build */ - #define InitSha512 InitSha512_fips - #define Sha512Update Sha512Update_fips - #define Sha512Final Sha512Final_fips + #define wc_InitSha512 wc_InitSha512_fips + #define wc_Sha512Update wc_Sha512Update_fips + #define wc_Sha512Final wc_Sha512Final_fips #endif /* FIPS_NO_WRAPPERS */ /* fips wrapper calls, user can call direct */ @@ -109,9 +113,9 @@ WOLFSSL_API int wc_Sha384Hash(const byte*, word32, byte*); WOLFSSL_API int wc_Sha384Final_fips(Sha384*, byte*); #ifndef FIPS_NO_WRAPPERS /* if not impl or fips.c impl wrapper force fips calls if fips build */ - #define InitSha384 InitSha384_fips - #define Sha384Update Sha384Update_fips - #define Sha384Final Sha384Final_fips + #define wc_InitSha384 wc_InitSha384_fips + #define wc_Sha384Update wc_Sha384Update_fips + #define wc_Sha384Final wc_Sha384Final_fips #endif /* FIPS_NO_WRAPPERS */ #endif /* HAVE_FIPS */ diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 73e936e27..4e38797a5 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -35,11 +35,6 @@ #ifndef WOLF_CRYPT_TFM_H #define WOLF_CRYPT_TFM_H -/* for fips compatibility @wc_fips */ -#ifdef HAVE_FIPS - #include -#else - #include #ifndef CHAR_BIT #include @@ -624,7 +619,7 @@ void fp_sqr_comba64(fp_int *a, fp_int *b); /** - * Used by CyaSSL + * Used by wolfSSL */ /* Types */ @@ -708,5 +703,5 @@ WOLFSSL_API word32 CheckRunTimeFastMath(void); } #endif -#endif /* HAVE_FIPS */ #endif /* WOLF_CRYPT_TFM_H */ + diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 6c354266a..4e51a4834 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -28,37 +28,6 @@ #include #include -/* for fips compatiblity @wc_fips */ -#ifdef HAVE_FIPS - #include - /* set old macros since this is often called for visibility also */ - #ifndef WOLFSSL_API - #define WOLFSSL_API CYASSL_API - #endif - #ifndef WOLFSSL_LOCAL - #define WOLFSSL_LOCAL CYASSL_LOCAL - #endif - #define WOLFSSL_MAX_ERROR_SZ CYASSL_MAX_ERROR_SZ - - #define WOLFSSL_WORD_SIZE CYASSL_WORD_SIZE - #define WOLFSSL_BIT_SIZE CYASSL_BIT_SIZE - #define WOLFSSL_MAX_16BIT CYASSL_MAX_16BIT - #define WOLFSSL_MAX_ERROR_SZ CYASSL_MAX_ERROR_SZ - #define wolfssl_word cyassl_word -/* memory macros */ - /* when using fips map wolfSSL to CyaSSL*/ - #define wolfSSL_Malloc_cb CyaSSL_Malloc_cb - #define wolfSSL_Free_cb CyaSSL_Free_cb - #define wolfSSL_Realloc_cb CyaSSL_Realloc_cb - #define wolfSSL_SetAllocators CyaSSL_SetAllocators - - /* Public in case user app wants to use XMALLOC/XFREE */ - #define wolfSSL_Malloc CyaSSL_Malloc - #define wolfSSL_Free CyaSSL_Free - #define wolfSSL_Realloc CyaSSL_Realloc - - -#else /* set old macros since this is often called for visibility also */ #ifndef CYASSL_API #define CYASSL_API WOLFSSL_API @@ -66,21 +35,21 @@ #ifndef CYASSL_LOCAL #define CYASSL_LOCAL WOLFSSL_LOCAL #endif - - + + #ifdef __cplusplus extern "C" { #endif - - + + #if defined(WORDS_BIGENDIAN) #define BIG_ENDIAN_ORDER #endif - + #ifndef BIG_ENDIAN_ORDER #define LITTLE_ENDIAN_ORDER #endif - + #ifndef WOLFSSL_TYPES #ifndef byte typedef unsigned char byte; @@ -88,8 +57,8 @@ typedef unsigned short word16; typedef unsigned int word32; #endif - - + + /* try to set SIZEOF_LONG or LONG_LONG if user didn't */ #if !defined(_MSC_VER) && !defined(__BCPLUSPLUS__) #if !defined(SIZEOF_LONG_LONG) && !defined(SIZEOF_LONG) @@ -103,8 +72,8 @@ #endif #endif #endif - - + + #if defined(_MSC_VER) || defined(__BCPLUSPLUS__) #define WORD64_AVAILABLE #define W64LIT(x) x##ui64 @@ -125,8 +94,8 @@ #define MP_16BIT /* for mp_int, mp_word needs to be twice as big as mp_digit, no 64 bit type so make mp_digit 16 bit */ #endif - - + + /* These platforms have 64-bit CPU registers. */ #if (defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || \ defined(__mips64) || defined(__x86_64__) || defined(_M_X64)) @@ -137,16 +106,16 @@ #define WOLFCRYPT_SLOW_WORD64 #endif #endif - - + + enum { WOLFSSL_WORD_SIZE = sizeof(wolfssl_word), WOLFSSL_BIT_SIZE = 8, WOLFSSL_WORD_BITS = WOLFSSL_WORD_SIZE * WOLFSSL_BIT_SIZE }; - + #define WOLFSSL_MAX_16BIT 0xffffU - + /* use inlining if compiler allows */ #ifndef INLINE #ifndef NO_INLINE @@ -165,8 +134,8 @@ #define INLINE #endif #endif - - + + /* set up rotate style */ #if defined(_MSC_VER) || defined(__BCPLUSPLUS__) #define INTEL_INTRINSICS @@ -179,8 +148,8 @@ instructions */ #define FAST_ROTATE #endif - - + + /* set up thread local storage if available */ #ifdef HAVE_THREAD_LS #if defined(_MSC_VER) @@ -191,15 +160,15 @@ #else #define THREAD_LS_T #endif - - + + /* Micrium will use Visual Studio for compilation but not the Win32 API */ #if defined(_WIN32) && !defined(MICRIUM) && !defined(FREERTOS) \ && !defined(EBSNET) #define USE_WINDOWS_API #endif - - + + /* idea to add global alloc override by Moisés Guimarães */ /* default to libc stuff */ /* XREALLOC is used once in normal math lib, not in fast math lib */ @@ -225,16 +194,16 @@ #define XFREE(p, h, t) {void* xp = (p); if((xp)) wolfSSL_Free((xp));} #define XREALLOC(p, n, h, t) wolfSSL_Realloc((p), (n)) #endif - + #ifndef STRING_USER #include char* mystrnstr(const char* s1, const char* s2, unsigned int n); - + #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) #define XMEMSET(b,c,l) memset((b),(c),(l)) #define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) - + #define XSTRLEN(s1) strlen((s1)) #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) /* strstr, strncmp, and strncat only used by wolfSSL proper, not required for @@ -251,7 +220,7 @@ #define XSNPRINTF _snprintf #endif #endif - + #ifndef CTYPE_USER #include #if defined(HAVE_ECC) || defined(HAVE_OCSP) @@ -266,8 +235,8 @@ #endif #define XTOLOWER(c) tolower((c)) #endif - - + + /* memory allocation types for user hints */ enum { DYNAMIC_TYPE_CA = 1, @@ -316,19 +285,19 @@ DYNAMIC_TYPE_OCSP = 44, DYNAMIC_TYPE_SIGNATURE = 45 }; - + /* max error buffer string size */ enum { WOLFSSL_MAX_ERROR_SZ = 80 }; - + /* stack protection */ enum { MIN_STACK_BUFFER = 8 }; - - - + + + /* settings detection for compile vs runtime math incombatibilities */ enum { #if !defined(USE_FAST_MATH) && !defined(SIZEOF_LONG) && !defined(SIZEOF_LONG_LONG) @@ -351,19 +320,18 @@ #error "bad math long / long long settings" #endif }; - - + + WOLFSSL_API word32 CheckRunTimeSettings(void); - + /* If user uses RSA, DH, DSA, or ECC math lib directly then fast math and long types need to match at compile time and run time, CheckCtcSettings will return 1 if a match otherwise 0 */ #define CheckCtcSettings() (CTC_SETTINGS == CheckRunTimeSettings()) - - + + #ifdef __cplusplus } /* extern "C" */ #endif - -#endif /* HAVE_FIPS */ + #endif /* WOLF_CRYPT_TYPES_H */ diff --git a/wolfssl/wolfcrypt/visibility.h b/wolfssl/wolfcrypt/visibility.h index dbd91d1e5..fbb82f09b 100644 --- a/wolfssl/wolfcrypt/visibility.h +++ b/wolfssl/wolfcrypt/visibility.h @@ -24,13 +24,6 @@ #ifndef WOLF_CRYPT_VISIBILITY_H #define WOLF_CRYPT_VISIBILITY_H -/* fips compatibility @wc_fips */ -#ifdef HAVE_FIPS - #include - #define WOLFSSL_API CYASSL_API - #define WOLFSSL_LOCAL CYASSL_LOCAL -#else - /* WOLFSSL_API is used for the public API symbols. It either imports or exports (or does nothing for static builds) @@ -70,6 +63,5 @@ #endif /* BUILDING_WOLFSSL */ -#endif /* HAVE_FIPS */ #endif /* WOLF_CRYPT_VISIBILITY_H */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 1177ff034..724f87f6a 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1,4 +1,4 @@ -/* port.h +/* wc_port.h * * Copyright (C) 2006-2014 wolfSSL Inc. * @@ -23,12 +23,6 @@ #ifndef WOLF_CRYPT_PORT_H #define WOLF_CRYPT_PORT_H -/* fips compatibility @wc_fips */ -#ifdef HAVE_FIPS - #include - #define wolfSSL_Mutex CyaSSL_Mutex -#else - #ifdef __cplusplus extern "C" { #endif @@ -201,6 +195,5 @@ WOLFSSL_LOCAL int UnLockMutex(wolfSSL_Mutex*); } /* extern "C" */ #endif -#endif /* HAVE_FIPS */ #endif /* WOLF_CRYPT_PORT_H */