/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <openssl/aes.h>
#include <openssl/hmac.h>

#include "FwdLockConv.h"
#include "FwdLockGlue.h"

#define TRUE 1
#define FALSE 0

#define INVALID_OFFSET ((off64_t)-1)

#define MAX_NUM_SESSIONS 32

#define OUTPUT_BUFFER_SIZE_INCREMENT 1024
#define READ_BUFFER_SIZE 1024

#define MAX_BOUNDARY_LENGTH 70
#define MAX_DELIMITER_LENGTH (MAX_BOUNDARY_LENGTH + 4)

#define STRING_LENGTH_INCREMENT 25

#define KEY_SIZE AES_BLOCK_SIZE
#define KEY_SIZE_IN_BITS (KEY_SIZE * 8)

#define SHA1_HASH_SIZE 20

#define FWD_LOCK_VERSION 0
#define FWD_LOCK_SUBFORMAT 0
#define USAGE_RESTRICTION_FLAGS 0
#define CONTENT_TYPE_LENGTH_POS 7
#define TOP_HEADER_SIZE 8

/**
 * Data type for the parser states of the converter.
 */
typedef enum FwdLockConv_ParserState {
    FwdLockConv_ParserState_WantsOpenDelimiter,
    FwdLockConv_ParserState_WantsMimeHeaders,
    FwdLockConv_ParserState_WantsBinaryEncodedData,
    FwdLockConv_ParserState_WantsBase64EncodedData,
    FwdLockConv_ParserState_Done
} FwdLockConv_ParserState_t;

/**
 * Data type for the scanner states of the converter.
 */
typedef enum FwdLockConv_ScannerState {
    FwdLockConv_ScannerState_WantsFirstDash,
    FwdLockConv_ScannerState_WantsSecondDash,
    FwdLockConv_ScannerState_WantsCR,
    FwdLockConv_ScannerState_WantsLF,
    FwdLockConv_ScannerState_WantsBoundary,
    FwdLockConv_ScannerState_WantsBoundaryEnd,
    FwdLockConv_ScannerState_WantsMimeHeaderNameStart,
    FwdLockConv_ScannerState_WantsMimeHeaderName,
    FwdLockConv_ScannerState_WantsMimeHeaderNameEnd,
    FwdLockConv_ScannerState_WantsContentTypeStart,
    FwdLockConv_ScannerState_WantsContentType,
    FwdLockConv_ScannerState_WantsContentTransferEncodingStart,
    FwdLockConv_ScannerState_Wants_A_OR_I,
    FwdLockConv_ScannerState_Wants_N,
    FwdLockConv_ScannerState_Wants_A,
    FwdLockConv_ScannerState_Wants_R,
    FwdLockConv_ScannerState_Wants_Y,
    FwdLockConv_ScannerState_Wants_S,
    FwdLockConv_ScannerState_Wants_E,
    FwdLockConv_ScannerState_Wants_6,
    FwdLockConv_ScannerState_Wants_4,
    FwdLockConv_ScannerState_Wants_B,
    FwdLockConv_ScannerState_Wants_I,
    FwdLockConv_ScannerState_Wants_T,
    FwdLockConv_ScannerState_WantsContentTransferEncodingEnd,
    FwdLockConv_ScannerState_WantsMimeHeaderValueEnd,
    FwdLockConv_ScannerState_WantsMimeHeadersEnd,
    FwdLockConv_ScannerState_WantsByte1,
    FwdLockConv_ScannerState_WantsByte1_AfterCRLF,
    FwdLockConv_ScannerState_WantsByte2,
    FwdLockConv_ScannerState_WantsByte3,
    FwdLockConv_ScannerState_WantsByte4,
    FwdLockConv_ScannerState_WantsPadding,
    FwdLockConv_ScannerState_WantsWhitespace,
    FwdLockConv_ScannerState_WantsWhitespace_AfterCRLF,
    FwdLockConv_ScannerState_WantsDelimiter
} FwdLockConv_ScannerState_t;

/**
 * Data type for the content transfer encoding.
 */
typedef enum FwdLockConv_ContentTransferEncoding {
    FwdLockConv_ContentTransferEncoding_Undefined,
    FwdLockConv_ContentTransferEncoding_Binary,
    FwdLockConv_ContentTransferEncoding_Base64
} FwdLockConv_ContentTransferEncoding_t;

/**
 * Data type for a dynamically growing string.
 */
typedef struct FwdLockConv_String {
    char *ptr;
    size_t length;
    size_t maxLength;
    size_t lengthIncrement;
} FwdLockConv_String_t;

/**
 * Data type for the per-file state information needed by the converter.
 */
typedef struct FwdLockConv_Session {
    FwdLockConv_ParserState_t parserState;
    FwdLockConv_ScannerState_t scannerState;
    FwdLockConv_ScannerState_t savedScannerState;
    off64_t numCharsConsumed;
    char delimiter[MAX_DELIMITER_LENGTH];
    size_t delimiterLength;
    size_t delimiterMatchPos;
    FwdLockConv_String_t mimeHeaderName;
    FwdLockConv_String_t contentType;
    FwdLockConv_ContentTransferEncoding_t contentTransferEncoding;
    unsigned char sessionKey[KEY_SIZE];
    void *pEncryptedSessionKey;
    size_t encryptedSessionKeyLength;
    AES_KEY encryptionRoundKeys;
    HMAC_CTX signingContext;
    unsigned char topHeader[TOP_HEADER_SIZE];
    unsigned char counter[AES_BLOCK_SIZE];
    unsigned char keyStream[AES_BLOCK_SIZE];
    int keyStreamIndex;
    unsigned char ch;
    size_t outputBufferSize;
    size_t dataOffset;
    size_t numDataBytes;
} FwdLockConv_Session_t;

static FwdLockConv_Session_t *sessionPtrs[MAX_NUM_SESSIONS] = { NULL };

static pthread_mutex_t sessionAcquisitionMutex = PTHREAD_MUTEX_INITIALIZER;

