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

2019-01-30 Thread Zhang, Shenglei


> -Original Message-
> From: Ni, Ray
> Sent: Wednesday, January 30, 2019 5:49 PM
> To: Zhang, Shenglei ; edk2-devel@lists.01.org
> Cc: Kinney, Michael D ; Mike Turner
> ; Gao, Liming 
> Subject: Re: [edk2] [PATCH v4] MdePkg/BaseLib: Add Base64Encode() and
> Base64Decode()
> 
> 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   SourceLengt

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

2019-01-30 Thread Ni, Ruiyu

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, 

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

2019-01-29 Thread Shenglei Zhang
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[] = {
+  //
+  // Valid characters 
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
+  // Also, set '=' as a zero for decoding
+  // 0  ,1,   2,   3,4,   5,   
 6,   7,   8,