/******************************************************************
 ******************************************************************
 ***                                                             **
 ***    (C)Copyright 2008-2009, American Megatrends Inc.         **
 ***                                                             **
 ***    All Rights Reserved.                                     **
 ***                                                             **
 ***    5555 , Oakbrook Pkwy, Norcross,                          **
 ***                                                             **
 ***    Georgia - 30093, USA. Phone-(770)-246-8600.              **
 ***                                                             **
 ******************************************************************
 ******************************************************************
 ******************************************************************
 *
 * AuthCode.c
 * Authentication Code Caluculation
 *
 *  Author: Winston <winstonv@amiindia.co.in>
 ******************************************************************/
#include "RMCP.h"
#include "MD.h"
#include <string.h>
#include <stdint.h>
#include "com_IPMIDefs.h"
#include "com_IPMI_RMCP.h"
#include "com_IPMI_AppDevice.h"
#include "Session.h"

/**
 * @fn ComputeAuthCode
 * @brief Compute authentication code.
 * @param pPassword     - User password.
 * @param pSessionHdr   - Session header RMCP message.
 * @param pIPMIMsg      - IPMI message payload.
 * @param pAuthCode     - Authentication Code being generated.
 * @param ChannelType   - Channel Type.
**/
void
ComputeAuthCode ( uint8_t* pPassword,  SessionHdr_T* pSessionHdr,
                  IPMIMsgHdr_T* pIPMIMsg,  uint8_t* pAuthCode,
                 uint8_t ChannelType)
{
    if (AUTH_TYPE_PASSWORD == pSessionHdr->AuthType)
    {
        memcpy (pAuthCode, pPassword, IPMI15_MAX_PASSWORD_LEN);
    }
    else
    {
        uint8_t   AuthBuf [MAX_AUTH_PARAM_SIZE];
        uint16_t  AuthBufLen = 0;
        uint8_t   IPMIMsgLen = *(( uint8_t*) pIPMIMsg - 1);

        /* Password */
        memcpy (AuthBuf, pPassword, IPMI15_MAX_PASSWORD_LEN);
        AuthBufLen += IPMI15_MAX_PASSWORD_LEN;
        /* Session ID */
        memcpy ((uint8_t*)(AuthBuf + AuthBufLen), (uint8_t*)(&pSessionHdr->SessionID), sizeof (uint32_t));
        AuthBufLen += sizeof (uint32_t);
        /* IPMI Response Message */
        memcpy (AuthBuf + AuthBufLen, pIPMIMsg, IPMIMsgLen);
        AuthBufLen += IPMIMsgLen;

        if (ChannelType == MULTI_SESSION_CHANNEL)
        {
            /* Session Sequence Number */
            memcpy ((uint8_t*)(AuthBuf + AuthBufLen), (uint8_t*)(&pSessionHdr->SessionSeqNum), sizeof (uint32_t));
            AuthBufLen += sizeof (uint32_t);
        }
        /* Password */
        memcpy (AuthBuf + AuthBufLen, pPassword, IPMI15_MAX_PASSWORD_LEN);
        AuthBufLen += IPMI15_MAX_PASSWORD_LEN;

        switch (pSessionHdr->AuthType)
        {
        case AUTH_TYPE_MD2 :
            AuthCodeCalMD2 (AuthBuf, pAuthCode, AuthBufLen);
            break;

        case AUTH_TYPE_MD5 :
            AuthCodeCalMD5 (AuthBuf, pAuthCode, AuthBufLen);
            break;

        default  :
            printf ("RMCP.c : Invalid Authentication Type \r\n");
        }
    }
}