static const FwdLockConv_String_t nullString = { NULL, 0, 0, STRING_LENGTH_INCREMENT };

static const unsigned char topHeaderTemplate[] =
    { 'F', 'W', 'L', 'K', FWD_LOCK_VERSION, FWD_LOCK_SUBFORMAT, USAGE_RESTRICTION_FLAGS };

static const char strContent[] = "content-";
static const char strType[] = "type";
static const char strTransferEncoding[] = "transfer-encoding";
static const char strTextPlain[] = "text/plain";
static const char strApplicationVndOmaDrmRightsXml[] = "application/vnd.oma.drm.rights+xml";
static const char strApplicationVndOmaDrmContent[] = "application/vnd.oma.drm.content";

static const size_t strlenContent = sizeof strContent - 1;
static const size_t strlenTextPlain = sizeof strTextPlain - 1;

static const signed char base64Values[] = {
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
};

/**
 * Acquires an unused converter session.
 *
 * @return A session ID.
 */
static int FwdLockConv_AcquireSession() {
    int sessionId = -1;
    int i;
    pthread_mutex_lock(&sessionAcquisitionMutex);
    for (i = 0; i < MAX_NUM_SESSIONS; ++i) {
        if (sessionPtrs[i] == NULL) {
            sessionPtrs[i] = malloc(sizeof *sessionPtrs[i]);
            if (sessionPtrs[i] != NULL) {
                sessionId = i;
            }
            break;
        }
    }
    pthread_mutex_unlock(&sessionAcquisitionMutex);
    return sessionId;
}

/**
 * Checks whether a session ID is in range and currently in use.
 *
 * @param[in] sessionID A session ID.
 *
 * @return A Boolean value indicating whether the session ID is in range and currently in use.
 */
static int FwdLockConv_IsValidSession(int sessionId) {
    return 0 <= sessionId && sessionId < MAX_NUM_SESSIONS && sessionPtrs[sessionId] != NULL;
}

/**
 * Releases a converter session.
 *
 * @param[in] sessionID A session ID.
 */
static void FwdLockConv_ReleaseSession(int sessionId) {
    pthread_mutex_lock(&sessionAcquisitionMutex);
    assert(FwdLockConv_IsValidSession(sessionId));
    memset(sessionPtrs[sessionId], 0, sizeof *sessionPtrs[sessionId]); // Zero out key data.
    free(sessionPtrs[sessionId]);
    sessionPtrs[sessionId] = NULL;
    pthread_mutex_unlock(&sessionAcquisitionMutex);
}

/**
 * Derives cryptographically independent keys for encryption and signing from the session key.
 *
 * @param[in,out] pSession A reference to a converter session.
 *
 * @return A status code.
 */
static int FwdLockConv_DeriveKeys(FwdLockConv_Session_t *pSession) {
    FwdLockConv_Status_t status;
    struct FwdLockConv_DeriveKeys_Data {
        AES_KEY sessionRoundKeys;
        unsigned char value[KEY_SIZE];
        unsigned char key[KEY_SIZE];
    };
    const size_t kSize = sizeof(struct FwdLockConv_DeriveKeys_Data);
    struct FwdLockConv_DeriveKeys_Data *pData = malloc(kSize);
    if (pData == NULL) {
        status = FwdLockConv_Status_OutOfMemory;
    } else {
        if (AES_set_encrypt_key(pSession->sessionKey, KEY_SIZE_IN_BITS,
                                &pData->sessionRoundKeys) != 0) {
            status = FwdLockConv_Status_ProgramError;
        } else {
            // Encrypt the 16-byte value {0, 0, ..., 0} to produce the encryption key.
            memset(pData->value, 0, KEY_SIZE);
            AES_encrypt(pData->value, pData->key, &pData->sessionRoundKeys);
            if (AES_set_encrypt_key(pData->key, KEY_SIZE_IN_BITS,
                                    &pSession->encryptionRoundKeys) != 0) {
                status = FwdLockConv_Status_ProgramError;
            } else {
                // Encrypt the 16-byte value {1, 0, ..., 0} to produce the signing key.
                ++pData->value[0];
                AES_encrypt(pData->value, pData->key, &pData->sessionRoundKeys);
                HMAC_CTX_init(&pSession->signingContext);
                HMAC_Init_ex(&pSession->signingContext, pData->key, KEY_SIZE, EVP_sha1(), NULL);
                status = FwdLockConv_Status_OK;
            }
        }
        memset(pData, 0, kSize); // Zero out key data.
        free(pData);
    }
    return status;
}

/**
 * Checks whether a given character is valid in a boundary. Allows some non-standard characters that
 * are invalid according to RFC 2046 but nevertheless used by one vendor's DRM packager. Note that
 * the boundary may contain leading and internal spaces.
 *
 * @param[in] ch The character to check.
 *
 * @return A Boolean value indicating whether the given character is valid in a boundary.
 */
static int FwdLockConv_IsBoundaryChar(int ch) {
    return isalnum(ch) || ch == '\'' || ch == '(' || ch == ')' || ch == '+' || ch == '_' ||
            ch == ',' || ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == '=' ||
            ch == '?' || ch == ' ' || ch == '%' || ch == '[' || ch == '&' || ch == '*' || ch == '^';
}

/**
 * Checks whether a given character should be considered whitespace, using a narrower definition
 * than the standard-library isspace() function.
 *
 * @param[in] ch The character to check.
 *
 * @return A Boolean value indicating whether the given character should be considered whitespace.
 */
static int FwdLockConv_IsWhitespace(int ch) {
    return ch == ' ' || ch == '\t';
}

