| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| */ |
| |
| /* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <time.h> |
| #include "ecdh_ZZZ.h" |
| #include "ecdh_support.h" |
| #include "randapi.h" |
| |
| int ecdh(csprng *RNG) |
| { |
| int i; |
| int res; |
| char *pp="M0ng00se"; |
| /* These octets are automatically protected against buffer overflow attacks */ |
| /* Note salt must be big enough to include an appended word */ |
| /* Note ECIES ciphertext C must be big enough to include at least 1 appended block */ |
| /* Recall EFS_ZZZ is field size in bytes. So EFS_ZZZ=32 for 256-bit curve */ |
| char s0[2*EGS_ZZZ]; |
| char s1[EGS_ZZZ]; |
| char w0[2*EFS_ZZZ+1]; |
| char w1[2*EFS_ZZZ+1]; |
| char z0[EFS_ZZZ]; |
| char z1[EFS_ZZZ]; |
| char key[AESKEY_ZZZ]; |
| char salt[40]; |
| char pw[40]; |
| octet S0= {0,sizeof(s0),s0}; |
| octet S1= {0,sizeof(s1),s1}; |
| octet W0= {0,sizeof(w0),w0}; |
| octet W1= {0,sizeof(w1),w1}; |
| octet Z0= {0,sizeof(z0),z0}; |
| octet Z1= {0,sizeof(z1),z1}; |
| octet KEY= {0,sizeof(key),key}; |
| octet SALT= {0,sizeof(salt),salt}; |
| octet PW= {0,sizeof(pw),pw}; |
| |
| SALT.len=8; |
| for (i=0; i<8; i++) SALT.val[i]=(char)(i+1); // set Salt |
| |
| printf("Alice's Passphrase= %s\n",pp); |
| |
| OCT_empty(&PW); |
| OCT_jstring(&PW,pp); // set Password from string |
| |
| /* private key S0 of size EGS_ZZZ bytes derived from Password and Salt */ |
| |
| PBKDF2(HASH_TYPE_ZZZ,&PW,&SALT,1000,EGS_ZZZ,&S0); |
| |
| printf("Alices private key= 0x"); |
| OCT_output(&S0); |
| |
| /* Generate Key pair S/W */ |
| |
| ECP_ZZZ_KEY_PAIR_GENERATE(NULL,&S0,&W0); |
| printf("Alices public key= 0x"); |
| OCT_output(&W0); |
| |
| res=ECP_ZZZ_PUBLIC_KEY_VALIDATE(&W0); |
| if (res!=0) |
| { |
| printf("ECP Public Key is invalid!\n"); |
| return 0; |
| } |
| |
| /* Random private key for other party */ |
| ECP_ZZZ_KEY_PAIR_GENERATE(RNG,&S1,&W1); |
| res=ECP_ZZZ_PUBLIC_KEY_VALIDATE(&W1); |
| if (res!=0) |
| { |
| printf("ECP Public Key is invalid!\n"); |
| return 0; |
| } |
| printf("Servers private key= 0x"); |
| OCT_output(&S1); |
| printf("Servers public key= 0x"); |
| OCT_output(&W1); |
| |
| /* Calculate common key using DH - IEEE 1363 method */ |
| |
| ECP_ZZZ_SVDP_DH(&S0,&W1,&Z0); |
| ECP_ZZZ_SVDP_DH(&S1,&W0,&Z1); |
| |
| if (!OCT_comp(&Z0,&Z1)) |
| { |
| printf("*** ECPSVDP-DH Failed\n"); |
| return 0; |
| } |
| |
| KDF2(HASH_TYPE_ZZZ,&Z0,NULL,AESKEY_ZZZ,&KEY); |
| |
| printf("Alice's DH Key= 0x"); |
| OCT_output(&KEY); |
| printf("Servers DH Key= 0x"); |
| OCT_output(&KEY); |
| |
| #if CURVETYPE_ZZZ != MONTGOMERY |
| |
| char ds[EGS_ZZZ]; |
| char p1[30]; |
| char p2[30]; |
| char v[2*EFS_ZZZ+1]; |
| char m[32]; |
| char c[64]; |
| char t[32]; |
| char cs[EGS_ZZZ]; |
| octet DS= {0,sizeof(ds),ds}; |
| octet CS= {0,sizeof(cs),cs}; |
| octet P1= {0,sizeof(p1),p1}; |
| octet P2= {0,sizeof(p2),p2}; |
| octet V= {0,sizeof(v),v}; |
| octet M= {0,sizeof(m),m}; |
| octet C= {0,sizeof(c),c}; |
| octet T= {0,sizeof(t),t}; |
| |
| printf("Testing ECIES\n"); |
| |
| P1.len=3; |
| P1.val[0]=0x0; |
| P1.val[1]=0x1; |
| P1.val[2]=0x2; |
| P2.len=4; |
| P2.val[0]=0x0; |
| P2.val[1]=0x1; |
| P2.val[2]=0x2; |
| P2.val[3]=0x3; |
| |
| M.len=17; |
| for (i=0; i<=16; i++) M.val[i]=(char)i; |
| |
| ECP_ZZZ_ECIES_ENCRYPT(HASH_TYPE_ZZZ,&P1,&P2,RNG,&W1,&M,12,&V,&C,&T); |
| |
| printf("Ciphertext= \n"); |
| printf("V= 0x"); |
| OCT_output(&V); |
| printf("C= 0x"); |
| OCT_output(&C); |
| printf("T= 0x"); |
| OCT_output(&T); |
| |
| if (!ECP_ZZZ_ECIES_DECRYPT(HASH_TYPE_ZZZ,&P1,&P2,&V,&C,&T,&S1,&M)) |
| { |
| printf("*** ECIES Decryption Failed\n"); |
| return 0; |
| } |
| else printf("Decryption succeeded\n"); |
| |
| printf("Message is 0x"); |
| OCT_output(&M); |
| |
| |
| printf("Testing ECDSA\n"); |
| |
| if (ECP_ZZZ_SP_DSA(HASH_TYPE_ZZZ,RNG,NULL,&S0,&M,&CS,&DS)!=0) |
| { |
| printf("***ECDSA Signature Failed\n"); |
| return 0; |
| } |
| |
| printf("Signature C = 0x"); |
| OCT_output(&CS); |
| printf("Signature D = 0x"); |
| OCT_output(&DS); |
| |
| if (ECP_ZZZ_VP_DSA(HASH_TYPE_ZZZ,&W0,&M,&CS,&DS)!=0) |
| { |
| printf("***ECDSA Verification Failed\n"); |
| return 0; |
| } |
| else |
| { |
| printf("ECDSA Signature/Verification succeeded\n"); |
| } |
| |
| #endif |
| |
| /* clear memory */ |
| OCT_clear(&S0); |
| OCT_clear(&S1); |
| OCT_clear(&W0); |
| OCT_clear(&W1); |
| OCT_clear(&Z0); |
| OCT_clear(&Z1); |
| OCT_clear(&KEY); |
| OCT_clear(&SALT); |
| OCT_clear(&PW); |
| #if CURVETYPE_ZZZ != MONTGOMERY |
| OCT_clear(&DS); |
| OCT_clear(&CS); |
| OCT_clear(&P1); |
| OCT_clear(&P2); |
| OCT_clear(&V); |
| OCT_clear(&M); |
| OCT_clear(&C); |
| OCT_clear(&T); |
| #endif |
| return 0; |
| } |
| |
| int main() |
| { |
| unsigned long ran; |
| |
| char raw[100]; |
| octet RAW= {0,sizeof(raw),raw}; |
| /* Crypto Strong RNG */ |
| csprng RNG; |
| |
| time((time_t *)&ran); |
| |
| /* fake random seed source */ |
| RAW.len=100; |
| RAW.val[0]=(char)ran; |
| RAW.val[1]=(char)(ran>>8); |
| RAW.val[2]=(char)(ran>>16); |
| RAW.val[3]=(char)(ran>>24); |
| for (int i=0; i<100; i++) RAW.val[i]=(char)(i+1); |
| |
| /* initialise strong RNG */ |
| CREATE_CSPRNG(&RNG,&RAW); |
| |
| ecdh(&RNG); |
| |
| KILL_CSPRNG(&RNG); |
| } |
| |