Base64Status_t base64Decode()

in source/ota_base64.c [420:514]


Base64Status_t base64Decode( uint8_t * pDest,
                             const size_t destLen,
                             size_t * pResultLen,
                             const uint8_t * pEncodedData,
                             const size_t encodedLen )
{
    uint32_t base64IndexBuffer = 0;
    uint32_t numDataInBuffer = 0;
    const uint8_t * pCurrBase64Symbol = pEncodedData;
    size_t outputLen = 0;
    int64_t numPadding = 0;
    int64_t numWhitespace = 0;
    Base64Status_t returnVal = Base64Success;

    if( ( pEncodedData == NULL ) || ( pDest == NULL ) || ( pResultLen == NULL ) )
    {
        returnVal = Base64NullPointerInput;
    }

    if( encodedLen < MIN_VALID_ENCODED_DATA_SIZE )
    {
        returnVal = Base64InvalidInputSize;
    }

    /* This loop will decode the first (encodedLen - (encodedLen % 4)) amount of data. */
    while( ( returnVal == Base64Success ) &&
           ( pCurrBase64Symbol < ( pEncodedData + encodedLen ) ) )
    {
        uint8_t base64Index = 0;
        /* Read in the next Ascii character that represents the current Base64 symbol. */
        uint8_t base64AsciiSymbol = *pCurrBase64Symbol++;
        /* Get the Base64 index that represents the Base64 symbol. */
        base64Index = pBase64SymbolToIndexMap[ base64AsciiSymbol ];

        /* Validate the input and update counters for padding and whitespace. */
        returnVal = preprocessBase64Index( base64Index,
                                           &numPadding,
                                           &numWhitespace );

        if( returnVal != Base64Success )
        {
            break;
        }

        /* Add the current Base64 index to a buffer. */
        updateBase64DecodingBuffer( base64Index,
                                    &base64IndexBuffer,
                                    &numDataInBuffer );

        /* Decode the buffer when it's full and store the result. */
        if( numDataInBuffer == MAX_NUM_BASE64_DATA )
        {
            returnVal = decodeBase64IndexBuffer( &base64IndexBuffer,
                                                 &numDataInBuffer,
                                                 pDest,
                                                 destLen,
                                                 &outputLen );
        }
    }

    if( returnVal == Base64Success )
    {
        /* This scenario is only possible when the number of encoded symbols ( excluding newlines
         * and padding ) being decoded mod four is equal to one. There is no valid scenario where
         * data can be encoded to create a result of this size. Therefore if this size is
         * encountered, it's assumed that the incoming Base64 data is not encoded correctly. */
        if( numDataInBuffer == 1U )
        {
            returnVal = Base64InvalidInputSize;
        }
    }

    if( returnVal == Base64Success )
    {
        /* Handle the scenarios where there is padding at the end of the encoded data.
         *
         * Note: This implementation assumes that non-zero padding bits are an error. This prevents
         * having multiple non-matching encoded data strings map to identical decoded strings. */
        if( ( numDataInBuffer == 2U ) || ( numDataInBuffer == 3U ) )
        {
            returnVal = decodeBase64IndexBuffer( &base64IndexBuffer,
                                                 &numDataInBuffer,
                                                 pDest,
                                                 destLen,
                                                 &outputLen );
        }
    }

    if( returnVal == Base64Success )
    {
        *pResultLen = outputLen;
    }

    return returnVal;
}