/**
 * Removes trailing spaces from the delimiter.
 *
 * @param[in,out] pSession A reference to a converter session.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_RightTrimDelimiter(FwdLockConv_Session_t *pSession) {
    while (pSession->delimiterLength > 4 &&
           pSession->delimiter[pSession->delimiterLength - 1] == ' ') {
        --pSession->delimiterLength;
    }
    if (pSession->delimiterLength > 4) {
        return FwdLockConv_Status_OK;
    }
    return FwdLockConv_Status_SyntaxError;
}

/**
 * Matches the open delimiter.
 *
 * @param[in,out] pSession A reference to a converter session.
 * @param[in] ch A character.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_MatchOpenDelimiter(FwdLockConv_Session_t *pSession,
                                                           int ch) {
    FwdLockConv_Status_t status = FwdLockConv_Status_OK;
    switch (pSession->scannerState) {
    case FwdLockConv_ScannerState_WantsFirstDash:
        if (ch == '-') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsSecondDash;
        } else if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else {
            pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
        }
        break;
    case FwdLockConv_ScannerState_WantsSecondDash:
        if (ch == '-') {
            // The delimiter starts with "\r\n--" (the open delimiter may omit the initial "\r\n").
            // The rest is the user-defined boundary that should come next.
            pSession->delimiter[0] = '\r';
            pSession->delimiter[1] = '\n';
            pSession->delimiter[2] = '-';
            pSession->delimiter[3] = '-';
            pSession->delimiterLength = 4;
            pSession->scannerState = FwdLockConv_ScannerState_WantsBoundary;
        } else if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else {
            pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
        }
        break;
    case FwdLockConv_ScannerState_WantsCR:
        if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        }
        break;
    case FwdLockConv_ScannerState_WantsLF:
        if (ch == '\n') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsFirstDash;
        } else if (ch != '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
        }
        break;
    case FwdLockConv_ScannerState_WantsBoundary:
        if (FwdLockConv_IsBoundaryChar(ch)) {
            // The boundary may contain leading and internal spaces, so trailing spaces will also be
            // matched here. These will be removed later.
            if (pSession->delimiterLength < MAX_DELIMITER_LENGTH) {
                pSession->delimiter[pSession->delimiterLength++] = ch;
            } else if (ch != ' ') {
                status = FwdLockConv_Status_SyntaxError;
            }
        } else if (ch == '\r') {
            status = FwdLockConv_RightTrimDelimiter(pSession);
            if (status == FwdLockConv_Status_OK) {
                pSession->scannerState = FwdLockConv_ScannerState_WantsBoundaryEnd;
            }
        } else if (ch == '\t') {
            status = FwdLockConv_RightTrimDelimiter(pSession);
            if (status == FwdLockConv_Status_OK) {
                pSession->scannerState = FwdLockConv_ScannerState_WantsWhitespace;
            }
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsWhitespace:
        if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsBoundaryEnd;
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsBoundaryEnd:
        if (ch == '\n') {
            pSession->parserState = FwdLockConv_ParserState_WantsMimeHeaders;
            pSession->scannerState = FwdLockConv_ScannerState_WantsMimeHeaderNameStart;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    default:
        status = FwdLockConv_Status_ProgramError;
        break;
    }
    return status;
}

/**
 * Checks whether a given character is valid in a MIME header name.
 *
 * @param[in] ch The character to check.
 *
 * @return A Boolean value indicating whether the given character is valid in a MIME header name.
 */
static int FwdLockConv_IsMimeHeaderNameChar(int ch) {
    return isgraph(ch) && ch != ':';
}

/**
 * Checks whether a given character is valid in a MIME header value.
 *
 * @param[in] ch The character to check.
 *
 * @return A Boolean value indicating whether the given character is valid in a MIME header value.
 */
static int FwdLockConv_IsMimeHeaderValueChar(int ch) {
    return isgraph(ch) && ch != ';';
}

