Regarding how to use symmetric key for an openssl engine

2022-09-29 Thread 董亚敏 via openssl-users
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

2022-09-29 Thread Lynch, Pat
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

2022-09-29 Thread Jay Foster
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

2022-09-29 Thread GonzalezVillalobos, Diego via openssl-users
[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

2022-09-29 Thread Cyprus Socialite
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

2022-09-29 Thread Tomas Mraz
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,
>