// Test vectors from RFC 6070. (See file header, above.) bool PBKDF2_TEST() { MemBuf mDig(100); MemBuf mOut(100); CvtHex( "0c60c80f961f0e71f3a9b524af6012062fe037a6", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 1, 20, mOut), 20 )) { return false; } CvtHex( "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 2, 20, mOut), 20 )) { return false; } CvtHex( "4b007901b765489abead49d926f721d065a429c1", mDig ); if (0 != memcmp( mDig, PBKDF2("password", "salt", 4096, 20, mOut), 20)) { return false; } // This one is rather time consuming. //CvtHex( "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984", mDig ); //if (0 != memcmp( mDig, PBKDF2("password", "salt", 16777216, 20, mOut), 20)) { return false; } CvtHex( "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", mDig ); if (0 != memcmp( mDig, PBKDF2("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25, mOut), 25)) { return false; } CvtHex( "56fa6aa75548099dcc37d7f03425e0c3", mDig ); BYTE text[] = { 'p', 'a', 's', 's', 0, 'w', 'o', 'r', 'd' } ; BYTE salt[] = { 's', 'a', 0, 'l', 't' } ; if (0 != memcmp( mDig, PBKDF2( MemBuf(text,NELEM(text)), MemBuf(salt,NELEM(salt)), 4096, 16, mOut), 16)) { return false; } return true; }
Blob Scrypt(const ConstBuf& password, const ConstBuf& salt, int n, int r, int p, size_t dkLen) { HmacPseudoRandomFunction<SHA256> prf; const size_t mfLen = r*128; Blob bb = PBKDF2(prf, password, salt, 1, p*mfLen); AlignedMem am((n+1)*r*128, 128); uint32_t *v = (uint32_t*)am.get(); SalsaBlockPtr tmp = (SalsaBlockPtr)alloca(r*128); for (int i=0; i<p; ++i) { SalsaBlockPtr x = (SalsaBlockPtr)(bb.data()+i*mfLen); for (int i=0; i<n; ++i) { memcpy(&v[i * 32 * r], x, 2*r * sizeof(x[0])); VectorMix(Salsa20Core, x, tmp, r, 8); } for (int i=0; i<n; ++i) { int j = 32*r * (x[2 * r - 1][0] & (n - 1)); VectorXor(x[0], &v[j], 2*r*16); VectorMix(Salsa20Core, x, tmp, r, 8); } } return PBKDF2(prf, password, bb, 1, dkLen); }
void pbkdf2_hmac_sha1 (size_t key_length, const uint8_t *key, unsigned iterations, size_t salt_length, const uint8_t *salt, size_t length, uint8_t *dst) { struct hmac_sha1_ctx sha1ctx; hmac_sha1_set_key (&sha1ctx, key_length, key); PBKDF2 (&sha1ctx, hmac_sha1_update, hmac_sha1_digest, SHA1_DIGEST_SIZE, iterations, salt_length, salt, length, dst); }
/* * krb5int_pbkdf2_hmac_sha1: Password based key derivation using CyaSSL * PBKDF2 from PKCS#5. * * Returns 0 on success, krb5_error_code on error */ krb5_error_code krb5int_pbkdf2_hmac_sha1 (const krb5_data *out, unsigned long count, const krb5_data *pass, const krb5_data *salt) { /* CyaSSL PBKDF2 from PKCS#5 */ PBKDF2( (unsigned char *)out->data, (unsigned char *) pass->data, pass->length, (unsigned char *)salt->data, salt->length, count, out->length, SHA); return 0; }
/* * Makes a cyptographically secure key by stretMDMching a user entered key */ int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad) { int ret; ret = RNG_GenerateBlock(rng, salt, SALT_SIZE-1); if (ret != 0) return -1020; if (pad == 0) /* sets first value of salt to check if the */ salt[0] = 0; /* message is padded */ /* stretches key */ ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096, size, SHA256); if (ret != 0) return -1030; return 0; }
static int dcrypt_gnutls_pbkdf2(const unsigned char *password, size_t password_len, const unsigned char *salt, size_t salt_len, const char *algorithm, unsigned int rounds, buffer_t *result, unsigned int result_len, const char **error_r) { unsigned char buf[result_len]; /* only sha1 or sha256 is supported */ if (strncasecmp(algorithm, "sha1", 4) == 0) { pbkdf2_hmac_sha1(password_len, password, rounds, salt_len, salt, result_len, buf); } else if (strncasecmp(algorithm, "sha256", 6) == 0) { pbkdf2_hmac_sha256(password_len, password, rounds, salt_len, salt, result_len, buf); } else if (strncasecmp(algorithm, "sha512", 6) == 0) { struct hmac_sha512_ctx ctx; hmac_sha512_set_key(&ctx, password_len, password); PBKDF2(&ctx, hmac_sha512_update, hmac_sha512_digest, 64, rounds, salt_len, salt, result_len, buf); i_zero(&ctx); } else { *error_r = "Unsupported algorithm"; return -1; } buffer_append(result, buf, result_len); memset(buf, 0, sizeof(buf)); return 0; }
BYTE *WPAPSK(PCBYTE text, int len, PCBYTE ssid, int ssidlen, BYTE *out) { if ((len < WPA_PASSPHRASE_LEN_MIN) || (WPA_PASSPHRASE_LEN_MAX < len)) { return NULL; } return PBKDF2( text, len, ssid, ssidlen, WPAPSK_COUNT, WPAPSK_LEN, out ); }
// -- convenience alias BYTE *PBKDF2( const MemBuf &text, const MemBuf &salt, int count, int length, MemBuf &out) { out.alloc( length ); return PBKDF2( text, text.size(), salt, salt.size(), count, length, out); }
// -- convenience alias BYTE *PBKDF2(const char *text, const char *salt, int count, int length, MemBuf &out) { MemBuf mText( (BYTE*)text, strlen( text )); MemBuf mSalt( (BYTE*)salt, strlen( salt )); return PBKDF2( mText, mSalt, count, length, out ); }
int main() { int i,j=0,res; int result; unsigned long ran; 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 is field size in bytes. So EFS=32 for 256-bit curve */ char s0[EGS],s1[EGS],w0[2*EFS+1],w1[2*EFS+1],z0[EFS],z1[EFS],raw[100],key[EAS],salt[32],pw[20],p1[30],p2[30],v[2*EFS+1],m[32],c[64],t[32],cs[EGS],ds[EGS]; 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 RAW={0,sizeof(raw),raw}; octet KEY={0,sizeof(key),key}; octet SALT={0,sizeof(salt),salt}; octet PW={0,sizeof(pw),pw}; 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}; octet CS={0,sizeof(cs),cs}; octet DS={0,sizeof(ds),ds}; /* Crypto Strong RNG */ csprng RNG; time((time_t *)&ran); /* fake random seed source */ RAW.len=100; RAW.val[0]=ran; RAW.val[1]=ran>>8; RAW.val[2]=ran>>16; RAW.val[3]=ran>>24; for (i=0;i<100;i++) RAW.val[i]=i; /* initialise strong RNG */ CREATE_CSPRNG(&RNG,&RAW); SALT.len=8; for (i=0;i<8;i++) SALT.val[i]=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 bytes derived from Password and Salt */ PBKDF2(&PW,&SALT,1000,EGS,&S0); printf("Alices private key= 0x"); OCT_output(&S0); /* Generate Key pair S/W */ ECP_KEY_PAIR_GENERATE(NULL,&S0,&W0); res=ECP_PUBLIC_KEY_VALIDATE(1,&W0); if (res!=0) { printf("ECP Public Key is invalid!\n"); return 1; } printf("Alice's public key= 0x"); OCT_output(&W0); /* Random private key for other party */ ECP_KEY_PAIR_GENERATE(&RNG,&S1,&W1); res=ECP_PUBLIC_KEY_VALIDATE(1,&W1); if (res!=0) { printf("ECP Public Key is invalid!\n"); return 1; } printf("Servers private key= 0x"); OCT_output(&S1); printf("Servers public key= 0x"); OCT_output(&W1); /* Calculate common key using DH - IEEE 1363 method */ ECPSVDP_DH(&S0,&W1,&Z0); ECPSVDP_DH(&S1,&W0,&Z1); if (!OCT_comp(&Z0,&Z1)) { printf("*** ECPSVDP-DH Failed\n"); return 0; } KDF2(&Z0,NULL,EAS,&KEY); printf("Alice's DH Key= 0x"); OCT_output(&KEY); printf("Servers DH Key= 0x"); OCT_output(&KEY); 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]=i; ECP_ECIES_ENCRYPT(&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_ECIES_DECRYPT(&P1,&P2,&V,&C,&T,&S1,&M)) { printf("*** ECIES Decryption Failed\n"); return 1; } else printf("Decryption succeeded\n"); printf("Message is 0x"); OCT_output(&M); printf("Testing ECDSA\n"); if (ECPSP_DSA(&RNG,&S0,&M,&CS,&DS)!=0) { printf("***ECDSA Signature Failed\n"); return 1; } printf("Signature C = 0x"); OCT_output(&CS); printf("Signature D = 0x"); OCT_output(&DS); if (ECPVP_DSA(&W0,&M,&CS,&DS)!=0) { printf("***ECDSA Verification Failed\n"); return 1; } else printf("ECDSA Signature/Verification succeeded %d\n",j); KILL_CSPRNG(&RNG); printf("SUCCESS\n"); return 0; }
static int pbkdf2_check( const struct berval *scheme, const struct berval *passwd, const struct berval *cred, const char **text) { int rc; int iteration; /* salt_value require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ unsigned char salt_value[PBKDF2_SALT_SIZE + 1]; char salt_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_SALT_SIZE) + 1]; /* dk_value require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ unsigned char dk_value[PBKDF2_MAX_DK_SIZE + 1]; char dk_b64[LUTIL_BASE64_ENCODE_LEN(PBKDF2_MAX_DK_SIZE) + 1]; unsigned char input_dk_value[PBKDF2_MAX_DK_SIZE]; size_t dk_len; #ifdef HAVE_OPENSSL const EVP_MD *md; #elif HAVE_GNUTLS struct hmac_sha1_ctx sha1_ctx; struct hmac_sha256_ctx sha256_ctx; struct hmac_sha512_ctx sha512_ctx; void * current_ctx = NULL; pbkdf2_hmac_update current_hmac_update = NULL; pbkdf2_hmac_digest current_hmac_digest = NULL; #endif #ifdef SLAPD_PBKDF2_DEBUG printf("Checking for %s\n", scheme->bv_val); printf(" Stored Value:\t%s\n", passwd->bv_val); printf(" Input Cred:\t%s\n", cred->bv_val); #endif #ifdef HAVE_OPENSSL if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk_len = PBKDF2_SHA256_DK_SIZE; md = EVP_sha256(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk_len = PBKDF2_SHA512_DK_SIZE; md = EVP_sha512(); }else{ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk_len = PBKDF2_SHA256_DK_SIZE; current_ctx = &sha256_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest; hmac_sha256_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk_len = PBKDF2_SHA512_DK_SIZE; current_ctx = &sha512_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest; hmac_sha512_set_key(current_ctx, cred->bv_len, (const uint8_t *) cred->bv_val); }else{ return LUTIL_PASSWD_ERR; } #endif iteration = atoi(passwd->bv_val); if(iteration < 1){ return LUTIL_PASSWD_ERR; } char *ptr; ptr = strchr(passwd->bv_val, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, salt_b64, sizeof(salt_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } ptr = strchr(ptr, '$'); if(!ptr){ return LUTIL_PASSWD_ERR; } ptr++; /* skip '$' */ rc = ab64_to_b64(ptr, dk_b64, sizeof(dk_b64)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_SALT_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(salt_b64, salt_value, PBKDF2_SALT_SIZE + 1); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != PBKDF2_SALT_SIZE){ return LUTIL_PASSWD_ERR; } /* The targetsize require PBKDF2_MAX_DK_SIZE + 1 in lutil_b64_pton. */ rc = lutil_b64_pton(dk_b64, dk_value, sizeof(dk_value)); if(rc < 0){ return LUTIL_PASSWD_ERR; } /* consistency check */ if(rc != dk_len){ return LUTIL_PASSWD_ERR; } #ifdef HAVE_OPENSSL if(!PKCS5_PBKDF2_HMAC(cred->bv_val, cred->bv_len, salt_value, PBKDF2_SALT_SIZE, iteration, md, dk_len, input_dk_value)){ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS PBKDF2(current_ctx, current_hmac_update, current_hmac_digest, dk_len, iteration, PBKDF2_SALT_SIZE, salt_value, dk_len, input_dk_value); #endif rc = memcmp(dk_value, input_dk_value, dk_len); #ifdef SLAPD_PBKDF2_DEBUG printf(" Iteration:\t%d\n", iteration); printf(" Base64 Salt:\t%s\n", salt_b64); printf(" Base64 DK:\t%s\n", dk_b64); int i; printf(" Stored Salt:\t"); for(i=0; i<PBKDF2_SALT_SIZE; i++){ printf("%02x", salt_value[i]); } printf("\n"); printf(" Stored DK:\t"); for(i=0; i<dk_len; i++){ printf("%02x", dk_value[i]); } printf("\n"); printf(" Input DK:\t"); for(i=0; i<dk_len; i++){ printf("%02x", input_dk_value[i]); } printf("\n"); printf(" Result:\t%d\n", rc); #endif return rc?LUTIL_PASSWD_ERR:LUTIL_PASSWD_OK; }
static int pbkdf2_encrypt( const struct berval *scheme, const struct berval *passwd, struct berval *msg, const char **text) { unsigned char salt_value[PBKDF2_SALT_SIZE]; struct berval salt; unsigned char dk_value[PBKDF2_MAX_DK_SIZE]; struct berval dk; int iteration = PBKDF2_ITERATION; int rc; #ifdef HAVE_OPENSSL const EVP_MD *md; #elif HAVE_GNUTLS struct hmac_sha1_ctx sha1_ctx; struct hmac_sha256_ctx sha256_ctx; struct hmac_sha512_ctx sha512_ctx; void * current_ctx = NULL; pbkdf2_hmac_update current_hmac_update = NULL; pbkdf2_hmac_digest current_hmac_digest = NULL; #endif salt.bv_val = (char *)salt_value; salt.bv_len = sizeof(salt_value); dk.bv_val = (char *)dk_value; #ifdef HAVE_OPENSSL if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; md = EVP_sha1(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk.bv_len = PBKDF2_SHA256_DK_SIZE; md = EVP_sha256(); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk.bv_len = PBKDF2_SHA512_DK_SIZE; md = EVP_sha512(); }else{ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS if(!ber_bvcmp(scheme, &pbkdf2_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha1_scheme)){ dk.bv_len = PBKDF2_SHA1_DK_SIZE; current_ctx = &sha1_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha1_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha1_digest; hmac_sha1_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha256_scheme)){ dk.bv_len = PBKDF2_SHA256_DK_SIZE; current_ctx = &sha256_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha256_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha256_digest; hmac_sha256_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else if(!ber_bvcmp(scheme, &pbkdf2_sha512_scheme)){ dk.bv_len = PBKDF2_SHA512_DK_SIZE; current_ctx = &sha512_ctx; current_hmac_update = (pbkdf2_hmac_update) &hmac_sha512_update; current_hmac_digest = (pbkdf2_hmac_digest) &hmac_sha512_digest; hmac_sha512_set_key(current_ctx, passwd->bv_len, (const uint8_t *) passwd->bv_val); }else{ return LUTIL_PASSWD_ERR; } #endif if(lutil_entropy((unsigned char *)salt.bv_val, salt.bv_len) < 0){ return LUTIL_PASSWD_ERR; } #ifdef HAVE_OPENSSL if(!PKCS5_PBKDF2_HMAC(passwd->bv_val, passwd->bv_len, (unsigned char *)salt.bv_val, salt.bv_len, iteration, md, dk.bv_len, dk_value)){ return LUTIL_PASSWD_ERR; } #elif HAVE_GNUTLS PBKDF2(current_ctx, current_hmac_update, current_hmac_digest, dk.bv_len, iteration, salt.bv_len, (const uint8_t *) salt.bv_val, dk.bv_len, dk_value); #endif #ifdef SLAPD_PBKDF2_DEBUG printf("Encrypt for %s\n", scheme->bv_val); printf(" Password:\t%s\n", passwd->bv_val); printf(" Salt:\t\t"); int i; for(i=0; i<salt.bv_len; i++){ printf("%02x", salt_value[i]); } printf("\n"); printf(" Iteration:\t%d\n", iteration); printf(" DK:\t\t"); for(i=0; i<dk.bv_len; i++){ printf("%02x", dk_value[i]); } printf("\n"); #endif rc = pbkdf2_format(scheme, iteration, &salt, &dk, msg); #ifdef SLAPD_PBKDF2_DEBUG printf(" Output:\t%s\n", msg->bv_val); #endif return rc; }
/* * Decrypts a file using Camellia */ int CamelliaDecrypt(Camellia* cam, byte* key, int size, FILE* inFile, FILE* outFile) { RNG rng; byte iv[CAMELLIA_BLOCK_SIZE]; byte* input; byte* output; byte salt[SALT_SIZE] = {0}; int i = 0; int ret = 0; int length; int aSize; fseek(inFile, 0, SEEK_END); length = ftell(inFile); fseek(inFile, 0, SEEK_SET); aSize = length; input = malloc(aSize); output = malloc(aSize); InitRng(&rng); /* reads from inFile and wrties whatever is there to the input array */ ret = fread(input, 1, length, inFile); if (ret == 0) { printf("Input file does not exist.\n"); return -1010; } for (i = 0; i < SALT_SIZE; i++) { /* finds salt from input message */ salt[i] = input[i]; } for (i = SALT_SIZE; i < CAMELLIA_BLOCK_SIZE + SALT_SIZE; i++) { /* finds iv from input message */ iv[i - SALT_SIZE] = input[i]; } /* replicates old key if keys match */ ret = PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096, size, SHA256); if (ret != 0) return -1050; /* sets key */ ret = CamelliaSetKey(cam, key, CAMELLIA_BLOCK_SIZE, iv); if (ret != 0) return -1002; /* change length to remove salt/iv block from being decrypted */ length -= (CAMELLIA_BLOCK_SIZE + SALT_SIZE); for (i = 0; i < length; i++) { /* shifts message: ignores salt/iv on message*/ input[i] = input[i + (CAMELLIA_BLOCK_SIZE + SALT_SIZE)]; } /* decrypts the message to output based on input length + padding */ CamelliaCbcDecrypt(cam, output, input, length); if (salt[0] != 0) { /* reduces length based on number of padded elements */ length -= output[length-1]; } /* writes output to the outFile based on shortened length */ fwrite(output, 1, length, outFile); /* closes the opened files and frees the memory*/ memset(input, 0, aSize); memset(output, 0, aSize); memset(key, 0, size); free(input); free(output); free(key); fclose(inFile); fclose(outFile); return 0; }
int main(int argc,char **argv) { int i,res; BOOL result; 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 is field size in bytes. So EFS=32 for 256-bit curve */ char s0[EGS],s1[EGS],w0[2*EFS+1],w1[2*EFS+1],z0[EFS],z1[EFS],raw[100],key[EAS],salt[32],pw[20],b64[4+((8*EFS+4)/3)],p1[30],p2[30],v[2*EFS+1],m[32],c[64],t[32],cs[EGS],ds[EGS]; 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 RAW={0,sizeof(raw),raw}; octet KEY={0,sizeof(key),key}; octet SALT={0,sizeof(salt),salt}; octet PW={0,sizeof(pw),pw}; 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}; octet CS={0,sizeof(cs),cs}; octet DS={0,sizeof(ds),ds}; ecp_domain epdom; csprng RNG; /* Crypto Strong RNG */ RAW.len=100; /* fake random seed source */ for (i=0;i<100;i++) RAW.val[i]=i+1; CREATE_CSPRNG(&RNG,&RAW); /* initialise strong RNG */ SALT.len=8; for (i=0;i<8;i++) SALT.val[i]=i+1; // set Salt printf("Alice's Passphrase= %s\n",pp); OCTET_JOIN_STRING(pp,&PW); // set Password from string /* First set up Elliptic Curve from ROM data */ ECP_DOMAIN_INIT(&epdom,ecrom); /* private key S0 of size EGS bytes derived from Password and Salt */ PBKDF2(&PW,&SALT,1000,EGS,&S0); OCTET_TO_BASE64(&S0,b64); printf("Alices private key= %s\n",b64); /* Generate Key pair S/W */ ECP_KEY_PAIR_GENERATE(&epdom,NULL,&S0,&W0); res=ECP_PUBLIC_KEY_VALIDATE(&epdom,TRUE,&W0); if (res!=0) { printf("ECP Public Key is invalid!\n"); return 0; } OCTET_TO_BASE64(&W0,b64); printf("Alice's public key= %s\n",b64); OCTET_FROM_BASE64(b64,&W0); /* Random private key for other party */ S1.len=3; S1.val[0]=0x01; S1.val[1]=0x23; S1.val[2]=0x45; ECP_KEY_PAIR_GENERATE(&epdom,NULL,&S1,&W1); res=ECP_PUBLIC_KEY_VALIDATE(&epdom,TRUE,&W1); if (res!=0) { printf("ECP Public Key is invalid!\n"); return 0; } OCTET_TO_BASE64(&W1,b64); printf("Servers public key= %s\n",b64); OCTET_FROM_BASE64(b64,&W1); /* Calculate common key using DH - IEEE 1363 method */ ECPSVDP_DH(&epdom,&S0,&W1,&Z0); ECPSVDP_DH(&epdom,&S1,&W0,&Z1); if (!OCTET_COMPARE(&Z0,&Z1)) { printf("*** ECPSVDP-DH Failed\n"); return 0; } KDF1(&Z0,EAS,&KEY); printf("Alice's DH Key= "); for (i=0;i<EAS;i++) printf("%u ",KEY.val[i]&0xff); printf("\n"); printf("Servers DH Key= "); for (i=0;i<EAS;i++) printf("%u ",KEY.val[i]&0xff); printf("\n"); 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]=i; /* fake a message */ ECP_ECIES_ENCRYPT(&epdom,&P1,&P2,&RNG,&W1,&M,12,&V,&C,&T); printf("Ciphertext= \n"); OCTET_TO_BASE64(&V,b64); printf("V= %s\n",b64); OCTET_FROM_BASE64(b64,&V); OCTET_TO_BASE64(&C,b64); printf("C= %s\n",b64); OCTET_FROM_BASE64(b64,&C); OCTET_TO_BASE64(&T,b64); printf("V= %s\n",b64); OCTET_FROM_BASE64(b64,&T); if (!ECP_ECIES_DECRYPT(&epdom,&P1,&P2,&V,&C,&T,&S1,&M)) { printf("*** ECIES Decryption Failed\n"); return 0; } else printf("Decryption succeeded\n"); printf("Message is "); OCTET_OUTPUT(&M); printf("Testing ECDSA\n"); if (ECPSP_DSA(&epdom,&RNG,&S0,&M,&CS,&DS)!=0) { printf("***ECDSA Signature Failed\n"); return 0; } OCTET_TO_BASE64(&CS,b64); printf("Signature C = %s\n",b64); OCTET_FROM_BASE64(b64,&CS); OCTET_TO_BASE64(&DS,b64); printf("Signature D = %s\n",b64); OCTET_FROM_BASE64(b64,&DS); if (ECPVP_DSA(&epdom,&W0,&M,&CS,&DS)!=0) { printf("***ECDSA Verification Failed\n"); return 0; } else printf("ECDSA Signature/Verification succeeded\n"); ECP_DOMAIN_KILL(&epdom); KILL_CSPRNG(&RNG); return 0; }
int main() { int i,j=0,res; int result; unsigned long ran; 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 is field size in bytes. So EFS=32 for 256-bit curve */ char s0[EGS],s1[EGS],w0[2*EFS+1],w1[2*EFS+1],z0[EFS],z1[EFS],raw[100],key[EAS],salt[32],pw[20]; 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 RAW={0,sizeof(raw),raw}; octet KEY={0,sizeof(key),key}; octet SALT={0,sizeof(salt),salt}; octet PW={0,sizeof(pw),pw}; /* Crypto Strong RNG */ csprng RNG; time((time_t *)&ran); /* fake random seed source */ RAW.len=100; RAW.val[0]=ran; RAW.val[1]=ran>>8; RAW.val[2]=ran>>16; RAW.val[3]=ran>>24; for (i=4;i<100;i++) RAW.val[i]=i; CREATE_CSPRNG(&RNG,&RAW); /* initialise strong RNG */ SALT.len=8; for (i=0;i<8;i++) SALT.val[i]=i+1; // set Salt printf("Alice's Passphrase= %s\n",pp); OCT_clear(&PW); OCT_jstring(&PW,pp); // set Password from string /* private key S0 of size EGS bytes derived from Password and Salt */ PBKDF2(&PW,&SALT,1000,EGS,&S0); printf("Alices private key= 0x"); OCT_output(&S0); /* Generate Key pair S/W */ ECP_KEY_PAIR_GENERATE(NULL,&S0,&W0); res=ECP_PUBLIC_KEY_VALIDATE(1,&W0); if (res!=0) { printf("Alice's ECP Public Key is invalid!\n"); return 1; } printf("Alice's public key= 0x"); OCT_output(&W0); /* Random private key for other party */ ECP_KEY_PAIR_GENERATE(&RNG,&S1,&W1); printf("Servers private key= 0x"); OCT_output(&S1); printf("Servers public key= 0x"); OCT_output(&W1); res=ECP_PUBLIC_KEY_VALIDATE(1,&W1); if (res!=0) { printf("Server's ECP Public Key is invalid!\n"); return 1; } /* Calculate common key using DH - IEEE 1363 method */ ECPSVDP_DH(&S0,&W1,&Z0); ECPSVDP_DH(&S1,&W0,&Z1); if (!OCT_comp(&Z0,&Z1)) { printf("*** ECPSVDP-DH Failed\n"); return 1; } KDF2(&Z0,NULL,EAS,&KEY); printf("Alice's DH Key= 0x"); OCT_output(&KEY); printf("Servers DH Key= 0x"); OCT_output(&KEY); printf("SUCCESS\n"); return 0; }