/**
 * Appends a character to the specified dynamically growing string.
 *
 * @param[in,out] pString A reference to a dynamically growing string.
 * @param[in] ch The character to append.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_StringAppend(FwdLockConv_String_t *pString, int ch) {
    if (pString->length == pString->maxLength) {
        size_t newMaxLength = pString->maxLength + pString->lengthIncrement;
        char *newPtr = realloc(pString->ptr, newMaxLength + 1);
        if (newPtr == NULL) {
            return FwdLockConv_Status_OutOfMemory;
        }
        pString->ptr = newPtr;
        pString->maxLength = newMaxLength;
    }
    pString->ptr[pString->length++] = ch;
    pString->ptr[pString->length] = '\0';
    return FwdLockConv_Status_OK;
}

/**
 * Attempts to recognize the MIME header name and changes the scanner state accordingly.
 *
 * @param[in,out] pSession A reference to a converter session.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_RecognizeMimeHeaderName(FwdLockConv_Session_t *pSession) {
    FwdLockConv_Status_t status = FwdLockConv_Status_OK;
    if (strncmp(pSession->mimeHeaderName.ptr, strContent, strlenContent) == 0) {
        if (strcmp(pSession->mimeHeaderName.ptr + strlenContent, strType) == 0) {
            if (pSession->contentType.ptr == NULL) {
                pSession->scannerState = FwdLockConv_ScannerState_WantsContentTypeStart;
            } else {
                status = FwdLockConv_Status_SyntaxError;
            }
        } else if (strcmp(pSession->mimeHeaderName.ptr + strlenContent, strTransferEncoding) == 0) {
            if (pSession->contentTransferEncoding ==
                    FwdLockConv_ContentTransferEncoding_Undefined) {
                pSession->scannerState = FwdLockConv_ScannerState_WantsContentTransferEncodingStart;
            } else {
                status = FwdLockConv_Status_SyntaxError;
            }
        } else {
            pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
        }
    } else {
        pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
    }
    return status;
}

/**
 * Applies defaults to missing MIME header values.
 *
 * @param[in,out] pSession A reference to a converter session.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_ApplyDefaults(FwdLockConv_Session_t *pSession) {
    if (pSession->contentType.ptr == NULL) {
        // Content type is missing: default to "text/plain".
        pSession->contentType.ptr = malloc(sizeof strTextPlain);
        if (pSession->contentType.ptr == NULL) {
            return FwdLockConv_Status_OutOfMemory;
        }
        memcpy(pSession->contentType.ptr, strTextPlain, sizeof strTextPlain);
        pSession->contentType.length = strlenTextPlain;
        pSession->contentType.maxLength = strlenTextPlain;
    }
    if (pSession->contentTransferEncoding == FwdLockConv_ContentTransferEncoding_Undefined) {
        // Content transfer encoding is missing: default to binary.
        pSession->contentTransferEncoding = FwdLockConv_ContentTransferEncoding_Binary;
    }
    return FwdLockConv_Status_OK;
}

/**
 * Verifies that the content type is supported.
 *
 * @param[in,out] pSession A reference to a converter session.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_VerifyContentType(FwdLockConv_Session_t *pSession) {
    FwdLockConv_Status_t status;
    if (pSession->contentType.ptr == NULL) {
        status = FwdLockConv_Status_ProgramError;
    } else if (strcmp(pSession->contentType.ptr, strApplicationVndOmaDrmRightsXml) == 0 ||
               strcmp(pSession->contentType.ptr, strApplicationVndOmaDrmContent) == 0) {
        status = FwdLockConv_Status_UnsupportedFileFormat;
    } else {
        status = FwdLockConv_Status_OK;
    }
    return status;
}

/**
 * Writes the header of the output file.
 *
 * @param[in,out] pSession A reference to a converter session.
 * @param[out] pOutput The output from the conversion process.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_WriteHeader(FwdLockConv_Session_t *pSession,
                                                    FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status;
    if (pSession->contentType.length > UCHAR_MAX) {
        status = FwdLockConv_Status_SyntaxError;
    } else {
        pSession->outputBufferSize = OUTPUT_BUFFER_SIZE_INCREMENT;
        pOutput->fromConvertData.pBuffer = malloc(pSession->outputBufferSize);
        if (pOutput->fromConvertData.pBuffer == NULL) {
            status = FwdLockConv_Status_OutOfMemory;
        } else {
            size_t encryptedSessionKeyPos = TOP_HEADER_SIZE + pSession->contentType.length;
            size_t dataSignaturePos = encryptedSessionKeyPos + pSession->encryptedSessionKeyLength;
            size_t headerSignaturePos = dataSignaturePos + SHA1_HASH_SIZE;
            pSession->dataOffset = headerSignaturePos + SHA1_HASH_SIZE;
            memcpy(pSession->topHeader, topHeaderTemplate, sizeof topHeaderTemplate);
            pSession->topHeader[CONTENT_TYPE_LENGTH_POS] =
                    (unsigned char)pSession->contentType.length;
            memcpy(pOutput->fromConvertData.pBuffer, pSession->topHeader, TOP_HEADER_SIZE);
            memcpy((char *)pOutput->fromConvertData.pBuffer + TOP_HEADER_SIZE,
                   pSession->contentType.ptr, pSession->contentType.length);
            memcpy((char *)pOutput->fromConvertData.pBuffer + encryptedSessionKeyPos,
                   pSession->pEncryptedSessionKey, pSession->encryptedSessionKeyLength);

            // Set the signatures to all zeros for now; they will have to be updated later.
            memset((char *)pOutput->fromConvertData.pBuffer + dataSignaturePos, 0,
                   SHA1_HASH_SIZE);
            memset((char *)pOutput->fromConvertData.pBuffer + headerSignaturePos, 0,
                   SHA1_HASH_SIZE);

            pOutput->fromConvertData.numBytes = pSession->dataOffset;
            status = FwdLockConv_Status_OK;
        }
    }
    return status;
}

/**
 * Matches the MIME headers.
 *
 * @param[in,out] pSession A reference to a converter session.
 * @param[in] ch A character.
 * @param[out] pOutput The output from the conversion process.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_MatchMimeHeaders(FwdLockConv_Session_t *pSession,
                                                         int ch,
                                                         FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status = FwdLockConv_Status_OK;
    switch (pSession->scannerState) {
    case FwdLockConv_ScannerState_WantsMimeHeaderNameStart:
        if (FwdLockConv_IsMimeHeaderNameChar(ch)) {
            pSession->mimeHeaderName.length = 0;
            status = FwdLockConv_StringAppend(&pSession->mimeHeaderName, tolower(ch));
            if (status == FwdLockConv_Status_OK) {
                pSession->scannerState = FwdLockConv_ScannerState_WantsMimeHeaderName;
            }
        } else if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsMimeHeadersEnd;
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsMimeHeaderName:
        if (FwdLockConv_IsMimeHeaderNameChar(ch)) {
            status = FwdLockConv_StringAppend(&pSession->mimeHeaderName, tolower(ch));
        } else if (ch == ':') {
            status = FwdLockConv_RecognizeMimeHeaderName(pSession);
        } else if (FwdLockConv_IsWhitespace(ch)) {
            pSession->scannerState = FwdLockConv_ScannerState_WantsMimeHeaderNameEnd;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsMimeHeaderNameEnd:
        if (ch == ':') {
            status = FwdLockConv_RecognizeMimeHeaderName(pSession);
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsContentTypeStart:
        if (FwdLockConv_IsMimeHeaderValueChar(ch)) {
            status = FwdLockConv_StringAppend(&pSession->contentType, tolower(ch));
            if (status == FwdLockConv_Status_OK) {
                pSession->scannerState = FwdLockConv_ScannerState_WantsContentType;
            }
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsContentType:
        if (FwdLockConv_IsMimeHeaderValueChar(ch)) {
            status = FwdLockConv_StringAppend(&pSession->contentType, tolower(ch));
        } else if (ch == ';') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
        } else if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (FwdLockConv_IsWhitespace(ch)) {
            pSession->scannerState = FwdLockConv_ScannerState_WantsMimeHeaderValueEnd;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsContentTransferEncodingStart:
        if (ch == 'b' || ch == 'B') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_A_OR_I;
        } else if (ch == '7' || ch == '8') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_B;
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_A_OR_I:
        if (ch == 'i' || ch == 'I') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_N;
        } else if (ch == 'a' || ch == 'A') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_S;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_N:
        if (ch == 'n' || ch == 'N') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_A;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_A:
        if (ch == 'a' || ch == 'A') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_R;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_R:
        if (ch == 'r' || ch == 'R') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_Y;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_Y:
        if (ch == 'y' || ch == 'Y') {
            pSession->contentTransferEncoding = FwdLockConv_ContentTransferEncoding_Binary;
            pSession->scannerState = FwdLockConv_ScannerState_WantsContentTransferEncodingEnd;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_S:
        if (ch == 's' || ch == 'S') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_E;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_E:
        if (ch == 'e' || ch == 'E') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_6;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_6:
        if (ch == '6') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_4;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_4:
        if (ch == '4') {
            pSession->contentTransferEncoding = FwdLockConv_ContentTransferEncoding_Base64;
            pSession->scannerState = FwdLockConv_ScannerState_WantsContentTransferEncodingEnd;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_B:
        if (ch == 'b' || ch == 'B') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_I;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_I:
        if (ch == 'i' || ch == 'I') {
            pSession->scannerState = FwdLockConv_ScannerState_Wants_T;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_Wants_T:
        if (ch == 't' || ch == 'T') {
            pSession->contentTransferEncoding = FwdLockConv_ContentTransferEncoding_Binary;
            pSession->scannerState = FwdLockConv_ScannerState_WantsContentTransferEncodingEnd;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_WantsContentTransferEncodingEnd:
        if (ch == ';') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
        } else if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (FwdLockConv_IsWhitespace(ch)) {
            pSession->scannerState = FwdLockConv_ScannerState_WantsMimeHeaderValueEnd;
        } else {
            status = FwdLockConv_Status_UnsupportedContentTransferEncoding;
        }
        break;
    case FwdLockConv_ScannerState_WantsMimeHeaderValueEnd:
        if (ch == ';') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsCR;
        } else if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsCR:
        if (ch == '\r') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        }
        break;
    case FwdLockConv_ScannerState_WantsLF:
        if (ch == '\n') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsMimeHeaderNameStart;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsMimeHeadersEnd:
        if (ch == '\n') {
            status = FwdLockConv_ApplyDefaults(pSession);
            if (status == FwdLockConv_Status_OK) {
                status = FwdLockConv_VerifyContentType(pSession);
            }
            if (status == FwdLockConv_Status_OK) {
                status = FwdLockConv_WriteHeader(pSession, pOutput);
            }
            if (status == FwdLockConv_Status_OK) {
                if (pSession->contentTransferEncoding ==
                        FwdLockConv_ContentTransferEncoding_Binary) {
                    pSession->parserState = FwdLockConv_ParserState_WantsBinaryEncodedData;
                } else {
                    pSession->parserState = FwdLockConv_ParserState_WantsBase64EncodedData;
                }
                pSession->scannerState = FwdLockConv_ScannerState_WantsByte1;
            }
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    default:
        status = FwdLockConv_Status_ProgramError;
        break;
    }
    return status;
}

/**
 * Increments the counter, treated as a 16-byte little-endian number, by one.
 *
 * @param[in,out] pSession A reference to a converter session.
 */
