/*
  <:copyright-BRCM:2016:DUAL/GPL:standard

  Broadcom Proprietary and Confidential.(c) 2016 Broadcom
  All Rights Reserved

  Unless you and Broadcom execute a separate written software license
  agreement governing use of this software, this software is licensed
  to you under the terms of the GNU General Public License version 2
  (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
  with the following added to such license:

  As a special exception, the copyright holders of this software give
  you permission to link this software with independent modules, and
  to copy and distribute the resulting executable under terms of your
  choice, provided that you also meet, for each linked independent
  module, the terms and conditions of the license of that module.
  An independent module is a module which is not derived from this
  software.  The special exception does not apply to any modifications
  of the software.

  Not withstanding the above, under no circumstances may you combine
  this software in any way with any other Broadcom software provided
  under a license other than the GPL, without Broadcom's express prior
  written consent.

  :>
*/

#include "dpoe_eap_tls.h"
#include "bcmolt_buf.h"
#include "dpoe_sec_fsm.h"

/* The destination multicast MAC address for EAPOL packets. */
static const bcmos_mac_address eapol_dst_mac = { { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 } };

/* The length of the RSA key used in the server_key_exchange TLS message sent to the ONU during DPoE bi-directional
   authentication. */
#define DPOE_BI_RSA_KEY_SIZE 2048

/* 2 1200 byte certs + some overhead.... */
#define EAPOL_PKT_SIZE 5000

typedef enum
{
    EAP_CODE_REQUEST = 1,
    EAP_CODE_RESPONSE,
    EAP_CODE_SUCCESS,
    EAP_CODE_FAILURE
} eap_code;

typedef struct
{
    uint8_t eap_code;
    uint8_t id;
    uint16_t length;
} eap_frame;

#define EAP_FRAME_SIZE 4

typedef enum
{
    EAP_TYPE_IDENTITY = 1,
    EAP_TYPE_NOTIFICATION,
    EAP_TYPE_NAK,
    EAP_TYPE_MD5,
    EAP_TYPE_OTP,
    EAP_TYPE_GENERIC_TOKEN_CARD,
    EAP_TYPE_TLS = 13
} eap_type;

#define TLS_MAJOR_VERSION 3
#define TLS_MINOR_VERSION 2

/* First the EAP structures.... */
typedef struct
{
    uint8_t auth_sub_type;
    uint8_t eap_tls_flags;
} eap_tls_hdr;

#define EAP_TLS_HDR_SIZE 2

#define EAP_HDR_SIZE (EAP_FRAME_SIZE + EAP_TLS_HDR_SIZE)

typedef enum
{
    TLS_CHANGE_CIPHER_SPEC_ID = 20,
    TLS_ALERT_ID = 21,
    TLS_HANDSHAKE_ID = 22,
    TLS_APPLICATION_DATA_ID = 23,
} tls_content_type;

typedef struct
{
    uint8_t content_type;
    tls_protocol_version tls_version;
    uint16_t tls_record_length;
} tls_record_hdr;

#define TLS_RECORD_HDR_SIZE (3 + PROTOCOL_VERSION_SIZE)

#define EAP_TLS_FLAG_LENGTH_OFFSET 7
#define EAP_TLS_FLAG_MORE_OFFSET 6
#define EAP_TLS_FLAG_START_OFFSET 5
#define EAP_TLS_FLAG_LENGTH_BIT (1U << EAP_TLS_FLAG_LENGTH_OFFSET)
#define EAP_TLS_FLAG_MORE_BIT (1U << EAP_TLS_FLAG_MORE_OFFSET)
#define EAP_TLS_FLAG_START_BIT (1U << EAP_TLS_FLAG_START_OFFSET)

typedef struct
{
    eap_frame hdr;
    eap_tls_hdr tls;
} eap_msg_buf;

typedef struct
{
    eapol_msg_hdr hdr;
    eap_msg_buf eap_msg;
} eapol_msg;

/* Now the TLS records. */
typedef struct tls_session_id
{
    uint8_t length;
    uint8_t session_id[SIZE_OF_TLS_SESSION_ID];
} tls_session_id;

typedef enum
{
    cm_null = 0
} compression_method;

typedef struct
{
    uint8_t length;
    uint8_t compression_method;
} compression_methods;

typedef enum
{
    RSA_SIGN                          = 1,
    DSS_SIGN                          = 2,
    RSA_FIXED_DH                      = 3,
    DSS_FIXED_DH                      = 4,
    RSA_EPHEMERAL_DH_RESERVED         = 5,
    DSS_EPHEMERAL_DH_RESERVED         = 6,
    FORTEZZA_DMS_RESERVED             = 20,
} client_certificate_type;

/* For 2048 bit RSA key */
#define SIZE_OF_RSA_MODULUS 256
#define SIZE_OF_RSA_EXPONENT 3

typedef enum
{
    HS_HELLO_REQUEST = 0,
    HS_CLIENT_HELLO = 1,
    HS_SERVER_HELLO = 2,
    HS_CERTIFICATE = 11,
    HS_SERVER_KEY_EXCHANGE = 12,
    HS_CERTIFICATE_REQUEST = 13,
    HS_SERVER_HELLO_DONE = 14,
    HS_CERTIFICATE_VERIFY = 15,
    HS_CLIENT_KEY_EXCHANGE = 16,
    HS_FINISHED = 20,
} handshake_type;

typedef struct
{
    uint8_t msg_id;
    uint32_t msg_length; /* actually U24 */
} tls_handshake;

#define TLS_HANDSHAKE_SIZE 4

typedef struct
{
    uint8_t *eapol;
    uint8_t *eap;
    uint8_t *eap_tls;
    uint8_t *tls_rec;
} eap_length_fields;

static f_dpoe_sec_cert_trust_cb _cert_trust;
static f_dpoe_sec_auth_cb _auth_complete;

static void _buffer_hash_data(dpoe_sec_link_rec *link_rec, const uint8_t *buf, uint32_t len)
{
    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    dpoe_sec_sha1_update(&link_rec->auth_ctrl.trans_data.sha1_hash, buf, len);
    dpoe_sec_md5_update(&link_rec->auth_ctrl.trans_data.md5_hash, buf, len);
}

static void _dpoe_eap_tls_compute_master_session_key(auth_trans_data *trans_data)
{
    uint8_t seed[(2* COUNT_OF_RANDOM_BYTES)];
    uint32_t seed_len = 0;

    /* Parameter checks. */
    BUG_ON(trans_data == NULL);

    /* The seed to the PRF is the client random value concatenated with the server random value. */
    memcpy(&seed[seed_len], trans_data->client_random, COUNT_OF_RANDOM_BYTES);
    seed_len += COUNT_OF_RANDOM_BYTES;
    memcpy(&seed[seed_len], trans_data->server_random, COUNT_OF_RANDOM_BYTES);
    seed_len += COUNT_OF_RANDOM_BYTES;

    dpoe_sec_prf_expand_4346(
        trans_data->pre_master_secret,
        sizeof(trans_data->pre_master_secret),
        (const uint8_t *)"master secret",
        strlen("master secret"),
        seed,
        seed_len,
        trans_data->master_secret,
        sizeof(trans_data->master_secret));
    dpoe_sec_prf_expand_4346(
        trans_data->master_secret,
        sizeof(trans_data->master_secret),
        (const uint8_t *)"client EAP encryption",
        strlen("client EAP encryption"),
        seed,
        seed_len,
        trans_data->key_material,
        sizeof(trans_data->key_material));

    memcpy(trans_data->master_session_key, trans_data->key_material, sizeof(trans_data->master_session_key));
}

