bool ECDSA_Sign(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { EC_KEY * eckey = NULL; byte rgbDigest[EVP_MAX_MD_SIZE]; unsigned int cbDigest = sizeof(rgbDigest); byte * pbSig = NULL; const EVP_MD * digest; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pSigner->m_allocContext; #endif cn_cbor * p = NULL; ECDSA_SIG * psig = NULL; cn_cbor_errback cbor_error; int cbR; byte rgbSig[66]; int cb; eckey = ECKey_From(pKey, &cbR, perr); if (eckey == NULL) { errorReturn: if (p != NULL) CN_CBOR_FREE(p, context); if (eckey != NULL) EC_KEY_free(eckey); return false; } switch (cbitDigest) { case 256: digest = EVP_sha256(); break; case 512: digest = EVP_sha512(); break; case 384: digest = EVP_sha384(); break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL); psig = ECDSA_do_sign(rgbDigest, cbDigest, eckey); CHECK_CONDITION(psig != NULL, COSE_ERR_CRYPTO_FAIL); pbSig = COSE_CALLOC(cbR, 2, context); CHECK_CONDITION(pbSig != NULL, COSE_ERR_OUT_OF_MEMORY); cb = BN_bn2bin(psig->r, rgbSig); CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER); memcpy(pbSig + cbR - cb, rgbSig, cb); cb = BN_bn2bin(psig->s, rgbSig); CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER); memcpy(pbSig + 2*cbR - cb, rgbSig, cb); p = cn_cbor_data_create(pbSig, cbR*2, CBOR_CONTEXT_PARAM_COMMA &cbor_error); CHECK_CONDITION_CBOR(p != NULL, cbor_error); CHECK_CONDITION(_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR); return true; }
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { mbedtls_ecp_keypair keypair; mbedtls_mpi r; mbedtls_mpi s; mbedtls_md_type_t mdType; const mbedtls_md_info_t *pmdInfo; byte rgbDigest[MBEDTLS_MD_MAX_SIZE]; cn_cbor * pSig; bool result = false; mbedtls_ecp_keypair_init(&keypair); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn; switch(cbitDigest) { case 256: mdType = MBEDTLS_MD_SHA256; break; case 384: mdType = MBEDTLS_MD_SHA384; break; case 512: mdType = MBEDTLS_MD_SHA512; break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } pmdInfo = mbedtls_md_info_from_type(mdType); CHECK_CONDITION(pmdInfo != NULL, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_md(pmdInfo, rgbToSign, cbToSign, rgbDigest) == 0, COSE_ERR_INVALID_PARAMETER); pSig = _COSE_arrayget_int(pSigner, index); CHECK_CONDITION((pSig != NULL) && (pSig->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_mpi_read_binary( &r, pSig->v.bytes, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_mpi_read_binary( &s, pSig->v.bytes + pSig->length / 2, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_ecdsa_verify(&keypair.grp, rgbDigest, mbedtls_md_get_size(pmdInfo), &keypair.Q, &r, &s) == 0, COSE_ERR_CRYPTO_FAIL); result = true; errorReturn: mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecp_keypair_free(&keypair); return result; }
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { EC_KEY * eckey = NULL; byte rgbDigest[EVP_MAX_MD_SIZE]; unsigned int cbDigest = sizeof(rgbDigest); const EVP_MD * digest; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pSigner->m_allocContext; #endif cn_cbor * p = NULL; ECDSA_SIG sig = { NULL, NULL }; int cbR; cn_cbor * pSig; size_t cbSignature; eckey = ECKey_From(pKey, &cbR, perr); if (eckey == NULL) { errorReturn: if (sig.r != NULL) BN_free(sig.r); if (sig.s != NULL) BN_free(sig.s); if (p != NULL) CN_CBOR_FREE(p, context); if (eckey != NULL) EC_KEY_free(eckey); return false; } switch (cbitDigest) { case 256: digest = EVP_sha256(); break; case 512: digest = EVP_sha512(); break; case 384: digest = EVP_sha384(); break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL); pSig = _COSE_arrayget_int(pSigner, index); CHECK_CONDITION(pSig != NULL, CN_CBOR_ERR_INVALID_PARAMETER); cbSignature = pSig->length; CHECK_CONDITION(cbSignature / 2 == cbR, COSE_ERR_INVALID_PARAMETER); sig.r = BN_bin2bn(pSig->v.bytes,(int) cbSignature/2, NULL); sig.s = BN_bin2bn(pSig->v.bytes+cbSignature/2, (int) cbSignature/2, NULL); CHECK_CONDITION(ECDSA_do_verify(rgbDigest, cbDigest, &sig, eckey) == 1, COSE_ERR_CRYPTO_FAIL); BN_free(sig.r); BN_free(sig.s); if (eckey != NULL) EC_KEY_free(eckey); return true; }
bool ECDSA_Sign(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { #if defined(MBEDTLS_ECDSA_DETERMINISTIC) byte rgbDigest[MBEDTLS_MD_MAX_SIZE]; uint8_t * pbSig = NULL; cn_cbor_errback cbor_error; int cbR; mbedtls_md_type_t mdType; const mbedtls_md_info_t *pmdInfo; mbedtls_ecp_keypair keypair; mbedtls_mpi r; mbedtls_mpi s; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pSigner->m_allocContext; #endif cn_cbor * p = NULL; bool result = false; mbedtls_ecp_keypair_init(&keypair); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn; CHECK_CONDITION(keypair.d.n != 0, COSE_ERR_INVALID_PARAMETER); switch(cbitDigest) { case 256: mdType = MBEDTLS_MD_SHA256; break; case 384: mdType = MBEDTLS_MD_SHA384; break; case 512: mdType = MBEDTLS_MD_SHA512; break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } pmdInfo = mbedtls_md_info_from_type(mdType); CHECK_CONDITION(pmdInfo != NULL, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_md(pmdInfo, rgbToSign, cbToSign, rgbDigest) == 0, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_ecdsa_sign_det(&keypair.grp, &r, &s, &keypair.d, rgbDigest, mbedtls_md_get_size(pmdInfo), mdType) == 0, COSE_ERR_CRYPTO_FAIL); cbR = (keypair.grp.nbits + 7) / 8; pbSig = COSE_CALLOC(cbR, 2, context); CHECK_CONDITION(pbSig != NULL, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_mpi_write_binary(&r, pbSig, cbR) == 0, COSE_ERR_INTERNAL); CHECK_CONDITION(mbedtls_mpi_write_binary(&s, pbSig + cbR, cbR) == 0, COSE_ERR_INTERNAL); p = cn_cbor_data_create(pbSig, cbR*2, CBOR_CONTEXT_PARAM_COMMA &cbor_error); CHECK_CONDITION_CBOR(p != NULL, cbor_error); CHECK_CONDITION(_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR); p = NULL; pbSig = NULL; result = true; errorReturn: cn_cbor_free(p CBOR_CONTEXT_PARAM); COSE_FREE(pbSig, context); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecp_keypair_free(&keypair); return result; #else return false; #endif }