Regarding how to use symmetric key for an openssl engine
Hi, Here is question,can you help me out? Thanks. Background: I am working to write an openssl engine to use cryptographic algorithm in a hardware device. The hardware device support asymmetric/symmetric algorithm, for example:rsa/aes. Question: When I write openssl engine, I shall use ENGINE_load_private_key() function to load and use asymmetric private key in the hardware device. How to set and use symmetric key in the hardware device ? is there any example for my case? #/**本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件! This e-mail and its attachments contain confidential information from XIAOMI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!**/#
RE: CA/Server configuration
Hello Cyprus, I’m not exactly what you’d call an expert on openssl, but I do use it frequently. There is a very good openssl wrapper project called EasyRSA that I highly recommend. We put together a very simple Certificate Authority for application testing using this package and it made things much easier. You can find it here: https://github.com/OpenVPN/easy-rsa Now to address your questions… First, -config allows you to specify a configuration file to use for the operation – from the OpenSsl documentation: (https://www.openssl.org/docs/man1.1.1/man1/openssl.html) Many commands use an external configuration file for some or all of their arguments and have a -config option to specify that file. The -extensions option allows you to provide certain configuration options (called extensions) on the command line instead of in a configuration file. These extensions are typically within the realm of X509 (certificates, CSRs, CRLs and the like). For example there is an Extended Key Usage extension - see https://www.openssl.org/docs/man1.1.1/man5/x509v3_config.html Second, depending on the operation and the specific configuration field, the lack of a value might result in a default value being used or it might cause the absence of the resulting field in the result of the operation. For example, if you don’t specify the digest when running openssl req it defaults to sha256 (but that also depends on the specified public key algorithm). In contrast, if you don’t specify the OCSP responder URI when signing a CSR there will not be an OCSP responder URI in the resulting signed certificate. Is it possible to create an unusable certificate with openssl? Probably. But, in general, it’s the application that is conducting the validation of your certificates that determines whether the certificate is rejected. An application might accept the certificate without any revocation checking extensions (CRL or OCSP) or prompt whether to trust it. I guess Windows 10 doesn’t support sha-3* digests and so rejects the certificate. Other operating systems and/or applications might very well accept the same certificate. Third, you’ll need to throw a study on the SSL/TLS protocols to understand how ciphers and digests are used in the communication process (I’m assuming that’s what you mean by communication). Yes, there are multiple ways to perform some operations – welcome to openssl. The differences typically allow for an operation “centric” approach meaning each operation has specific defaults that may differ from other operations or one operation might provide multiple outputs whereas another only provides one as you observed. My advice here is to choose the operation that makes the most sense with respect to the desired end result or the operation that ends up being easier for you to code against. With respect to a configuration reference, here is my go-to: https://www.phildev.net/ssl/opensslconf.html I don’t know whether it’s 100% complete or not but it has served me well. Cheers! -Pat From: openssl-users On Behalf Of Cyprus Socialite Sent: Thursday, September 29, 2022 11:07 AM To: openssl-users@openssl.org Subject: CA/Server configuration CAUTION: Email originated externally. Do not click links or open attachments unless you recognize the sender and know the content is safe. Hello I am looking to clarify some conceptual and practical questions I've accumulated while trying to configure a private 'Root CA - Intermediate CA - Server' setup. Most of my confusion revolves around the configuration of the Intermediate CA due to its role as both a requester and a provider of certificates. The first and perhaps most fundamental thing unclear to me is what the configuration and extensions (provided via -config and -extensions arguments) actually configure and extend. For instance, does `default_ca` specify the parameters of the CA I'm operating, or the CA I'm requesting a certificate from? Does the `[req]` section configure the requests I create or the way I process others' requests (and so the certificates I output)? To further the confusion, the `copy_extensions` setting seems to imply that the extensions exist on both the CA and the requester side! Secondly, how is the absence of a configuration field/section/extension handled? Does it default to some value (e.g. from /etc/ssl/openssl.cnf) or simply remain empty? For example, if I have no interest in OCSP functionality, is the non-provision of all of the related fields enough to prevent my certificates being declared invalid because CRL requests fail? Thirdly, I would like to understand the difference between the 'digest' and the 'cipher' and what roles they perform in the communication process, especially in relation to the actual signing algorithm. As an aside: I've noticed that using any of the `sha3-*` digests somehow prevents Windows 10 from verifying my certificates. Onto more practical
BIO_flush Segmentation Fault Issue
I have an application that constructs a chain of BIOs. Sometimes this chain also includes an SSL BIO. Years ago, I ran into a problem that caused BIO_flush() to segfault on the SSL BIO. This turned out to happen because the SSL BIO is added using SSL_set_bio() instead of BIO_push(). SSL_set_bio() results in the SSL BIO always having a NULL bio_next value, so BIO_flush then crashes dereferencing this NULL pointer when it calls BIO_copy_next_retry() on the SSL BIO (see BIO_CTRL_FLUSH in ssl/bio_ssl.c). This was reported as ticket 2615 years ago. My question is, how could calling BIO_flush() on a BIO chain with an SSL BIO ever work? Is there a way to add the SSL BIO using BIO_push() instead of SSL_set_bio()? Jay
RE: Updating RSA public key generation and signature verification from 1.1.1 to 3.0
[AMD Official Use Only - General] Hello Tomas, So, I made sure that px_size and py_size are equal to the group order (48). I was able to verify successfully using our previous method (deprecated) with the new key generation method, but I'm still not able to get the digestverify to work successfully. As a reminder this is how we were verifying before: // Determine if SHA_TYPE is 256 bit or 384 bit if (parent_cert->pub_key_algo == SEV_SIG_ALGO_RSA_SHA256 || parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA256 ||parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDH_SHA256) { sha_type = SHA_TYPE_256; sha_digest = sha_digest_256; sha_length = sizeof(hmac_sha_256); } else if (parent_cert->pub_key_algo == SEV_SIG_ALGO_RSA_SHA384 || parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA384 || parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDH_SHA384) { sha_type = SHA_TYPE_384; sha_digest = sha_digest_384; sha_length = sizeof(hmac_sha_512); } else { break; } // 1. SHA256 hash the cert from Version through pub_key parameters // Calculate the digest of the input message rsa.c -> rsa_pss_verify_msg() // SHA256/SHA384 hash the cert from the [Version:pub_key] params uint32_t pub_key_offset = offsetof(sev_cert, sig_1_usage); // 16 + sizeof(SEV_PUBKEY) if (!digest_sha((uint8_t *)child_cert, pub_key_offset, sha_digest, sha_length, sha_type)) { break; } if ((parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA256) || (parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA384) || (parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDH_SHA256) || (parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDH_SHA384)) { // ecdsa.c -> sign_verify_msg ECDSA_SIG *tmp_ecdsa_sig = ECDSA_SIG_new(); BIGNUM *r_big_num = BN_new(); BIGNUM *s_big_num = BN_new(); // Store the x and y components as separate BIGNUM objects. The values in the // SEV certificate are little-endian, must reverse bytes before storing in BIGNUM r_big_num = BN_lebin2bn(cert_sig[i].ecdsa.r, sizeof(sev_ecdsa_sig::r), r_big_num);// LE to BE s_big_num = BN_lebin2bn(cert_sig[i].ecdsa.s, sizeof(sev_ecdsa_sig::s), s_big_num); // Calling ECDSA_SIG_set0() transfers the memory management of the values to // the ECDSA_SIG object, and therefore the values that have been passed // in should not be freed directly after this function has been called if (ECDSA_SIG_set0(tmp_ecdsa_sig, r_big_num, s_big_num) != 1) { BN_free(s_big_num); // Frees BIGNUMs manually here BN_free(r_big_num); ECDSA_SIG_free(tmp_ecdsa_sig); continue; } EC_KEY *tmp_ec_key = EVP_PKEY_get1_EC_KEY(parent_signing_key); // Make a local key so you can free it later if (ECDSA_do_verify(sha_digest, (uint32_t)sha_length, tmp_ecdsa_sig, tmp_ec_key) != 1) { EC_KEY_free(tmp_ec_key); ECDSA_SIG_free(tmp_ecdsa_sig); // Frees BIGNUMs too continue; } found_match = true; EC_KEY_free(tmp_ec_key); ECDSA_SIG_free(tmp_ecdsa_sig); // Frees BIGNUMs too break; } Digest sha function: bool digest_sha(const void *msg, size_t msg_len, uint8_t *digest, size_t digest_len, SHA_TYPE sha_type) { bool ret = false; do {//TODO 384 vs 512 is all a mess if ((sha_type == SHA_TYPE_256 && digest_len != SHA256_DIGEST_LENGTH)/* || (sha_type == SHA_TYPE_384 && digest_len != SHA384_DIGEST_LENGTH)*/) break; if (sha_type == SHA_TYPE_256) { SHA256_CTX context; if (SHA256_Init() != 1) break; if (SHA256_Update(, (void *)msg, msg_len) != 1) break; if (SHA256_Final(digest, ) != 1) break; } else if (sha_type == SHA_TYPE_384) { SHA512_CTX context; if (SHA384_Init() != 1) break; if (SHA384_Update(, (void *)msg, msg_len) != 1) break; if (SHA384_Final(digest, ) != 1) break; } ret = true; } while (0); return ret; } This works using the new EC EVP key generation. The current verification method keeps failing: if ((parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA256) || (parent_cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA384) || (parent_cert->pub_key_algo ==
CA/Server configuration
Hello I am looking to clarify some conceptual and practical questions I've accumulated while trying to configure a private 'Root CA - Intermediate CA - Server' setup. Most of my confusion revolves around the configuration of the Intermediate CA due to its role as both a requester and a provider of certificates. The first and perhaps most fundamental thing unclear to me is *what* the configuration and extensions (provided via -config and -extensions arguments) actually configure and extend. For instance, does `default_ca` specify the parameters of the CA I'm operating, or the CA I'm requesting a certificate from? Does the `[req]` section configure the requests I create or the way I process others' requests (and so the certificates I output)? To further the confusion, the `copy_extensions` setting seems to imply that the extensions exist on both the CA and the requester side! Secondly, how is the absence of a configuration field/section/extension handled? Does it default to some value (e.g. from /etc/ssl/openssl.cnf) or simply remain empty? For example, if I have no interest in OCSP functionality, is the non-provision of all of the related fields enough to prevent my certificates being declared invalid because CRL requests fail? Thirdly, I would like to understand the difference between the 'digest' and the 'cipher' and what roles they perform in the communication process, especially in relation to the actual signing algorithm. As an aside: I've noticed that using any of the `sha3-*` digests somehow prevents Windows 10 from verifying my certificates. Onto more practical concerns, I am thoroughly confused by how many OpenSSL tools seemingly perform the same tasks. For example, one can generate a certificate using any one of `req`, `ca`, and `x509 -req`. I understand that some of these have additional functionality, such as generating key, CSR, and certificate all at once, so I would like to know what the go-to lowest-level, DOTADIW tools are for these purposes. At the moment, I am using `genpkey` for, well, private key generation, and `req -new` for the CSR. Finally, if anyone happens to be in possession of an exhaustive configuration file that includes *all* possible sections and fields supported by OpenSSL, I would very much appreciate a copy! I hope I've managed to present my questions clearly enough, but would be happy to provide clarifications if needed. Thanks - “*The nice thing about standards is that there are so many to choose from*” — Andrew S. Tanenbaum
Re: Updating RSA public key generation and signature verification from 1.1.1 to 3.0
Hi, comments below. On Wed, 2022-09-28 at 22:12 +, GonzalezVillalobos, Diego wrote: > [AMD Official Use Only - General] > > Hello Tomas, > > I generated the key as you suggested, and I am no longer getting an > error message! Thank you for that. Here is how I'm generating the key > now: > > // SEV certificate are little-endian, must reverse bytes before > generating key > if ((cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA256) || > (cert->pub_key_algo == SEV_SIG_ALGO_ECDSA_SHA384)) { > //Grab x param and flip bytes to BE > memcpy(px, >pub_key.ecdsa.qx, ec_group_order); > if(!sev::reverse_bytes(px, sizeof(px))) > break; > //Grab y param and flip bytes to BE > memcpy(py, >pub_key.ecdsa.qy, ec_group_order); > if(!sev::reverse_bytes(py, sizeof(py))) > break; > } > else if ((cert->pub_key_algo == > SEV_SIG_ALGO_ECDH_SHA256) || > (cert->pub_key_algo == SEV_SIG_ALGO_ECDH_SHA384)) > { > //Grab x param and flip bytes to BE > memcpy(px, >pub_key.ecdh.qx, ec_group_order); > if(!sev::reverse_bytes(px, sizeof(px))) > break; > //Grab y param and flip bytes to BE > memcpy(py, >pub_key.ecdh.qy, ec_group_order); > if(!sev::reverse_bytes(py, sizeof(py))) > break; > } > > int px_size = sizeof(px)/sizeof(*px); > int py_size = sizeof(py)/sizeof(*py); > > // Will contain x and y components > unsigned char public_key_xy[1 + px_size + py_size] = {0}; > > //Add point conversion as first value > public_key_xy[0] = POINT_CONVERSION_UNCOMPRESSED; > > //Add x components after point compression > memcpy(public_key_xy + 1, px, px_size); > //Add y components after x > memcpy(public_key_xy + px_size + 1, py ,py_size); > > // int nid = EC_curve_nist2nid("P-384"); // > NID_secp384r1 > > OSSL_PARAM_BLD *params_build = OSSL_PARAM_BLD_new(); > > if ( params_build == NULL ) { > cout << "Params build fails" << endl; > break; > } > > if (!OSSL_PARAM_BLD_push_utf8_string(params_build, > OSSL_PKEY_PARAM_GROUP_NAME, "P-384", 0)) { > cout<< "Push EC curve to build fails" << endl; > break; > } > > if (!OSSL_PARAM_BLD_push_octet_string(params_build, > OSSL_PKEY_PARAM_PUB_KEY, public_key_xy, sizeof(public_key_xy))) { > cout << "Error: failed to push qx into param build." > << endl; > break; > } > > OSSL_PARAM *params = > OSSL_PARAM_BLD_to_param(params_build); > > if ( params == NULL ) { > cout << "Error: building parameters." << endl; > break; > } > > OSSL_PARAM_BLD_free(params_build); > > key_gen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); > > if(EVP_PKEY_fromdata_init(key_gen_ctx) != 1) { > cout << "failed to initialize key creation." << endl; > break; > } > > if(EVP_PKEY_fromdata(key_gen_ctx, _pub_key, > EVP_PKEY_PUBLIC_KEY, params) != 1) { > cout << "key generation breaks" << endl; > printf("Failed Final Verify > %s\n",ERR_error_string(ERR_get_error(),NULL)); > break; > } > > if (EVP_PKEY_get_base_id(evp_pub_key) != EVP_PKEY_EC) { > cout << "wrong key type" << endl; > break; > } > } > > if (!evp_pub_key) { > cout << "no evp pkey" << endl; > break; > } > cout << "compile key succesful" << endl; > cmd_ret = STATUS_SUCCESS; > > Although the key generation works and I'm not getting a verify error > anymore, I am still unsuccessful on verifying the digest. It keeps > failing (returning 0). Here is how I'm currently trying to do the > verification. Are you sure the px_size and py_size is equal to the group order? The x and y values must be padded to the group order with 0 (at the start because the values need to be BE). > ECDSA_SIG *tmp_ecdsa_sig = ECDSA_SIG_new(); > BIGNUM *r_big_num = BN_new(); > BIGNUM *s_big_num = BN_new(); > uint32_t sig_len; > unsigned char* der_sig; > > // Store the x and y components as separate BIGNUM > objects. The values in the > // SEV certificate are little-endian, must reverse > bytes before storing in BIGNUM > r_big_num = BN_lebin2bn(cert_sig[i].ecdsa.r, >