9#include "InternalCryptLib.h"
10#include <openssl/objects.h>
11#include <openssl/bn.h>
12#include <openssl/ec.h>
36 case CRYPTO_NID_SECP256R1:
37 Nid = NID_X9_62_prime256v1;
39 case CRYPTO_NID_SECP384R1:
42 case CRYPTO_NID_SECP521R1:
45 case CRYPTO_NID_BRAINPOOLP512R1:
46 Nid = NID_brainpoolP512r1;
80 return EC_GROUP_new_by_curve_name (Nid);
108 return (BOOLEAN)EC_GROUP_get_curve (EcGroup, BnPrime, BnA, BnB, BnCtx);
130 return (BOOLEAN)EC_GROUP_get_order (EcGroup, BnOrder,
NULL);
144 EC_GROUP_free (EcGroup);
162 return EC_POINT_new (EcGroup);
179 EC_POINT_clear_free (EcPoint);
181 EC_POINT_free (EcPoint);
210 return (BOOLEAN)EC_POINT_get_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx);
235 return (BOOLEAN)EC_POINT_set_affine_coordinates (EcGroup, EcPoint, BnX, BnY, BnCtx);
255 OUT VOID *EcPointResult,
261 return (BOOLEAN)EC_POINT_add (EcGroup, EcPointResult, EcPointA, EcPointB, BnCtx);
281 OUT VOID *EcPointResult,
287 return (BOOLEAN)EC_POINT_mul (EcGroup, EcPointResult,
NULL, EcPoint, BnPScalar, BnCtx);
304 IN OUT VOID *EcPoint,
308 return (BOOLEAN)EC_POINT_invert (EcGroup, EcPoint, BnCtx);
329 return EC_POINT_is_on_curve (EcGroup, EcPoint, BnCtx) == 1;
348 return EC_POINT_is_at_infinity (EcGroup, EcPoint) == 1;
371 return EC_POINT_cmp (EcGroup, EcPointA, EcPointB, BnCtx) == 0;
401 return (BOOLEAN)EC_POINT_set_compressed_coordinates (EcGroup, EcPoint, BnX, YBit, BnCtx);
426 if (OpenSslNid < 0) {
430 return (VOID *)EC_KEY_new_by_curve_name (OpenSslNid);
444 EC_KEY_free ((EC_KEY *)EcContext);
476 IN OUT VOID *EcContext,
477 OUT UINT8 *PublicKey,
482 CONST EC_GROUP *Group;
483 CONST EC_POINT *EcPoint;
491 if ((EcContext ==
NULL) || (PublicKeySize ==
NULL)) {
495 if ((PublicKey ==
NULL) && (*PublicKeySize != 0)) {
499 EcKey = (EC_KEY *)EcContext;
500 Group = EC_KEY_get0_group (EcKey);
501 HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;
504 if (EC_KEY_generate_key (EcKey) != 1) {
508 if (*PublicKeySize < HalfSize * 2) {
509 *PublicKeySize = HalfSize * 2;
513 *PublicKeySize = HalfSize * 2;
515 EcPoint = EC_KEY_get0_public_key (EcKey);
516 if (EcPoint ==
NULL) {
523 if ((BnX ==
NULL) || (BnY ==
NULL)) {
527 if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY,
NULL) != 1) {
531 XSize = BN_num_bytes (BnX);
532 YSize = BN_num_bytes (BnY);
533 if ((XSize <= 0) || (YSize <= 0)) {
537 ASSERT ((
UINTN)XSize <= HalfSize && (
UINTN)YSize <= HalfSize);
539 ZeroMem (PublicKey, *PublicKeySize);
540 BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]);
541 BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]);
568 IN OUT VOID *EcContext,
569 OUT UINT8 *PublicKey,
574 CONST EC_GROUP *Group;
575 CONST EC_POINT *EcPoint;
583 if ((EcContext ==
NULL) || (PublicKeySize ==
NULL)) {
587 if ((PublicKey ==
NULL) && (*PublicKeySize != 0)) {
591 EcKey = (EC_KEY *)EcContext;
592 Group = EC_KEY_get0_group (EcKey);
593 HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;
594 if (*PublicKeySize < HalfSize * 2) {
595 *PublicKeySize = HalfSize * 2;
599 *PublicKeySize = HalfSize * 2;
601 EcPoint = EC_KEY_get0_public_key (EcKey);
602 if (EcPoint ==
NULL) {
609 if ((BnX ==
NULL) || (BnY ==
NULL)) {
613 if (EC_POINT_get_affine_coordinates (Group, EcPoint, BnX, BnY,
NULL) != 1) {
617 XSize = BN_num_bytes (BnX);
618 YSize = BN_num_bytes (BnY);
619 if ((XSize <= 0) || (YSize <= 0)) {
623 ASSERT ((
UINTN)XSize <= HalfSize && (
UINTN)YSize <= HalfSize);
625 if (PublicKey !=
NULL) {
626 ZeroMem (PublicKey, *PublicKeySize);
627 BN_bn2bin (BnX, &PublicKey[0 + HalfSize - XSize]);
628 BN_bn2bin (BnY, &PublicKey[HalfSize + HalfSize - YSize]);
668 IN OUT VOID *EcContext,
678 CONST EC_GROUP *Group;
686 if ((EcContext ==
NULL) || (PeerPublic ==
NULL) || (KeySize ==
NULL)) {
690 if ((Key ==
NULL) && (*KeySize != 0)) {
694 if (PeerPublicSize > INT_MAX) {
698 EcKey = (EC_KEY *)EcContext;
699 Group = EC_KEY_get0_group (EcKey);
700 HalfSize = (EC_GROUP_get_degree (Group) + 7) / 8;
701 if ((CompressFlag ==
NULL) && (PeerPublicSize != HalfSize * 2)) {
705 if ((CompressFlag !=
NULL) && (PeerPublicSize != HalfSize)) {
709 if (*KeySize < HalfSize) {
718 BnX = BN_bin2bn (PeerPublic, (INT32)HalfSize,
NULL);
720 Point = EC_POINT_new (Group);
722 if ((BnX ==
NULL) || (Point ==
NULL)) {
726 if (CompressFlag ==
NULL) {
727 BnY = BN_bin2bn (PeerPublic + HalfSize, (INT32)HalfSize,
NULL);
732 if (EC_POINT_set_affine_coordinates (Group, Point, BnX, BnY,
NULL) != 1) {
736 if (EC_POINT_set_compressed_coordinates (Group, Point, BnX, *CompressFlag,
NULL) != 1) {
742 OpenSslNid = EC_GROUP_get_curve_name (Group);
743 PeerEcKey = EC_KEY_new_by_curve_name (OpenSslNid);
744 if (PeerEcKey ==
NULL) {
748 if (EC_KEY_set_public_key (PeerEcKey, Point) != 1) {
752 if (EC_KEY_check_key (PeerEcKey) != 1) {
756 if (ECDH_compute_key (Key, *KeySize, Point, EcKey,
NULL) <= 0) {
765 EC_POINT_free (Point);
766 EC_KEY_free (PeerEcKey);
806 OUT UINT8 *Signature,
819 if ((EcContext ==
NULL) || (MessageHash ==
NULL)) {
823 if (Signature ==
NULL) {
827 EcKey = (EC_KEY *)EcContext;
828 OpenSslNid = EC_GROUP_get_curve_name (EC_KEY_get0_group (EcKey));
829 switch (OpenSslNid) {
830 case NID_X9_62_prime256v1:
839 case NID_brainpoolP512r1:
846 if (*SigSize < (
UINTN)(HalfSize * 2)) {
847 *SigSize = HalfSize * 2;
851 *SigSize = HalfSize * 2;
855 case CRYPTO_NID_SHA256:
862 case CRYPTO_NID_SHA384:
869 case CRYPTO_NID_SHA512:
880 EcDsaSig = ECDSA_do_sign (
885 if (EcDsaSig ==
NULL) {
889 ECDSA_SIG_get0 (EcDsaSig, (
CONST BIGNUM **)&R, (
CONST BIGNUM **)&S);
891 RSize = BN_num_bytes (R);
892 SSize = BN_num_bytes (S);
893 if ((RSize <= 0) || (SSize <= 0)) {
894 ECDSA_SIG_free (EcDsaSig);
898 ASSERT ((
UINTN)RSize <= HalfSize && (
UINTN)SSize <= HalfSize);
900 BN_bn2bin (R, &Signature[0 + HalfSize - RSize]);
901 BN_bn2bin (S, &Signature[HalfSize + HalfSize - SSize]);
903 ECDSA_SIG_free (EcDsaSig);
950 if ((EcContext ==
NULL) || (MessageHash ==
NULL) || (Signature ==
NULL)) {
954 if ((SigSize > INT_MAX) || (SigSize == 0)) {
958 EcKey = (EC_KEY *)EcContext;
959 OpenSslNid = EC_GROUP_get_curve_name (EC_KEY_get0_group (EcKey));
960 switch (OpenSslNid) {
961 case NID_X9_62_prime256v1:
970 case NID_brainpoolP512r1:
977 if (SigSize != (
UINTN)(HalfSize * 2)) {
982 case CRYPTO_NID_SHA256:
989 case CRYPTO_NID_SHA384:
996 case CRYPTO_NID_SHA512:
1007 EcDsaSig = ECDSA_SIG_new ();
1008 if (EcDsaSig ==
NULL) {
1009 ECDSA_SIG_free (EcDsaSig);
1013 R = BN_bin2bn (Signature, (UINT32)HalfSize,
NULL);
1014 S = BN_bin2bn (Signature + HalfSize, (UINT32)HalfSize,
NULL);
1016 ECDSA_SIG_free (EcDsaSig);
1020 ECDSA_SIG_set0 (EcDsaSig, R, S);
1022 Result = ECDSA_do_verify (
1029 ECDSA_SIG_free (EcDsaSig);
1031 return (Result == 1);
#define SHA512_DIGEST_SIZE
#define SHA256_DIGEST_SIZE
#define SHA384_DIGEST_SIZE
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI EcPointInvert(IN CONST VOID *EcGroup, IN OUT VOID *EcPoint, IN VOID *BnCtx)
BOOLEAN EFIAPI EcPointSetCompressedCoordinates(IN CONST VOID *EcGroup, IN VOID *EcPoint, IN CONST VOID *BnX, IN UINT8 YBit, IN VOID *BnCtx)
BOOLEAN EFIAPI EcPointMul(IN CONST VOID *EcGroup, OUT VOID *EcPointResult, IN CONST VOID *EcPoint, IN CONST VOID *BnPScalar, IN VOID *BnCtx)
BOOLEAN EFIAPI EcPointAdd(IN CONST VOID *EcGroup, OUT VOID *EcPointResult, IN CONST VOID *EcPointA, IN CONST VOID *EcPointB, IN VOID *BnCtx)
BOOLEAN EFIAPI EcGenerateKey(IN OUT VOID *EcContext, OUT UINT8 *PublicKey, IN OUT UINTN *PublicKeySize)
BOOLEAN EFIAPI EcPointIsOnCurve(IN CONST VOID *EcGroup, IN CONST VOID *EcPoint, IN VOID *BnCtx)
BOOLEAN EFIAPI EcPointIsAtInfinity(IN CONST VOID *EcGroup, IN CONST VOID *EcPoint)
BOOLEAN EFIAPI EcGetPubKey(IN OUT VOID *EcContext, OUT UINT8 *PublicKey, IN OUT UINTN *PublicKeySize)
BOOLEAN EFIAPI EcDsaSign(IN VOID *EcContext, IN UINTN HashNid, IN CONST UINT8 *MessageHash, IN UINTN HashSize, OUT UINT8 *Signature, IN OUT UINTN *SigSize)
VOID *EFIAPI EcNewByNid(IN UINTN Nid)
VOID *EFIAPI EcPointInit(IN CONST VOID *EcGroup)
VOID *EFIAPI EcGroupInit(IN UINTN CryptoNid)
BOOLEAN EFIAPI EcPointEqual(IN CONST VOID *EcGroup, IN CONST VOID *EcPointA, IN CONST VOID *EcPointB, IN VOID *BnCtx)
BOOLEAN EFIAPI EcGroupGetCurve(IN CONST VOID *EcGroup, OUT VOID *BnPrime, OUT VOID *BnA, OUT VOID *BnB, IN VOID *BnCtx)
VOID EFIAPI EcPointDeInit(IN VOID *EcPoint, IN BOOLEAN Clear)
BOOLEAN EFIAPI EcDsaVerify(IN VOID *EcContext, IN UINTN HashNid, IN CONST UINT8 *MessageHash, IN UINTN HashSize, IN CONST UINT8 *Signature, IN UINTN SigSize)
STATIC INT32 CryptoNidToOpensslNid(IN UINTN CryptoNid)
BOOLEAN EFIAPI EcGroupGetOrder(IN VOID *EcGroup, OUT VOID *BnOrder)
BOOLEAN EFIAPI EcDhComputeKey(IN OUT VOID *EcContext, IN CONST UINT8 *PeerPublic, IN UINTN PeerPublicSize, IN CONST INT32 *CompressFlag, OUT UINT8 *Key, IN OUT UINTN *KeySize)
VOID EFIAPI EcGroupFree(IN VOID *EcGroup)
BOOLEAN EFIAPI EcPointGetAffineCoordinates(IN CONST VOID *EcGroup, IN CONST VOID *EcPoint, OUT VOID *BnX, OUT VOID *BnY, IN VOID *BnCtx)
BOOLEAN EFIAPI EcPointSetAffineCoordinates(IN CONST VOID *EcGroup, IN VOID *EcPoint, IN CONST VOID *BnX, IN CONST VOID *BnY, IN VOID *BnCtx)
VOID EFIAPI EcFree(IN VOID *EcContext)