TianoCore EDK2 master
Loading...
Searching...
No Matches
TlsConfig.c
Go to the documentation of this file.
1
10#include "InternalTlsLib.h"
11
12typedef struct {
13 //
14 // TLS Algorithm
15 //
16 UINT8 Algo;
17 //
18 // TLS Algorithm name
19 //
20 CONST CHAR8 *Name;
22
23STATIC CONST TLS_ALGO_TO_NAME TlsHashAlgoToName[] = {
24 { TlsHashAlgoNone, NULL },
25 { TlsHashAlgoMd5, "MD5" },
26 { TlsHashAlgoSha1, "SHA1" },
27 { TlsHashAlgoSha224, "SHA224" },
28 { TlsHashAlgoSha256, "SHA256" },
29 { TlsHashAlgoSha384, "SHA384" },
30 { TlsHashAlgoSha512, "SHA512" },
31};
32
33STATIC CONST TLS_ALGO_TO_NAME TlsSignatureAlgoToName[] = {
34 { TlsSignatureAlgoAnonymous, NULL },
35 { TlsSignatureAlgoRsa, "RSA" },
36 { TlsSignatureAlgoDsa, "DSA" },
37 { TlsSignatureAlgoEcdsa, "ECDSA" },
38};
39
55EFIAPI
57 IN VOID *Tls,
58 IN UINT8 MajorVer,
59 IN UINT8 MinorVer
60 )
61{
62 TLS_CONNECTION *TlsConn;
63 UINT16 ProtoVersion;
64
65 TlsConn = (TLS_CONNECTION *)Tls;
66 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
67 return EFI_INVALID_PARAMETER;
68 }
69
70 ProtoVersion = (MajorVer << 8) | MinorVer;
71
72 //
73 // Bound TLS method to the particular specified version.
74 //
75 switch (ProtoVersion) {
76 case TLS1_VERSION:
77 //
78 // TLS 1.0
79 //
80 SSL_set_min_proto_version (TlsConn->Ssl, TLS1_VERSION);
81 SSL_set_max_proto_version (TlsConn->Ssl, TLS1_VERSION);
82 break;
83 case TLS1_1_VERSION:
84 //
85 // TLS 1.1
86 //
87 SSL_set_min_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
88 SSL_set_max_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
89 break;
90 case TLS1_2_VERSION:
91 //
92 // TLS 1.2
93 //
94 SSL_set_min_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
95 SSL_set_max_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
96 break;
97 default:
98 //
99 // Unsupported Protocol Version
100 //
101 return EFI_UNSUPPORTED;
102 }
103
104 return EFI_SUCCESS;
105}
106
121EFIAPI
123 IN VOID *Tls,
124 IN BOOLEAN IsServer
125 )
126{
127 TLS_CONNECTION *TlsConn;
128
129 TlsConn = (TLS_CONNECTION *)Tls;
130 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
131 return EFI_INVALID_PARAMETER;
132 }
133
134 if (!IsServer) {
135 //
136 // Set TLS to work in Client mode.
137 //
138 SSL_set_connect_state (TlsConn->Ssl);
139 } else {
140 //
141 // Set TLS to work in Server mode.
142 // It is unsupported for UEFI version currently.
143 //
144 // SSL_set_accept_state (TlsConn->Ssl);
145 return EFI_UNSUPPORTED;
146 }
147
148 return EFI_SUCCESS;
149}
150
170EFIAPI
172 IN VOID *Tls,
173 IN UINT16 *CipherId,
174 IN UINTN CipherNum
175 )
176{
177 TLS_CONNECTION *TlsConn;
178 EFI_STATUS Status;
179 CONST SSL_CIPHER **MappedCipher;
180 UINTN MappedCipherBytes;
181 UINTN MappedCipherCount;
182 UINTN CipherStringSize;
183 UINTN Index;
184 INT32 StackIdx;
185 CHAR8 *CipherString;
186 CHAR8 *CipherStringPosition;
187
188 STACK_OF (SSL_CIPHER) *OpensslCipherStack;
189 CONST SSL_CIPHER *OpensslCipher;
190 CONST CHAR8 *OpensslCipherName;
191 UINTN OpensslCipherNameLength;
192
193 TlsConn = (TLS_CONNECTION *)Tls;
194 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (CipherId == NULL)) {
195 return EFI_INVALID_PARAMETER;
196 }
197
198 //
199 // Allocate the MappedCipher array for recording the mappings that we find
200 // for the input IANA identifiers in CipherId.
201 //
202 Status = SafeUintnMult (
203 CipherNum,
204 sizeof (*MappedCipher),
205 &MappedCipherBytes
206 );
207 if (EFI_ERROR (Status)) {
208 return EFI_OUT_OF_RESOURCES;
209 }
210
211 MappedCipher = AllocatePool (MappedCipherBytes);
212 if (MappedCipher == NULL) {
213 return EFI_OUT_OF_RESOURCES;
214 }
215
216 OpensslCipherStack = SSL_get_ciphers (TlsConn->Ssl);
217
218 //
219 // Map the cipher IDs, and count the number of bytes for the full
220 // CipherString.
221 //
222 MappedCipherCount = 0;
223 CipherStringSize = 0;
224 for (Index = 0; OpensslCipherStack != NULL && Index < CipherNum; Index++) {
225 //
226 // Look up the IANA-to-OpenSSL mapping.
227 //
228 for (StackIdx = 0; StackIdx < sk_SSL_CIPHER_num (OpensslCipherStack); StackIdx++) {
229 OpensslCipher = sk_SSL_CIPHER_value (OpensslCipherStack, StackIdx);
230 if (CipherId[Index] == SSL_CIPHER_get_protocol_id (OpensslCipher)) {
231 break;
232 }
233 }
234
235 if (StackIdx == sk_SSL_CIPHER_num (OpensslCipherStack)) {
236 DEBUG ((
237 DEBUG_VERBOSE,
238 "%a:%a: skipping CipherId=0x%04x\n",
239 gEfiCallerBaseName,
240 __func__,
241 CipherId[Index]
242 ));
243 //
244 // Skipping the cipher is valid because CipherId is an ordered
245 // preference list of ciphers, thus we can filter it as long as we
246 // don't change the relative order of elements on it.
247 //
248 continue;
249 }
250
251 //
252 // Accumulate cipher name string length into CipherStringSize. If this
253 // is not the first successful mapping, account for a colon (":") prefix
254 // too.
255 //
256 if (MappedCipherCount > 0) {
257 Status = SafeUintnAdd (CipherStringSize, 1, &CipherStringSize);
258 if (EFI_ERROR (Status)) {
259 Status = EFI_OUT_OF_RESOURCES;
260 goto FreeMappedCipher;
261 }
262 }
263
264 Status = SafeUintnAdd (
265 CipherStringSize,
266 AsciiStrLen (SSL_CIPHER_get_name (OpensslCipher)),
267 &CipherStringSize
268 );
269 if (EFI_ERROR (Status)) {
270 Status = EFI_OUT_OF_RESOURCES;
271 goto FreeMappedCipher;
272 }
273
274 //
275 // Record the mapping.
276 //
277 MappedCipher[MappedCipherCount++] = OpensslCipher;
278 }
279
280 //
281 // Verify that at least one IANA cipher ID could be mapped; account for the
282 // terminating NUL character in CipherStringSize; allocate CipherString.
283 //
284 if (MappedCipherCount == 0) {
285 DEBUG ((
286 DEBUG_ERROR,
287 "%a:%a: no CipherId could be mapped\n",
288 gEfiCallerBaseName,
289 __func__
290 ));
291 Status = EFI_UNSUPPORTED;
292 goto FreeMappedCipher;
293 }
294
295 Status = SafeUintnAdd (CipherStringSize, 1, &CipherStringSize);
296 if (EFI_ERROR (Status)) {
297 Status = EFI_OUT_OF_RESOURCES;
298 goto FreeMappedCipher;
299 }
300
301 CipherString = AllocatePool (CipherStringSize);
302 if (CipherString == NULL) {
303 Status = EFI_OUT_OF_RESOURCES;
304 goto FreeMappedCipher;
305 }
306
307 //
308 // Go over the collected mappings and populate CipherString.
309 //
310 CipherStringPosition = CipherString;
311 for (Index = 0; Index < MappedCipherCount; Index++) {
312 OpensslCipher = MappedCipher[Index];
313 OpensslCipherName = SSL_CIPHER_get_name (OpensslCipher);
314 OpensslCipherNameLength = AsciiStrLen (OpensslCipherName);
315 //
316 // Append the colon (":") prefix except for the first mapping, then append
317 // OpensslCipherName.
318 //
319 if (Index > 0) {
320 *(CipherStringPosition++) = ':';
321 }
322
323 CopyMem (
324 CipherStringPosition,
325 OpensslCipherName,
326 OpensslCipherNameLength
327 );
328 CipherStringPosition += OpensslCipherNameLength;
329 }
330
331 //
332 // NUL-terminate CipherString.
333 //
334 *(CipherStringPosition++) = '\0';
335 ASSERT (CipherStringPosition == CipherString + CipherStringSize);
336
337 //
338 // Log CipherString for debugging. CipherString can be very long if the
339 // caller provided a large CipherId array, so log CipherString in segments of
340 // 79 non-newline characters. (MAX_DEBUG_MESSAGE_LENGTH is usually 0x100 in
341 // DebugLib instances.)
342 //
344 UINTN FullLength;
345 UINTN SegmentLength;
346
347 FullLength = CipherStringSize - 1;
348 DEBUG ((
349 DEBUG_VERBOSE,
350 "%a:%a: CipherString={\n",
351 gEfiCallerBaseName,
352 __func__
353 ));
354 for (CipherStringPosition = CipherString;
355 CipherStringPosition < CipherString + FullLength;
356 CipherStringPosition += SegmentLength)
357 {
358 SegmentLength = FullLength - (CipherStringPosition - CipherString);
359 if (SegmentLength > 79) {
360 SegmentLength = 79;
361 }
362
363 DEBUG ((DEBUG_VERBOSE, "%.*a\n", SegmentLength, CipherStringPosition));
364 }
365
366 DEBUG ((DEBUG_VERBOSE, "}\n"));
367 //
368 // Restore the pre-debug value of CipherStringPosition by skipping over the
369 // trailing NUL.
370 //
371 CipherStringPosition++;
372 ASSERT (CipherStringPosition == CipherString + CipherStringSize);
374
375 //
376 // Sets the ciphers for use by the Tls object.
377 //
378 if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {
379 Status = EFI_UNSUPPORTED;
380 goto FreeCipherString;
381 }
382
383 Status = EFI_SUCCESS;
384
385FreeCipherString:
386 FreePool (CipherString);
387
388FreeMappedCipher:
389 FreePool ((VOID *)MappedCipher);
390
391 return Status;
392}
393
407EFIAPI
409 IN UINT8 CompMethod
410 )
411{
412 COMP_METHOD *Cm;
413 INTN Ret;
414
415 Cm = NULL;
416 Ret = 0;
417
418 if (CompMethod == 0) {
419 //
420 // TLS defines one standard compression method, CompressionMethod.null (0),
421 // which specifies that data exchanged via the record protocol will not be compressed.
422 // So, return EFI_SUCCESS directly (RFC 3749).
423 //
424 return EFI_SUCCESS;
425 } else if (CompMethod == 1) {
426 Cm = COMP_zlib ();
427 } else {
428 return EFI_UNSUPPORTED;
429 }
430
431 //
432 // Adds the compression method to the list of available
433 // compression methods.
434 //
435 Ret = SSL_COMP_add_compression_method (CompMethod, Cm);
436 if (Ret != 0) {
437 return EFI_UNSUPPORTED;
438 }
439
440 return EFI_SUCCESS;
441}
442
452VOID
453EFIAPI
455 IN VOID *Tls,
456 IN UINT32 VerifyMode
457 )
458{
459 TLS_CONNECTION *TlsConn;
460
461 TlsConn = (TLS_CONNECTION *)Tls;
462 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
463 return;
464 }
465
466 //
467 // Set peer certificate verification parameters with NULL callback.
468 //
469 SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
470}
471
485EFIAPI
487 IN VOID *Tls,
488 IN UINT32 Flags,
489 IN CHAR8 *HostName
490 )
491{
492 TLS_CONNECTION *TlsConn;
493 X509_VERIFY_PARAM *VerifyParam;
494 UINTN BinaryAddressSize;
495 UINT8 BinaryAddress[MAX (NS_INADDRSZ, NS_IN6ADDRSZ)];
496 INTN ParamStatus;
497
498 TlsConn = (TLS_CONNECTION *)Tls;
499 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (HostName == NULL)) {
500 return EFI_INVALID_PARAMETER;
501 }
502
503 DEBUG ((
504 DEBUG_VERBOSE,
505 "%a:%a: SNI hostname: %a\n",
506 gEfiCallerBaseName,
507 __func__,
508 HostName
509 ));
510
511 if (!SSL_set_tlsext_host_name (TlsConn->Ssl, HostName)) {
512 DEBUG ((
513 DEBUG_ERROR,
514 "%a:%a: Could not set hostname %a for SNI\n",
515 gEfiCallerBaseName,
516 __func__,
517 HostName
518 ));
519 }
520
521 SSL_set_hostflags (TlsConn->Ssl, Flags);
522
523 VerifyParam = SSL_get0_param (TlsConn->Ssl);
524 ASSERT (VerifyParam != NULL);
525
526 BinaryAddressSize = 0;
527 if (inet_pton (AF_INET6, HostName, BinaryAddress) == 1) {
528 BinaryAddressSize = NS_IN6ADDRSZ;
529 } else if (inet_pton (AF_INET, HostName, BinaryAddress) == 1) {
530 BinaryAddressSize = NS_INADDRSZ;
531 }
532
533 if (BinaryAddressSize > 0) {
534 DEBUG ((
535 DEBUG_VERBOSE,
536 "%a:%a: parsed \"%a\" as an IPv%c address "
537 "literal\n",
538 gEfiCallerBaseName,
539 __func__,
540 HostName,
541 (UINTN)((BinaryAddressSize == NS_IN6ADDRSZ) ? '6' : '4')
542 ));
543 ParamStatus = X509_VERIFY_PARAM_set1_ip (
544 VerifyParam,
545 BinaryAddress,
546 BinaryAddressSize
547 );
548 } else {
549 ParamStatus = X509_VERIFY_PARAM_set1_host (VerifyParam, HostName, 0);
550 }
551
552 return (ParamStatus == 1) ? EFI_SUCCESS : EFI_ABORTED;
553}
554
571EFIAPI
573 IN VOID *Tls,
574 IN UINT8 *SessionId,
575 IN UINT16 SessionIdLen
576 )
577{
578 TLS_CONNECTION *TlsConn;
579 SSL_SESSION *Session;
580
581 TlsConn = (TLS_CONNECTION *)Tls;
582 Session = NULL;
583
584 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (SessionId == NULL)) {
585 return EFI_INVALID_PARAMETER;
586 }
587
588 Session = SSL_get_session (TlsConn->Ssl);
589 if (Session == NULL) {
590 return EFI_UNSUPPORTED;
591 }
592
593 SSL_SESSION_set1_id (Session, (const unsigned char *)SessionId, SessionIdLen);
594
595 return EFI_SUCCESS;
596}
597
616EFIAPI
618 IN VOID *Tls,
619 IN VOID *Data,
620 IN UINTN DataSize
621 )
622{
623 BIO *BioCert;
624 X509 *Cert;
625 X509_STORE *X509Store;
626 EFI_STATUS Status;
627 TLS_CONNECTION *TlsConn;
628 SSL_CTX *SslCtx;
629 INTN Ret;
630
631 BioCert = NULL;
632 Cert = NULL;
633 X509Store = NULL;
634 Status = EFI_SUCCESS;
635 TlsConn = (TLS_CONNECTION *)Tls;
636 Ret = 0;
637
638 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
639 return EFI_INVALID_PARAMETER;
640 }
641
642 //
643 // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
644 // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
645 //
646 Cert = d2i_X509 (NULL, (const unsigned char **)&Data, (long)DataSize);
647 if (Cert == NULL) {
648 //
649 // Certificate is from PEM encoding.
650 //
651 BioCert = BIO_new (BIO_s_mem ());
652 if (BioCert == NULL) {
653 Status = EFI_OUT_OF_RESOURCES;
654 goto ON_EXIT;
655 }
656
657 if (BIO_write (BioCert, Data, (UINT32)DataSize) <= 0) {
658 Status = EFI_ABORTED;
659 goto ON_EXIT;
660 }
661
662 Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
663 if (Cert == NULL) {
664 Status = EFI_ABORTED;
665 goto ON_EXIT;
666 }
667 }
668
669 SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
670 X509Store = SSL_CTX_get_cert_store (SslCtx);
671 if (X509Store == NULL) {
672 Status = EFI_ABORTED;
673 goto ON_EXIT;
674 }
675
676 //
677 // Add certificate to X509 store
678 //
679 Ret = X509_STORE_add_cert (X509Store, Cert);
680 if (Ret != 1) {
681 unsigned long ErrorCode;
682
683 ErrorCode = ERR_peek_last_error ();
684 //
685 // Ignore "already in table" errors
686 //
687 if (!((ERR_GET_LIB (ErrorCode) == ERR_LIB_X509) &&
688 (ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)))
689 {
690 Status = EFI_ABORTED;
691 goto ON_EXIT;
692 }
693 }
694
695ON_EXIT:
696 if (BioCert != NULL) {
697 BIO_free (BioCert);
698 }
699
700 if (Cert != NULL) {
701 X509_free (Cert);
702 }
703
704 return Status;
705}
706
725EFIAPI
727 IN VOID *Tls,
728 IN VOID *Data,
729 IN UINTN DataSize
730 )
731{
732 BIO *BioCert;
733 X509 *Cert;
734 EFI_STATUS Status;
735 TLS_CONNECTION *TlsConn;
736
737 BioCert = NULL;
738 Cert = NULL;
739 Status = EFI_SUCCESS;
740 TlsConn = (TLS_CONNECTION *)Tls;
741
742 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
743 return EFI_INVALID_PARAMETER;
744 }
745
746 //
747 // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
748 // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
749 //
750 Cert = d2i_X509 (NULL, (const unsigned char **)&Data, (long)DataSize);
751 if (Cert == NULL) {
752 //
753 // Certificate is from PEM encoding.
754 //
755 BioCert = BIO_new (BIO_s_mem ());
756 if (BioCert == NULL) {
757 Status = EFI_OUT_OF_RESOURCES;
758 goto ON_EXIT;
759 }
760
761 if (BIO_write (BioCert, Data, (UINT32)DataSize) <= 0) {
762 Status = EFI_ABORTED;
763 goto ON_EXIT;
764 }
765
766 Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
767 if (Cert == NULL) {
768 Status = EFI_ABORTED;
769 goto ON_EXIT;
770 }
771 }
772
773 if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {
774 Status = EFI_ABORTED;
775 goto ON_EXIT;
776 }
777
778ON_EXIT:
779 if (BioCert != NULL) {
780 BIO_free (BioCert);
781 }
782
783 if (Cert != NULL) {
784 X509_free (Cert);
785 }
786
787 return Status;
788}
789
809EFIAPI
811 IN VOID *Tls,
812 IN VOID *Data,
813 IN UINTN DataSize,
814 IN VOID *Password OPTIONAL
815 )
816{
817 TLS_CONNECTION *TlsConn;
818 BIO *Bio;
819 EVP_PKEY *Pkey;
820 BOOLEAN Verify;
821
822 TlsConn = (TLS_CONNECTION *)Tls;
823
824 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
825 return EFI_INVALID_PARAMETER;
826 }
827
828 // Try to parse the private key in DER format or un-encrypted PKC#8
829 if (SSL_use_PrivateKey_ASN1 (
830 EVP_PKEY_RSA,
831 TlsConn->Ssl,
832 Data,
833 (long)DataSize
834 ) == 1)
835 {
836 goto verify;
837 }
838
839 if (SSL_use_PrivateKey_ASN1 (
840 EVP_PKEY_DSA,
841 TlsConn->Ssl,
842 Data,
843 (long)DataSize
844 ) == 1)
845 {
846 goto verify;
847 }
848
849 if (SSL_use_PrivateKey_ASN1 (
850 EVP_PKEY_EC,
851 TlsConn->Ssl,
852 Data,
853 (long)DataSize
854 ) == 1)
855 {
856 goto verify;
857 }
858
859 // Try to parse the private key in PEM format or encrypted PKC#8
860 Bio = BIO_new_mem_buf (Data, (int)DataSize);
861 if (Bio != NULL) {
862 Verify = FALSE;
863 Pkey = PEM_read_bio_PrivateKey (Bio, NULL, NULL, Password);
864 if ((Pkey != NULL) && (SSL_use_PrivateKey (TlsConn->Ssl, Pkey) == 1)) {
865 Verify = TRUE;
866 }
867
868 EVP_PKEY_free (Pkey);
869 BIO_free (Bio);
870
871 if (Verify) {
872 goto verify;
873 }
874 }
875
876 return EFI_ABORTED;
877
878verify:
879 if (SSL_check_private_key (TlsConn->Ssl) == 1) {
880 return EFI_SUCCESS;
881 }
882
883 return EFI_ABORTED;
884}
885
903EFIAPI
905 IN VOID *Tls,
906 IN VOID *Data,
907 IN UINTN DataSize
908 )
909{
910 return TlsSetHostPrivateKeyEx (Tls, Data, DataSize, NULL);
911}
912
928EFIAPI
930 IN VOID *Data,
931 IN UINTN DataSize
932 )
933{
934 return EFI_UNSUPPORTED;
935}
936
955EFIAPI
957 IN VOID *Tls,
958 IN UINT8 *Data,
959 IN UINTN DataSize
960 )
961{
962 TLS_CONNECTION *TlsConn;
963 UINTN Index;
964 UINTN SignAlgoStrSize;
965 CHAR8 *SignAlgoStr;
966 CHAR8 *Pos;
967 UINT8 *SignatureAlgoList;
968 EFI_STATUS Status;
969
970 TlsConn = (TLS_CONNECTION *)Tls;
971
972 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize < 3) ||
973 ((DataSize % 2) == 0) || (Data[0] != DataSize - 1))
974 {
975 return EFI_INVALID_PARAMETER;
976 }
977
978 SignatureAlgoList = Data + 1;
979 SignAlgoStrSize = 0;
980 for (Index = 0; Index < Data[0]; Index += 2) {
981 CONST CHAR8 *Tmp;
982
983 if (SignatureAlgoList[Index] >= ARRAY_SIZE (TlsHashAlgoToName)) {
984 return EFI_INVALID_PARAMETER;
985 }
986
987 Tmp = TlsHashAlgoToName[SignatureAlgoList[Index]].Name;
988 if (!Tmp) {
989 return EFI_INVALID_PARAMETER;
990 }
991
992 // Add 1 for the '+'
993 SignAlgoStrSize += AsciiStrLen (Tmp) + 1;
994
995 if (SignatureAlgoList[Index + 1] >= ARRAY_SIZE (TlsSignatureAlgoToName)) {
996 return EFI_INVALID_PARAMETER;
997 }
998
999 Tmp = TlsSignatureAlgoToName[SignatureAlgoList[Index + 1]].Name;
1000 if (!Tmp) {
1001 return EFI_INVALID_PARAMETER;
1002 }
1003
1004 // Add 1 for the ':' or for the NULL terminator
1005 SignAlgoStrSize += AsciiStrLen (Tmp) + 1;
1006 }
1007
1008 if (!SignAlgoStrSize) {
1009 return EFI_UNSUPPORTED;
1010 }
1011
1012 SignAlgoStr = AllocatePool (SignAlgoStrSize);
1013 if (SignAlgoStr == NULL) {
1014 return EFI_OUT_OF_RESOURCES;
1015 }
1016
1017 Pos = SignAlgoStr;
1018 for (Index = 0; Index < Data[0]; Index += 2) {
1019 CONST CHAR8 *Tmp;
1020
1021 Tmp = TlsHashAlgoToName[SignatureAlgoList[Index]].Name;
1022 CopyMem (Pos, Tmp, AsciiStrLen (Tmp));
1023 Pos += AsciiStrLen (Tmp);
1024 *Pos++ = '+';
1025
1026 Tmp = TlsSignatureAlgoToName[SignatureAlgoList[Index + 1]].Name;
1027 CopyMem (Pos, Tmp, AsciiStrLen (Tmp));
1028 Pos += AsciiStrLen (Tmp);
1029 *Pos++ = ':';
1030 }
1031
1032 *(Pos - 1) = '\0';
1033
1034 if (SSL_set1_sigalgs_list (TlsConn->Ssl, SignAlgoStr) < 1) {
1035 Status = EFI_INVALID_PARAMETER;
1036 } else {
1037 Status = EFI_SUCCESS;
1038 }
1039
1040 FreePool (SignAlgoStr);
1041 return Status;
1042}
1043
1059EFIAPI
1061 IN VOID *Tls,
1062 IN UINT8 *Data,
1063 IN UINTN DataSize
1064 )
1065{
1066 TLS_CONNECTION *TlsConn;
1067 EC_KEY *EcKey;
1068 INT32 Nid;
1069 INT32 Ret;
1070
1071 TlsConn = (TLS_CONNECTION *)Tls;
1072
1073 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize != sizeof (UINT32))) {
1074 return EFI_INVALID_PARAMETER;
1075 }
1076
1077 switch (*((UINT32 *)Data)) {
1078 case TlsEcNamedCurveSecp256r1:
1079 return EFI_UNSUPPORTED;
1080 case TlsEcNamedCurveSecp384r1:
1081 Nid = NID_secp384r1;
1082 break;
1083 case TlsEcNamedCurveSecp521r1:
1084 Nid = NID_secp521r1;
1085 break;
1086 case TlsEcNamedCurveX25519:
1087 Nid = NID_X25519;
1088 break;
1089 case TlsEcNamedCurveX448:
1090 Nid = NID_X448;
1091 break;
1092 default:
1093 return EFI_UNSUPPORTED;
1094 }
1095
1096 if (SSL_set1_curves (TlsConn->Ssl, &Nid, 1) != 1) {
1097 return EFI_UNSUPPORTED;
1098 }
1099
1100 EcKey = EC_KEY_new_by_curve_name (Nid);
1101 if (EcKey == NULL) {
1102 return EFI_UNSUPPORTED;
1103 }
1104
1105 Ret = SSL_set_tmp_ecdh (TlsConn->Ssl, EcKey);
1106 EC_KEY_free (EcKey);
1107
1108 if (Ret != 1) {
1109 return EFI_UNSUPPORTED;
1110 }
1111
1112 return EFI_SUCCESS;
1113}
1114
1128UINT16
1129EFIAPI
1131 IN VOID *Tls
1132 )
1133{
1134 TLS_CONNECTION *TlsConn;
1135
1136 TlsConn = (TLS_CONNECTION *)Tls;
1137
1138 ASSERT (TlsConn != NULL);
1139
1140 return (UINT16)(SSL_version (TlsConn->Ssl));
1141}
1142
1156UINT8
1157EFIAPI
1159 IN VOID *Tls
1160 )
1161{
1162 TLS_CONNECTION *TlsConn;
1163
1164 TlsConn = (TLS_CONNECTION *)Tls;
1165
1166 ASSERT (TlsConn != NULL);
1167
1168 return (UINT8)SSL_is_server (TlsConn->Ssl);
1169}
1170
1186EFIAPI
1188 IN VOID *Tls,
1189 IN OUT UINT16 *CipherId
1190 )
1191{
1192 TLS_CONNECTION *TlsConn;
1193 CONST SSL_CIPHER *Cipher;
1194
1195 TlsConn = (TLS_CONNECTION *)Tls;
1196 Cipher = NULL;
1197
1198 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (CipherId == NULL)) {
1199 return EFI_INVALID_PARAMETER;
1200 }
1201
1202 Cipher = SSL_get_current_cipher (TlsConn->Ssl);
1203 if (Cipher == NULL) {
1204 return EFI_UNSUPPORTED;
1205 }
1206
1207 *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;
1208
1209 return EFI_SUCCESS;
1210}
1211
1229EFIAPI
1231 IN VOID *Tls,
1232 IN OUT UINT8 *CompressionId
1233 )
1234{
1235 return EFI_UNSUPPORTED;
1236}
1237
1251UINT32
1252EFIAPI
1254 IN VOID *Tls
1255 )
1256{
1257 TLS_CONNECTION *TlsConn;
1258
1259 TlsConn = (TLS_CONNECTION *)Tls;
1260
1261 ASSERT (TlsConn != NULL);
1262
1263 return SSL_get_verify_mode (TlsConn->Ssl);
1264}
1265
1282EFIAPI
1284 IN VOID *Tls,
1285 IN OUT UINT8 *SessionId,
1286 IN OUT UINT16 *SessionIdLen
1287 )
1288{
1289 TLS_CONNECTION *TlsConn;
1290 SSL_SESSION *Session;
1291 CONST UINT8 *SslSessionId;
1292
1293 TlsConn = (TLS_CONNECTION *)Tls;
1294 Session = NULL;
1295
1296 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (SessionId == NULL) || (SessionIdLen == NULL)) {
1297 return EFI_INVALID_PARAMETER;
1298 }
1299
1300 Session = SSL_get_session (TlsConn->Ssl);
1301 if (Session == NULL) {
1302 return EFI_UNSUPPORTED;
1303 }
1304
1305 SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen);
1306 CopyMem (SessionId, SslSessionId, *SessionIdLen);
1307
1308 return EFI_SUCCESS;
1309}
1310
1322VOID
1323EFIAPI
1325 IN VOID *Tls,
1326 IN OUT UINT8 *ClientRandom
1327 )
1328{
1329 TLS_CONNECTION *TlsConn;
1330
1331 TlsConn = (TLS_CONNECTION *)Tls;
1332
1333 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (ClientRandom == NULL)) {
1334 return;
1335 }
1336
1337 SSL_get_client_random (TlsConn->Ssl, ClientRandom, SSL3_RANDOM_SIZE);
1338}
1339
1351VOID
1352EFIAPI
1354 IN VOID *Tls,
1355 IN OUT UINT8 *ServerRandom
1356 )
1357{
1358 TLS_CONNECTION *TlsConn;
1359
1360 TlsConn = (TLS_CONNECTION *)Tls;
1361
1362 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (ServerRandom == NULL)) {
1363 return;
1364 }
1365
1366 SSL_get_server_random (TlsConn->Ssl, ServerRandom, SSL3_RANDOM_SIZE);
1367}
1368
1384EFIAPI
1386 IN VOID *Tls,
1387 IN OUT UINT8 *KeyMaterial
1388 )
1389{
1390 TLS_CONNECTION *TlsConn;
1391 SSL_SESSION *Session;
1392
1393 TlsConn = (TLS_CONNECTION *)Tls;
1394 Session = NULL;
1395
1396 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (KeyMaterial == NULL)) {
1397 return EFI_INVALID_PARAMETER;
1398 }
1399
1400 Session = SSL_get_session (TlsConn->Ssl);
1401
1402 if (Session == NULL) {
1403 return EFI_UNSUPPORTED;
1404 }
1405
1406 SSL_SESSION_get_master_key (Session, KeyMaterial, SSL3_MASTER_SECRET_SIZE);
1407
1408 return EFI_SUCCESS;
1409}
1410
1428EFIAPI
1430 IN VOID *Tls,
1431 OUT VOID *Data,
1432 IN OUT UINTN *DataSize
1433 )
1434{
1435 return EFI_UNSUPPORTED;
1436}
1437
1456EFIAPI
1458 IN VOID *Tls,
1459 OUT VOID *Data,
1460 IN OUT UINTN *DataSize
1461 )
1462{
1463 X509 *Cert;
1464 TLS_CONNECTION *TlsConn;
1465
1466 Cert = NULL;
1467 TlsConn = (TLS_CONNECTION *)Tls;
1468
1469 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data == NULL))) {
1470 return EFI_INVALID_PARAMETER;
1471 }
1472
1473 Cert = SSL_get_certificate (TlsConn->Ssl);
1474 if (Cert == NULL) {
1475 return EFI_NOT_FOUND;
1476 }
1477
1478 //
1479 // Only DER encoding is supported currently.
1480 //
1481 if (*DataSize < (UINTN)i2d_X509 (Cert, NULL)) {
1482 *DataSize = (UINTN)i2d_X509 (Cert, NULL);
1483 return EFI_BUFFER_TOO_SMALL;
1484 }
1485
1486 *DataSize = (UINTN)i2d_X509 (Cert, (unsigned char **)&Data);
1487
1488 return EFI_SUCCESS;
1489}
1490
1508EFIAPI
1510 IN VOID *Tls,
1511 OUT VOID *Data,
1512 IN OUT UINTN *DataSize
1513 )
1514{
1515 return EFI_UNSUPPORTED;
1516}
1517
1534EFIAPI
1536 OUT VOID *Data,
1537 IN OUT UINTN *DataSize
1538 )
1539{
1540 return EFI_UNSUPPORTED;
1541}
1542
1562EFIAPI
1564 IN VOID *Tls,
1565 IN CONST VOID *Label,
1566 IN CONST VOID *Context,
1567 IN UINTN ContextLen,
1568 OUT VOID *KeyBuffer,
1569 IN UINTN KeyBufferLen
1570 )
1571{
1572 TLS_CONNECTION *TlsConn;
1573
1574 TlsConn = (TLS_CONNECTION *)Tls;
1575
1576 if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
1577 return EFI_INVALID_PARAMETER;
1578 }
1579
1580 return SSL_export_keying_material (
1581 TlsConn->Ssl,
1582 KeyBuffer,
1583 KeyBufferLen,
1584 Label,
1585 AsciiStrLen (Label),
1586 Context,
1587 ContextLen,
1588 Context != NULL
1589 ) == 1 ?
1590 EFI_SUCCESS : EFI_PROTOCOL_ERROR;
1591}
UINT64 UINTN
INT64 INTN
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define MAX(a, b)
Definition: Base.h:992
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFIAPI SafeUintnAdd(IN UINTN Augend, IN UINTN Addend, OUT UINTN *Result)
Definition: SafeIntLib32.c:338
RETURN_STATUS EFIAPI SafeUintnMult(IN UINTN Multiplicand, IN UINTN Multiplier, OUT UINTN *Result)
Definition: SafeIntLib32.c:430
VOID EFIAPI TlsGetServerRandom(IN VOID *Tls, IN OUT UINT8 *ServerRandom)
Definition: TlsConfig.c:1353
EFI_STATUS EFIAPI TlsGetHostPublicCert(IN VOID *Tls, OUT VOID *Data, IN OUT UINTN *DataSize)
Definition: TlsConfig.c:1457
EFI_STATUS EFIAPI TlsSetVerifyHost(IN VOID *Tls, IN UINT32 Flags, IN CHAR8 *HostName)
Definition: TlsConfig.c:486
EFI_STATUS EFIAPI TlsGetKeyMaterial(IN VOID *Tls, IN OUT UINT8 *KeyMaterial)
Definition: TlsConfig.c:1385
UINT32 EFIAPI TlsGetVerify(IN VOID *Tls)
Definition: TlsConfig.c:1253
EFI_STATUS EFIAPI TlsGetCurrentCipher(IN VOID *Tls, IN OUT UINT16 *CipherId)
Definition: TlsConfig.c:1187
EFI_STATUS EFIAPI TlsSetCertRevocationList(IN VOID *Data, IN UINTN DataSize)
Definition: TlsConfig.c:929
EFI_STATUS EFIAPI TlsGetCertRevocationList(OUT VOID *Data, IN OUT UINTN *DataSize)
Definition: TlsConfig.c:1535
EFI_STATUS EFIAPI TlsSetCompressionMethod(IN UINT8 CompMethod)
Definition: TlsConfig.c:408
EFI_STATUS EFIAPI TlsSetCaCertificate(IN VOID *Tls, IN VOID *Data, IN UINTN DataSize)
Definition: TlsConfig.c:617
EFI_STATUS EFIAPI TlsSetCipherList(IN VOID *Tls, IN UINT16 *CipherId, IN UINTN CipherNum)
Definition: TlsConfig.c:171
EFI_STATUS EFIAPI TlsGetCurrentCompressionId(IN VOID *Tls, IN OUT UINT8 *CompressionId)
Definition: TlsConfig.c:1230
EFI_STATUS EFIAPI TlsSetConnectionEnd(IN VOID *Tls, IN BOOLEAN IsServer)
Definition: TlsConfig.c:122
EFI_STATUS EFIAPI TlsSetSessionId(IN VOID *Tls, IN UINT8 *SessionId, IN UINT16 SessionIdLen)
Definition: TlsConfig.c:572
EFI_STATUS EFIAPI TlsSetHostPrivateKey(IN VOID *Tls, IN VOID *Data, IN UINTN DataSize)
Definition: TlsConfig.c:904
EFI_STATUS EFIAPI TlsSetHostPublicCert(IN VOID *Tls, IN VOID *Data, IN UINTN DataSize)
Definition: TlsConfig.c:726
UINT8 EFIAPI TlsGetConnectionEnd(IN VOID *Tls)
Definition: TlsConfig.c:1158
VOID EFIAPI TlsSetVerify(IN VOID *Tls, IN UINT32 VerifyMode)
Definition: TlsConfig.c:454
VOID EFIAPI TlsGetClientRandom(IN VOID *Tls, IN OUT UINT8 *ClientRandom)
Definition: TlsConfig.c:1324
EFI_STATUS EFIAPI TlsSetVersion(IN VOID *Tls, IN UINT8 MajorVer, IN UINT8 MinorVer)
Definition: TlsConfig.c:56
EFI_STATUS EFIAPI TlsSetHostPrivateKeyEx(IN VOID *Tls, IN VOID *Data, IN UINTN DataSize, IN VOID *Password OPTIONAL)
Definition: TlsConfig.c:810
EFI_STATUS EFIAPI TlsGetSessionId(IN VOID *Tls, IN OUT UINT8 *SessionId, IN OUT UINT16 *SessionIdLen)
Definition: TlsConfig.c:1283
UINT16 EFIAPI TlsGetVersion(IN VOID *Tls)
Definition: TlsConfig.c:1130
EFI_STATUS EFIAPI TlsSetEcCurve(IN VOID *Tls, IN UINT8 *Data, IN UINTN DataSize)
Definition: TlsConfig.c:1060
EFI_STATUS EFIAPI TlsGetExportKey(IN VOID *Tls, IN CONST VOID *Label, IN CONST VOID *Context, IN UINTN ContextLen, OUT VOID *KeyBuffer, IN UINTN KeyBufferLen)
Definition: TlsConfig.c:1563
EFI_STATUS EFIAPI TlsGetCaCertificate(IN VOID *Tls, OUT VOID *Data, IN OUT UINTN *DataSize)
Definition: TlsConfig.c:1429
EFI_STATUS EFIAPI TlsGetHostPrivateKey(IN VOID *Tls, OUT VOID *Data, IN OUT UINTN *DataSize)
Definition: TlsConfig.c:1509
EFI_STATUS EFIAPI TlsSetSignatureAlgoList(IN VOID *Tls, IN UINT8 *Data, IN UINTN DataSize)
Definition: TlsConfig.c:956
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112