static bcmos_bool _dpoe_eap_tls_prepare_security_data(dpoe_sec_link_rec *link_rec)
{
    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    /* If bidirectional, compute the master session key and generate the RSA public/private key pair */
    if (link_rec->cfg.enc_mode == BCMOLT_EPON_OAM_DPOE_ENCRYPTION_MODE_TEN_BI)
    {
        _dpoe_eap_tls_compute_master_session_key(&link_rec->auth_ctrl.trans_data);
    }

    return BCMOS_TRUE;
}

static bcmos_bool _dpoe_eap_tls_skip_length(bcmolt_buf *buf, uint32_t skip, uint8_t** len)
{
    *len = bcmolt_buf_snap_get(buf);
    return bcmolt_buf_skip(buf, skip);
}

static bcmos_bool _dpoe_eap_tls_init_eap_hdr(
    dpoe_sec_link_rec *link_rec,
    bcmolt_buf *buf,
    eap_code code,
    eap_length_fields *lf)
{
    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    return
        bcmolt_buf_write_mac_address(buf, eapol_dst_mac) &&
        bcmolt_buf_write_mac_address(buf, link_rec->ni_mac) &&
        bcmolt_buf_write_u16_be(buf, ETHERTYPE_EAPOL) &&
        bcmolt_buf_write_u8(buf, EAPOL_PROTOCOL_VERSION_DPOE) &&
        bcmolt_buf_write_u8(buf, EAPOL_TYPE_PACKET) &&
        /* Eapol Length - we re-compute this after building the packet */
        _dpoe_eap_tls_skip_length(buf, sizeof(uint16_t), &lf->eapol) &&
        /* EAP layer headers */
        bcmolt_buf_write_u8(buf, code) &&
        bcmolt_buf_write_u8(buf, link_rec->auth_ctrl.current_packet_id++) &&
        /* EAP length - again, computed when the packet is packed! */
        _dpoe_eap_tls_skip_length(buf, sizeof(uint16_t), &lf->eap);
}

static bcmos_bool _dpoe_eap_tls_init_tls_hdr(bcmolt_buf *buf, uint8_t eapTlsFlags, eap_length_fields *lf)
{
    bcmos_bool rc = BCMOS_FALSE;

    /* Parameter checks. */
    BUG_ON(buf == NULL);

    if (bcmolt_buf_write_u8(buf, EAP_TYPE_TLS) &&
        bcmolt_buf_write_u8(buf, eapTlsFlags))
    {
        if ((eapTlsFlags & EAP_TLS_FLAG_LENGTH_BIT) == EAP_TLS_FLAG_LENGTH_BIT)
        {
            /* EAP-TLS length - computed at pack completion only allocate room for this if EapTlsFlagLengthBit is set
               But if the EapTlsFlagLengthBit is set, we also write the TLS Record header. */
            if (_dpoe_eap_tls_skip_length(buf, sizeof(uint32_t), &lf->eap_tls) &&
                bcmolt_buf_write_u8(buf, TLS_HANDSHAKE_ID) &&
                bcmolt_buf_write_u8(buf, TLS_MAJOR_VERSION) &&
                bcmolt_buf_write_u8(buf, TLS_MINOR_VERSION) &&
                /* Another length field, the TLS record length */
                _dpoe_eap_tls_skip_length(buf, sizeof(uint16_t), &lf->tls_rec))
            {
                rc = BCMOS_TRUE;
            }
        }
        else
        {
            rc = BCMOS_TRUE;
        }
    }

    return rc;
}

static void _dpoe_eap_tls_pack_handshake_length(
    dpoe_sec_link_rec *link_rec,
    bcmolt_buf *buf,
    uint8_t *start,
    uint8_t *len)
{
    uint32_t rec_len;
    uint8_t *end;

    /* Now go back and fill in the length field.  This is the length of the TlsHandshake record */
    end = bcmolt_buf_snap_get(buf);
    rec_len = end - start;
    bcmolt_buf_snap_restore(buf, len);
    bcmolt_buf_write_u24(buf, uint32_to_24(rec_len - TLS_HANDSHAKE_SIZE));
    bcmolt_buf_snap_restore(buf, end);
    _buffer_hash_data(link_rec, start, rec_len);
}

