The implementation of ECC algorithm analysis--OPENSSL and its invocation process

Source: Internet
Author: User
Tags abstract openssl

ECC process is very different from RSA, ECC involves a lot of additional concepts, such as group and so on, in addition ECC contains two different sets of mechanisms, this is ECDSA and ECDH, these two sets of mechanisms unified in ECC, in non-ECC algorithm, These two sets of mechanisms are implemented by two independent algorithms, such as for the encryption/decryption and signature/verification of the requirements of the use of RSA,DSA, for the requirements of key negotiation is the use of DH, how to unify these two types of algorithms in a structure is similar to the framework of OpenSSL, such as the need to solve the problem, OpenSSL puts all the information about the "key" in a struct, which is Evp_pkey, which includes the key itself and the operations on those keys, the most important of which are operations such as generating a key and verifying the signature. Because the key operation is only a few standards, the various institutions can have their own customized implementation, so the role of the engine is reflected, according to Oo point of view, the engine encapsulated in the key is a good design, because almost all cryptographic decryption signature verification operations are around key, So the engine is almost all in the key-related structure, and for the symmetric algorithm, the engine specifically provides a mechanism, detailed information is described earlier.
struct EVP_PKEY_ST
{
int type;
int save_type;
int references;
union{
Char *ptr;
#ifndef Openssl_no_rsa
struct Rsa_st *rsa; /* RSA */
#endif
...
#ifndef OPENSSL_NO_EC
struct Ec_key_st *ec; /* ECC */
#endif
} Pkey;
int save_parameters;
Stack_of (X509_attribute) *attributes; /* [0] */
...
}
For RSA it is very simple, one of the following rsa_st enough to hold all the data and operations, including the public key, the private key, sign,verify and so on:
struct RSA_ST
{
int pad;
Long version;
Const Rsa_method *meth; The method that can be overloaded, all the operations about RSA are all in this meth.
/* Functional Reference if ' meth ' is engine-provided */
ENGINE *engine; The current engine, which contains a rsa_methed, the methed can overload the meth above
Bignum *n;
Bignum *e;
Bignum *d;
Bignum *p;
Bignum *q;
Bignum *DMP1;
Bignum *dmq1;
Bignum *iqmp;
...
}
But for ECC it is not so simple, although it also has a similar RSA_ST ec_key_st structure, it is obvious that this structure is stored in the information about the key or the key itself and the operation of the key, but this structure to serve two mechanisms, is the key negotiation algorithm and the public/private key algorithm (or called the signature algorithm, because almost no ECC ECDSA for encryption/decryption and digital envelope), a feasible but unreasonable organization is to all of these two kinds of algorithms all the operation functions in a struct such as called ecc_ Methed_st, and then add this structure to the engine structure, exactly like RSA, although seemingly concise, but it is not reasonable, because the signature algorithm and the key negotiation algorithm is not very close, forcing them to glue together there are many problems, For example, an engine realizes a ECC signature algorithm using its own hardware encryption card, but he does not want to control what key negotiations and other things, so in order to ecc_methed_st the integrity of the structure, he had to get ECC for key negotiation of the default implementation, Then join in the Ecc_methed_st, this kind of work can be avoided by better design. So the two separate, so that they belong to two engine, that is, different engine management of different algorithms, so there is the following structure:
typedef struct ECDH_DATA_ST {
/* Ec_key_meth_data Part */
Int (*init) (Ec_key *);
/* Method Specific part */
ENGINE *engine;
int flags;
Const Ecdh_method *meth;
Crypto_ex_data Ex_data;
} Ecdh_data;
typedef struct ECDSA_DATA_ST {
/* Ec_key_meth_data Part */
Int (*init) (Ec_key *);
/* Method (ECDSA) specific part */
ENGINE *engine;
int flags;
Const Ecdsa_method *meth;
Crypto_ex_data Ex_data;
} Ecdsa_data;
It can be seen that these two structures are very similar to RSA, in order not to touch the fine structure of the evp_pkey, it is necessary to have an equally well-designed ec_key_st structure, the structure can be dynamically determined to use Ecdh_data or use Ecdsa_data, That is, the role of an engine switch, from the design level to understand Ec_key_st, its content is actually ECDH and ECDSA public information, according to the principle of ECC, their public information is a public key and a private key, the difference is the operation of the public key and use, And these operations and uses will be reflected in the engine, so there are the following structure:
struct Ec_key_st {
int version;
Ec_group *group; Curve Group, which is the core concept of ECC
Ec_point *pub_key; Public key, in ECC, hunch over is a "point" on a curve.
Bignum *priv_key; Private key, in ECC, the private key is a large number, multiplied by this large number and "base point" to get the public key
unsigned int enc_flag;
Point_conversion_form_t Conv_form;
int references;
Ec_extra_data *method_data; This structure is dynamically determined to be DH or DSA or something else. Note 0
}/* Ec_key */;
Note 0 said there would be something else, what that means. The Ec_key_st method_data field is actually a linked list:
typedef struct EC_EXTRA_DATA_ST {
struct Ec_extra_data_st *next;
void *data; This data is the Ecdsa_data or ecdh_data of the above and the other methed
void * (*DUP_FUNC) (void *);
void (*free_func) (void *);
void (*clear_free_func) (void *);
} Ec_extra_data; /* Used in Ec_group */
Since Method_data is a dynamic decision, then who decides what method it is, which is actually determined by the caller, because through the program execution process can know what needs to be done at this time, then you can get the corresponding method_data structure, Then it can be handed to the engine of the method to implement the function.
Next, use a practical process to experience the execution of OpenSSL for ECC signature validation:
The 1.openssl command is followed by the verify parameter, followed by the CA certificate and the user certificate;
2. Enter VERIFY.C, extract the certificate, verify the certificate chain (see preceding), extract the signature algorithm, extract the public key;
3.x509_get_pubkey get Evp_pkey structure. According to the X509 structure can get the signature algorithm and the public key itself, and then according to the OID of the signature algorithm can get the corresponding key type, and then:
else if (Ret->type = = Evp_pkey_ec) {
if (a->parameter && (A->parameter->type = = v_asn1_sequence)) {
if ((ret->pkey.ec= ec_key_new ()) = = NULL)//Initialize Ec_key_st
...
4. Enter x509_verify to verify the signature, first need to re-make a summary of the signed message, and then verify that the logic of the function asn1_item_verify very clear, the principle of depth first into the asn1_item_verify and deep understanding of:
int asn1_item_verify (const asn1_item *it, X509_algor *a, asn1_bit_string *signature, void *asn, Evp_pkey *pkey)
{
Evp_md_ctx CTX;
Const EVP_MD *type;
Evp_md_ctx_init (&CTX);
I=obj_obj2nid (A->algorithm); Get the algorithm of NID
Type=evp_get_digestbyname (OBJ_NID2SN (i)); Get the abstract processing function structure of the corresponding NID algorithm, note 1
EVP_VERIFYINIT_EX (&ctx,type, NULL);
INL = asn1_item_i2d (ASN, &buf_in, it);
Evp_verifyupdate (&ctx, (unsigned char *) BUF_IN,INL);
Evp_verifyfinal (&ctx, (unsigned char *) Signature->data,
(unsigned int) signature->length,pkey);//implementation validation
...
}
For note 1 It is necessary to explain that EVP_MD is a very important data structure, but also a data and operations encapsulated in the structure, the implementation of a signature and signature verification of the logical framework, EVP_MD is a logically higher than the engine of the package, EVP_ MD can be seen as a logical package, while the engine is the algorithm encapsulation that implements these logic:
struct Env_md_st {
int type;
int pkey_type;
int md_size;
unsigned long flags;
Int (*init) (Evp_md_ctx *ctx); Initialization
Int (*update) (evp_md_ctx *ctx,const void *data,size_t count); Operation
Int (*final) (Evp_md_ctx *ctx,unsigned char *md); End of Operation
Int (*copy) (Evp_md_ctx *to,const evp_md_ctx *from);
Int (*cleanup) (Evp_md_ctx *ctx);
Int (*sign) (int type, const unsigned char *m, unsigned int m_length,
unsigned char *sigret, unsigned int *siglen, void *key);
Int (*verify) (int type, const unsigned char *m, unsigned int m_length,
Const unsigned char *sigbuf, unsigned int siglen,
void *key);
int required_pkey_type[5]; /*EVP_PKEY_XXX * *
int block_size;
int ctx_size;
}/* EVP_MD */;
EVP_MD not only implements the digest algorithm, but also contains the signature and verification process encapsulation function, in fact, the so-called signature algorithm is a combination of abstract algorithm and asymmetric private key encryption algorithm, such as abstract algorithm has many kinds, md5,sha1 and so on, and asymmetric private key encryption algorithm has many, such as RSA, Dsa,ecdsa and so on, so the signature algorithm is their Cartesian product. EVP_MD's init,updatefinal is basically a summary of the calculations, and often in the higher-level logic after the final call to call verify to verify the signature or call sign to signature, such as evp_verifyfinal and EVP_ The SIGNFINAL,EVP_ series functions are the most upper-level logic for OpenSSL cryptography. The following 4 begins to look at procedure 5.
5. Call EVP_VERIFYINIT_EX, the function will find the corresponding type of EVP_MD from the default engine, if you have your own engine and implement the corresponding EVP_MD, then you can load their own engine to use their own EVP_MD By the way, EVP_MD from the engine of the extraction process and cipher from the engine of the extraction process is the same.
6. Call Evp_verifyupdate, which is done by calling the update callback function in the EVP_MD of the 5th step initialization;
7. Call Evp_verifyfinal to complete the final steps. In Evp_verifyfinal, first call EVP_DIGESTFINAL_EX to complete the calculation of the digest, and then call EVP_MD's Verify callback function:
EVP_DIGESTFINAL_EX (&tmp_ctx,& (m[0]), &m_len);
i = ctx->digest->verify (Ctx->digest->type,m,m_len, sigbuf,siglen,pkey->pkey.ptr);
8. For ECC, the callback function verify is ecdsa_verify, which eventually calls Ecdsa_do_verify:
int ecdsa_do_verify (const unsigned char *dgst, int dgst_len,
Const Ecdsa_sig *sig, Ec_key *eckey)
{//The last parameter of the callback function differs from the algorithm because the Pkey member is a federated
Ecdsa_data *ECDSA = Ecdsa_check (Eckey);
Return Ecdsa->meth->ecdsa_do_verify (Dgst, Dgst_len, Sig, Eckey);
}
9. Finally Ecdsa_check decided to use the data of the type Ecdsa_data in the method_data in Ec_key now;
10. Next call Ecdsa_method's ecdsa_do_verify to complete the final operation.
The above 10 steps are the steps that the verify command needs to perform, and the same is true for the X509 command to issue a certificate, except to change verify to sign. If you compare the signature and verification process of RSA, you will find that ECC has one more step, this extra step is the process of ecdsa_check.
     so far, the approximate implementation of ECC is very clear, but what exactly is ECC, ECC key exactly what is going on or a problem, just from the programming point of view of ECC is not enough, the following in turn introduces the principle of ECC, If only programming, at best it is a migrant workers, so for a technology, not only to know it but also to know why.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.