Re: [edk2] [PATCH v2] MdePkg/BaseLib: Add Base64Encode() and Base64Decode()
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()
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,