Re: [edk2] [PATCH v2] MdePkg/BaseLib: Add Base64Encode() and Base64Decode()

2019-01-28 Thread Ni, Ray
Minor comments regarding the parameter name.

> -Original Message-
> From: edk2-devel  On Behalf Of Shenglei
> Zhang
> Sent: Thursday, January 10, 2019 8:44 PM
> To: edk2-devel@lists.01.org
> Cc: Kinney, Michael D ; Gao, Liming
> 
> Subject: [edk2] [PATCH v2] MdePkg/BaseLib: Add Base64Encode() and
> Base64Decode()
> 
> 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
> 
> 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  | 345
> +++
>  2 files changed, 401 insertions(+)
> 
> diff --git a/MdePkg/Include/Library/BaseLib.h
> b/MdePkg/Include/Library/BaseLib.h
> index 1eb842384e..9317888a7e 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
> AsciiPtr and AsciiSize.
> +  The Ascii string is produced by converting the data string specified by
> DataPtr and DataLen.
> +
> +  @param DataPtr Input UINT8 data
> +  @param DataLenNumber of UINT8 bytes of data
> +  @param AsciiPtr  Pointer to output string buffer
> +  @param AsciiSize   Size of ascii buffer. Set to 0 to get the size needed.
> +   Caller is responsible for passing in
> + buffer of AsciiSize
> +
> +  @retval RETURN_SUCCESSWhen ascii buffer is filled in.
> +  @retval RETURN_INVALID_PARAMETER   If DataPtr is NULL or AsciiSize is
> NULL.
> +  @retval RETURN_INVALID_PARAMETER   If DataLen or AsciiSize is too big.
> +  @retval RETURN_BUFFER_TOO_SMALL   If DataLen is 0 and AsciiSize is <1.
> +  @retval RETURN_BUFFER_TOO_SMALL   If AsciiPtr is NULL or too small.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +Base64Encode (
> +  IN  CONST UINT8  *DataPtr,
1. Data or Source?
> +  INUINTN   DataLen,
2. DataLength or SourceLength?
> +  OUT   CHAR8  *AsciiPtr  OPTIONAL,
3. AsciiString or Destination?
> +  IN OUTUINTN  *AsciiSize
4. AsciiStringSize or DestinationSize?
> +  );
> +
> +/**
> +  Convert Base64 ascii string to binary data based on RFC4648.
> +
> +  Produce Null-terminated binary data in the output buffer specified by
> BinPtr and BinSize.
> +  The binary data is produced by converting the Base64 ascii string specified
> by DataPtr and DataLen.
> +
> +  @param DataPtr  Input ASCII characters
> +  @param DataLen Number of ASCII characters
> +  @param BinPtrPointer to output buffer
> +  @param BinSize  Caller is responsible for passing in buffer of at least
> BinSize.
> +Set 0 to get the size needed. Set to bytes 
> stored on return.
> +
> +  @retval RETURN_SUCCESSWhen binary buffer is filled in.
> +  @retval RETURN_INVALID_PARAMETER   If DataPtr is NULL or BinSize is
> NULL.
> +  @retval RETURN_INVALID_PARAMETER   If DataLen or BinSize is too big.
> +  @retval RETURN_INVALID_PARAMETER   If BinPtr NULL and BinSize != 0.
> +  @retval RETURN_INVALID_PARAMETER   If there is any Invalid character in
> input stream.
> +  @retval RETURN_BUFFER_TOO_SMALL   If Buffer length is too small.
> + **/
> +RETURN_STATUS
> +EFIAPI
> +Base64Decode (
> +  IN  CONST CHAR8  *DataPtr,
5. AsciiString or Source? At least I don't think "DataPtr" is proper here. It's 
not the same "DataPtr" in Encode() API.
> +  INUINTN   DataLen,
6. AsciiStringLength or SourceLength?
> +  OUT   UINT8  *BinPtr  OPTIONAL,
7. Data or Destination?
> +  IN OUTUINTN  *BinSize
8. DataSize or 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..761ff6830a 100644
> --- a/MdePkg/Library/BaseLib/String.c
> +++ b/MdePkg/Library/BaseLib/String.c
> @@ -1763,6 +1763,351 @@ 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. 

[edk2] [PATCH v2] MdePkg/BaseLib: Add Base64Encode() and Base64Decode()

2019-01-10 Thread Shenglei Zhang
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

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  | 345 +++
 2 files changed, 401 insertions(+)

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 1eb842384e..9317888a7e 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 
AsciiPtr and AsciiSize.
+  The Ascii string is produced by converting the data string specified by 
DataPtr and DataLen.
+
+  @param DataPtr Input UINT8 data
+  @param DataLenNumber of UINT8 bytes of data
+  @param AsciiPtr  Pointer to output string buffer
+  @param AsciiSize   Size of ascii buffer. Set to 0 to get the size needed.
+   Caller is responsible for passing in buffer of 
AsciiSize
+
+  @retval RETURN_SUCCESSWhen ascii buffer is filled in.
+  @retval RETURN_INVALID_PARAMETER   If DataPtr is NULL or AsciiSize is NULL.
+  @retval RETURN_INVALID_PARAMETER   If DataLen or AsciiSize is too big.
+  @retval RETURN_BUFFER_TOO_SMALL   If DataLen is 0 and AsciiSize is <1.
+  @retval RETURN_BUFFER_TOO_SMALL   If AsciiPtr is NULL or too small.
+
+**/
+RETURN_STATUS
+EFIAPI
+Base64Encode (
+  IN  CONST UINT8  *DataPtr,
+  INUINTN   DataLen,
+  OUT   CHAR8  *AsciiPtr  OPTIONAL,
+  IN OUTUINTN  *AsciiSize
+  );
+
+/**
+  Convert Base64 ascii string to binary data based on RFC4648.
+
+  Produce Null-terminated binary data in the output buffer specified by BinPtr 
and BinSize.
+  The binary data is produced by converting the Base64 ascii string specified 
by DataPtr and DataLen.
+
+  @param DataPtr  Input ASCII characters
+  @param DataLen Number of ASCII characters
+  @param BinPtrPointer to output buffer
+  @param BinSize  Caller is responsible for passing in buffer of at least 
BinSize.
+Set 0 to get the size needed. Set to bytes 
stored on return.
+
+  @retval RETURN_SUCCESSWhen binary buffer is filled in.
+  @retval RETURN_INVALID_PARAMETER   If DataPtr is NULL or BinSize is NULL.
+  @retval RETURN_INVALID_PARAMETER   If DataLen or BinSize is too big.
+  @retval RETURN_INVALID_PARAMETER   If BinPtr NULL and BinSize != 0.
+  @retval RETURN_INVALID_PARAMETER   If there is any Invalid character in 
input stream.
+  @retval RETURN_BUFFER_TOO_SMALL   If Buffer length is too small.
+ **/
+RETURN_STATUS
+EFIAPI
+Base64Decode (
+  IN  CONST CHAR8  *DataPtr,
+  INUINTN   DataLen,
+  OUT   UINT8  *BinPtr  OPTIONAL,
+  IN OUTUINTN  *BinSize
+  );
+
 /**
   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..761ff6830a 100644
--- a/MdePkg/Library/BaseLib/String.c
+++ b/MdePkg/Library/BaseLib/String.c
@@ -1763,6 +1763,351 @@ 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[] = {
+  //
+  // Valid characters 
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
+  // Also, set '=' as a zero for decoding
+  // 0  ,1,   2,   3,4,   5,   
 6,   7,   8,9,   a,b,  
  c,   d,e,f
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  
BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //   0
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  
BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,   //  10
+  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,  BAD_V,