static bcmos_bool _dpoe_eap_tls_pack_server_hello_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    uint8_t *start;
    uint8_t *len;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    start = bcmolt_buf_snap_get(buf);
    if (bcmolt_buf_write_u8(buf, HS_SERVER_HELLO) &&
        (len = bcmolt_buf_snap_get(buf), bcmolt_buf_skip(buf, sizeof(uint24_t))) &&
        bcmolt_buf_write_u8(buf, link_rec->auth_ctrl.version.major) &&
        bcmolt_buf_write_u8(buf, link_rec->auth_ctrl.version.minor) &&
        bcmolt_buf_write(buf, link_rec->auth_ctrl.trans_data.server_random, COUNT_OF_RANDOM_BYTES) &&
        bcmolt_buf_write_u8(buf, COUNT_OF_RANDOM_BYTES) &&
        bcmolt_buf_write(buf, link_rec->auth_ctrl.trans_data.server_random, COUNT_OF_RANDOM_BYTES) &&

        /* Cipher Suites - we write 0 as the length of the Cipher Suites
           Short circuit if using pre-release authentication */
        ((link_rec->auth_ctrl.version.minor == 3) || bcmolt_buf_write_u16_be(buf, 0)) &&

        /* CompressionMethods also write 0 as the length */
        bcmolt_buf_write_u8(buf, 0))
    {
        _dpoe_eap_tls_pack_handshake_length(link_rec, buf, start, len);
        return BCMOS_TRUE;
    }
    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_pack_server_key_exchange_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    uint8_t *start;
    uint8_t *len;
    uint8_t rsa_modulus[SIZE_OF_RSA_MODULUS] = {};
    uint8_t rsa_exponent[SIZE_OF_RSA_EXPONENT] = {};

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    /* If not bidirectional, just return BCMOS_TRUE */
    if (link_rec->cfg.enc_mode != BCMOLT_EPON_OAM_DPOE_ENCRYPTION_MODE_TEN_BI)
    {
        return BCMOS_TRUE;
    }

    /* Verify that the length of the public key (modulus) of the private key matches the expected length. Also, verify
       that the modulus is successfully read from the RSA key. */
    start = bcmolt_buf_snap_get(buf);
    if ((dpoe_sec_rsa_public_get(link_rec->auth_ctrl.trans_data.rsa, rsa_modulus, rsa_exponent)) &&
        bcmolt_buf_write_u8(buf, HS_SERVER_KEY_EXCHANGE) &&
        (len = bcmolt_buf_snap_get(buf), bcmolt_buf_skip(buf, sizeof(uint24_t))) &&
        bcmolt_buf_write(buf, rsa_modulus, sizeof(rsa_modulus)) &&
        bcmolt_buf_write(buf, rsa_exponent, sizeof(rsa_exponent)))
    {
        _dpoe_eap_tls_pack_handshake_length(link_rec, buf, start, len);
        return BCMOS_TRUE;
    }
    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_pack_cert_req_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    uint8_t *start;
    uint8_t *len;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    start = bcmolt_buf_snap_get(buf);
    if (bcmolt_buf_write_u8(buf, HS_CERTIFICATE_REQUEST) &&
        (len = bcmolt_buf_snap_get(buf), bcmolt_buf_skip(buf, sizeof(uint24_t))) &&
        bcmolt_buf_write_u8(buf, 1) && /* length of 'Certificate Type' */
        bcmolt_buf_write_u8(buf, RSA_SIGN) && /* Certificate Type */
        bcmolt_buf_write_u16_be(buf, 0)) /* zero length for cert authorities */
    {
        _dpoe_eap_tls_pack_handshake_length(link_rec, buf, start, len);
        return BCMOS_TRUE;
    }
    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_pack_server_hello_done_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    uint8_t *start;
    uint8_t *len;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    start = bcmolt_buf_snap_get(buf);
    if (bcmolt_buf_write_u8(buf, HS_SERVER_HELLO_DONE) &&
        (len = bcmolt_buf_snap_get(buf), bcmolt_buf_skip(buf, sizeof(uint24_t))))
    {
        _dpoe_eap_tls_pack_handshake_length(link_rec, buf, start, len);
        return BCMOS_TRUE;
    }
    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_pack_finished_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    uint8_t *start;
    uint8_t *len;

    start = bcmolt_buf_snap_get(buf);
    if (bcmolt_buf_write_u8(buf, HS_FINISHED) &&
        (len = bcmolt_buf_snap_get(buf), bcmolt_buf_skip(buf, sizeof(uint24_t))))
    {
        _dpoe_eap_tls_pack_handshake_length(link_rec, buf, start, len);
        return BCMOS_TRUE;
    }
    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_pack_msg_lengths(bcmolt_buf *buf, uint8_t eap_tls_flags, eap_length_fields *lf)
{
    uint16_t eapol_length;
    uint32_t eap_tls_length;
    uint8_t *snap = bcmolt_buf_snap_get(buf);

    /* Parameter checks. */
    BUG_ON(buf == NULL);
    BUG_ON(lf == NULL);

    eapol_length = bcmolt_buf_get_used(buf) - EAPOL_MSG_HDR_SIZE;

    /* Seems odd that these two would be the same. But eapolLength is defined as the length of the body fields of the
       Eapol buffer, which does not include the Eapol header. EAP is different, the EAP length is define to include the
       entire EAP packet, including the header. */
    bcmolt_buf_snap_restore(buf, lf->eapol);
    if (!bcmolt_buf_write_u16_be(buf, eapol_length))
    {
        bcmolt_buf_snap_restore(buf, snap);
        return BCMOS_FALSE;
    }

    bcmolt_buf_snap_restore(buf, lf->eap);
    if (!bcmolt_buf_write_u16_be(buf, eapol_length))
    {
        bcmolt_buf_snap_restore(buf, snap);
        return BCMOS_FALSE;
    }

    if ((eap_tls_flags & EAP_TLS_FLAG_LENGTH_BIT) == EAP_TLS_FLAG_LENGTH_BIT)
    {
        /* The TLS message length - take away the EapTlsHdr, AND the EapMsgHdr which, surprisingly was not removed in
           the previous step. */
        eap_tls_length = eapol_length - (EAP_FRAME_SIZE + EAP_TLS_HDR_SIZE + sizeof(uint32_t));

        bcmolt_buf_snap_restore(buf, lf->eap_tls);
        if (!bcmolt_buf_write_u32_be(buf, eap_tls_length))
        {
            bcmolt_buf_snap_restore(buf, snap);
            return BCMOS_FALSE;
        }

        bcmolt_buf_snap_restore(buf, lf->tls_rec);
        if (!bcmolt_buf_write_u16_be(buf, (uint16_t)eap_tls_length - TLS_RECORD_HDR_SIZE))
        {
            bcmolt_buf_snap_restore(buf, snap);
            return BCMOS_FALSE;
        }
    }

    bcmolt_buf_snap_restore(buf, snap);
    return BCMOS_TRUE;
}

static bcmos_errno _dpoe_eap_tls_pack_start(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    bcmos_errno rc = BCM_ERR_NOMEM;
    uint8_t flags = EAP_TLS_FLAG_START_BIT;
    eap_length_fields lf;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    if (_dpoe_eap_tls_init_eap_hdr(link_rec, buf, EAP_CODE_REQUEST, &lf) &&
        _dpoe_eap_tls_init_tls_hdr(buf, flags, &lf) &&
        _dpoe_eap_tls_pack_msg_lengths(buf, flags, &lf))
    {
        rc = BCM_ERR_OK;
    }

    return rc;
}

static bcmos_bool _dpoe_eap_tls_send_cert_request(dpoe_sec_link_rec *link_rec)
{
    bcmos_bool rc = BCMOS_FALSE;
    bcmos_errno err;
    bcmolt_buf buf;
    uint8_t *msg = NULL;
    eap_length_fields lf;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    msg = bcmos_calloc(EAPOL_PKT_SIZE);
    if (msg == NULL)
    {
        return BCMOS_FALSE;
    }

    /* Initialize the maximum supported length EAP-TLS message buffer. The various TLS records contained in an EAP-TLS
       message are variable size. However, this can only be a combined maximum length. */
    bcmolt_buf_init(&buf, EAPOL_PKT_SIZE, msg, BCMOLT_BUF_ENDIAN_FIXED);
    if (_dpoe_eap_tls_init_eap_hdr(link_rec, &buf, EAP_CODE_REQUEST, &lf) &&
        _dpoe_eap_tls_init_tls_hdr(&buf, EAP_TLS_FLAG_LENGTH_BIT, &lf))
    {
        /* The Cert request contains 3 or 4 TLS records (3 for DS-only and 4 for bi-directional). The TLS records are
           ordered as:
           - Server Hello
           - Server Key Exchange (if bi-directional)
           - Certificate Request
           - Server Hello Done */
        if (_dpoe_eap_tls_pack_server_hello_hs(link_rec, &buf) &&
            _dpoe_eap_tls_pack_server_key_exchange_hs(link_rec, &buf) &&
            _dpoe_eap_tls_pack_cert_req_hs(link_rec, &buf) &&
            _dpoe_eap_tls_pack_server_hello_done_hs(link_rec, &buf))
        {
            _dpoe_eap_tls_pack_msg_lengths(&buf, EAP_TLS_FLAG_LENGTH_BIT, &lf);

            /* Send the message */
            err = dpoe_sec_send_eapol(link_rec->device, &link_rec->key, msg, bcmolt_buf_get_used(&buf));
            if (err != BCM_ERR_OK)
            {
                bcmos_free(msg);
                return BCMOS_FALSE;
            }

            /* Authentication has begun. */
            link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_EAP_START;
            rc = BCMOS_TRUE;
        }
    }

    /* Free the message. */
    bcmos_free(msg);

    return rc;
}

