/* generate an ed25519 key pair. * returns 0 on success */ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) { byte az[ED25519_PRV_KEY_SIZE]; int ret; ge_p3 A; if (rng == NULL || key == NULL) return BAD_FUNC_ARG; /* ed25519 has 32 byte key sizes */ if (keySz != ED25519_KEY_SIZE) return BAD_FUNC_ARG; ret = wc_RNG_GenerateBlock(rng, key->k, ED25519_KEY_SIZE); if (ret != 0) return ret; ret = wc_Sha512Hash(key->k, ED25519_KEY_SIZE, az); if (ret != 0) { ForceZero(key->k, ED25519_KEY_SIZE); return ret; } /* apply clamp */ az[0] &= 248; az[31] &= 63; /* same than az[31] &= 127 because of az[31] |= 64 */ az[31] |= 64; ge_scalarmult_base(&A, az); ge_p3_tobytes(key->p, &A); /* put public key after private key, on the same buffer */ XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE); return ret; }
static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, word32 pkcsBlockLen, byte padValue, WC_RNG* rng) { if (inputLen == 0) return 0; pkcsBlock[0] = 0x0; /* set first byte to zero and advance */ pkcsBlock++; pkcsBlockLen--; pkcsBlock[0] = padValue; /* insert padValue */ if (padValue == RSA_BLOCK_TYPE_1) /* pad with 0xff bytes */ XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2); else { /* pad with non-zero random bytes */ word32 padLen = pkcsBlockLen - inputLen - 1, i; int ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); if (ret != 0) return ret; /* remove zeros */ for (i = 1; i < padLen; i++) if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01; } pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */ XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); return 0; }
/* * makes a cyptographically secure key by stretching a user entered pwdKey */ int wolfsslGenKey(RNG* rng, byte* pwdKey, int size, byte* salt, int pad) { int ret; /* return variable */ /* randomly generates salt */ ret = wc_RNG_GenerateBlock(rng, salt, SALT_SIZE-1); if (ret != 0) return ret; /* set first value of salt to let us know * if message has padding or not */ if (pad == 0) salt[0] = 0; /* stretches pwdKey */ ret = (int) wc_PBKDF2(pwdKey, pwdKey, (int) strlen((const char*)pwdKey), salt, SALT_SIZE, 4096, size, SHA256); if (ret != 0) return ret; return 0; }
int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa) { unsigned char *buf; int qsize, err; if (rng == NULL || dsa == NULL) return BAD_FUNC_ARG; qsize = mp_unsigned_bin_size(&dsa->q); if (qsize == 0) return BAD_FUNC_ARG; /* allocate ram */ buf = (unsigned char *)XMALLOC(qsize, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buf == NULL) return MEMORY_E; if (mp_init(&dsa->x) != MP_OKAY) { XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MP_INIT_E; } do { /* make a random exponent mod q */ err = wc_RNG_GenerateBlock(rng, buf, qsize); if (err != MP_OKAY) { mp_clear(&dsa->x); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return err; } err = mp_read_unsigned_bin(&dsa->x, buf, qsize); if (err != MP_OKAY) { mp_clear(&dsa->x); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return err; } } while (mp_cmp_d(&dsa->x, 1) != MP_GT); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (mp_init(&dsa->y) != MP_OKAY) { mp_clear(&dsa->x); return MP_INIT_E; } /* public key : y = g^x mod p */ err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y); if (err != MP_OKAY) { mp_clear(&dsa->x); mp_clear(&dsa->y); return err; } dsa->type = DSA_PRIVATE; return MP_OKAY; }
static int GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) { int ret; word32 sz = mp_unsigned_bin_size(&key->p); sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1); ret = wc_RNG_GenerateBlock(rng, priv, sz); if (ret != 0) return ret; priv[0] |= 0x0C; *privSz = sz; return 0; }
/* Create a random reply. * * reply The buffer to put the random data into. * replyLen The amount of data to generate. */ static void RandomReply(char* reply, int replyLen) { int ret; WC_RNG rng; ret = wc_InitRng(&rng); if (ret != 0) { fprintf(stderr, "Error: initialize random\n"); exit(EXIT_FAILURE); } ret = wc_RNG_GenerateBlock(&rng, (byte*)reply, replyLen); wc_FreeRng(&rng); if (ret != 0) { fprintf(stderr, "Error: initialize random\n"); exit(EXIT_FAILURE); } }
/* * Makes a cryptographically secure key by stretching a user entered key */ int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad) { int ret; ret = wc_RNG_GenerateBlock(rng, salt, SALT_SIZE); if (ret != 0) return -1020; if (pad == 0) salt[0] = 0; /* stretches key */ ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096, size, WC_SHA256); if (ret != 0) return -1030; return 0; }
/* * Makes a cryptographically secure key by stretMDMching a user entered key */ int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad) { int ret; ret = wc_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 = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096, size, SHA256); if (ret != 0) return -1030; return 0; }
static int GeneratePrivate(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz) { int ret; word32 sz = mp_unsigned_bin_size(&key->p); /* Table of predetermined values from the operation 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1 Sizes in table checked against RFC 3526 */ WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */ switch (sz) { case 128: sz = 21; break; case 256: sz = 29; break; case 384: sz = 34; break; case 512: sz = 39; break; case 640: sz = 42; break; case 768: sz = 46; break; case 896: sz = 49; break; case 1024: sz = 52; break; default: #ifndef WOLFSSL_DH_CONST /* if using floating points and size of p is not in table */ sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1); break; #else return BAD_FUNC_ARG; #endif } ret = wc_RNG_GenerateBlock(rng, priv, sz); if (ret != 0) return ret; priv[0] |= 0x0C; *privSz = sz; return 0; }
/* * Encrypts a file using AES */ int AesEncrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile) { RNG rng; byte iv[AES_BLOCK_SIZE]; byte* input; byte* output; byte salt[SALT_SIZE] = {0}; int i = 0; int ret = 0; int inputLength; int length; int padCounter = 0; fseek(inFile, 0, SEEK_END); inputLength = ftell(inFile); fseek(inFile, 0, SEEK_SET); length = inputLength; /* pads the length until it evenly matches a block / increases pad number*/ while (length % AES_BLOCK_SIZE != 0) { length++; padCounter++; } input = malloc(length); output = malloc(length); ret = wc_InitRng(&rng); if (ret != 0) { printf("Failed to initialize random number generator\n"); return -1030; } /* reads from inFile and writes whatever is there to the input array */ ret = fread(input, 1, inputLength, inFile); if (ret == 0) { printf("Input file does not exist.\n"); return -1010; } for (i = inputLength; i < length; i++) { /* pads the added characters with the number of pads */ input[i] = padCounter; } ret = wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); if (ret != 0) return -1020; /* stretches key to fit size */ ret = GenerateKey(&rng, key, size, salt, padCounter); if (ret != 0) return -1040; /* sets key */ ret = wc_AesSetKey(aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); if (ret != 0) return -1001; /* encrypts the message to the output based on input length + padding */ ret = wc_AesCbcEncrypt(aes, output, input, length); if (ret != 0) return -1005; /* writes to outFile */ fwrite(salt, 1, SALT_SIZE, outFile); fwrite(iv, 1, AES_BLOCK_SIZE, outFile); fwrite(output, 1, length, outFile); /* closes the opened files and frees the memory*/ memset(input, 0, length); memset(output, 0, length); memset(key, 0, size); free(input); free(output); free(key); fclose(inFile); fclose(outFile); wc_FreeRng(&rng); return ret; }
int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) { return wc_RNG_GenerateBlock(rng, b, 1); }
/* * benchmarking funciton */ int wolfCLU_benchmark(int timer, int* option) { int i = 0; /* A looping variable */ int loop = 1; /* benchmarking loop */ int64_t blocks = 0; /* blocks used during benchmarking */ #ifndef NO_AES Aes aes; /* aes declaration */ #endif #ifndef NO_DES3 Des3 des3; /* 3des declaration */ #endif RNG rng; /* random number generator */ int ret = 0; /* return variable */ double stop = 0.0; /* stop breaks loop */ double start; /* start time */ double currTime; /* current time*/ ALIGN16 byte* plain; /* plain text */ ALIGN16 byte* cipher; /* cipher */ ALIGN16 byte* key; /* key for testing */ ALIGN16 byte* iv; /* iv for initial encoding */ byte* digest; /* message digest */ wc_InitRng(&rng); signal(SIGALRM, wolfCLU_stop); i = 0; #ifndef NO_AES /* aes test */ if (option[i] == 1) { plain = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_AesSetKey(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); while (loop) { wc_AesCbcEncrypt(&aes, cipher, plain, AES_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("\n"); printf("AES-CBC "); wolfCLU_stats(start, AES_BLOCK_SIZE, blocks); XMEMSET(plain, 0, AES_BLOCK_SIZE); XMEMSET(cipher, 0, AES_BLOCK_SIZE); XMEMSET(key, 0, AES_BLOCK_SIZE); XMEMSET(iv, 0, AES_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef WOLFSSL_AES_COUNTER /* aes-ctr test */ if (option[i] == 1) { plain = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(AES_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, AES_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, AES_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_AesSetKeyDirect(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); while (loop) { wc_AesCtrEncrypt(&aes, cipher, plain, AES_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("AES-CTR "); wolfCLU_stats(start, AES_BLOCK_SIZE, blocks); XMEMSET(plain, 0, AES_BLOCK_SIZE); XMEMSET(cipher, 0, AES_BLOCK_SIZE); XMEMSET(key, 0, AES_BLOCK_SIZE); XMEMSET(iv, 0, AES_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_DES3 /* 3des test */ if (option[i] == 1) { plain = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(DES3_BLOCK_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, DES3_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, DES3_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, DES3_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, DES3_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION); while (loop) { wc_Des3_CbcEncrypt(&des3, cipher, plain, DES3_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("3DES "); wolfCLU_stats(start, DES3_BLOCK_SIZE, blocks); XMEMSET(plain, 0, DES3_BLOCK_SIZE); XMEMSET(cipher, 0, DES3_BLOCK_SIZE); XMEMSET(key, 0, DES3_BLOCK_SIZE); XMEMSET(iv, 0, DES3_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef HAVE_CAMELLIA #define CAM_SZ CAMELLIA_BLOCK_SIZE /* camellia test */ if (option[i] == 1) { Camellia camellia; plain = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { return MEMORY_E; } cipher = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (cipher == NULL) { wolfCLU_freeBins(plain, NULL, NULL, NULL, NULL); return MEMORY_E; } key = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (key == NULL) { wolfCLU_freeBins(plain, cipher, NULL, NULL, NULL); return MEMORY_E; } iv = XMALLOC(CAM_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (iv == NULL) { wolfCLU_freeBins(plain, cipher, key, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, CAMELLIA_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, cipher, CAMELLIA_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, key, CAMELLIA_BLOCK_SIZE); wc_RNG_GenerateBlock(&rng, iv, CAMELLIA_BLOCK_SIZE); start = wolfCLU_getTime(); alarm(timer); wc_CamelliaSetKey(&camellia, key, CAMELLIA_BLOCK_SIZE, iv); while (loop) { wc_CamelliaCbcEncrypt(&camellia, cipher, plain, CAMELLIA_BLOCK_SIZE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } printf("Camellia "); wolfCLU_stats(start, CAMELLIA_BLOCK_SIZE, blocks); XMEMSET(plain, 0, CAMELLIA_BLOCK_SIZE); XMEMSET(cipher, 0, CAMELLIA_BLOCK_SIZE); XMEMSET(key, 0, CAMELLIA_BLOCK_SIZE); XMEMSET(iv, 0, CAMELLIA_BLOCK_SIZE); wolfCLU_freeBins(plain, cipher, key, iv, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_MD5 /* md5 test */ if (option[i] == 1) { Md5 md5; digest = XMALLOC(MD5_DIGEST_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitMd5(&md5); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Md5Update(&md5, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Md5Final(&md5, digest); printf("MD5 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, MD5_DIGEST_SIZE); wolfCLU_freeBins(digest, plain, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_SHA /* sha test */ if (option[i] == 1) { Sha sha; digest = XMALLOC(SHA_DIGEST_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha(&sha); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_ShaUpdate(&sha, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_ShaFinal(&sha, digest); printf("Sha "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifndef NO_SHA256 #define SHA256_SZ SHA256_DIGEST_SIZE /* sha256 test */ if (option[i] == 1) { Sha256 sha256; digest = XMALLOC(SHA256_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha256(&sha256); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Sha256Update(&sha256, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Sha256Final(&sha256, digest); printf("Sha256 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA256_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); /* resets used for debug, uncomment if needed */ blocks = 0; loop = 1; } i++; #endif #ifdef WOLFSSL_SHA384 #define SHA384_SZ SHA384_DIGEST_SIZE /* sha384 test */ if (option[i] == 1) { Sha384 sha384; digest = XMALLOC(SHA384_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha384(&sha384); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Sha384Update(&sha384, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Sha384Final(&sha384, digest); printf("Sha384 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA384_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef WOLFSSL_SHA512 #define SHA512_SZ SHA512_DIGEST_SIZE /* sha512 test */ if (option[i] == 1) { Sha512 sha512; digest = XMALLOC(SHA512_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitSha512(&sha512); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Sha512Update(&sha512, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Sha512Final(&sha512, digest); printf("Sha512 "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, SHA512_DIGEST_SIZE); wolfCLU_freeBins(plain, digest, NULL, NULL, NULL); blocks = 0; loop = 1; } i++; #endif #ifdef HAVE_BLAKE2 /* blake2b test */ if (option[i] == 1) { Blake2b b2b; digest = XMALLOC(BLAKE_DIGEST_SIZE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (digest == NULL) return MEMORY_E; plain = XMALLOC(MEGABYTE, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (plain == NULL) { wolfCLU_freeBins(digest, NULL, NULL, NULL, NULL); return MEMORY_E; } wc_RNG_GenerateBlock(&rng, plain, MEGABYTE); wc_InitBlake2b(&b2b, BLAKE_DIGEST_SIZE); start = wolfCLU_getTime(); alarm(timer); while (loop) { wc_Blake2bUpdate(&b2b, plain, MEGABYTE); blocks++; currTime = wolfCLU_getTime(); stop = currTime - start; /* if stop >= timer, loop = 0 */ loop = (stop >= timer) ? 0 : 1; } wc_Blake2bFinal(&b2b, digest, BLAKE_DIGEST_SIZE); printf("Blake2b "); wolfCLU_stats(start, MEGABYTE, blocks); XMEMSET(plain, 0, MEGABYTE); XMEMSET(digest, 0, BLAKE_DIGEST_SIZE); wolfCLU_freeBins(digest, plain, NULL, NULL, NULL); } #endif return ret; }
int get_rand_digit(WC_RNG* rng, mp_digit* d) { return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit)); }
int wolfsslEncrypt(char* alg, char* mode, byte* pwdKey, byte* key, int size, char* in, char* out, byte* iv, int block, int ivCheck, int inputHex) { #ifndef NO_AES Aes aes; /* aes declaration */ #endif #ifndef NO_DES3 Des3 des3; /* 3des declaration */ #endif #ifdef HAVE_CAMELLIA Camellia camellia; /* camellia declaration */ #endif FILE* tempInFile = NULL; /* if user not provide a file */ FILE* inFile = NULL; /* input file */ FILE* outFile = NULL; /* output file */ RNG rng; /* random number generator declaration */ byte* input = NULL; /* input buffer */ byte* output = NULL; /* output buffer */ byte salt[SALT_SIZE] = {0}; /* salt variable */ int ret = 0; /* return variable */ int inputLength = 0; /* length of input */ int length = 0; /* total length */ int padCounter = 0; /* number of padded bytes */ int i = 0; /* loop variable */ int hexRet = 0; /* hex -> bin return*/ word32 tempInputL = 0; /* temporary input Length */ word32 tempMax = MAX; /* controls encryption amount */ char inputString[MAX]; /* the input string */ char* userInputBuffer = NULL; /* buffer when input is not a file */ if (access (in, F_OK) == -1) { printf("file did not exist, encrypting string following \"-i\"" "instead.\n"); /* use user entered data to encrypt */ inputLength = (int) strlen(in); userInputBuffer = (char*) malloc(inputLength); /* writes the entered text to the input buffer */ XMEMCPY(userInputBuffer, in, inputLength); /* open the file to write */ tempInFile = fopen(in, "wb"); fwrite(userInputBuffer, 1, inputLength, tempInFile); fclose(tempInFile); /* free buffer */ free(userInputBuffer); } /* open the inFile in read mode */ inFile = fopen(in, "rb"); /* find length */ fseek(inFile, 0, SEEK_END); inputLength = (int) ftell(inFile); fseek(inFile, 0, SEEK_SET); length = inputLength; /* Start up the random number generator */ ret = (int) wc_InitRng(&rng); if (ret != 0) { printf("Random Number Generator failed to start.\n"); return ret; } /* pads the length until it matches a block, * and increases pad number */ while (length % block != 0) { length++; padCounter++; } /* if the iv was not explicitly set, * generate an iv and use the pwdKey */ if (ivCheck == 0) { /* IV not set, generate it */ ret = wc_RNG_GenerateBlock(&rng, iv, block); if (ret != 0) { return ret; } /* stretches pwdKey to fit size based on wolfsslGetAlgo() */ ret = wolfsslGenKey(&rng, pwdKey, size, salt, padCounter); if (ret != 0) { printf("failed to set pwdKey.\n"); return ret; } /* move the generated pwdKey to "key" for encrypting */ for (i = 0; i < size; i++) { key[i] = pwdKey[i]; } } /* open the outFile in write mode */ outFile = fopen(out, "wb"); fwrite(salt, 1, SALT_SIZE, outFile); fwrite(iv, 1, block, outFile); fclose(outFile); /* malloc 1kB buffers */ input = (byte*) malloc(MAX); output = (byte*) malloc(MAX); /* loop, encrypt 1kB at a time till length <= 0 */ while (length > 0) { /* Read in 1kB to input[] */ if (inputHex == 1) ret = (int) fread(inputString, 1, MAX, inFile); else ret = (int) fread(input, 1, MAX, inFile); if (ret != MAX) { /* check for end of file */ if (feof(inFile)) { /* hex or ascii */ if (inputHex == 1) { hexRet = wolfsslHexToBin(inputString, &input, &tempInputL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (hexRet != 0) { printf("failed during conversion of input," " ret = %d\n", hexRet); return hexRet; } }/* end hex or ascii */ /* pad to end of block */ for (i = ret ; i < (ret + padCounter); i++) { input[i] = padCounter; } /* adjust tempMax for less than 1kB encryption */ tempMax = ret + padCounter; } else { /* otherwise we got a file read error */ wolfsslFreeBins(input, output, NULL, NULL, NULL); return FREAD_ERROR; }/* End feof check */ }/* End fread check */ /* sets key encrypts the message to ouput from input */ #ifndef NO_AES if (XSTRNCMP(alg, "aes", 3) == 0) { if (XSTRNCMP(mode, "cbc", 3) == 0) { ret = wc_AesSetKey(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); if (ret != 0) { printf("wc_AesSetKey failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ret; } ret = wc_AesCbcEncrypt(&aes, output, input, tempMax); if (ret != 0) { printf("wc_AesCbcEncrypt failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ENCRYPT_ERROR; } } #ifdef WOLFSSL_AES_COUNTER else if (XSTRNCMP(mode, "ctr", 3) == 0) { /* if mode is ctr */ wc_AesSetKeyDirect(&aes, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); wc_AesCtrEncrypt(&aes, output, input, tempMax); } #endif } #endif #ifndef NO_DES3 if (XSTRNCMP(alg, "3des", 4) == 0) { ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION); if (ret != 0) { printf("wc_Des3_SetKey failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ret; } ret = wc_Des3_CbcEncrypt(&des3, output, input, tempMax); if (ret != 0) { printf("wc_Des3_cbcEncrypt failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ENCRYPT_ERROR; } } #endif #ifdef HAVE_CAMELLIA if (XSTRNCMP(alg, "camellia", 8) == 0) { ret = wc_CamelliaSetKey(&camellia, key, block, iv); if (ret != 0) { printf("CamelliaSetKey failed.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return ret; } if (XSTRNCMP(mode, "cbc", 3) == 0) { wc_CamelliaCbcEncrypt(&camellia, output, input, tempMax); } else { printf("Incompatible mode while using Camellia.\n"); wolfsslFreeBins(input, output, NULL, NULL, NULL); return FATAL_ERROR; } } #endif /* HAVE_CAMELLIA */ /* this method added for visual confirmation of nist test vectors, * automated tests to come soon */ /* something in the output buffer and using hex */ if (output != NULL && inputHex == 1) { int tempi; printf("\nUser specified hex input this is a representation of " "what\nis being written to file in hex form.\n\n[ "); for (tempi = 0; tempi < block; tempi++ ) { printf("%02x", output[tempi]); } printf(" ]\n\n"); } /* end visual confirmation */ /* Open the outFile in append mode */ outFile = fopen(out, "ab"); ret = (int) fwrite(output, 1, tempMax, outFile); if (ferror(outFile)) { printf("failed to write to file.\n"); if (input != NULL) XMEMSET(input, 0, tempMax); if (output != NULL) XMEMSET(output, 0, tempMax); wolfsslFreeBins(input, output, NULL, NULL, NULL); return FWRITE_ERROR; } if (ret > MAX) { printf("Wrote too much to file.\n"); if (input != NULL) XMEMSET(input, 0, tempMax); if (output != NULL) XMEMSET(output, 0, tempMax); wolfsslFreeBins(input, output, NULL, NULL, NULL); return FWRITE_ERROR; } /* close the outFile */ fclose(outFile); length -= tempMax; if (length < 0) printf("length went past zero.\n"); if (input != NULL) XMEMSET(input, 0, tempMax); if (output != NULL) XMEMSET(output, 0, tempMax); } /* closes the opened files and frees the memory */ fclose(inFile); XMEMSET(key, 0, size); XMEMSET(iv, 0 , block); XMEMSET(alg, 0, size); XMEMSET(mode, 0 , block); /* Use the wolfssl free for rng */ wc_FreeRng(&rng); wolfsslFreeBins(input, output, NULL, NULL, NULL); return 0; }
int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) { mp_int k, kInv, r, s, H; int ret, sz; byte buffer[DSA_HALF_SIZE]; sz = min((int)sizeof(buffer), mp_unsigned_bin_size(&key->q)); /* generate k */ ret = wc_RNG_GenerateBlock(rng, buffer, sz); if (ret != 0) return ret; buffer[0] |= 0x0C; if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) return MP_INIT_E; if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) ret = MP_READ_E; if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT) ret = MP_CMP_E; /* inverse k mod q */ if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY) ret = MP_INVMOD_E; /* generate r, r = (g exp k mod p) mod q */ if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY) ret = MP_EXPTMOD_E; if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY) ret = MP_MOD_E; /* generate H from sha digest */ if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY) ret = MP_READ_E; /* generate s, s = (kInv * (H + x*r)) % q */ if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY) ret = MP_MUL_E; if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY) ret = MP_ADD_E; if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY) ret = MP_MULMOD_E; /* write out */ if (ret == 0) { int rSz = mp_unsigned_bin_size(&r); int sSz = mp_unsigned_bin_size(&s); if (rSz == DSA_HALF_SIZE - 1) { out[0] = 0; out++; } if (mp_to_unsigned_bin(&r, out) != MP_OKAY) ret = MP_TO_E; else { if (sSz == DSA_HALF_SIZE - 1) { out[rSz] = 0; out++; } ret = mp_to_unsigned_bin(&s, out + rSz); } } mp_clear(&H); mp_clear(&s); mp_clear(&r); mp_clear(&kInv); mp_clear(&k); return ret; }
/* modulus_size in bits */ int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) { mp_int tmp, tmp2; int err, msize, qsize, loop_check_prime = 0, check_prime = MP_NO; unsigned char *buf; if (rng == NULL || dsa == NULL) return BAD_FUNC_ARG; /* set group size in bytes from modulus size * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256) */ switch (modulus_size) { case 1024: qsize = 20; break; case 2048: case 3072: qsize = 32; break; default: return BAD_FUNC_ARG; break; } /* modulus size in bytes */ msize = modulus_size / 8; /* allocate ram */ buf = (unsigned char *)XMALLOC(msize - qsize, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buf == NULL) { return MEMORY_E; } /* make a random string that will be multplied against q */ err = wc_RNG_GenerateBlock(rng, buf, msize - qsize); if (err != MP_OKAY) { XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return err; } /* force magnitude */ buf[0] |= 0xC0; /* force even */ buf[msize - qsize - 1] &= ~1; if (mp_init_multi(&tmp2, &dsa->p, &dsa->q, 0, 0, 0) != MP_OKAY) { mp_clear(&dsa->q); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MP_INIT_E; } err = mp_read_unsigned_bin(&tmp2, buf, msize - qsize); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp2); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return err; } XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); /* make our prime q */ err = mp_rand_prime(&dsa->q, qsize, rng, NULL); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp2); return err; } /* p = random * q */ err = mp_mul(&dsa->q, &tmp2, &dsa->p); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp2); return err; } /* p = random * q + 1, so q is a prime divisor of p-1 */ err = mp_add_d(&dsa->p, 1, &dsa->p); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp2); return err; } if (mp_init(&tmp) != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp2); return MP_INIT_E; } /* tmp = 2q */ err = mp_add(&dsa->q, &dsa->q, &tmp); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp); mp_clear(&tmp2); return err; } /* loop until p is prime */ while (check_prime == MP_NO) { err = mp_prime_is_prime(&dsa->p, 8, &check_prime); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp); mp_clear(&tmp2); return err; } if (check_prime != MP_YES) { /* p += 2q */ err = mp_add(&tmp, &dsa->p, &dsa->p); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp); mp_clear(&tmp2); return err; } loop_check_prime++; } } /* tmp2 += (2*loop_check_prime) * to have p = (q * tmp2) + 1 prime */ if (loop_check_prime) { err = mp_add_d(&tmp2, 2*loop_check_prime, &tmp2); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp); mp_clear(&tmp2); return err; } } if (mp_init(&dsa->g) != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&tmp); mp_clear(&tmp2); return MP_INIT_E; } /* find a value g for which g^tmp2 != 1 */ mp_set(&dsa->g, 1); do { err = mp_add_d(&dsa->g, 1, &dsa->g); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&dsa->g); mp_clear(&tmp); mp_clear(&tmp2); return err; } err = mp_exptmod(&dsa->g, &tmp2, &dsa->p, &tmp); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); mp_clear(&dsa->g); mp_clear(&tmp); mp_clear(&tmp2); return err; } } while (mp_cmp_d(&tmp, 1) == MP_EQ); /* at this point tmp generates a group of order q mod p */ mp_exch(&tmp, &dsa->g); mp_clear(&tmp); mp_clear(&tmp2); return MP_OKAY; }
int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, int doDTLS, int throughput) { double start, conn_time = 0, tx_time = 0, rx_time = 0; SOCKET_T sockfd; WOLFSSL* ssl; int ret; start = current_time(); ssl = wolfSSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL object"); tcp_connect(&sockfd, host, port, doDTLS, ssl); wolfSSL_set_fd(ssl, sockfd); if (wolfSSL_connect(ssl) == SSL_SUCCESS) { /* Perform throughput test */ char *tx_buffer, *rx_buffer; /* Record connection time */ conn_time = current_time() - start; /* Allocate TX/RX buffers */ tx_buffer = (char*)malloc(TEST_BUFFER_SIZE); rx_buffer = (char*)malloc(TEST_BUFFER_SIZE); if(tx_buffer && rx_buffer) { WC_RNG rng; /* Startup the RNG */ ret = wc_InitRng(&rng); if(ret == 0) { int xfer_bytes; /* Generate random data to send */ ret = wc_RNG_GenerateBlock(&rng, (byte*)tx_buffer, TEST_BUFFER_SIZE); wc_FreeRng(&rng); if(ret != 0) { err_sys("wc_RNG_GenerateBlock failed"); } /* Perform TX and RX of bytes */ xfer_bytes = 0; while(throughput > xfer_bytes) { int len, rx_pos, select_ret; /* Determine packet size */ len = min(TEST_BUFFER_SIZE, throughput - xfer_bytes); /* Perform TX */ start = current_time(); if (wolfSSL_write(ssl, tx_buffer, len) != len) { int writeErr = wolfSSL_get_error(ssl, 0); printf("wolfSSL_write error %d!\n", writeErr); err_sys("wolfSSL_write failed"); } tx_time += current_time() - start; /* Perform RX */ select_ret = tcp_select(sockfd, 1); /* Timeout=1 second */ if (select_ret == TEST_RECV_READY) { start = current_time(); rx_pos = 0; while(rx_pos < len) { ret = wolfSSL_read(ssl, &rx_buffer[rx_pos], len - rx_pos); if(ret <= 0) { int readErr = wolfSSL_get_error(ssl, 0); if (readErr != SSL_ERROR_WANT_READ) { printf("wolfSSL_read error %d!\n", readErr); err_sys("wolfSSL_read failed"); } } else { rx_pos += ret; } } rx_time += current_time() - start; } /* Compare TX and RX buffers */ if(XMEMCMP(tx_buffer, rx_buffer, len) != 0) { err_sys("Compare TX and RX buffers failed"); } /* Update overall position */ xfer_bytes += len; } } else { err_sys("wc_InitRng failed"); } } else { err_sys("Client buffer malloc failed"); } if(tx_buffer) free(tx_buffer); if(rx_buffer) free(rx_buffer); } else { err_sys("wolfSSL_connect failed"); } wolfSSL_shutdown(ssl); wolfSSL_free(ssl); CloseSocket(sockfd); printf("wolfSSL Client Benchmark %d bytes\n" "\tConnect %8.3f ms\n" "\tTX %8.3f ms (%8.3f MBps)\n" "\tRX %8.3f ms (%8.3f MBps)\n", throughput, conn_time * 1000, tx_time * 1000, throughput / tx_time / 1024 / 1024, rx_time * 1000, throughput / rx_time / 1024 / 1024 ); return EXIT_SUCCESS; }