static void FwdLockConv_IncrementCounter(FwdLockConv_Session_t *pSession) {
    size_t i = 0;
    while ((++pSession->counter[i] == 0) && (++i < AES_BLOCK_SIZE))
        ;
}

/**
 * Encrypts the given character and writes it to the output buffer.
 *
 * @param[in,out] pSession A reference to a converter session.
 * @param[in] ch The character to encrypt and write.
 * @param[in,out] pOutput The output from the conversion process.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_WriteEncryptedChar(FwdLockConv_Session_t *pSession,
                                                           unsigned char ch,
                                                           FwdLockConv_Output_t *pOutput) {
    if (pOutput->fromConvertData.numBytes == pSession->outputBufferSize) {
        void *pBuffer;
        pSession->outputBufferSize += OUTPUT_BUFFER_SIZE_INCREMENT;
        pBuffer = realloc(pOutput->fromConvertData.pBuffer, pSession->outputBufferSize);
        if (pBuffer == NULL) {
            return FwdLockConv_Status_OutOfMemory;
        }
        pOutput->fromConvertData.pBuffer = pBuffer;
    }
    if (++pSession->keyStreamIndex == AES_BLOCK_SIZE) {
        FwdLockConv_IncrementCounter(pSession);
        pSession->keyStreamIndex = 0;
    }
    if (pSession->keyStreamIndex == 0) {
        AES_encrypt(pSession->counter, pSession->keyStream, &pSession->encryptionRoundKeys);
    }
    ch ^= pSession->keyStream[pSession->keyStreamIndex];
    ((unsigned char *)pOutput->fromConvertData.pBuffer)[pOutput->fromConvertData.numBytes++] = ch;
    ++pSession->numDataBytes;
    return FwdLockConv_Status_OK;
}

/**
 * Matches binary-encoded content data and encrypts it, while looking out for the close delimiter.
 *
 * @param[in,out] pSession A reference to a converter session.
 * @param[in] ch A character.
 * @param[in,out] pOutput The output from the conversion process.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_MatchBinaryEncodedData(FwdLockConv_Session_t *pSession,
                                                               int ch,
                                                               FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status = FwdLockConv_Status_OK;
    switch (pSession->scannerState) {
    case FwdLockConv_ScannerState_WantsByte1:
        if (ch != pSession->delimiter[pSession->delimiterMatchPos]) {
            // The partial match of the delimiter turned out to be spurious. Flush the matched bytes
            // to the output buffer and start over.
            size_t i;
            for (i = 0; i < pSession->delimiterMatchPos; ++i) {
                status = FwdLockConv_WriteEncryptedChar(pSession, pSession->delimiter[i], pOutput);
                if (status != FwdLockConv_Status_OK) {
                    return status;
                }
            }
            pSession->delimiterMatchPos = 0;
        }
        if (ch != pSession->delimiter[pSession->delimiterMatchPos]) {
            // The current character isn't part of the delimiter. Write it to the output buffer.
            status = FwdLockConv_WriteEncryptedChar(pSession, ch, pOutput);
        } else if (++pSession->delimiterMatchPos == pSession->delimiterLength) {
            // The entire delimiter has been matched. The only valid characters now are the "--"
            // that complete the close delimiter (no more message parts are expected).
            pSession->scannerState = FwdLockConv_ScannerState_WantsFirstDash;
        }
        break;
    case FwdLockConv_ScannerState_WantsFirstDash:
        if (ch == '-') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsSecondDash;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsSecondDash:
        if (ch == '-') {
            pSession->parserState = FwdLockConv_ParserState_Done;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    default:
        status = FwdLockConv_Status_ProgramError;
        break;
    }
    return status;
}

/**
 * Checks whether a given character is valid in base64-encoded data.
 *
 * @param[in] ch The character to check.
 *
 * @return A Boolean value indicating whether the given character is valid in base64-encoded data.
 */