static bcmos_errno _dpoe_eap_tls_send_finished_hs(dpoe_sec_link_rec *link_rec)
{
    bcmos_errno rc = BCM_ERR_OVERFLOW;
    bcmolt_buf buf;
    uint8_t *msg = NULL;
    eap_length_fields lf;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    msg = bcmos_calloc(EAPOL_PKT_SIZE);
    if (msg == NULL)
    {
        return BCM_ERR_NOMEM;
    }

    /* Initialize the EAP-TLS message buffer. */
    bcmolt_buf_init(&buf, EAPOL_PKT_SIZE, msg, BCMOLT_BUF_ENDIAN_FIXED);
    if (_dpoe_eap_tls_init_eap_hdr(link_rec, &buf, EAP_CODE_REQUEST, &lf) &&
        _dpoe_eap_tls_init_tls_hdr(&buf, EAP_TLS_FLAG_LENGTH_BIT, &lf) &&
        _dpoe_eap_tls_pack_finished_hs(link_rec, &buf))
    {
        _dpoe_eap_tls_pack_msg_lengths(&buf, EAP_TLS_FLAG_LENGTH_BIT, &lf);
        /* No error detection here. We have already authenticated. this message is just for standards compliance */
        rc = dpoe_sec_send_eapol(link_rec->device, &link_rec->key, msg, bcmolt_buf_get_used(&buf));
    }

    /* Free the message. */
    bcmos_free(msg);

    return rc;
}

static bcmos_errno _dpoe_eap_tls_send_result(dpoe_sec_link_rec *link_rec, eap_code result)
{
    uint8_t *msg;
    bcmolt_buf buf;
    bcmos_errno rc = BCM_ERR_INTERNAL;
    eap_length_fields lf;

    /* Parameter checks */
    BUG_ON(link_rec == NULL);

    msg = bcmos_calloc(EAPOL_PKT_SIZE);
    if (msg == NULL)
    {
        return BCM_ERR_NOMEM;
    }

    /* Initialize the EAP-TLS message buffer. */
    bcmolt_buf_init(&buf, EAPOL_PKT_SIZE, msg, BCMOLT_BUF_ENDIAN_FIXED);
    /* Encode the EAP-Success message to the buffer. */
    if (_dpoe_eap_tls_init_eap_hdr(link_rec, &buf, result, &lf) &&
        _dpoe_eap_tls_pack_msg_lengths(&buf, 0, &lf))
    {
        rc = dpoe_sec_send_eapol(link_rec->device, &link_rec->key, msg, bcmolt_buf_get_used(&buf));
    }

    bcmos_free(msg);

    return rc;
}

static bcmos_bool _dpoe_eap_tls_parse_certificate(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    bcmos_bool            rc = BCMOS_FALSE;
    uint24_t length;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    link_rec->auth_ctrl.certificate = bcmos_calloc(EAPOL_PKT_SIZE);
    if (link_rec->auth_ctrl.certificate == NULL)
    {
        return BCMOS_FALSE;
    }

    if (bcmolt_buf_read_u24(buf, &length) &&
        ((link_rec->auth_ctrl.certLen = (uint16_t)uint24_to_32(length)), (link_rec->auth_ctrl.certLen <= EAPOL_PKT_SIZE)) &&
        bcmolt_buf_read(buf, link_rec->auth_ctrl.certificate, link_rec->auth_ctrl.certLen))
    {
        rc = BCMOS_TRUE;
    }

    return rc;
}

static bcmos_bool _dpoe_eap_tls_parse_client_key_exchange(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    bcmos_bool rc = BCMOS_FALSE;
    uint16_t length;
    uint8_t encrypted_buf[SIZE_OF_RSA_ENCRYPTED_BLOCK] = {};

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    if (bcmolt_buf_read_u16_be(buf, &length) &&
        (length == (SIZE_OF_RSA_ENCRYPTED_BLOCK)) &&
        bcmolt_buf_read(buf, encrypted_buf, sizeof(encrypted_buf)))
    {
        int val;

        val = dpoe_sec_rsa_private_decrypt(
            sizeof(encrypted_buf),
            encrypted_buf,
            link_rec->auth_ctrl.trans_data.pre_master_secret,
            link_rec->auth_ctrl.trans_data.rsa);

        if (val == SIZE_OF_PRE_MASTER_SECRET)
        {
            /* We now need the security data - we have the "client random", "server random", and "pre master secret". */
            _dpoe_eap_tls_prepare_security_data(link_rec);
            rc = BCMOS_TRUE;
        }
        else
        {
            DPOE_SEC_LINK_LOG(ERROR, link_rec, "RSA decrypt pre-master secret failed: %d\n", val);
        }
    }
    else
    {
        DPOE_SEC_LINK_LOG(ERROR, link_rec, "Failed to parse client key exchange: %u\n", length);
    }

    return rc;
}

static bcmos_bool _dpoe_eap_tls_parse_cert_verify(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    uint16_t length;
    bcmos_bool ret = BCMOS_FALSE;

    if (bcmolt_buf_read_u16_be(buf, &length) &&
        (length <= (2 * SIZE_OF_RSA_ENCRYPTED_BLOCK)))
    {
        bcmolt_buf cert_buf;
        uint24_t temp;
        const uint8_t *cert;
        uint32_t cert_len = 0;
        uint8_t cert_verify[sizeof(dpoe_sec_sha1_digest) + sizeof(dpoe_sec_md5_digest)];
        uint8_t *enc_buf;
        dpoe_sec_rsa_key *rsa;

        bcmolt_buf_init(&cert_buf, link_rec->auth_ctrl.certLen, link_rec->auth_ctrl.certificate, BCMOLT_BUF_ENDIAN_FIXED);

        /* Get the pointer to the ONU cert and its length */
        bcmolt_buf_read_u24(&cert_buf, &temp);
        cert_len = uint24_to_32(temp);
        cert = bcmolt_buf_snap_get(&cert_buf);

        enc_buf = bcmolt_buf_snap_get(buf);
        bcmolt_buf_skip(buf, length);

        /* Get the public key from the ONU cert. */
        rsa = dpoe_sec_x509_pub_key_get(cert, cert_len);

        /* decrypt the remainder of the buf with the ONU cert. */
        if (rsa != NULL)
        {
            if (dpoe_sec_rsa_public_decrypt(length, enc_buf, cert_verify, rsa) >= 0)
            {
                /* RSA_size() returns the size of the modulus in bytes. Convert to bits. */
                link_rec->auth_ctrl.onu_cert_key_size = dpoe_sec_rsa_size(rsa) * 8;

                /* Compare the output (should be 36 bytes) to sha1/md5 messages digests If they match, we are good */
                if ((memcmp(&cert_verify[0],
                            link_rec->auth_ctrl.trans_data.md5_digest,
                            sizeof(dpoe_sec_md5_digest)) == 0) &&
                    (memcmp(&cert_verify[sizeof(dpoe_sec_md5_digest)],
                            link_rec->auth_ctrl.trans_data.sha1_digest,
                            sizeof(dpoe_sec_sha1_digest)) == 0))
                {
                    bcmolt_buf_init(&cert_buf, link_rec->auth_ctrl.certLen, link_rec->auth_ctrl.certificate, BCMOLT_BUF_ENDIAN_FIXED);

                    /* Get the pointer to the ONU certificate. */
                    bcmolt_buf_read_u24(&cert_buf, &temp);
                    link_rec->auth_ctrl.onu_cert_len = uint24_to_32(temp);
                    link_rec->auth_ctrl.onu_cert = bcmolt_buf_snap_get(&cert_buf);

                    bcmolt_buf_skip(&cert_buf, link_rec->auth_ctrl.onu_cert_len);

                    /* Get the pointer to the Manufacturer CA certificate. */
                    bcmolt_buf_read_u24(&cert_buf, &temp);
                    link_rec->auth_ctrl.mfg_cert_len = uint24_to_32(temp);
                    link_rec->auth_ctrl.mfg_cert = bcmolt_buf_snap_get(&cert_buf);

                    ret = BCMOS_TRUE;
                }
                else
                {
                    DPOE_SEC_LINK_LOG(ERROR, link_rec, "Cert Verify failed\n");
                }
            }
            else
            {
                DPOE_SEC_LINK_LOG(ERROR, link_rec, "RSA public decrypt/verify failed\n");
            }
        }
        else
        {
            DPOE_SEC_LINK_LOG(ERROR, link_rec, "Failed to retrieve RSA key\n");
        }

        dpoe_sec_rsa_key_free(rsa);
    }

    return ret;
}

