Comments in below.
On 1/30/2019 2:28 PM, Shenglei Zhang wrote:
From: Mike Turner
Introduce public functions Base64Encode and Base64Decode.
https://bugzilla.tianocore.org/show_bug.cgi?id=1370
v2:1.Remove some white space.
2.Add unit test with test vectors in RFC 4648.
https://github.com/shenglei10/edk2/tree/encode_test
https://github.com/shenglei10/edk2/tree/decode_test
v3:1.Align white space.
2.Update comments of Base64Encode and Base64Decode.
3.Change the use of macro RETURN_DEVICE_ERROR to
RETURN_INVALID_PARAMETER in string.c.
v4:Change parameters' names.
Cc: Michael D Kinney
Cc: Liming Gao
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Shenglei Zhang
---
MdePkg/Include/Library/BaseLib.h | 56 +
MdePkg/Library/BaseLib/String.c | 344 +++
2 files changed, 400 insertions(+)
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 1eb842384e..03173def58 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -2720,6 +2720,62 @@ AsciiStrnToUnicodeStrS (
OUT UINTN *DestinationLength
);
+/**
+ Convert binary data to a Base64 encoded ascii string based on RFC4648.
+
+ Produce a Null-terminated Ascii string in the output buffer specified by
Destination and DestinationSize.
+ The Ascii string is produced by converting the data string specified by
Source and SourceLength.
+
+ @param Source Input UINT8 data
+ @param SourceLength Number of UINT8 bytes of data
+ @param Destination Pointer to output string buffer
+ @param DestinationSize Size of ascii buffer. Set to 0 to get the size
needed.
+ Caller is responsible for passing in buffer of
DestinationSize
+
+ @retval RETURN_SUCCESS When ascii buffer is filled in.
+ @retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is
NULL.
+ @retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is
bigger than (MAX_ADDRESS - (UINTN)Destination).
+ @retval RETURN_BUFFER_TOO_SMALLIf SourceLength is 0 and DestinationSize is
<1.
+ @retval RETURN_BUFFER_TOO_SMALLIf Destination is NULL or DestinationSize
is smaller than required buffersize.
+
+**/
+RETURN_STATUS
+EFIAPI
+Base64Encode (
+ IN CONST UINT8 *Source,
+ INUINTN SourceLength,
+ OUT CHAR8 *Destination OPTIONAL,
+ IN OUTUINTN *DestinationSize
+ );
+
+/**
+ Convert Base64 ascii string to binary data based on RFC4648.
+
+ Produce Null-terminated binary data in the output buffer specified by
Destination and DestinationSize.
+ The binary data is produced by converting the Base64 ascii string specified
by Source and SourceLength.
+
+ @param Source Input ASCII characters
+ @param SourceLengthNumber of ASCII characters
+ @param Destination Pointer to output buffer
+ @param DestinationSize Caller is responsible for passing in buffer of at
least DestinationSize.
+ Set 0 to get the size needed. Set to bytes stored on
return.
+
+ @retval RETURN_SUCCESS When binary buffer is filled in.
+ @retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is
NULL.
+ @retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is
bigger than (MAX_ADDRESS -(UINTN)Destination ).
+ @retval RETURN_INVALID_PARAMETER If there is any invalid character in
input stream.
+ @retval RETURN_BUFFER_TOO_SMALLIf buffer length is smaller than required
buffer size.
+
+ **/
+RETURN_STATUS
+EFIAPI
+Base64Decode (
+ IN CONST CHAR8 *Source,
+ INUINTN SourceLength,
+ OUT UINT8 *Destination OPTIONAL,
+ IN OUTUINTN *DestinationSize
+ );
+
/**
Converts an 8-bit value to an 8-bit BCD value.
diff --git a/MdePkg/Library/BaseLib/String.c b/MdePkg/Library/BaseLib/String.c
index e6df12797d..e4aa5a57e4 100644
--- a/MdePkg/Library/BaseLib/String.c
+++ b/MdePkg/Library/BaseLib/String.c
@@ -1763,6 +1763,350 @@ AsciiStrToUnicodeStr (
#endif
+//
+// The basis for Base64 encoding is RFC 4686
https://tools.ietf.org/html/rfc4648
+//
+// RFC 4686 has a number of MAY and SHOULD cases. This implementation chooses
+// the more restrictive versions for security concerns (see RFC 4686 section
3.3).
+//
+// A invalid character, if encountered during the decode operation, causes the
data
+// to be rejected. In addition, the '=' padding character is only allowed at
the end
+// of the Base64 encoded string.
+//
+#define BAD_V 99
+
+STATIC CHAR8 Encoding_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+"abcdefghijklmnopqrstuvwxyz"
+"0123456789+/";
+
+STATIC UINT8 Decoding_table[] = {
1. Can the Encoding_table/Decoding_table pass ECC check?
+ //
+ // Valid characters
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
+ // Also,