EC_KEY_free (PeerEcKey);\r
return RetVal;\r
}\r
+\r
+/**\r
+ Carries out the EC-DSA signature.\r
+\r
+ This function carries out the EC-DSA signature.\r
+ If the Signature buffer is too small to hold the contents of signature, FALSE\r
+ is returned and SigSize is set to the required buffer size to obtain the signature.\r
+\r
+ If EcContext is NULL, then return FALSE.\r
+ If MessageHash is NULL, then return FALSE.\r
+ If HashSize need match the HashNid. HashNid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384, SHA3_512.\r
+ If SigSize is large enough but Signature is NULL, then return FALSE.\r
+\r
+ For P-256, the SigSize is 64. First 32-byte is R, Second 32-byte is S.\r
+ For P-384, the SigSize is 96. First 48-byte is R, Second 48-byte is S.\r
+ For P-521, the SigSize is 132. First 66-byte is R, Second 66-byte is S.\r
+\r
+ @param[in] EcContext Pointer to EC context for signature generation.\r
+ @param[in] HashNid hash NID\r
+ @param[in] MessageHash Pointer to octet message hash to be signed.\r
+ @param[in] HashSize Size of the message hash in bytes.\r
+ @param[out] Signature Pointer to buffer to receive EC-DSA signature.\r
+ @param[in, out] SigSize On input, the size of Signature buffer in bytes.\r
+ On output, the size of data returned in Signature buffer in bytes.\r
+\r
+ @retval TRUE Signature successfully generated in EC-DSA.\r
+ @retval FALSE Signature generation failed.\r
+ @retval FALSE SigSize is too small.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcDsaSign (\r
+ IN VOID *EcContext,\r
+ IN UINTN HashNid,\r
+ IN CONST UINT8 *MessageHash,\r
+ IN UINTN HashSize,\r
+ OUT UINT8 *Signature,\r
+ IN OUT UINTN *SigSize\r
+ )\r
+{\r
+ EC_KEY *EcKey;\r
+ ECDSA_SIG *EcDsaSig;\r
+ INT32 OpenSslNid;\r
+ UINT8 HalfSize;\r
+ BIGNUM *R;\r
+ BIGNUM *S;\r
+ INTN RSize;\r
+ INTN SSize;\r
+\r
+ if ((EcContext == NULL) || (MessageHash == NULL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (Signature == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ EcKey = (EC_KEY *)EcContext;\r
+ OpenSslNid = EC_GROUP_get_curve_name (EC_KEY_get0_group (EcKey));\r
+ switch (OpenSslNid) {\r
+ case NID_X9_62_prime256v1:\r
+ HalfSize = 32;\r
+ break;\r
+ case NID_secp384r1:\r
+ HalfSize = 48;\r
+ break;\r
+ case NID_secp521r1:\r
+ HalfSize = 66;\r
+ break;\r
+ default:\r
+ return FALSE;\r
+ }\r
+\r
+ if (*SigSize < (UINTN)(HalfSize * 2)) {\r
+ *SigSize = HalfSize * 2;\r
+ return FALSE;\r
+ }\r
+\r
+ *SigSize = HalfSize * 2;\r
+ ZeroMem (Signature, *SigSize);\r
+\r
+ switch (HashNid) {\r
+ case CRYPTO_NID_SHA256:\r
+ if (HashSize != SHA256_DIGEST_SIZE) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ case CRYPTO_NID_SHA384:\r
+ if (HashSize != SHA384_DIGEST_SIZE) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ case CRYPTO_NID_SHA512:\r
+ if (HashSize != SHA512_DIGEST_SIZE) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+\r
+ EcDsaSig = ECDSA_do_sign (\r
+ MessageHash,\r
+ (UINT32)HashSize,\r
+ (EC_KEY *)EcContext\r
+ );\r
+ if (EcDsaSig == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ ECDSA_SIG_get0 (EcDsaSig, (CONST BIGNUM **)&R, (CONST BIGNUM **)&S);\r
+\r
+ RSize = BN_num_bytes (R);\r
+ SSize = BN_num_bytes (S);\r
+ if ((RSize <= 0) || (SSize <= 0)) {\r
+ ECDSA_SIG_free (EcDsaSig);\r
+ return FALSE;\r
+ }\r
+\r
+ ASSERT ((UINTN)RSize <= HalfSize && (UINTN)SSize <= HalfSize);\r
+\r
+ BN_bn2bin (R, &Signature[0 + HalfSize - RSize]);\r
+ BN_bn2bin (S, &Signature[HalfSize + HalfSize - SSize]);\r
+\r
+ ECDSA_SIG_free (EcDsaSig);\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Verifies the EC-DSA signature.\r
+\r
+ If EcContext is NULL, then return FALSE.\r
+ If MessageHash is NULL, then return FALSE.\r
+ If Signature is NULL, then return FALSE.\r
+ If HashSize need match the HashNid. HashNid could be SHA256, SHA384, SHA512, SHA3_256, SHA3_384, SHA3_512.\r
+\r
+ For P-256, the SigSize is 64. First 32-byte is R, Second 32-byte is S.\r
+ For P-384, the SigSize is 96. First 48-byte is R, Second 48-byte is S.\r
+ For P-521, the SigSize is 132. First 66-byte is R, Second 66-byte is S.\r
+\r
+ @param[in] EcContext Pointer to EC context for signature verification.\r
+ @param[in] HashNid hash NID\r
+ @param[in] MessageHash Pointer to octet message hash to be checked.\r
+ @param[in] HashSize Size of the message hash in bytes.\r
+ @param[in] Signature Pointer to EC-DSA signature to be verified.\r
+ @param[in] SigSize Size of signature in bytes.\r
+\r
+ @retval TRUE Valid signature encoded in EC-DSA.\r
+ @retval FALSE Invalid signature or invalid EC context.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EcDsaVerify (\r
+ IN VOID *EcContext,\r
+ IN UINTN HashNid,\r
+ IN CONST UINT8 *MessageHash,\r
+ IN UINTN HashSize,\r
+ IN CONST UINT8 *Signature,\r
+ IN UINTN SigSize\r
+ )\r
+{\r
+ INT32 Result;\r
+ EC_KEY *EcKey;\r
+ ECDSA_SIG *EcDsaSig;\r
+ INT32 OpenSslNid;\r
+ UINT8 HalfSize;\r
+ BIGNUM *R;\r
+ BIGNUM *S;\r
+\r
+ if ((EcContext == NULL) || (MessageHash == NULL) || (Signature == NULL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if ((SigSize > INT_MAX) || (SigSize == 0)) {\r
+ return FALSE;\r
+ }\r
+\r
+ EcKey = (EC_KEY *)EcContext;\r
+ OpenSslNid = EC_GROUP_get_curve_name (EC_KEY_get0_group (EcKey));\r
+ switch (OpenSslNid) {\r
+ case NID_X9_62_prime256v1:\r
+ HalfSize = 32;\r
+ break;\r
+ case NID_secp384r1:\r
+ HalfSize = 48;\r
+ break;\r
+ case NID_secp521r1:\r
+ HalfSize = 66;\r
+ break;\r
+ default:\r
+ return FALSE;\r
+ }\r
+\r
+ if (SigSize != (UINTN)(HalfSize * 2)) {\r
+ return FALSE;\r
+ }\r
+\r
+ switch (HashNid) {\r
+ case CRYPTO_NID_SHA256:\r
+ if (HashSize != SHA256_DIGEST_SIZE) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ case CRYPTO_NID_SHA384:\r
+ if (HashSize != SHA384_DIGEST_SIZE) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ case CRYPTO_NID_SHA512:\r
+ if (HashSize != SHA512_DIGEST_SIZE) {\r
+ return FALSE;\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ return FALSE;\r
+ }\r
+\r
+ EcDsaSig = ECDSA_SIG_new ();\r
+ if (EcDsaSig == NULL) {\r
+ ECDSA_SIG_free (EcDsaSig);\r
+ return FALSE;\r
+ }\r
+\r
+ R = BN_bin2bn (Signature, (UINT32)HalfSize, NULL);\r
+ S = BN_bin2bn (Signature + HalfSize, (UINT32)HalfSize, NULL);\r
+ if ((R == NULL) || (S == NULL)) {\r
+ ECDSA_SIG_free (EcDsaSig);\r
+ return FALSE;\r
+ }\r
+\r
+ ECDSA_SIG_set0 (EcDsaSig, R, S);\r
+\r
+ Result = ECDSA_do_verify (\r
+ MessageHash,\r
+ (UINT32)HashSize,\r
+ EcDsaSig,\r
+ (EC_KEY *)EcContext\r
+ );\r
+\r
+ ECDSA_SIG_free (EcDsaSig);\r
+\r
+ return (Result == 1);\r
+}\r