static bcmos_bool _dpoe_eap_tls_parse_verify_data(dpoe_sec_link_rec *link_rec)
{
    bcmos_bool rc = BCMOS_FALSE;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    if (link_rec->auth_ctrl.version.minor == TLS_MINOR_VERSION)
    {
        /* This version of authentication does not parse verify data */
        rc = BCMOS_TRUE;
    }
    return rc;
}

static bcmos_bool _dpoe_eap_tls_parse_client_hello(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    tls_protocol_version version;
    tls_session_id session_id;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    if (bcmolt_buf_read_u8(buf, &version.major) &&
        (version.major == TLS_MAJOR_VERSION) &&
        bcmolt_buf_read_u8(buf, &version.minor) &&
        (version.minor >= TLS_MINOR_VERSION) &&
        bcmolt_buf_read(buf, link_rec->auth_ctrl.trans_data.client_random, COUNT_OF_RANDOM_BYTES) &&
        bcmolt_buf_read_u8(buf, &session_id.length) &&
        (session_id.length <= sizeof(session_id.session_id)) &&
        bcmolt_buf_read(buf, session_id.session_id, session_id.length))
    {
        compression_methods comp_methods;
        uint16_t tlvLen;
        uint8_t cipher_suites[2];
        uint8_t *cm_snap = bcmolt_buf_snap_get(buf);

        memset(&comp_methods, 0, sizeof(comp_methods));

        /* Cipher Suites may be present -if so parse over it and it will be ignored. Still check that comp methods is
           NULL */
        if (bcmolt_buf_read_u16_be(buf, &tlvLen) && /* Cipher Suites */
            (tlvLen <= sizeof(uint16_t)) &&
            bcmolt_buf_read(buf, cipher_suites, tlvLen) &&
            bcmolt_buf_read_u8(buf, &comp_methods.length) && /* Compression Methods */
            (comp_methods.length == sizeof(comp_methods.compression_method)) &&
            bcmolt_buf_read(buf, &comp_methods.compression_method, comp_methods.length) &&
            (comp_methods.compression_method == cm_null) )
        {
            link_rec->auth_ctrl.version.major = version.major;
            link_rec->auth_ctrl.version.minor = version.minor;
            return BCMOS_TRUE;
        }

        /* No cipher suites, check that comp method is null */
        memset(&comp_methods, 0, sizeof(comp_methods));
        bcmolt_buf_snap_restore(buf, cm_snap);
        if (bcmolt_buf_read_u8(buf, &comp_methods.length) &&  /* Compression Methods */
           (comp_methods.length == sizeof(comp_methods.compression_method)) &&
           bcmolt_buf_read(buf, &comp_methods.compression_method, comp_methods.length) &&
           (comp_methods.compression_method == cm_null) )
        {
            link_rec->auth_ctrl.version.major = version.major;
            link_rec->auth_ctrl.version.minor = version.minor;
            return BCMOS_TRUE;
        }

        /* Ok we failed to decode what was sent as cipher suites and comp methods. Do we care? Absolutely Not! */
        link_rec->auth_ctrl.version.major = version.major;
        link_rec->auth_ctrl.version.minor = version.minor;
        return BCMOS_TRUE;
    }

    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_handle_client_hello_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    if (_dpoe_eap_tls_parse_client_hello(link_rec, buf))
    {
        /* We now have the data, build the EAP session ID (see RFC 5216) */
        link_rec->auth_ctrl.trans_data.session_id[0] = 0xd;
        memcpy(
            &link_rec->auth_ctrl.trans_data.session_id[1],
            link_rec->auth_ctrl.trans_data.client_random,
            COUNT_OF_RANDOM_BYTES);
        memcpy(
            &link_rec->auth_ctrl.trans_data.session_id[COUNT_OF_RANDOM_BYTES + 1],
            link_rec->auth_ctrl.trans_data.server_random,
            COUNT_OF_RANDOM_BYTES);

        if (_dpoe_eap_tls_send_cert_request(link_rec))
        {
            link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_CERT_REQUEST;
            return BCMOS_TRUE;
        }
    }

    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_handle_certificate_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    if (_dpoe_eap_tls_parse_certificate(link_rec, buf))
    {
        if (link_rec->auth_ctrl.version.minor == TLS_MINOR_VERSION)
        {
            link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_CERT_RECEIVED;
            return BCMOS_TRUE;
        }
    }
    return BCMOS_FALSE;
}

/******************************************************************************/
static bcmos_bool _dpoe_eap_tls_handle_client_key_exchange_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    if (_dpoe_eap_tls_parse_client_key_exchange(link_rec, buf))
    {
        if (link_rec->auth_ctrl.version.minor == TLS_MINOR_VERSION)
        {
            link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_CLIENT_KEY_RECEIVED;
            return BCMOS_TRUE;
        }
        else
        {
            DPOE_SEC_LINK_LOG(ERROR, link_rec, "Wrong TLS version in client key exchange: %u\n",
                              link_rec->auth_ctrl.version.minor);
        }
    }
    else
    {
        DPOE_SEC_LINK_LOG(ERROR, link_rec, "Failed to parse client key exchange\n");
    }

    return BCMOS_FALSE;
}

static bcmos_bool _dpoe_eap_tls_handle_cert_verify_hs(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    bcmos_bool success;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(buf == NULL);

    success = _dpoe_eap_tls_parse_cert_verify(link_rec, buf);

    if (success)
    {
        link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_CERT_VALIDATED;
    }
    else
    {
        link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_FAILED;
        if (_auth_complete != NULL)
        {
            _auth_complete(link_rec, BCM_ERR_ONU_ERR_RESP);
        }
    }

    return success;
}