static int FwdLockConv_IsBase64Char(int ch) {
    return 0 <= ch && ch <= 'z' && base64Values[ch] >= 0;
}

/**
 * Matches base64-encoded content data and encrypts it, while looking out for the close delimiter.
 *
 * @param[in,out] pSession A reference to a converter session.
 * @param[in] ch A character.
 * @param[in,out] pOutput The output from the conversion process.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_MatchBase64EncodedData(FwdLockConv_Session_t *pSession,
                                                               int ch,
                                                               FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status = FwdLockConv_Status_OK;
    switch (pSession->scannerState) {
    case FwdLockConv_ScannerState_WantsByte1:
    case FwdLockConv_ScannerState_WantsByte1_AfterCRLF:
        if (FwdLockConv_IsBase64Char(ch)) {
            pSession->ch = base64Values[ch] << 2;
            pSession->scannerState = FwdLockConv_ScannerState_WantsByte2;
        } else if (ch == '\r') {
            pSession->savedScannerState = FwdLockConv_ScannerState_WantsByte1_AfterCRLF;
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (ch == '-') {
            if (pSession->scannerState == FwdLockConv_ScannerState_WantsByte1_AfterCRLF) {
                pSession->delimiterMatchPos = 3;
                pSession->scannerState = FwdLockConv_ScannerState_WantsDelimiter;
            } else {
                status = FwdLockConv_Status_SyntaxError;
            }
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsByte2:
        if (FwdLockConv_IsBase64Char(ch)) {
            pSession->ch |= base64Values[ch] >> 4;
            status = FwdLockConv_WriteEncryptedChar(pSession, pSession->ch, pOutput);
            if (status == FwdLockConv_Status_OK) {
                pSession->ch = base64Values[ch] << 4;
                pSession->scannerState = FwdLockConv_ScannerState_WantsByte3;
            }
        } else if (ch == '\r') {
            pSession->savedScannerState = pSession->scannerState;
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsByte3:
        if (FwdLockConv_IsBase64Char(ch)) {
            pSession->ch |= base64Values[ch] >> 2;
            status = FwdLockConv_WriteEncryptedChar(pSession, pSession->ch, pOutput);
            if (status == FwdLockConv_Status_OK) {
                pSession->ch = base64Values[ch] << 6;
                pSession->scannerState = FwdLockConv_ScannerState_WantsByte4;
            }
        } else if (ch == '\r') {
            pSession->savedScannerState = pSession->scannerState;
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (ch == '=') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsPadding;
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsByte4:
        if (FwdLockConv_IsBase64Char(ch)) {
            pSession->ch |= base64Values[ch];
            status = FwdLockConv_WriteEncryptedChar(pSession, pSession->ch, pOutput);
            if (status == FwdLockConv_Status_OK) {
                pSession->scannerState = FwdLockConv_ScannerState_WantsByte1;
            }
        } else if (ch == '\r') {
            pSession->savedScannerState = pSession->scannerState;
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (ch == '=') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsWhitespace;
        } else if (!FwdLockConv_IsWhitespace(ch)) {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsLF:
        if (ch == '\n') {
            pSession->scannerState = pSession->savedScannerState;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsPadding:
        if (ch == '=') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsWhitespace;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsWhitespace:
    case FwdLockConv_ScannerState_WantsWhitespace_AfterCRLF:
        if (ch == '\r') {
            pSession->savedScannerState = FwdLockConv_ScannerState_WantsWhitespace_AfterCRLF;
            pSession->scannerState = FwdLockConv_ScannerState_WantsLF;
        } else if (ch == '-') {
            if (pSession->scannerState == FwdLockConv_ScannerState_WantsWhitespace_AfterCRLF) {
                pSession->delimiterMatchPos = 3;
                pSession->scannerState = FwdLockConv_ScannerState_WantsDelimiter;
            } else {
                status = FwdLockConv_Status_SyntaxError;
            }
        } else if (FwdLockConv_IsWhitespace(ch)) {
            pSession->scannerState = FwdLockConv_ScannerState_WantsWhitespace;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsDelimiter:
        if (ch != pSession->delimiter[pSession->delimiterMatchPos]) {
            status = FwdLockConv_Status_SyntaxError;
        } else if (++pSession->delimiterMatchPos == pSession->delimiterLength) {
            pSession->scannerState = FwdLockConv_ScannerState_WantsFirstDash;
        }
        break;
    case FwdLockConv_ScannerState_WantsFirstDash:
        if (ch == '-') {
            pSession->scannerState = FwdLockConv_ScannerState_WantsSecondDash;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    case FwdLockConv_ScannerState_WantsSecondDash:
        if (ch == '-') {
            pSession->parserState = FwdLockConv_ParserState_Done;
        } else {
            status = FwdLockConv_Status_SyntaxError;
        }
        break;
    default:
        status = FwdLockConv_Status_ProgramError;
        break;
    }
    return status;
}

/**
 * Pushes a single character into the converter's state machine.
 *
 * @param[in,out] pSession A reference to a converter session.
 * @param[in] ch A character.
 * @param[in,out] pOutput The output from the conversion process.
 *
 * @return A status code.
 */
