BYTE Snmpv3AuthenticateTxPduForDataIntegrity(SNMPV3_RESPONSE_WHOLEMSG* txDataPtr) { UINT8* secNamePtr; UINT8 i; static HASH_SUM md5; UINT8* tempPtr; UINT8 hashTYpe; hashTYpe=snmpV3UserDataBase[gSnmpv3UserDBIndex].userHashType; if(hashTYpe == SNMPV3_HAMC_MD5) { MD5Initialize(&md5); MD5AddData(&md5,snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacIpad, (WORD)0x40); MD5AddData(&md5, txDataPtr->wholeMsgHead, txDataPtr->wholeMsgLen.Val); MD5Calculate(&md5, HmacMd5Digest); MD5Initialize(&md5); MD5AddData(&md5, snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacOpad, (WORD)0x40); MD5AddData(&md5, HmacMd5Digest,16); MD5Calculate(&md5, HmacMd5Digest); } else if(hashTYpe == SNMPV3_HMAC_SHA1) { SHA1Initialize(&md5); SHA1AddData(&md5,snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacIpad, (WORD)0x40); SHA1AddData(&md5, txDataPtr->wholeMsgHead, txDataPtr->wholeMsgLen.Val); SHA1Calculate(&md5, HmacSHADigest); SHA1Initialize(&md5); SHA1AddData(&md5, snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacOpad, (WORD)0x40); SHA1AddData(&md5, HmacSHADigest,20); SHA1Calculate(&md5, HmacSHADigest); } else return SNMPV3_MSG_AUTH_FAIL ; //Authparam validated on WholeMsg. Write back the auth param string to received buffer tempPtr=snmpOutMsgAuthParamStrng; if(hashTYpe == SNMPV3_HAMC_MD5) secNamePtr=HmacMd5Digest; else if(hashTYpe == SNMPV3_HMAC_SHA1) secNamePtr=HmacSHADigest; i=0; for(i=0;i < 12/*snmpOutMsgAuthParamLen Should be 12 Bytes*/;i++) { tempPtr[i]=secNamePtr[i]; } return SNMPV3_MSG_AUTH_PASS; }
/**************************************************************************** Function: static void SNMPv3PswdToLocalizedAuthKeySHAHashing(UINT8* pswdToLocalized, UINT8 pswdLen) Summary: Convert SHA Auth password to the localized Key using SNMPEngineID. Description: This routine converts HMAC-SHA authentication password key to localized key using snmpSngineID(RFC- 3414). Precondition: SNMPv3Init() and ProcessVariabels() are called. Parameters: pswdToLocalized - password storage poniter pswdLen - password length. Return Values: None Remarks: None ***************************************************************************/ static void SNMPv3PswdToLocalizedAuthKeySHAHashing(uint8_t* pswdToLocalized, uint8_t pswdLen) { static HASH_SUM sha1; uint8_t *compressionPtr, pswdBuf[72]; uint32_t index = 0; uint32_t count = 0, i; uint8_t* pswdPtr; SNMPV3_PROCESSING_MEM_INFO_PTRS snmpv3PktProcessingMemPntr; SNMPV3_STACK_DCPT_STUB * snmpv3EngnDcptMemoryStubPtr=0; SNMPv3GetPktProcessingDynMemStubPtrs(&snmpv3PktProcessingMemPntr); snmpv3EngnDcptMemoryStubPtr=snmpv3PktProcessingMemPntr.snmpv3StkProcessingDynMemStubPtr; pswdPtr=pswdToLocalized; SHA1Initialize(&sha1); while (count < 1048576) { compressionPtr = pswdBuf; for (i = 0; i < 64; i++) { *compressionPtr++ = pswdPtr[index++ % pswdLen]; } SHA1AddData(&sha1, pswdBuf, 64); count+=64; } SHA1Calculate(&sha1, sha1LocalizedAuthKey); memcpy(pswdBuf, sha1LocalizedAuthKey, 20 /*SHA1 localizedAuthKey buf len*/); memcpy(pswdBuf+20, snmpv3EngnDcptMemoryStubPtr->SnmpEngineID, snmpv3EngnDcptMemoryStubPtr->SnmpEngnIDLength); memcpy(pswdBuf+20+snmpv3EngnDcptMemoryStubPtr->SnmpEngnIDLength, sha1LocalizedAuthKey, 20 /*SHA1 localizedAuthKey buf len*/); SHA1Initialize(&sha1); SHA1AddData(&sha1,pswdBuf,40+snmpv3EngnDcptMemoryStubPtr->SnmpEngnIDLength); SHA1Calculate(&sha1, sha1LocalizedAuthKey); count+=64; return; }
void Snmpv3Pswd2LocalizedAuthKeySHAHashing(UINT8* pswdToLocalized, UINT8 pswdLen) { static HASH_SUM sha1; UINT8 *compressionPtr, pswdBuf[72]; UINT32 index = 0; UINT32 count = 0, i; UINT8* pswdPtr; pswdPtr=pswdToLocalized; SHA1Initialize(&sha1); while (count < 1048576) { compressionPtr = pswdBuf; for (i = 0; i < 64; i++) { *compressionPtr++ = pswdPtr[index++ % pswdLen]; } SHA1AddData(&sha1, pswdBuf, 64); count+=64; } SHA1Calculate(&sha1, sha1LocalizedAuthKey); memcpy(pswdBuf, sha1LocalizedAuthKey, 20 /*SHA1 localizedAuthKey buf len*/); memcpy(pswdBuf+20, snmpEngineID, snmpEngnIDLength); memcpy(pswdBuf+20+snmpEngnIDLength, sha1LocalizedAuthKey, 20 /*SHA1 localizedAuthKey buf len*/); SHA1Initialize(&sha1); SHA1AddData(&sha1,pswdBuf,40+snmpEngnIDLength); SHA1Calculate(&sha1, sha1LocalizedAuthKey); count+=64; return; }
UINT8* Snmpv3ComputeHmacShaDigest(UINT8 * inData, UINT32 dataLen,UINT8* userExtendedLclzdKeyIpad,UINT8* userExtendedLclzdKeyOpad) { static HASH_SUM sha1; UINT8 * data2Hmac; data2Hmac=inData; SHA1Initialize(&sha1); SHA1AddData(&sha1, authKey_iPad, (WORD)0x40); SHA1AddData(&sha1, data2Hmac, (WORD)dataLen); SHA1Calculate(&sha1, HmacSHADigest); SHA1Initialize(&sha1); SHA1AddData(&sha1, authKey_oPad, (WORD)0x40); SHA1AddData(&sha1, HmacSHADigest,20); SHA1Calculate(&sha1, HmacSHADigest); return HmacSHADigest; }
/**************************************************************************** Function: UINT8* SNMPv3ComputeHmacShaDigest(UINT8 * inData, UINT32 dataLen, UINT8* userExtendedLclzdKeyIpad, UINT8* userExtendedLclzdKeyOpad) Summary: Compute HMAC - SHA authentication code Description: This routine supports data origin authentication and data integrity SHA authentication . Both iPAD and OPAD is used to calculate the authencate digest string. RFC - 3414 ( section 6) Precondition: SNMPv3Init() and ProcessVariabels() are called. Parameters: digestptr - output string indata - input data dataLen - input data length userExtendedLclzdKeyIpad - IPAD userExtendedLclzdKeyOpad - OPAD Return Values: UINT8 * - HMAC SHA digest string Remarks: None ***************************************************************************/ uint8_t* SNMPv3ComputeHmacShaDigest(uint8_t * inData, uint32_t dataLen,uint8_t* userExtendedLclzdKeyIpad,uint8_t* userExtendedLclzdKeyOpad) { static HASH_SUM sha1; uint8_t * data2Hmac; data2Hmac=inData; SHA1Initialize(&sha1); SHA1AddData(&sha1, authKey_iPad, (uint16_t)0x40); SHA1AddData(&sha1, data2Hmac, (uint16_t)dataLen); SHA1Calculate(&sha1, HmacSHADigest); SHA1Initialize(&sha1); SHA1AddData(&sha1, authKey_oPad, (uint16_t)0x40); SHA1AddData(&sha1, HmacSHADigest,20); SHA1Calculate(&sha1, HmacSHADigest); return HmacSHADigest; }
/********************************************************************* * Function: void RandomInit(void) * * PreCondition: None * * Input: None * * Output: Random number generator is initialized. * * Side Effects: None * * Overview: Sets up the random generator structure. * * Note: Data may not be secure until several packets have * been received. ********************************************************************/ void RandomInit(void) { unsigned char i; unsigned long dw; SHA1Initialize(&randHash); // Add some starting entropy to the pool. This is slow. for(i = 0; i < 5; i++) { dw = GenerateRandomDWORD(); RandomAdd(((BYTE*)&dw)[0]); RandomAdd(((BYTE*)&dw)[1]); RandomAdd(((BYTE*)&dw)[2]); RandomAdd(((BYTE*)&dw)[3]); } bCount = 20; }
/********************************************************************* * Function: void _SYS_RANDOM_INIT(void) * * PreCondition: None * * Input: None * * Output: Random number generator is initialized. * * Side Effects: None * * Overview: Sets up the random generator structure. * * Note: Data may not be secure until several packets have * been received. ********************************************************************/ bool _SYS_RANDOM_INIT(void) { unsigned char i; unsigned long dw; SHA1Initialize(&randHash); // Add some starting entropy to the pool. This is slow. for(i = 0; i < 5; i++) { dw = SYS_GENERATE_RANDOM_DWORD(); SYS_RANDOM_ADD(((uint8_t*)&dw)[0]); SYS_RANDOM_ADD(((uint8_t*)&dw)[1]); SYS_RANDOM_ADD(((uint8_t*)&dw)[2]); SYS_RANDOM_ADD(((uint8_t*)&dw)[3]); } bCount = 20; return true; }
/**************************************************************************** Function: BYTE Snmpv3AuthenticateRxedPduForDataIntegrity(SNMPV3_REQUEST_WHOLEMSG* rxDataPtr) Summary: Authenticate an incoming SNMPV3 USM PDU using MD5 or SHA Description: This routine authenticates SNMPV3 incoming report PDU message and also for different type of GET requests with both MD5 and SHA protocol.If the received PDU username is similar to "initial", then there shoud be report PDU. RFC - 3414. Precondition: SNMPv3Init() and ProcessVariabels() are called. Parameters: rxDataPtr - incoming PDU Return Values: SNMPV3_MSG_AUTH_PASS - Authentication success SNMPV3_MSG_AUTH_FAIL - Authentication failure Remarks: None ***************************************************************************/ BYTE Snmpv3AuthenticateRxedPduForDataIntegrity(SNMPV3_REQUEST_WHOLEMSG* rxDataPtr) { UINT8 reportMsgName[7]="initial";//respose is "report" 0xa8 msg UINT8* secNamePtr; UINT8 i; WORD authParamOffset; UINT8 hashTYpe; static HASH_SUM md5; UINT8* tempPtr; secNamePtr= securityPrimitivesOfIncomingPdu.securityName; hashTYpe=snmpV3UserDataBase[gSnmpv3UserDBIndex].userHashType; //Check if the received packet is expecting "report" as response. if(!strncmp((const char *)secNamePtr, (const char *)reportMsgName, (securityPrimitivesOfIncomingPdu.securityNameLength))) return FALSE; //If "report" is expected, Retrun. authParamOffset=gSnmpV3InPduWholeMsgBuf.msgAuthParamOffsetInWholeMsg; tempPtr=gSnmpV3InPduWholeMsgBuf.snmpMsgHead; for(i=0;i<snmpInMsgAuthParamLen /*Should be 12 Bytes*/;i++) { //RFC3414 Section 6.3.2 Page#56 Step3 *(tempPtr+authParamOffset+i)=0x00; } if(hashTYpe == SNMPV3_HAMC_MD5) { MD5Initialize(&md5); MD5AddData(&md5,snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacIpad, (WORD)0x40); MD5AddData(&md5, rxDataPtr->wholeMsgHead, rxDataPtr->wholeMsgLen.Val); MD5Calculate(&md5, HmacMd5Digest); MD5Initialize(&md5); MD5AddData(&md5, snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacOpad, (WORD)0x40); MD5AddData(&md5, HmacMd5Digest,16); MD5Calculate(&md5, HmacMd5Digest); } else if(hashTYpe == SNMPV3_HMAC_SHA1) { SHA1Initialize(&md5); SHA1AddData(&md5,snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacIpad, (WORD)0x40); SHA1AddData(&md5, rxDataPtr->wholeMsgHead, rxDataPtr->wholeMsgLen.Val); SHA1Calculate(&md5, HmacSHADigest); SHA1Initialize(&md5); SHA1AddData(&md5, snmpV3UserDataBase[gSnmpv3UserDBIndex].userAuthLocalKeyHmacOpad, (WORD)0x40); SHA1AddData(&md5, HmacSHADigest,20); SHA1Calculate(&md5, HmacSHADigest); //return TRUE; } else return SNMPV3_MSG_AUTH_FAIL ; if(hashTYpe == SNMPV3_HAMC_MD5) { i=strncmp((const char *)&snmpInMsgAuthParamStrng,(const char *)&HmacMd5Digest,12); } else if(hashTYpe == SNMPV3_HMAC_SHA1) { i=strncmp((const char *)&snmpInMsgAuthParamStrng,(const char *)&HmacSHADigest,12); } if(i!=0) return SNMPV3_MSG_AUTH_FAIL; //Authparam validated on WholeMsg. Write back the auth param string to received buffer tempPtr=gSnmpV3InPduWholeMsgBuf.snmpMsgHead; for(i=0;i<snmpInMsgAuthParamLen /*Should be 12 Bytes*/;i++) { *(tempPtr+authParamOffset+i)=snmpInMsgAuthParamStrng[i]; } return SNMPV3_MSG_AUTH_PASS; }
/**************************************************************************** Function: BYTE SNMPv3AuthenticateTxPduForDataIntegrity(SNMPV3_RESPONSE_WHOLEMSG* txDataPtr) Summary: Authenticate to an outgoing SNMPV3 USM PDU using MD5 or SHA Description: This routine authenticates SNMPV3 outgoing report PDU message and also for GET Response PDU for whole message. RFC - 3414. Precondition: SNMPv3Init() and ProcessVariabels() are called. Parameters: txDataPtr - outgoing PDU Return Values: SNMPV3_MSG_AUTH_PASS - Authentication success SNMPV3_MSG_AUTH_FAIL - Authentication failure Remarks: None ***************************************************************************/ uint8_t SNMPv3AuthenticateTxPduForDataIntegrity(SNMPV3_RESPONSE_WHOLEMSG* txDataPtr) { uint8_t* secNamePtr; uint8_t i; static HASH_SUM md5; uint8_t* tempPtr; uint8_t hashTYpe; SNMPV3_PROCESSING_MEM_INFO_PTRS snmpv3PktProcessingMemPntr; SNMPV3_STACK_DCPT_STUB * snmpv3EngnDcptMemoryStubPtr=0; SNMPv3GetPktProcessingDynMemStubPtrs(&snmpv3PktProcessingMemPntr); snmpv3EngnDcptMemoryStubPtr=snmpv3PktProcessingMemPntr.snmpv3StkProcessingDynMemStubPtr; hashTYpe=snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userHashType; if(hashTYpe == SNMPV3_HAMC_MD5) { MD5Initialize(&md5); MD5AddData(&md5,snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacIpad, (uint16_t)0x40); MD5AddData(&md5, txDataPtr->wholeMsgHead, txDataPtr->wholeMsgLen.Val); MD5Calculate(&md5, HmacMd5Digest); MD5Initialize(&md5); MD5AddData(&md5, snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacOpad, (uint16_t)0x40); MD5AddData(&md5, HmacMd5Digest,16); MD5Calculate(&md5, HmacMd5Digest); } else if(hashTYpe == SNMPV3_HMAC_SHA1) { SHA1Initialize(&md5); SHA1AddData(&md5,snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacIpad, (uint16_t)0x40); SHA1AddData(&md5, txDataPtr->wholeMsgHead, txDataPtr->wholeMsgLen.Val); SHA1Calculate(&md5, HmacSHADigest); SHA1Initialize(&md5); SHA1AddData(&md5, snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacOpad, (uint16_t)0x40); SHA1AddData(&md5, HmacSHADigest,20); SHA1Calculate(&md5, HmacSHADigest); } else return SNMPV3_MSG_AUTH_FAIL ; //Authparam validated on WholeMsg. Write back the auth param string to received buffer tempPtr=snmpv3EngnDcptMemoryStubPtr->SnmpOutMsgAuthParaStrng; if(hashTYpe == SNMPV3_HAMC_MD5) secNamePtr=HmacMd5Digest; else if(hashTYpe == SNMPV3_HMAC_SHA1) secNamePtr=HmacSHADigest; i=0; for(i=0;i < 12/*SnmpOutMsgAuthParmLen Should be 12 Bytes*/;i++) { tempPtr[i]=secNamePtr[i]; } return SNMPV3_MSG_AUTH_PASS; }
/**************************************************************************** Function: BYTE SNMPv3AuthenticateRxedPduForDataIntegrity(SNMPV3_REQUEST_WHOLEMSG* rxDataPtr) Summary: Authenticate an incoming SNMPV3 USM PDU using MD5 or SHA Description: This routine authenticates SNMPV3 incoming report PDU message and also for different type of GET requests with both MD5 and SHA protocol.If the received PDU username is similar to "initial", then there shoud be report PDU. RFC - 3414. Precondition: SNMPv3Init() and ProcessVariabels() are called. Parameters: rxDataPtr - incoming PDU Return Values: SNMPV3_MSG_AUTH_PASS - Authentication success SNMPV3_MSG_AUTH_FAIL - Authentication failure Remarks: None ***************************************************************************/ uint8_t SNMPv3AuthenticateRxedPduForDataIntegrity(SNMPV3_REQUEST_WHOLEMSG* rxDataPtr) { uint8_t reportMsgName[7]="initial";//respose is "report" 0xa8 msg uint8_t* secNamePtr; uint8_t i; uint16_t authParamOffset; uint8_t hashTYpe; static HASH_SUM md5; uint8_t* tempPtr; SNMPV3_PROCESSING_MEM_INFO_PTRS snmpv3PktProcessingMemPntr; SNMPV3_STACK_DCPT_STUB * snmpv3EngnDcptMemoryStubPtr=0; SNMPv3GetPktProcessingDynMemStubPtrs(&snmpv3PktProcessingMemPntr); snmpv3EngnDcptMemoryStubPtr=snmpv3PktProcessingMemPntr.snmpv3StkProcessingDynMemStubPtr; secNamePtr= snmpv3EngnDcptMemoryStubPtr->SecurtyPrimtvesOfIncmngPdu.securityName; hashTYpe=snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userHashType; //Check if the received packet is expecting "report" as response. if(!strncmp((const char *)secNamePtr, (const char *)reportMsgName, (snmpv3EngnDcptMemoryStubPtr->SecurtyPrimtvesOfIncmngPdu.securityNameLength))) return false; //If "report" is expected, Retrun. authParamOffset=snmpv3EngnDcptMemoryStubPtr->InPduWholeMsgBuf.msgAuthParamOffsetInWholeMsg; tempPtr=snmpv3EngnDcptMemoryStubPtr->InPduWholeMsgBuf.snmpMsgHead; for(i=0;i<snmpv3EngnDcptMemoryStubPtr->SnmpInMsgAuthParamLen /*Should be 12 Bytes*/;i++) { //RFC3414 Section 6.3.2 Page#56 Step3 *(tempPtr+authParamOffset+i)=0x00; } if(hashTYpe == SNMPV3_HAMC_MD5) { MD5Initialize(&md5); MD5AddData(&md5,snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacIpad, (uint16_t)0x40); MD5AddData(&md5, rxDataPtr->wholeMsgHead, rxDataPtr->wholeMsgLen.Val); MD5Calculate(&md5, HmacMd5Digest); MD5Initialize(&md5); MD5AddData(&md5, snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacOpad, (uint16_t)0x40); MD5AddData(&md5, HmacMd5Digest,16); MD5Calculate(&md5, HmacMd5Digest); } else if(hashTYpe == SNMPV3_HMAC_SHA1) { SHA1Initialize(&md5); SHA1AddData(&md5,snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacIpad, (uint16_t)0x40); SHA1AddData(&md5, rxDataPtr->wholeMsgHead, rxDataPtr->wholeMsgLen.Val); SHA1Calculate(&md5, HmacSHADigest); SHA1Initialize(&md5); SHA1AddData(&md5, snmpv3EngnDcptMemoryStubPtr->UserInfoDataBase[snmpv3EngnDcptMemoryStubPtr->UserInfoDataBaseIndx].userAuthLocalKeyHmacOpad, (uint16_t)0x40); SHA1AddData(&md5, HmacSHADigest,20); SHA1Calculate(&md5, HmacSHADigest); //return true; } else return SNMPV3_MSG_AUTH_FAIL ; if(hashTYpe == SNMPV3_HAMC_MD5) { i=strncmp((const char *)&snmpv3EngnDcptMemoryStubPtr->SnmpInMsgAuthParmStrng,(const char *)&HmacMd5Digest,12); } else if(hashTYpe == SNMPV3_HMAC_SHA1) { i=strncmp((const char *)&snmpv3EngnDcptMemoryStubPtr->SnmpInMsgAuthParmStrng,(const char *)&HmacSHADigest,12); } if(i!=0) return SNMPV3_MSG_AUTH_FAIL; //Authparam validated on WholeMsg. Write back the auth param string to received buffer tempPtr=snmpv3EngnDcptMemoryStubPtr->InPduWholeMsgBuf.snmpMsgHead; for(i=0;i<snmpv3EngnDcptMemoryStubPtr->SnmpInMsgAuthParamLen /*Should be 12 Bytes*/;i++) { *(tempPtr+authParamOffset+i)=snmpv3EngnDcptMemoryStubPtr->SnmpInMsgAuthParmStrng[i]; } return SNMPV3_MSG_AUTH_PASS; }
/********************************************************************* * Function: void RandomInit(void) * * PreCondition: None * * Input: None * * Output: Random number generator is initialized. * * Side Effects: None * * Overview: Sets up the random generator structure. * * Note: Data is not secure until several packets have * been received. ********************************************************************/ void RandomInit(void) { SHA1Initialize(&randHash); bCount = 20; }