static bcmos_bool _dpoe_eap_tls_handle_finished_hs(dpoe_sec_link_rec *link_rec)
{
    bcmos_bool success;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    success = _dpoe_eap_tls_parse_verify_data(link_rec);

    /* And send the final Finished Hs to the ONU */
    if (link_rec->auth_ctrl.version.minor == TLS_MINOR_VERSION)
    {
        _dpoe_eap_tls_send_finished_hs(link_rec);
    }

    if (success)
    {
        if ((_cert_trust == NULL) || (_cert_trust(link_rec)))
        {
            link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_AUTHENTICATED;
            _dpoe_eap_tls_send_result(link_rec, EAP_CODE_SUCCESS);
            if (_auth_complete != NULL)
            {
                _auth_complete(link_rec, BCM_ERR_OK);
            }
        }
        else
        {
            link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_FAILED;
            _dpoe_eap_tls_send_result(link_rec, EAP_CODE_FAILURE);
            success = BCMOS_FALSE;
            if (_auth_complete != NULL)
            {
                _auth_complete(link_rec, BCM_ERR_INTERNAL);
            }
        }
    }
    else
    {
        /* Reset ALL the state variables! */
        memset(&link_rec->auth_ctrl, 0, sizeof(link_rec->auth_ctrl));
    }

    return success;
}

static bcmos_bool _dpoe_eap_tls_alloc_tls_frag_buffer(onu_auth_control *auth_ctrl)
{
    /* Parameter checks. */
    BUG_ON(auth_ctrl == NULL);

    if (auth_ctrl->tls_frag_buffer == NULL)
    {
        auth_ctrl->tls_frag_buffer = bcmos_calloc(EAPOL_PKT_SIZE);
        auth_ctrl->tls_frag_length = 0;
        auth_ctrl->tls_total_length = 0;
    }

    if (auth_ctrl->tls_frag_buffer == NULL)
    {
        return BCMOS_FALSE;
    }

    return BCMOS_TRUE;
}

static void _dpoe_eap_tls_free_tls_frag_buffer(onu_auth_control *auth_ctrl)
{
    /* Parameter checks. */
    BUG_ON(auth_ctrl == NULL);

    if (auth_ctrl->tls_frag_buffer != NULL)
    {
        bcmos_free(auth_ctrl->tls_frag_buffer);
        auth_ctrl->tls_frag_buffer = NULL;
        auth_ctrl->tls_frag_length = 0;
        auth_ctrl->tls_total_length = 0;
    }
}

static bcmos_errno _dpoe_eap_tls_send_tls_frag_ack_to_onu(dpoe_sec_link_rec *link_rec)
{
    bcmos_errno rc;
    bcmolt_buf buf;
    uint8_t *msg;
    eap_length_fields lf;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    /* Allocate a message buffer */
    msg = bcmos_calloc(EAPOL_PKT_SIZE);
    if (NULL == msg)
    {
        return BCM_ERR_NOMEM;
    }

    /* Initialize the EAP-TLS buffer. */
    bcmolt_buf_init(&buf, EAPOL_PKT_SIZE, msg, BCMOLT_BUF_ENDIAN_FIXED);
    if (_dpoe_eap_tls_init_eap_hdr(link_rec, &buf, EAP_CODE_REQUEST, &lf) &&
        _dpoe_eap_tls_init_tls_hdr(&buf, 0, &lf) &&
        _dpoe_eap_tls_pack_msg_lengths(&buf, 0, &lf))
    {
        /* Send the message */
        rc = dpoe_sec_send_eapol(link_rec->device, &link_rec->key, msg, bcmolt_buf_get_used(&buf));
        if (rc != BCM_ERR_OK)
        {
            bcmos_free(msg);
            return rc;
        }
    }
    else
    {
        rc = BCM_ERR_OVERFLOW;
    }

    bcmos_free(msg);

    return rc;
}

static bcmos_bool _dpoe_eap_tls_unpack_tls_handshake(bcmolt_buf *buf, tls_handshake* hs)
{
    uint24_t temp;
    bcmos_bool rc = BCMOS_FALSE;

    if (bcmolt_buf_read_u8(buf, &hs->msg_id) &&
        bcmolt_buf_read_u24(buf, &temp))
    {
        hs->msg_length = uint24_to_32(temp);
        rc = BCMOS_TRUE;
    }

    return rc;
}

static bcmos_errno _dpoe_eap_tls_run_auth_state_machine(dpoe_sec_link_rec *link_rec, bcmolt_buf *buf)
{
    bcmos_errno rc = BCM_ERR_OK;
    uint8_t *hs_snap;
    tls_handshake handshake;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    while (hs_snap = bcmolt_buf_snap_get(buf), _dpoe_eap_tls_unpack_tls_handshake(buf, &handshake))
    {
        bcmos_bool success = BCMOS_TRUE;

        if (handshake.msg_length > EAPOL_PKT_SIZE)
        {
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "Handshake length is insane: msg %u, len %u\n",
                              handshake.msg_id, handshake.msg_length);
            return BCM_ERR_PARSE;
        }

        if ((handshake.msg_id == HS_CLIENT_HELLO) &&
            (link_rec->auth_ctrl.onu_auth_state == DPOE_ONU_AUTH_STATE_EAP_START))
        {
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "EAP TLS RX msg %u in state %u\n",
                              handshake.msg_id, link_rec->auth_ctrl.onu_auth_state);
            _buffer_hash_data(link_rec, hs_snap, handshake.msg_length + TLS_HANDSHAKE_SIZE);
            success = _dpoe_eap_tls_handle_client_hello_hs(link_rec, buf);
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "New auth state %u\n", link_rec->auth_ctrl.onu_auth_state);
        }
        else if ((handshake.msg_id == HS_CERTIFICATE) &&
                 (link_rec->auth_ctrl.onu_auth_state == DPOE_ONU_AUTH_STATE_CERT_REQUEST))
        {
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "EAP TLS RX msg %u in state %u\n",
                              handshake.msg_id, link_rec->auth_ctrl.onu_auth_state);
            _buffer_hash_data(link_rec, hs_snap, handshake.msg_length + TLS_HANDSHAKE_SIZE);
            success = _dpoe_eap_tls_handle_certificate_hs(link_rec, buf);
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "New auth state %u\n", link_rec->auth_ctrl.onu_auth_state);
        }
        else if ((handshake.msg_id == HS_CLIENT_KEY_EXCHANGE) &&
                 (link_rec->auth_ctrl.onu_auth_state == DPOE_ONU_AUTH_STATE_CERT_RECEIVED))
        {
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "EAP TLS RX msg %u in state %u\n",
                              handshake.msg_id, link_rec->auth_ctrl.onu_auth_state);
            _buffer_hash_data(link_rec, hs_snap, handshake.msg_length + TLS_HANDSHAKE_SIZE);
            success = _dpoe_eap_tls_handle_client_key_exchange_hs(link_rec, buf);
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "New auth state %u\n", link_rec->auth_ctrl.onu_auth_state);
        }
        else if ((handshake.msg_id == HS_CERTIFICATE_VERIFY) &&
                 ((link_rec->auth_ctrl.onu_auth_state == DPOE_ONU_AUTH_STATE_CERT_RECEIVED) ||
                  (link_rec->auth_ctrl.onu_auth_state == DPOE_ONU_AUTH_STATE_CLIENT_KEY_RECEIVED)))

        {
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "EAP TLS RX msg %u in state %u\n",
                              handshake.msg_id, link_rec->auth_ctrl.onu_auth_state);
            dpoe_sec_sha1_final(link_rec->auth_ctrl.trans_data.sha1_digest, &link_rec->auth_ctrl.trans_data.sha1_hash);
            dpoe_sec_md5_final(link_rec->auth_ctrl.trans_data.md5_digest, &link_rec->auth_ctrl.trans_data.md5_hash);
            success = _dpoe_eap_tls_handle_cert_verify_hs(link_rec, buf);
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "New auth state %u\n", link_rec->auth_ctrl.onu_auth_state);
        }
        else if ((handshake.msg_id == HS_FINISHED) &&
                 (link_rec->auth_ctrl.onu_auth_state == DPOE_ONU_AUTH_STATE_CERT_VALIDATED))
        {
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "EAP TLS RX msg %u in state %u\n",
                              handshake.msg_id, link_rec->auth_ctrl.onu_auth_state);
            success = _dpoe_eap_tls_handle_finished_hs(link_rec);
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "New auth state %u\n", link_rec->auth_ctrl.onu_auth_state);
        }
        else
        {
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "EAP TLS RX msg %u in state %u\n",
                              handshake.msg_id, link_rec->auth_ctrl.onu_auth_state);
            success = BCMOS_FALSE;
        }

        if (!success)
        {
            /* Something went wrong, just abort... */
            DPOE_SEC_LINK_LOG(DEBUG, link_rec, "EAP TLS handshake processing failed: %u\n", handshake.msg_id);
            rc = BCM_ERR_PARSE;
        }
    }

    return rc;
}

