static cl_error_t egg_parse_encrypt_header(const uint8_t* index, size_t size, egg_encrypt** encryptInfo)
{
    /*
     * The EGG specification (last updated 2016) for the encrypt header is not accurate.
     * The following describes my findings of the actual format for the encrypt header.
     *
     * The significant discrepancy is that the Size includes the size of the header iself, not just the data following it.
     * No other extra_field header's size field includes the size of itself.
     * This must be accounted for by the caller of this function (see the "Fudge factor" comments where this function is used).
     *
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | Magic(ENCRYP) |    4    |    0x08D1470F                                                                                              |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | Bit flag      |    1    |    0                                                                                                       |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | Size          |    2    | sizeof( Magic ) + sizeof( Bit flag ) + sizeof( Size ) + sizeof( Encrypt Method ) + sizeof( Method Header ) |
     *     |---------------|---------|---|--------------------------------------------------------------------------------------------------------|
     *     | Encrypt       |    1    | 0 | KeyBase (XOR)                                                                                          |
     *     | Method        |         |---|--------------------------------------------------------------------------------------------------------|
     *     |               |         | 1 | AES128                                                                                                 |
     *     |               |         |---|--------------------------------------------------------------------------------------------------------|
     *     |               |         | 2 | AES256                                                                                                 |
     *     |               |         |---|--------------------------------------------------------------------------------------------------------|
     *     |               |         | 5 | LEA128                                                                                                 |
     *     |               |         |---|--------------------------------------------------------------------------------------------------------|
     *     |               |         | 6 | LEA256                                                                                                 |
     *     |---------------|---------|---|--------------------------------------------------------------------------------------------------------|
     *
     * Depending on the Method (XOR / AES/LEA128 / AES/LEA256) The above will be be followed one of the following Method Headers:
     *
     *   XOR (KeyBase):
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | verify Data   |   12    |   Encryption Verification Data                                                                             |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | CRC32         |    4    |   Partial Block CRC                                                                                        |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *
     *   AES / LEA 128
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | Magic(ENCRYP) |   10    |   AES/LEA Header                                                                                           |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | Magic(ENCRYP) |   10    |   AES/LEA Footer                                                                                           |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *
     *   AES / LEA 256
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | Magic(ENCRYP) |   18    |   AES/LEA Header                                                                                           |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     *     | Magic(ENCRYP) |   10    |   AES/LEA Footer                                                                                           |
     *     |---------------|---------|------------------------------------------------------------------------------------------------------------|
     */
    cl_error_t status    = CL_EPARSE;
    egg_encrypt* encrypt = NULL;

    if (!index || 0 == size || !encryptInfo) {
        cli_errmsg("egg_parse_encrypt_header: Invalid args.\n");
        status = CL_EARG;
        goto done;
    }

    *encryptInfo = NULL;

    cli_dbgmsg("egg_parse_encrypt_header: Encrypted archive.\n");
    cli_dbgmsg("egg_parse_encrypt_header: size of encrypt extra_field data: %zu\n", size);

    if (size < sizeof(encrypt_header)) {
        cli_warnmsg("egg_parse_encrypt_header: Encrypt header size too small (%zu < %zu)\n", size, sizeof(encrypt_header));
        goto done;
    }

    encrypt = (egg_encrypt*)cli_calloc(1, sizeof(egg_encrypt));
    if (NULL == encrypt) {
        cli_errmsg("egg_parse_encrypt_header: Failed to allocate memory for egg_encrypt.\n");
        status = CL_EMEM;
        goto done;
    }

    encrypt->header = (encrypt_header*)index;

    cli_dbgmsg("egg_parse_encrypt_header: encrypt_header->encrypt_method: %02x (%s)\n", encrypt->header->encrypt_method, getEncryptName(encrypt->header->encrypt_method));

    index += sizeof(encrypt_header);
    size -= sizeof(encrypt_header);

    if (ENCRYPT_HEADER_ENCRYPT_METHOD_XOR == encrypt->header->encrypt_method) {
        if (size != sizeof(zip2_xor_keybase)) {
            cli_warnmsg("egg_parse_encrypt_header: Encrypt header size for XOR is different than expected (%zu != %zu)\n", size, sizeof(zip2_xor_keybase));
            goto done;
        }

        encrypt->encrypt_al.xor = (zip2_xor_keybase*)index;

        cli_dbgmsg("egg_parse_encrypt_header: encrypt_header->crc32:          %08x\n", le32_to_host(encrypt->encrypt_al.xor->crc32));
    } else {
        /*
         * For AES/LEA, the additional information is found inside of embedded extra field.
         */
        switch (encrypt->header->encrypt_method) {
            case ENCRYPT_HEADER_ENCRYPT_METHOD_AES128:
            case ENCRYPT_HEADER_ENCRYPT_METHOD_LEA128: {
                if (size < sizeof(aes_lea_128)) {
                    cli_warnmsg("egg_parse_encrypt_header: Encrypt header size for AES/LEA128 is different than expected (%zu != %zu)\n", size, sizeof(aes_lea_128));
                    goto done;
                }

                encrypt->encrypt_al.al128 = (aes_lea_128*)index;

                index += sizeof(aes_lea_128);
                size -= sizeof(aes_lea_128);
                break;
            }
            case ENCRYPT_HEADER_ENCRYPT_METHOD_AES256:
            case ENCRYPT_HEADER_ENCRYPT_METHOD_LEA256: {
                if (size < sizeof(aes_lea_256)) {
                    cli_warnmsg("egg_parse_encrypt_header: Encrypt header size for AES/LEA256 is different than expected (%zu != %zu)\n", size, sizeof(aes_lea_256));
                    goto done;
                }

                encrypt->encrypt_al.al256 = (aes_lea_256*)index;

                index += sizeof(aes_lea_256);
                size -= sizeof(aes_lea_256);
                break;
            }
            default: {
                cli_warnmsg("egg_parse_encrypt_header: Unknown encrypt method: %d\n", encrypt->header->encrypt_method);
                goto done;
            }
        }
    }

    *encryptInfo = encrypt;
    status       = CL_SUCCESS;

done:

    if (CL_SUCCESS != status) {
        egg_free_encrypt(encrypt);
    }

    return status;
}
static cl_error_t egg_parse_encrypt_header(const uint8_t* index, size_t size, egg_encrypt** encryptInfo)
{
     
    cl_error_t status    = CL_EPARSE;
    egg_encrypt* encrypt = NULL;

    if (!index || 0 == size || !encryptInfo) {
        cli_errmsg("egg_parse_encrypt_header: Invalid args.\n");
        status = CL_EARG;
        goto done;
    }

    *encryptInfo = NULL;

    cli_dbgmsg("egg_parse_encrypt_header: Encrypted archive.\n");
    cli_dbgmsg("egg_parse_encrypt_header: size of encrypt extra_field data: %zu\n", size);

    if (size < sizeof(encrypt_header)) {
        cli_warnmsg("egg_parse_encrypt_header: Encrypt header size too small (%zu < %zu)\n", size, sizeof(encrypt_header));
        goto done;
    }

    encrypt = (egg_encrypt*)cli_calloc(1, sizeof(egg_encrypt));
    if (NULL == encrypt) {
        cli_errmsg("egg_parse_encrypt_header: Failed to allocate memory for egg_encrypt.\n");
        status = CL_EMEM;
        goto done;
    }

    encrypt->header = (encrypt_header*)index;

    cli_dbgmsg("egg_parse_encrypt_header: encrypt_header->encrypt_method: %02x (%s)\n", encrypt->header->encrypt_method, getEncryptName(encrypt->header->encrypt_method));

    index += sizeof(encrypt_header);
    size -= sizeof(encrypt_header);

    if (ENCRYPT_HEADER_ENCRYPT_METHOD_XOR == encrypt->header->encrypt_method) {
        if (size != sizeof(zip2_xor_keybase)) {
            cli_warnmsg("egg_parse_encrypt_header: Encrypt header size for XOR is different than expected (%zu != %zu)\n", size, sizeof(zip2_xor_keybase));
            goto done;
        }

        encrypt->encrypt_al.xor = (zip2_xor_keybase*)index;

        cli_dbgmsg("egg_parse_encrypt_header: encrypt_header->crc32:          %08x\n", le32_to_host(encrypt->encrypt_al.xor->crc32));
    } else {
         
        switch (encrypt->header->encrypt_method) {
            case ENCRYPT_HEADER_ENCRYPT_METHOD_AES128:
            case ENCRYPT_HEADER_ENCRYPT_METHOD_LEA128: {
                if (size < sizeof(aes_lea_128)) {
                    cli_warnmsg("egg_parse_encrypt_header: Encrypt header size for AES/LEA128 is different than expected (%zu != %zu)\n", size, sizeof(aes_lea_128));
                    goto done;
                }

                encrypt->encrypt_al.al128 = (aes_lea_128*)index;

                index += sizeof(aes_lea_128);
                size -= sizeof(aes_lea_128);
                break;
            }
            case ENCRYPT_HEADER_ENCRYPT_METHOD_AES256:
            case ENCRYPT_HEADER_ENCRYPT_METHOD_LEA256: {
                if (size < sizeof(aes_lea_256)) {
                    cli_warnmsg("egg_parse_encrypt_header: Encrypt header size for AES/LEA256 is different than expected (%zu != %zu)\n", size, sizeof(aes_lea_256));
                    goto done;
                }

                encrypt->encrypt_al.al256 = (aes_lea_256*)index;

                index += sizeof(aes_lea_256);
                size -= sizeof(aes_lea_256);
                break;
            }
            default: {
                cli_warnmsg("egg_parse_encrypt_header: Unknown encrypt method: %d\n", encrypt->header->encrypt_method);
                goto done;
            }
        }
    }

    *encryptInfo = encrypt;
    status       = CL_SUCCESS;

done:

    if (CL_SUCCESS != status) {
        egg_free_encrypt(encrypt);
    }

    return status;
}