/*
 * 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 <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;
}