static bcmos_bool _dpoe_eap_tls_unpack_tls_record_hdr(bcmolt_buf *buf, tls_record_hdr *msg)
{
    return bcmolt_buf_read_u8(buf, &msg->content_type) &&
        bcmolt_buf_read_u8(buf, &msg->tls_version.major) &&
        bcmolt_buf_read_u8(buf, &msg->tls_version.minor) &&
        bcmolt_buf_read_u16_be(buf, &msg->tls_record_length);
}

static bcmos_errno _dpoe_eap_tls_process_tls_records(dpoe_sec_link_rec *link_rec)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_buf buf;
    tls_record_hdr tls_hdr;

    /* Parameter checks. */
    BUG_ON(link_rec == NULL);

    bcmolt_buf_init(&buf, link_rec->auth_ctrl.tls_frag_length, link_rec->auth_ctrl.tls_frag_buffer, BCMOLT_BUF_ENDIAN_FIXED);
    while ((rc == BCM_ERR_OK) && _dpoe_eap_tls_unpack_tls_record_hdr(&buf, &tls_hdr))
    {
        rc = _dpoe_eap_tls_run_auth_state_machine(link_rec, &buf);
    }

    return rc;
}

static bcmos_bool _dpoe_eap_tls_check_tls_version(const tls_record_hdr *tls_rec_hdr)
{
    /* Parameter checks. */
    BUG_ON(tls_rec_hdr == NULL);

    if ((tls_rec_hdr->content_type != TLS_HANDSHAKE_ID) ||
        (tls_rec_hdr->tls_version.major != TLS_MAJOR_VERSION) ||
        (tls_rec_hdr->tls_version.minor < TLS_MINOR_VERSION))
    {
        return BCMOS_TRUE;
    }
    return BCMOS_FALSE;
}

static void _dpoe_eap_tls_buffer_tls_data(dpoe_sec_link_rec *link_rec, const void *data, uint32_t length)
{
    /* Parameter checks. */
    BUG_ON(link_rec == NULL);
    BUG_ON(data == NULL);

    /* do not overrun the buffer, no matter how much data received */
    if ((link_rec->auth_ctrl.tls_frag_length + length) > EAPOL_PKT_SIZE)
    {
        length = EAPOL_PKT_SIZE - link_rec->auth_ctrl.tls_frag_length;
    }

    memcpy(&link_rec->auth_ctrl.tls_frag_buffer[link_rec->auth_ctrl.tls_frag_length], data, length);
    link_rec->auth_ctrl.tls_frag_length += length;
}

static bcmos_bool _dpoe_eap_tls_unpack_msg(bcmolt_buf *buf, eapol_msg *msg)
{
    return dpoe_sec_eapol_unpack(buf, &msg->hdr) &&
        bcmolt_buf_read_u8(buf, &msg->eap_msg.hdr.eap_code) &&
        bcmolt_buf_read_u8(buf, &msg->eap_msg.hdr.id) &&
        bcmolt_buf_read_u16_be(buf, &msg->eap_msg.hdr.length) &&
        bcmolt_buf_read_u8(buf, &msg->eap_msg.tls.auth_sub_type) &&
        bcmolt_buf_read_u8(buf, &msg->eap_msg.tls.eap_tls_flags);
}

static bcmos_errno _dpoe_eap_tls_gen_key(auth_trans_data *trans_data)
{
    bcmos_errno rc = BCM_ERR_OK;
    dpoe_sec_rsa_key *rsa = NULL;

    /* Parameter checks */
    BUG_ON(trans_data == NULL);

    /* Generate the RSA key to be used in the ServerKeyExchange and ClientKeyExchange */
    rsa = dpoe_sec_rsa_generate_key(DPOE_BI_RSA_KEY_SIZE);
    if (rsa == NULL)
    {
        rc = BCM_ERR_INTERNAL;
    }
    else
    {
        /* Store the pointer to the key. */
        trans_data->rsa = rsa;
    }

    return rc;
}

bcmos_errno dpoe_eap_tls_send_start(dpoe_sec_link_rec *link_rec)
{
    bcmos_errno rc = BCM_ERR_OK;
    bcmolt_buf buf;
    uint8_t *msg;
    time_t unix_time;

    /* Parameter checks */
    BUG_ON(link_rec == NULL);

    /* Initialize the authentication control data. */
    memset(&link_rec->auth_ctrl, 0, sizeof(link_rec->auth_ctrl));
    dpoe_sec_sha1_init(&link_rec->auth_ctrl.trans_data.sha1_hash);
    dpoe_sec_md5_init(&link_rec->auth_ctrl.trans_data.md5_hash);

    /* Per standard, the first four bytes of the server random value should be "unix time" */
    unix_time = time(NULL);
    memcpy(link_rec->auth_ctrl.trans_data.server_random, &unix_time, sizeof(unix_time));
    dpoe_sec_generate_n_byte_random_number(&link_rec->auth_ctrl.trans_data.server_random[sizeof(unix_time)], COUNT_OF_RANDOM_BYTES - sizeof(unix_time));

    /* If bidirectional, generate the RSA public/private key pair for the ServerKeyExchange and ClientKeyExchange. */
    if (link_rec->cfg.enc_mode == BCMOLT_EPON_OAM_DPOE_ENCRYPTION_MODE_TEN_BI)
    {
        rc = _dpoe_eap_tls_gen_key(&link_rec->auth_ctrl.trans_data);
        BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != rc, rc);
    }

    /* Allocate a message buffer */
    msg = bcmos_calloc(EAPOL_PKT_SIZE);
    if (NULL == msg)
    {
        return BCM_ERR_NOMEM;
    }

    /* Initialize the EAP-TLS buffer. */
    bcmolt_buf_init(&buf, EAPOL_PKT_SIZE, msg, BCMOLT_BUF_ENDIAN_FIXED);

    /* Encode the EAP-TLS Start message to the buffer. */
    _dpoe_eap_tls_pack_start(link_rec, &buf);

    /* Send the message */
    rc = dpoe_sec_send_eapol(link_rec->device, &link_rec->key, msg, bcmolt_buf_get_used(&buf));
    bcmos_free(msg);
    BCMOS_CHECK_RETURN_ERROR(BCM_ERR_OK != rc, rc);

    /* Authentication has begun. */
    link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_EAP_START;

    return rc;
}