static FwdLockConv_Status_t FwdLockConv_PushChar(FwdLockConv_Session_t *pSession,
                                                 int ch,
                                                 FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status;
    ++pSession->numCharsConsumed;
    switch (pSession->parserState) {
    case FwdLockConv_ParserState_WantsOpenDelimiter:
        status = FwdLockConv_MatchOpenDelimiter(pSession, ch);
        break;
    case FwdLockConv_ParserState_WantsMimeHeaders:
        status = FwdLockConv_MatchMimeHeaders(pSession, ch, pOutput);
        break;
    case FwdLockConv_ParserState_WantsBinaryEncodedData:
        status = FwdLockConv_MatchBinaryEncodedData(pSession, ch, pOutput);
        break;
    case FwdLockConv_ParserState_WantsBase64EncodedData:
        if (ch == '\n' && pSession->scannerState != FwdLockConv_ScannerState_WantsLF) {
            // Repair base64-encoded data that doesn't have carriage returns in its line breaks.
            status = FwdLockConv_MatchBase64EncodedData(pSession, '\r', pOutput);
            if (status != FwdLockConv_Status_OK) {
                break;
            }
        }
        status = FwdLockConv_MatchBase64EncodedData(pSession, ch, pOutput);
        break;
    case FwdLockConv_ParserState_Done:
        status = FwdLockConv_Status_OK;
        break;
    default:
        status = FwdLockConv_Status_ProgramError;
        break;
    }
    return status;
}

FwdLockConv_Status_t FwdLockConv_OpenSession(int *pSessionId, FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status;
    if (pSessionId == NULL || pOutput == NULL) {
        status = FwdLockConv_Status_InvalidArgument;
    } else {
        *pSessionId = FwdLockConv_AcquireSession();
        if (*pSessionId < 0) {
            status = FwdLockConv_Status_TooManySessions;
        } else {
            FwdLockConv_Session_t *pSession = sessionPtrs[*pSessionId];
            pSession->encryptedSessionKeyLength = FwdLockGlue_GetEncryptedKeyLength(KEY_SIZE);
            if (pSession->encryptedSessionKeyLength < AES_BLOCK_SIZE) {
                // The encrypted session key is used as the CTR-mode nonce, so it must be at least
                // the size of a single AES block.
                status = FwdLockConv_Status_ProgramError;
            } else {
                pSession->pEncryptedSessionKey = malloc(pSession->encryptedSessionKeyLength);
                if (pSession->pEncryptedSessionKey == NULL) {
                    status = FwdLockConv_Status_OutOfMemory;
                } else {
                    if (!FwdLockGlue_GetRandomNumber(pSession->sessionKey, KEY_SIZE)) {
                        status = FwdLockConv_Status_RandomNumberGenerationFailed;
                    } else if (!FwdLockGlue_EncryptKey(pSession->sessionKey, KEY_SIZE,
                                                       pSession->pEncryptedSessionKey,
                                                       pSession->encryptedSessionKeyLength)) {
                        status = FwdLockConv_Status_KeyEncryptionFailed;
                    } else {
                        status = FwdLockConv_DeriveKeys(pSession);
                    }
                    if (status == FwdLockConv_Status_OK) {
                        memset(pSession->sessionKey, 0, KEY_SIZE); // Zero out key data.
                        memcpy(pSession->counter, pSession->pEncryptedSessionKey, AES_BLOCK_SIZE);
                        pSession->parserState = FwdLockConv_ParserState_WantsOpenDelimiter;
                        pSession->scannerState = FwdLockConv_ScannerState_WantsFirstDash;
                        pSession->numCharsConsumed = 0;
                        pSession->delimiterMatchPos = 0;
                        pSession->mimeHeaderName = nullString;
                        pSession->contentType = nullString;
                        pSession->contentTransferEncoding =
                                FwdLockConv_ContentTransferEncoding_Undefined;
                        pSession->keyStreamIndex = -1;
                        pOutput->fromConvertData.pBuffer = NULL;
                        pOutput->fromConvertData.errorPos = INVALID_OFFSET;
                    } else {
                        free(pSession->pEncryptedSessionKey);
                    }
                }
            }
            if (status != FwdLockConv_Status_OK) {
                FwdLockConv_ReleaseSession(*pSessionId);
                *pSessionId = -1;
            }
        }
    }
    return status;
}

FwdLockConv_Status_t FwdLockConv_ConvertData(int sessionId,
                                             const void *pBuffer,
                                             size_t numBytes,
                                             FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status;
    if (!FwdLockConv_IsValidSession(sessionId) || pBuffer == NULL || pOutput == NULL) {
        status = FwdLockConv_Status_InvalidArgument;
    } else {
        size_t i;
        FwdLockConv_Session_t *pSession = sessionPtrs[sessionId];
        pSession->dataOffset = 0;
        pSession->numDataBytes = 0;
        pOutput->fromConvertData.numBytes = 0;
        status = FwdLockConv_Status_OK;

        for (i = 0; i < numBytes; ++i) {
            status = FwdLockConv_PushChar(pSession, ((char *)pBuffer)[i], pOutput);
            if (status != FwdLockConv_Status_OK) {
                break;
            }
        }
        if (status == FwdLockConv_Status_OK) {
            // Update the data signature.
            HMAC_Update(&pSession->signingContext,
                        &((unsigned char *)pOutput->fromConvertData.pBuffer)[pSession->dataOffset],
                        pSession->numDataBytes);
        } else if (status == FwdLockConv_Status_SyntaxError) {
            pOutput->fromConvertData.errorPos = pSession->numCharsConsumed;
        }
    }
    return status;
}

