uint32 CRegProtocol::GetMsgType(uint32 &msgType, BufferObj &msg)
{
    try
    {
        CTlvVersion bufVersion(WSC_ID_VERSION, msg);
        CTlvMsgType bufMsgType(WSC_ID_MSG_TYPE, msg);
        msgType = bufMsgType.Value();
        msg.Rewind();
        return WSC_SUCCESS;
    }
    catch(uint32 err)
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: GetMsgType generated an "
                 "error: %d\n", err));
        return err;
    }
    catch(...)
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: GetMsgType generated an "
                 "unknown exception\n"));
        return WSC_ERR_SYSTEM;
    }
}//GetMsgType
int WPSRegistrar::ProcessDone()
{
	uint32 err;

	err = g_regProtocol.ProcessMessageDone(&m_regInfo, m_msgBuffer );
    if(WSC_SUCCESS != err)
    {
		return err_process_Done;
    }
	printf("\n*****  Successfully processed Message Done\n");
	if (m_regInfo.p_enrolleeInfo) {
		WPSDeviceWasAuthenticated(* ((GUID*) & (m_regInfo.p_enrolleeInfo->uuid)));
	}

	//****** Derivation of UPnP Protected Setup AuthKey and KeyWrapKey ******
    //1. declare and initialize the appropriate buffer objects
	BufferObj kdkBuf(m_regInfo.emsk.GetBuf(), SIZE_256_BITS);
    BufferObj pString((uint8 *)UPNP_PERSONALIZATION_STRING, 
                        strlen(UPNP_PERSONALIZATION_STRING));
    BufferObj keys;

    //2. call the key derivation function
    g_regProtocol.DeriveKey(kdkBuf, pString, 256 + 128, keys);

    //3. split the key into the component keys and store them
    keys.Rewind(keys.Length());
    m_regInfo.UPnPPSauthKey.Reset();
	m_regInfo.UPnPPSkeyWrapKey.Reset();

	m_regInfo.UPnPPSauthKey.Append(SIZE_256_BITS, keys.Pos());
    keys.Advance(SIZE_256_BITS);

    m_regInfo.UPnPPSkeyWrapKey.Append(SIZE_128_BITS, keys.Pos());
	// **** End of key derivation code

	return init;
}
void 
CRegProtocol::DecryptData(BufferObj &cipherText, 
                          BufferObj &iv,
                          BufferObj &encrKey, 
                          BufferObj &authKey, 
                          BufferObj &plainText)
{
    EVP_CIPHER_CTX ctx;
    if(0 == EVP_DecryptInit(&ctx, EVP_aes_128_cbc(), encrKey.GetBuf(), iv.GetBuf()))
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: DecryptInit failed\n"));
        throw RPROT_ERR_CRYPTO;
    }

    BufferObj buf;

    int bufLen = 1024;
    uint8 outBuf[1024];
    int outLen, currentLength;
    //block size = 1024 bytes - 128 bits, 
    //leave 128 bits at the end to accommodate any possible padding 
    //and avoid a buffer overflow
    int blockSize = bufLen - SIZE_128_BITS; 
    int length = cipherText.Length();

    uint8 *bufPtr = cipherText.GetBuf();
 
    while(length)
    {
        if(length > blockSize)
            currentLength = blockSize;
        else
            currentLength = length;

        if(0 == EVP_DecryptUpdate(&ctx, outBuf, &outLen, bufPtr, currentLength))
        {
            TUTRACE((TUTRACE_ERR, "RPROTO: DecryptUpdate failed\n"));
            throw RPROT_ERR_CRYPTO;
        }

        buf.Append(outLen, outBuf);
        bufPtr += currentLength;
        length -= currentLength;
    }

    if(0 == EVP_DecryptFinal(&ctx, outBuf, &outLen))
    {
        TUTRACE((TUTRACE_ERR, "RPROTO: DecryptFinal failed\n"));
        throw RPROT_ERR_CRYPTO;
    }

    buf.Append(outLen, outBuf);

    //Validate the mac at the end of the decrypted buffer
    //uint8 *mac = buf.GetBuf()+(buf.Length()-SIZE_256_BITS);//get the last 256 bits
    //if(0 == ValidateMac(BufferObj(buf.GetBuf(), buf.Length()-SIZE_256_BITS), mac, authKey))
    //{
    //    TUTRACE((TUTRACE_ERR, "RPROTO: Mac validation failed\n"));
    //    throw RPROT_ERR_INVALID_VALUE;
    //}
    //plainText.Append(buf.Length()-SIZE_256_BITS, buf.GetBuf());
    plainText.Append(buf.Length(), buf.GetBuf());
    plainText.Rewind(plainText.Length());
}