bcmos_errno dpoe_eap_tls_process_eapol_pkt(dpoe_sec_link_rec *link_rec, uint8_t *msg, uint32_t msg_len)
{
    bcmos_errno rc = BCM_ERR_INTERNAL;
    uint32_t eap_tls_length;
    tls_record_hdr tls_rec_hdr;
    eapol_msg unpacked_msg;
    bcmolt_buf buf;

    /* Parameter checks */
    BUG_ON(link_rec == NULL);
    BUG_ON(msg == NULL);

    bcmolt_buf_init(&buf, msg_len, msg, BCMOLT_BUF_ENDIAN_FIXED);
    _dpoe_eap_tls_unpack_msg(&buf, &unpacked_msg);

    if (unpacked_msg.eap_msg.tls.auth_sub_type == EAP_TYPE_NAK)
    {
        link_rec->auth_ctrl.onu_auth_state = DPOE_ONU_AUTH_STATE_FAILED;
        return BCM_ERR_ONU_ERR_RESP;
    }

    if (unpacked_msg.hdr.eapol_length != unpacked_msg.eap_msg.hdr.length)
    {
        return BCM_ERR_PARSE;
    }

    /* We should only read the length if the length bit is set. */
    if ((unpacked_msg.eap_msg.tls.eap_tls_flags & EAP_TLS_FLAG_LENGTH_BIT) != 0)
    {
        bcmolt_buf_read_u32_be(&buf, &eap_tls_length);
        uint8_t *tls_data = bcmolt_buf_snap_get(&buf);
        _dpoe_eap_tls_unpack_tls_record_hdr(&buf, &tls_rec_hdr);
        if (_dpoe_eap_tls_check_tls_version(&tls_rec_hdr))
        {
            /* Invalid TLS record, discard... */
            return BCM_ERR_PARSE;
        }

        /* Allocate the fragmentation buffer. Multiple calls to the frag alloc function is allowed since it allocates a
           new buffer only if there is no frag buffer currently allocated. The frag buffer is also freed if the EAP-TLS
           session goes down for some reason. */
        if (!_dpoe_eap_tls_alloc_tls_frag_buffer(&link_rec->auth_ctrl))
        {
            return BCM_ERR_NOMEM;
        }

        /* If the length bit is set, and the more bit is not, this is likely a single fragment packet.  In that case
           the TlsMsg length must be present, and match the size of the buffer. It is also possible that this is a
           subsequent fragment and the client always adds the length (which per standard is the length of the set of
           fragments), in which case we cannot validate this now. The best we can do is save this size, and validate
           when all fragments have been received. */
        if (link_rec->auth_ctrl.tls_total_length == 0)
        {
            link_rec->auth_ctrl.tls_total_length = eap_tls_length;
        }

        if (link_rec->auth_ctrl.tls_total_length != eap_tls_length)
        {
            return BCM_ERR_PARSE;
        }

        _dpoe_eap_tls_buffer_tls_data(
            link_rec,
            tls_data,
            unpacked_msg.hdr.eapol_length - (EAP_FRAME_SIZE + EAP_TLS_HDR_SIZE + sizeof(uint32_t)));

        if ((unpacked_msg.eap_msg.tls.eap_tls_flags & EAP_TLS_FLAG_MORE_BIT) != 0)
        {
            /* Need to acknowledge the fragment */
            _dpoe_eap_tls_send_tls_frag_ack_to_onu(link_rec);
            rc = BCM_ERR_IN_PROGRESS;
        }
        else
        {
            /* Either a single fragment packet, or the last fragment of a multi-fragment packet. If it is the last
               fragment of a multi-fragment, then all we can check is that eapTlsLength is one TlsRecordHdr bigger than
               the buffered (authCtrl->tlsFragLen) data stream. The same logic works on a single frag packet. */
            if ((eap_tls_length != link_rec->auth_ctrl.tls_total_length) ||
                (eap_tls_length != link_rec->auth_ctrl.tls_frag_length))
            {
                return BCM_ERR_PARSE;
            }

            rc = _dpoe_eap_tls_process_tls_records(link_rec);
            _dpoe_eap_tls_free_tls_frag_buffer(&link_rec->auth_ctrl);
        }
    }
    else
    {
        uint8_t *tls_data = bcmolt_buf_snap_get(&buf);

        /* No length field - must be fragmented, and not first */
        if (link_rec->auth_ctrl.tls_frag_buffer == NULL)
        {
            return BCM_ERR_OUT_OF_SYNC;
        }

        _dpoe_eap_tls_buffer_tls_data(
            link_rec,
            tls_data,
            unpacked_msg.hdr.eapol_length - (EAP_FRAME_SIZE + EAP_TLS_HDR_SIZE));

        /* If the more bit is set, wait for the next fragment. Otherwise dump what we have into the state machine. */
        if ((unpacked_msg.eap_msg.tls.eap_tls_flags & EAP_TLS_FLAG_MORE_BIT) != 0)
        {
            /* Need to acknowledge the fragment? The standard does not define a message set that will get us here. */
            _dpoe_eap_tls_send_tls_frag_ack_to_onu(link_rec);
            rc = BCM_ERR_IN_PROGRESS;
        }
        else
        {
            if (link_rec->auth_ctrl.tls_total_length != link_rec->auth_ctrl.tls_frag_length)
            {
                return BCM_ERR_PARSE;
            }

            rc = _dpoe_eap_tls_process_tls_records(link_rec);
            _dpoe_eap_tls_free_tls_frag_buffer(&link_rec->auth_ctrl);
        }
    }

    return rc;
}

void dpoe_eap_tls_cleanup(dpoe_sec_link_rec *link_rec)
{
    /* Parameter checks */
    BUG_ON(link_rec == NULL);

    // We are done with this.
    if (link_rec->auth_ctrl.certificate != NULL)
    {
        bcmos_free(link_rec->auth_ctrl.certificate);
    }

    if (link_rec->auth_ctrl.trans_data.rsa != NULL)
    {
        dpoe_sec_rsa_key_free(link_rec->auth_ctrl.trans_data.rsa);
        link_rec->auth_ctrl.trans_data.rsa = NULL;
    }

    link_rec->auth_ctrl.certLen = 0;

    _dpoe_eap_tls_free_tls_frag_buffer(&link_rec->auth_ctrl);

    memset(&link_rec->auth_ctrl, 0, sizeof(link_rec->auth_ctrl));
}

bcmos_errno dpoe_eap_tls_init(f_dpoe_sec_auth_cb auth_cb, f_dpoe_sec_cert_trust_cb cert_trust_cb)
{
    _auth_complete = auth_cb;
    _cert_trust = cert_trust_cb;

    return dpoe_sec_rng_seed();
}

