<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<p class="msipheaderdf3d92d6" align="Left" style="margin:0"><span style="font-size:10.0pt;font-family:Arial;color:#0000FF">[AMD Official Use Only - General]</span></p>
<br>
<div class="WordSection1">
<p class="MsoNormal">Hello everyone,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I am currently working on updating a signature verification function in C++ and I am a bit stuck. I am trying to replace the deprecated 1.1.1 functions to the appropriate 3.0 versions. The function takes in 2 certificate objects (parent
 and cert), which are not x509 certificates, but certificates the company had previously defined. Using the contents from parent we create an RSA public key and using the contents from cert we create the digest and grab the signature to verify.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">In the 1.1.1 version we were using the RSA Object and the rsa_set0_key function to create the RSA public key and then used RSA_public_decrypt to decrypt the signature and RSA_verify_PKCS1_PSS to verify it. This whole workflow is now deprecated.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">//OPENSSL 1.1.1 Code<o:p></o:p></p>
<p class="MsoNormal">SEV_ERROR_CODE AMDCert::amd_cert_validate_sig(const amd_cert *cert,<o:p></o:p></p>
<p class="MsoNormal">                                              const amd_cert *parent,<o:p></o:p></p>
<p class="MsoNormal">                                              ePSP_DEVICE_TYPE device_type)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">    SEV_ERROR_CODE cmd_ret = ERROR_INVALID_CERTIFICATE;<o:p></o:p></p>
<p class="MsoNormal">    hmac_sha_256 sha_digest_256;<o:p></o:p></p>
<p class="MsoNormal">    hmac_sha_512 sha_digest_384;<o:p></o:p></p>
<p class="MsoNormal">    SHA_TYPE algo = SHA_TYPE_256;<o:p></o:p></p>
<p class="MsoNormal">    uint8_t *sha_digest = NULL;<o:p></o:p></p>
<p class="MsoNormal">    size_t sha_length = 0;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    RSA *rsa_pub_key = NULL;<o:p></o:p></p>
<p class="MsoNormal">    BIGNUM *modulus = NULL;<o:p></o:p></p>
<p class="MsoNormal">    BIGNUM *pub_exp = NULL;<o:p></o:p></p>
<p class="MsoNormal">    EVP_MD_CTX* md_ctx = NULL;<o:p></o:p></p>
<p class="MsoNormal">    uint32_t sig_len = cert->modulus_size/8;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    uint32_t digest_len = 0;<o:p></o:p></p>
<p class="MsoNormal">    uint8_t decrypted[AMD_CERT_KEY_BYTES_4K] = {0}; // TODO wrong length<o:p></o:p></p>
<p class="MsoNormal">    uint8_t signature[AMD_CERT_KEY_BYTES_4K] = {0};<o:p></o:p></p>
<p class="MsoNormal">    uint32_t fixed_offset = offsetof(amd_cert, pub_exp);    // 64 bytes<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    do {<o:p></o:p></p>
<p class="MsoNormal">        if (!cert || !parent) {<o:p></o:p></p>
<p class="MsoNormal">            cmd_ret = ERROR_INVALID_PARAM;<o:p></o:p></p>
<p class="MsoNormal">           break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Set SHA_TYPE to 256 bit or 384 bit depending on device_type<o:p></o:p></p>
<p class="MsoNormal">        if (device_type == PSP_DEVICE_TYPE_NAPLES) {<o:p></o:p></p>
<p class="MsoNormal">            algo = SHA_TYPE_256;<o:p></o:p></p>
<p class="MsoNormal">            sha_digest = sha_digest_256;<o:p></o:p></p>
<p class="MsoNormal">            sha_length = sizeof(hmac_sha_256);<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">        else /*if (ROME/MILAN)*/ {<o:p></o:p></p>
<p class="MsoNormal">            algo = SHA_TYPE_384;<o:p></o:p></p>
<p class="MsoNormal">            sha_digest = sha_digest_384;<o:p></o:p></p>
<p class="MsoNormal">            sha_length = sizeof(hmac_sha_512);<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Memzero all the buffers<o:p></o:p></p>
<p class="MsoNormal">        memset(sha_digest, 0, sha_length);<o:p></o:p></p>
<p class="MsoNormal">        memset(decrypted, 0, sizeof(decrypted));<o:p></o:p></p>
<p class="MsoNormal">        memset(signature, 0, sizeof(signature));<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // New up the RSA key<o:p></o:p></p>
<p class="MsoNormal">        rsa_pub_key = RSA_new();<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Convert the parent to an RSA key to pass into RSA_verify<o:p></o:p></p>
<p class="MsoNormal">        modulus = BN_lebin2bn((uint8_t *)&parent->modulus, parent->modulus_size/8, NULL);  // n    // New's up BigNum<o:p></o:p></p>
<p class="MsoNormal">        pub_exp = BN_lebin2bn((uint8_t *)&parent->pub_exp, parent->pub_exp_size/8, NULL);   // e<o:p></o:p></p>
<p class="MsoNormal">        if (RSA_set0_key(rsa_pub_key, modulus, pub_exp, NULL) != 1)<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        <o:p></o:p></p>
<p class="MsoNormal">                             // Create digest from certificate<o:p></o:p></p>
<p class="MsoNormal">        md_ctx = EVP_MD_CTX_create();<o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestInit(md_ctx, (algo == SHA_TYPE_256) ? EVP_sha256() : EVP_sha384()) <= 0)<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestUpdate(md_ctx, cert, fixed_offset) <= 0)     // Calls SHA256_UPDATE<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestUpdate(md_ctx, &cert->pub_exp, cert->pub_exp_size/8) <= 0)<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestUpdate(md_ctx, &cert->modulus, cert->modulus_size/8) <= 0)<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        EVP_DigestFinal(md_ctx, sha_digest, &digest_len);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Swap the bytes of the signature<o:p></o:p></p>
<p class="MsoNormal">        memcpy(signature, &cert->sig, parent->modulus_size/8);<o:p></o:p></p>
<p class="MsoNormal">        if (!sev::reverse_bytes(signature, parent->modulus_size/8))<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Now we will verify the signature. Start by a RAW decrypt of the signature<o:p></o:p></p>
<p class="MsoNormal">        if (RSA_public_decrypt(sig_len, signature, decrypted, rsa_pub_key, RSA_NO_PADDING) == -1)<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Verify the data<o:p></o:p></p>
<p class="MsoNormal">        // SLen of -2 means salt length is recovered from the signature<o:p></o:p></p>
<p class="MsoNormal">        if (RSA_verify_PKCS1_PSS(rsa_pub_key, sha_digest,<o:p></o:p></p>
<p class="MsoNormal">                                (algo == SHA_TYPE_256) ? EVP_sha256() : EVP_sha384(),<o:p></o:p></p>
<p class="MsoNormal">                                decrypted, -2) != 1)<o:p></o:p></p>
<p class="MsoNormal">        {<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        cmd_ret = STATUS_SUCCESS;<o:p></o:p></p>
<p class="MsoNormal">    } while (0);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    // Free the keys and contexts<o:p></o:p></p>
<p class="MsoNormal">    if (rsa_pub_key)<o:p></o:p></p>
<p class="MsoNormal">        RSA_free(rsa_pub_key);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    if (md_ctx)<o:p></o:p></p>
<p class="MsoNormal">        EVP_MD_CTX_free(md_ctx);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    return cmd_ret;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">My current attempt to do this update is first creating an EVP_PKEY object which will now store the public key and inputting the same data from parent by using the EVP_PKEY_fromdata generation function. I build my OSSL_PARAMETERS using OSSL_PARAM_BLD
 to which I push the data from parent. Lastly for the verification I am using the EVP_DigestVerifyFinal procedure. I create the digest using EVP_DigestVerifyInit and EVP_DigestVerifyUpdate and passing in the same data from cert that we were using in the 1.1.1
 version of the function. I have tried different approaches to both creating the key and the verification procedure, but I cannot seem to get it to work.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">// OPENSSL 3.0 code<o:p></o:p></p>