FwdLockConv_Status_t FwdLockConv_CloseSession(int sessionId, FwdLockConv_Output_t *pOutput) {
    FwdLockConv_Status_t status;
    if (!FwdLockConv_IsValidSession(sessionId) || pOutput == NULL) {
        status = FwdLockConv_Status_InvalidArgument;
    } else {
        FwdLockConv_Session_t *pSession = sessionPtrs[sessionId];
        free(pOutput->fromConvertData.pBuffer);
        if (pSession->parserState != FwdLockConv_ParserState_Done) {
            pOutput->fromCloseSession.errorPos = pSession->numCharsConsumed;
            status = FwdLockConv_Status_SyntaxError;
        } else {
            // Finalize the data signature.
            unsigned int signatureSize = SHA1_HASH_SIZE;
            HMAC_Final(&pSession->signingContext, pOutput->fromCloseSession.signatures,
                       &signatureSize);
            if (signatureSize != SHA1_HASH_SIZE) {
                status = FwdLockConv_Status_ProgramError;
            } else {
                // Calculate the header signature, which is a signature of the rest of the header
                // including the data signature.
                HMAC_Init_ex(&pSession->signingContext, NULL, KEY_SIZE, NULL, NULL);
                HMAC_Update(&pSession->signingContext, pSession->topHeader, TOP_HEADER_SIZE);
                HMAC_Update(&pSession->signingContext, (unsigned char *)pSession->contentType.ptr,
                            pSession->contentType.length);
                HMAC_Update(&pSession->signingContext, pSession->pEncryptedSessionKey,
                            pSession->encryptedSessionKeyLength);
                HMAC_Update(&pSession->signingContext, pOutput->fromCloseSession.signatures,
                            SHA1_HASH_SIZE);
                HMAC_Final(&pSession->signingContext,
                           &pOutput->fromCloseSession.signatures[SHA1_HASH_SIZE], &signatureSize);
                if (signatureSize != SHA1_HASH_SIZE) {
                    status = FwdLockConv_Status_ProgramError;
                } else {
                    pOutput->fromCloseSession.fileOffset = TOP_HEADER_SIZE +
                            pSession->contentType.length + pSession->encryptedSessionKeyLength;
                    status = FwdLockConv_Status_OK;
                }
            }
            pOutput->fromCloseSession.errorPos = INVALID_OFFSET;
        }
        free(pSession->mimeHeaderName.ptr);
        free(pSession->contentType.ptr);
        free(pSession->pEncryptedSessionKey);
        HMAC_CTX_cleanup(&pSession->signingContext);
        FwdLockConv_ReleaseSession(sessionId);
    }
    return status;
}

FwdLockConv_Status_t FwdLockConv_ConvertOpenFile(int inputFileDesc,
                                                 FwdLockConv_ReadFunc_t *fpReadFunc,
                                                 int outputFileDesc,
                                                 FwdLockConv_WriteFunc_t *fpWriteFunc,
                                                 FwdLockConv_LSeekFunc_t *fpLSeekFunc,
                                                 off64_t *pErrorPos) {
    FwdLockConv_Status_t status;
    if (pErrorPos != NULL) {
        *pErrorPos = INVALID_OFFSET;
    }
    if (fpReadFunc == NULL || fpWriteFunc == NULL || fpLSeekFunc == NULL || inputFileDesc < 0 ||
        outputFileDesc < 0) {
        status = FwdLockConv_Status_InvalidArgument;
    } else {
        char *pReadBuffer = malloc(READ_BUFFER_SIZE);
        if (pReadBuffer == NULL) {
            status = FwdLockConv_Status_OutOfMemory;
        } else {
            int sessionId;
            FwdLockConv_Output_t output;
            status = FwdLockConv_OpenSession(&sessionId, &output);
            if (status == FwdLockConv_Status_OK) {
                ssize_t numBytesRead;
                FwdLockConv_Status_t closeStatus;
                while ((numBytesRead =
                        fpReadFunc(inputFileDesc, pReadBuffer, READ_BUFFER_SIZE)) > 0) {
                    status = FwdLockConv_ConvertData(sessionId, pReadBuffer, (size_t)numBytesRead,
                                                     &output);
                    if (status == FwdLockConv_Status_OK) {
                        if (output.fromConvertData.pBuffer != NULL &&
                            output.fromConvertData.numBytes > 0) {
                            ssize_t numBytesWritten = fpWriteFunc(outputFileDesc,
                                                                  output.fromConvertData.pBuffer,
                                                                  output.fromConvertData.numBytes);
                            if (numBytesWritten != (ssize_t)output.fromConvertData.numBytes) {
                                status = FwdLockConv_Status_FileWriteError;
                                break;
                            }
                        }
                    } else {
                        if (status == FwdLockConv_Status_SyntaxError && pErrorPos != NULL) {
                            *pErrorPos = output.fromConvertData.errorPos;
                        }
                        break;
                    }
                } // end while
                if (numBytesRead < 0) {
                    status = FwdLockConv_Status_FileReadError;
                }
                closeStatus = FwdLockConv_CloseSession(sessionId, &output);
                if (status == FwdLockConv_Status_OK) {
                    if (closeStatus != FwdLockConv_Status_OK) {
                        if (closeStatus == FwdLockConv_Status_SyntaxError && pErrorPos != NULL) {
                            *pErrorPos = output.fromCloseSession.errorPos;
                        }
                        status = closeStatus;
                    } else if (fpLSeekFunc(outputFileDesc, output.fromCloseSession.fileOffset,
                                           SEEK_SET) < 0) {
                        status = FwdLockConv_Status_FileSeekError;
                    } else if (fpWriteFunc(outputFileDesc, output.fromCloseSession.signatures,
                                           FWD_LOCK_SIGNATURES_SIZE) != FWD_LOCK_SIGNATURES_SIZE) {
                        status = FwdLockConv_Status_FileWriteError;
                    }
                }
            }
            free(pReadBuffer);
        }
    }
    return status;
}
