/* ECC DSA Hash Sign */ int CRYPT_ECC_DSA_HashSign(CRYPT_ECC_CTX* ecc, CRYPT_RNG_CTX* rng, unsigned char* sig, unsigned int sigSz, unsigned int* usedSz, const unsigned char* in, unsigned int inSz) { int ret; unsigned int inOut = sigSz; if (ecc == NULL || rng == NULL || sig == NULL || usedSz == NULL || in == NULL) return BAD_FUNC_ARG; ret = wc_ecc_sign_hash(in, inSz, sig, &inOut, (WC_RNG*)rng, (ecc_key*)ecc->holder); *usedSz = inOut; return ret; }
/* Example crypto dev callback function that calls software versions, could * be set up to call down to hardware module for crypto operations if * desired by user. If an algorithm is not supported by hardware, or user * callback, the cryptodev callback can return NOT_COMPILED_IN to default * back to using software crypto implementation. */ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) { int ret = NOT_COMPILED_IN; /* return this to bypass HW and use SW */ myCryptoDevCtx* myCtx = (myCryptoDevCtx*)ctx; if (info == NULL) return BAD_FUNC_ARG; if (info->algo_type == WC_ALGO_TYPE_PK) { #ifdef DEBUG_WOLFSSL printf("CryptoDevCb: Pk Type %d\n", info->pk.type); #endif #ifndef NO_RSA if (info->pk.type == WC_PK_TYPE_RSA) { /* set devId to invalid, so software is used */ info->pk.rsa.key->devId = INVALID_DEVID; switch (info->pk.rsa.type) { case RSA_PUBLIC_ENCRYPT: case RSA_PUBLIC_DECRYPT: /* perform software based RSA public op */ ret = wc_RsaFunction( info->pk.rsa.in, info->pk.rsa.inLen, info->pk.rsa.out, info->pk.rsa.outLen, info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); break; case RSA_PRIVATE_ENCRYPT: case RSA_PRIVATE_DECRYPT: /* perform software based RSA private op */ ret = wc_RsaFunction( info->pk.rsa.in, info->pk.rsa.inLen, info->pk.rsa.out, info->pk.rsa.outLen, info->pk.rsa.type, info->pk.rsa.key, info->pk.rsa.rng); break; } /* reset devId */ info->pk.rsa.key->devId = devIdArg; } #ifdef WOLFSSL_KEY_GEN else if (info->pk.type == WC_PK_TYPE_RSA_KEYGEN) { info->pk.rsakg.key->devId = INVALID_DEVID; ret = wc_MakeRsaKey(info->pk.rsakg.key, info->pk.rsakg.size, info->pk.rsakg.e, info->pk.rsakg.rng); /* reset devId */ info->pk.rsakg.key->devId = devIdArg; } #endif #endif /* !NO_RSA */ #ifdef HAVE_ECC if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) { /* set devId to invalid, so software is used */ info->pk.eckg.key->devId = INVALID_DEVID; ret = wc_ecc_make_key_ex(info->pk.eckg.rng, info->pk.eckg.size, info->pk.eckg.key, info->pk.eckg.curveId); /* reset devId */ info->pk.eckg.key->devId = devIdArg; } else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) { /* set devId to invalid, so software is used */ info->pk.eccsign.key->devId = INVALID_DEVID; ret = wc_ecc_sign_hash( info->pk.eccsign.in, info->pk.eccsign.inlen, info->pk.eccsign.out, info->pk.eccsign.outlen, info->pk.eccsign.rng, info->pk.eccsign.key); /* reset devId */ info->pk.eccsign.key->devId = devIdArg; } else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) { /* set devId to invalid, so software is used */ info->pk.eccverify.key->devId = INVALID_DEVID; ret = wc_ecc_verify_hash( info->pk.eccverify.sig, info->pk.eccverify.siglen, info->pk.eccverify.hash, info->pk.eccverify.hashlen, info->pk.eccverify.res, info->pk.eccverify.key); /* reset devId */ info->pk.eccverify.key->devId = devIdArg; } else if (info->pk.type == WC_PK_TYPE_ECDH) { /* set devId to invalid, so software is used */ info->pk.ecdh.private_key->devId = INVALID_DEVID; ret = wc_ecc_shared_secret( info->pk.ecdh.private_key, info->pk.ecdh.public_key, info->pk.ecdh.out, info->pk.ecdh.outlen); /* reset devId */ info->pk.ecdh.private_key->devId = devIdArg; } #endif /* HAVE_ECC */ } else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { #if !defined(NO_AES) && defined(HAVE_AESGCM) if (info->cipher.type == WC_CIPHER_AES_GCM) { if (info->cipher.enc) { /* set devId to invalid, so software is used */ info->cipher.aesgcm_enc.aes->devId = INVALID_DEVID; ret = wc_AesGcmEncrypt( info->cipher.aesgcm_enc.aes, info->cipher.aesgcm_enc.out, info->cipher.aesgcm_enc.in, info->cipher.aesgcm_enc.sz, info->cipher.aesgcm_enc.iv, info->cipher.aesgcm_enc.ivSz, info->cipher.aesgcm_enc.authTag, info->cipher.aesgcm_enc.authTagSz, info->cipher.aesgcm_enc.authIn, info->cipher.aesgcm_enc.authInSz); /* reset devId */ info->cipher.aesgcm_enc.aes->devId = devIdArg; } else { /* set devId to invalid, so software is used */ info->cipher.aesgcm_dec.aes->devId = INVALID_DEVID; ret = wc_AesGcmDecrypt( info->cipher.aesgcm_dec.aes, info->cipher.aesgcm_dec.out, info->cipher.aesgcm_dec.in, info->cipher.aesgcm_dec.sz, info->cipher.aesgcm_dec.iv, info->cipher.aesgcm_dec.ivSz, info->cipher.aesgcm_dec.authTag, info->cipher.aesgcm_dec.authTagSz, info->cipher.aesgcm_dec.authIn, info->cipher.aesgcm_dec.authInSz); /* reset devId */ info->cipher.aesgcm_dec.aes->devId = devIdArg; } } #endif /* !NO_AES && HAVE_AESGCM */ } (void)devIdArg; (void)myCtx; return ret; }
int wc_SignatureGenerate( enum wc_HashType hash_type, enum wc_SignatureType sig_type, const byte* data, word32 data_len, byte* sig, word32 *sig_len, const void* key, word32 key_len, RNG* rng) { int ret, hash_len; byte *hash_data = NULL; /* Supress possible unused arg if all signature types are disabled */ (void)rng; /* Check arguments */ if (data == NULL || data_len <= 0 || sig == NULL || sig_len == NULL || *sig_len <= 0 || key == NULL || key_len <= 0) { return BAD_FUNC_ARG; } /* Validate signature len (needs to be at least max) */ if ((int)*sig_len < wc_SignatureGetSize(sig_type, key, key_len)) { WOLFSSL_MSG("wc_SignatureGenerate: Invalid sig type/len"); return BAD_FUNC_ARG; } /* Validate hash size */ hash_len = wc_HashGetDigestSize(hash_type); if (hash_len <= 0) { WOLFSSL_MSG("wc_SignatureGenerate: Invalid hash type/len"); return BAD_FUNC_ARG; } /* Allocate temporary buffer for hash data */ hash_data = XMALLOC(hash_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (hash_data == NULL) { return MEMORY_E; } /* Perform hash of data */ ret = wc_Hash(hash_type, data, data_len, hash_data, hash_len); if (ret == 0) { /* Create signature using hash as data */ switch(sig_type) { #ifdef HAVE_ECC case WC_SIGNATURE_TYPE_ECC: { /* Create signature using provided ECC key */ ret = wc_ecc_sign_hash(hash_data, hash_len, sig, sig_len, rng, (ecc_key*)key); break; } #endif #ifndef NO_RSA case WC_SIGNATURE_TYPE_RSA: /* Create signature using provided RSA key */ ret = wc_RsaSSL_Sign(hash_data, hash_len, sig, *sig_len, (RsaKey*)key, rng); if (ret > 0) { *sig_len = ret; } break; #endif case WC_SIGNATURE_TYPE_NONE: default: ret = BAD_FUNC_ARG; break; } } if (hash_data) { XFREE(hash_data, NULL, DYNAMIC_TYPE_TMP_BUFFER); } return ret; }
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_ECC_doSign (JNIEnv* jenv, jobject jcl, jobject in, jlong inSz, jobject out, jlongArray outSz, jobject keyDer, jlong keySz) { int ret; RNG rng; ecc_key myKey; unsigned int tmpOut; unsigned int idx = 0; /* check in and key sz */ if ((inSz < 0) || (keySz < 0)) { return -1; } /* get pointers to our buffers */ unsigned char* inBuf = (*jenv)->GetDirectBufferAddress(jenv, in); if (inBuf == NULL) { printf("problem getting in buffer address\n"); return -1; } unsigned char* outBuf = (*jenv)->GetDirectBufferAddress(jenv, out); if (outBuf == NULL) { printf("problem getting out buffer address\n"); return -1; } unsigned char* keyBuf = (*jenv)->GetDirectBufferAddress(jenv, keyDer); if (keyBuf == NULL) { printf("problem getting key buffer address\n"); return -1; } /* set previous value of outSz */ jlong tmp; (*jenv)->GetLongArrayRegion(jenv, outSz, 0, 1, &tmp); tmpOut = (unsigned int)tmp; wc_InitRng(&rng); wc_ecc_init(&myKey); ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &myKey, keySz); if (ret == 0) { ret = wc_ecc_sign_hash(inBuf, (unsigned int)inSz, outBuf, &tmpOut, &rng, &myKey); if (ret != 0) { printf("wc_ecc_sign_hash failed, ret = %d\n", ret); wc_ecc_free(&myKey); return -1; } } else { printf("wc_EccPrivateKeyDecode failed, ret = %d\n", ret); return -1; } wc_ecc_free(&myKey); (*jenv)->SetLongArrayRegion(jenv, outSz, 0, 1, (jlong*)&tmpOut); return ret; }