<p class="MsoNormal">SEV_ERROR_CODE AMDCert::amd_cert_validate_sig(const amd_cert *cert,<o:p></o:p></p>
<p class="MsoNormal">                                              const amd_cert *parent,<o:p></o:p></p>
<p class="MsoNormal">                                              ePSP_DEVICE_TYPE device_type)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">    SEV_ERROR_CODE cmd_ret = ERROR_INVALID_CERTIFICATE;<o:p></o:p></p>
<p class="MsoNormal">    hmac_sha_256 sha_digest_256;<o:p></o:p></p>
<p class="MsoNormal">    hmac_sha_512 sha_digest_384;<o:p></o:p></p>
<p class="MsoNormal">    SHA_TYPE algo = SHA_TYPE_256;<o:p></o:p></p>
<p class="MsoNormal">    uint8_t *sha_digest = NULL;<o:p></o:p></p>
<p class="MsoNormal">    size_t sha_length = 0;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    EVP_PKEY *rsa_pub_key = EVP_PKEY_new();<o:p></o:p></p>
<p class="MsoNormal">    RSA *old_rsa_pub_key = NULL;<o:p></o:p></p>
<p class="MsoNormal">    BIGNUM *modulus = NULL;<o:p></o:p></p>
<p class="MsoNormal">    BIGNUM *pub_exp = NULL;<o:p></o:p></p>
<p class="MsoNormal">    EVP_PKEY_CTX *key_gen_ctx = NULL;<o:p></o:p></p>
<p class="MsoNormal">    uint32_t sig_len = cert->modulus_size/8;<o:p></o:p></p>
<p class="MsoNormal">    EVP_MD_CTX* verify_md_ctx = NULL;<o:p></o:p></p>
<p class="MsoNormal">    uint32_t digest_len = 0;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    uint8_t signature[AMD_CERT_KEY_BYTES_4K] = {0};<o:p></o:p></p>
<p class="MsoNormal">    uint32_t fixed_offset = offsetof(amd_cert, pub_exp);    // 64 bytes<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    do {<o:p></o:p></p>
<p class="MsoNormal">        if (!cert || !parent) {<o:p></o:p></p>
<p class="MsoNormal">            cmd_ret = ERROR_INVALID_PARAM;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Set SHA_TYPE to 256 bit or 384 bit depending on device_type<o:p></o:p></p>
<p class="MsoNormal">        if (device_type == PSP_DEVICE_TYPE_NAPLES) {<o:p></o:p></p>
<p class="MsoNormal">            algo = SHA_TYPE_256;<o:p></o:p></p>
<p class="MsoNormal">            sha_digest = sha_digest_256;<o:p></o:p></p>
<p class="MsoNormal">            sha_length = sizeof(hmac_sha_256);<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">        else /*if (ROME/MILAN)*/ {<o:p></o:p></p>
<p class="MsoNormal">            algo = SHA_TYPE_384;<o:p></o:p></p>
<p class="MsoNormal">            sha_digest = sha_digest_384;<o:p></o:p></p>
<p class="MsoNormal">            sha_length = sizeof(hmac_sha_512);<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Memzero all the buffers<o:p></o:p></p>
<p class="MsoNormal">        memset(sha_digest, 0, sha_length);<o:p></o:p></p>
<p class="MsoNormal">        memset(signature, 0, sizeof(signature));<o:p></o:p></p>
<p class="MsoNormal">        <o:p></o:p></p>
<p class="MsoNormal">        //Convert the parent to an RSA key to pass into EVP_DigesetVerify<o:p></o:p></p>
<p class="MsoNormal">        modulus = BN_lebin2bn((uint8_t *)&parent->modulus, parent->modulus_size/8, NULL);  // n    // New's up BigNum<o:p></o:p></p>
<p class="MsoNormal">        pub_exp = BN_lebin2bn((uint8_t *)&parent->pub_exp, parent->pub_exp_size/8, NULL);   // e<o:p></o:p></p>
<p class="MsoNormal">                             <o:p></o:p></p>
<p class="MsoNormal">        // Creating parameter build<o:p></o:p></p>
<p class="MsoNormal">        OSSL_PARAM_BLD *params_build = OSSL_PARAM_BLD_new();<o:p></o:p></p>
<p class="MsoNormal">        if ( params_build == NULL ) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Init fails " << endl;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Push modulus<o:p></o:p></p>
<p class="MsoNormal">        if ( !OSSL_PARAM_BLD_push_BN(params_build, "n", modulus) ) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Error: failed to push modulus into param build." << endl;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Push pub_exp<o:p></o:p></p>
<p class="MsoNormal">        if ( !OSSL_PARAM_BLD_push_BN(params_build, "e", pub_exp) ) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Error: failed to push exponent into param build." << endl;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">                             <o:p></o:p></p>
<p class="MsoNormal">        // Build parameters<o:p></o:p></p>
<p class="MsoNormal">        OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(params_build);<o:p></o:p></p>
<p class="MsoNormal">        if ( params == NULL ) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Error: building parameters." << endl;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">              }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Free BLD struct<o:p></o:p></p>
<p class="MsoNormal">        OSSL_PARAM_BLD_free(params_build);<o:p></o:p></p>
<p class="MsoNormal">                             <o:p></o:p></p>
<p class="MsoNormal">        // Create key_gen context<o:p></o:p></p>
<p class="MsoNormal">        key_gen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        //EVP_PKEY_keygen_init(pctx);<o:p></o:p></p>
<p class="MsoNormal">        if(EVP_PKEY_fromdata_init(key_gen_ctx) != 1) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "failed to initialize key creation." << endl;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">        <o:p></o:p></p>
<p class="MsoNormal">        // Generate rsa public key<o:p></o:p></p>
<p class="MsoNormal">        if(EVP_PKEY_fromdata(key_gen_ctx, &rsa_pub_key, EVP_PKEY_PUBLIC_KEY, params) != 1) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "key generation breaks" << endl;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">                             <o:p></o:p></p>
<p class="MsoNormal">        // Free PARAM structure<o:p></o:p></p>
<p class="MsoNormal">        OSSL_PARAM_free(params);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Swap the bytes of the signature<o:p></o:p></p>
<p class="MsoNormal">        memcpy(signature, &cert->sig, parent->modulus_size/8);<o:p></o:p></p>
<p class="MsoNormal">        if (!sev::reverse_bytes(signature, parent->modulus_size/8))<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        // Create digest context<o:p></o:p></p>
<p class="MsoNormal">        verify_md_ctx = EVP_MD_CTX_create();<o:p></o:p></p>
<p class="MsoNormal">        <o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        if (!verify_md_ctx) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Error allocating pkey context " << endl;;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">        <o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestVerifyInit(verify_md_ctx, NULL, (algo == SHA_TYPE_256) ? EVP_sha256() : EVP_sha384(), NULL, rsa_pub_key) <= 0) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Init fails " << endl;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">                <o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestVerifyUpdate(verify_md_ctx, cert, fixed_offset) <= 0)     // Calls SHA256_UPDATE<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestVerifyUpdate(verify_md_ctx, &cert->pub_exp, cert->pub_exp_size/8) <= 0)<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        if (EVP_DigestVerifyUpdate(verify_md_ctx, &cert->modulus, cert->modulus_size/8) <= 0)<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">                <o:p></o:p></p>
<p class="MsoNormal">        // Get Verify return<o:p></o:p></p>
<p class="MsoNormal">        int ret = EVP_DigestVerifyFinal(verify_md_ctx,signature,sig_len);<o:p></o:p></p>
<p class="MsoNormal">        if (ret == 0) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Verify digest fails" << endl;<o:p></o:p></p>
<p class="MsoNormal">            break; <o:p></o:p></p>
<p class="MsoNormal">        } else if (ret < 0) {<o:p></o:p></p>
<p class="MsoNormal">            cout << "Verify error" << endl;<o:p></o:p></p>
<p class="MsoNormal">            break;<o:p></o:p></p>
<p class="MsoNormal">        }<o:p></o:p></p>
<p class="MsoNormal">        <o:p></o:p></p>
<p class="MsoNormal">        cmd_ret = STATUS_SUCCESS;<o:p></o:p></p>
<p class="MsoNormal">    } while (0);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    // Free the keys and contexts<o:p></o:p></p>
<p class="MsoNormal">    if (rsa_pub_key)<o:p></o:p></p>
<p class="MsoNormal">        EVP_PKEY_free(rsa_pub_key);<o:p></o:p></p>
<p class="MsoNormal">    if (key_gen_ctx)<o:p></o:p></p>
<p class="MsoNormal">        EVP_PKEY_CTX_free(key_gen_ctx);<o:p></o:p></p>
<p class="MsoNormal">    if (verify_md_ctx)<o:p></o:p></p>
<p class="MsoNormal">        EVP_MD_CTX_free(verify_md_ctx);<o:p></o:p></p>
<p class="MsoNormal">    <o:p></o:p></p>
<p class="MsoNormal">    return cmd_ret;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Is this the correct way of creating RSA keys now? Where is my logic failing? Can the same type of procedure even be done on 3.0? Any advice would be really appreciated.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thank you in advance,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b><span lang="ES-MX" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black">Diego Gonzalez Villalobos</span></b><span lang="ES-MX" style="font-size:10.0pt;font-family:"Arial",sans-serif;color:black"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:"Arial",sans-serif;color:black">Software System Designer I</span><span style="font-family:"Arial",sans-serif;color:black"><o:p></o:p></span></p>
</div>
</body>
</html>