int TMsg::setAuthInfoKey() { #ifndef MOD_DISABLE_AUTH // key = HMAC-SHA1 (AAA-key, {Key Generation Nonce || client identifier}) char *KeyGenNonce_ClientID; char * AAAkey; uint32_t AAAkeyLen; if (!KeyGenNonce) KeyGenNonceLen = 16; /// @todo set proper size of Client ID (DUID?) (here and in hmac_sha()) KeyGenNonce_ClientID = new char[KeyGenNonceLen+128]; AAAkey = getAAAKey(AAASPI, &AAAkeyLen); std::string fname = getAAAKeyFilename(AAASPI); // error, no file? if (!AAAkey) { Log(Error) << "Auth: Unable to load key file for SPI " << std::hex << AAASPI <<": " << fname << " not found." << std::dec << LogEnd; AuthInfoKey = NULL; delete [] KeyGenNonce_ClientID; return -1; } Log(Debug) << "Auth: AAA-key loaded from file " << fname << "." << LogEnd; PrintHex("Auth: AAA-key: ", AAAkey, AAAkeyLen); memset(KeyGenNonce_ClientID, 0, KeyGenNonceLen+128); if (KeyGenNonce) memcpy(KeyGenNonce_ClientID, KeyGenNonce, KeyGenNonceLen); /// @todo fill also with ClientID (DUID?) PrintHex("Auth: Infokey: using KeyGenNonce+CliendID: ", KeyGenNonce_ClientID, KeyGenNonceLen+128); Log(Debug) << "Auth: AAAKeyLen: " << AAAkeyLen << ", KeyGenNonceLen: " << KeyGenNonceLen << LogEnd; AuthInfoKey = new char[AUTHKEYLEN]; hmac_sha(KeyGenNonce_ClientID, KeyGenNonceLen+128, AAAkey, AAAkeyLen, (char *)AuthInfoKey, 1); PrintHex("Auth: AuthInfoKey (calculated): ", AuthInfoKey, AUTHKEYLEN); delete [] KeyGenNonce_ClientID; #endif return 0; }
/* prepares binary version of this message, returns number of bytes used **/ int TMsg::storeSelf(char * buffer) { char *start = buffer; int tmp = this->TransID; enum DigestTypes UsedDigestType; if (Bulk) { int tmpSize = this->MsgSize; Log(Debug) <<"MsgSize - DHCP "<<this->MsgSize<< LogEnd; buffer[1]=tmpSize%256; tmpSize/=256; buffer[0]=tmpSize%256; tmpSize/=256; buffer[2]=(char)MsgType; buffer[5] = tmp%256; tmp = tmp/256; buffer[4] = tmp%256; tmp = tmp/256; buffer[3] = tmp%256; tmp = tmp/256; buffer+=6; } else { *(buffer++) = (char)MsgType; /* ugly 3-byte version of htons/htonl */ buffer[2] = tmp%256; tmp = tmp/256; buffer[1] = tmp%256; tmp = tmp/256; buffer[0] = tmp%256; tmp = tmp/256; buffer+=3; } TOptList::iterator option; for (option=Options.begin(); option!=Options.end(); ++option) { (*option)->storeSelf(buffer); buffer += (*option)->getSize(); } #ifndef MOD_DISABLE_AUTH // for AAAAUTH use only HMAC-SHA1 if (getOption(OPTION_AAAAUTH)) UsedDigestType = DIGEST_HMAC_SHA1; else UsedDigestType = DigestType; if (AuthInfoKey && AuthInfoPtr && (getOption(OPTION_AUTH) || getOption(OPTION_AAAAUTH)) && UsedDigestType != DIGEST_NONE) { Log(Debug) << "Auth: Used digest type is " << getDigestName(UsedDigestType) << LogEnd; switch (UsedDigestType) { case DIGEST_PLAIN: memcpy(AuthInfoPtr, "This is 32-byte plain testkey...", getDigestSize(UsedDigestType)); break; case DIGEST_HMAC_MD5: hmac_md5(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr); break; case DIGEST_HMAC_SHA1: hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 1); break; case DIGEST_HMAC_SHA224: hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 224); break; case DIGEST_HMAC_SHA256: hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 256); break; case DIGEST_HMAC_SHA384: hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 384); break; case DIGEST_HMAC_SHA512: hmac_sha(start, buffer-start, AuthInfoKey, AUTHKEYLEN, (char *)AuthInfoPtr, 512); break; default: break; } PrintHex("Auth: Sending digest: ", AuthInfoPtr, getDigestSize(UsedDigestType)); } #endif return buffer-start; }
bool TMsg::validateAuthInfo(char *buf, int bufSize, AuthProtocols proto, const DigestTypesLst& acceptedDigestTypes) { bool is_ok = false; bool dt_in_list = false; switch (proto) { case AUTH_PROTO_NOT_SUPPORTED: case AUTH_PROTO_NONE: return true; case AUTH_PROTO_DELAYED: { SPtr<TOptAuthentication> auth = (Ptr*)getOption(OPTION_AUTH); if (!auth) { Log(Warning) << "AUTH: Mandatory AUTH option missing in delayed auth." << LogEnd; return false; } if (auth->getProto() != AUTH_PROTO_DELAYED) { Log(Warning) << "AUTH: Bad protocol in auth: expected 2(delayed auth), but got " << int(auth->getProto()) << ", key ignored." << LogEnd; return false; } if (auth->getAlgorithm() != 1) { Log(Warning) << "AUTH: Bad algorithm in auth option: expected 1 (HMAC-MD5), but got " << int(auth->getAlgorithm()) << ", key ignored." << LogEnd; return false; } if (MsgType == SOLICIT_MSG) { if (auth->getSize() != TOptAuthentication::OPT_AUTH_FIXED_SIZE + TOpt::OPTION6_HDR_LEN) { Log(Warning) << "AUTH: Received non-empty delayed-auth option in SOLICIT," << " expected empty." << LogEnd; return false; } else { return true; // delayed auth in Solicit should come in empty } } if (SPI_ == 0) { Log(Warning) << "AUTH: Received invalid SPI = 0." << LogEnd; return false; } if (!loadAuthKey()) { Log(Warning) << "AUTH: Failed to load delayed auth key with key id=" << std::hex << getSPI() << std::dec << LogEnd; return false; } // Ok, let's do validation char *rcvdAuthInfo = new char[RECONFIGURE_DIGEST_SIZE]; char *goodAuthInfo = new char[RECONFIGURE_DIGEST_SIZE]; memmove(rcvdAuthInfo, AuthDigestPtr_, DELAYED_AUTH_DIGEST_SIZE); memset(AuthDigestPtr_, 0, DELAYED_AUTH_DIGEST_SIZE); hmac_md5(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo); Log(Debug) << "Auth: Checking delayed-auth (HMAC-MD5) digest:" << LogEnd; PrintHex("Auth:received digest: ", (uint8_t*)rcvdAuthInfo, DELAYED_AUTH_DIGEST_SIZE); PrintHex("Auth: proper digest: ", (uint8_t*)goodAuthInfo, DELAYED_AUTH_DIGEST_SIZE); if (0 == memcmp(goodAuthInfo, rcvdAuthInfo, DELAYED_AUTH_DIGEST_SIZE)) is_ok = true; delete [] rcvdAuthInfo; delete [] goodAuthInfo; return is_ok; } case AUTH_PROTO_RECONFIGURE_KEY: { if (MsgType != RECONFIGURE_MSG) return true; SPtr<TOptAuthentication> auth = (Ptr*)getOption(OPTION_AUTH); if (!auth) { Log(Warning) << "AUTH: Mandatory AUTH option missing in RECONFIGURE." << LogEnd; return false; } if (auth->getProto() != AUTH_PROTO_RECONFIGURE_KEY) { Log(Warning) << "AUTH: Bad protocol in auth: expected 3(reconfigure-key), but got " << int(auth->getProto()) << ", key ignored." << LogEnd; return false; } if (auth->getAlgorithm() != 1) { Log(Warning) << "AUTH: Bad algorithm in auth option: expected 1, but got " << int(auth->getAlgorithm()) << ", key ignored." << LogEnd; return false; } if (auth->getRDM() != AUTH_REPLAY_NONE) { Log(Warning) << "AUTH: Bad replay detection method (RDM) value: expected 0," << ", but got " << auth->getRDM() << LogEnd; // This is small issue enough, so we can continue. } if (AuthKey_.size() != RECONFIGURE_KEY_SIZE) { Log(Error) << "AUTH: Failed to verify incoming RECONFIGURE message due to " << "reconfigure-key issue: expected size " << RECONFIGURE_KEY_SIZE << ", but got " << AuthKey_.size() << ", message dropped." << LogEnd; return false; } if (!AuthDigestPtr_) { Log(Error) << "AUTH: Failed to verify incoming RECONFIGURE message: " << "AuthDigestPtr_ not set, message dropped." << LogEnd; return false; } char *rcvdAuthInfo = new char[RECONFIGURE_DIGEST_SIZE]; char *goodAuthInfo = new char[RECONFIGURE_DIGEST_SIZE]; memmove(rcvdAuthInfo, AuthDigestPtr_, RECONFIGURE_DIGEST_SIZE); memset(AuthDigestPtr_, 0, RECONFIGURE_DIGEST_SIZE); hmac_md5(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo); Log(Debug) << "Auth: Checking reconfigure-key" << LogEnd; PrintHex("Auth:received digest: ", (uint8_t*)rcvdAuthInfo, RECONFIGURE_DIGEST_SIZE); PrintHex("Auth: proper digest: ", (uint8_t*)goodAuthInfo, RECONFIGURE_DIGEST_SIZE); if (0 == memcmp(goodAuthInfo, rcvdAuthInfo, RECONFIGURE_DIGEST_SIZE)) is_ok = true; delete [] rcvdAuthInfo; delete [] goodAuthInfo; return is_ok; } case AUTH_PROTO_DIBBLER: break; } //empty list means that any digest type is accepted if (acceptedDigestTypes.empty()) { dt_in_list = true; } else { // check if the digest is allowed AUTH list for (unsigned i = 0; i < acceptedDigestTypes.size(); ++i) { if (acceptedDigestTypes[i] == DigestType_) { dt_in_list = true; break; } } } if (dt_in_list == false) { if (DigestType_ == DIGEST_NONE) Log(Warning) << "Authentication option is required." << LogEnd; else Log(Warning) << "Authentication method " << getDigestName(DigestType_) << " not accepted." << LogEnd; return false; } if (DigestType_ == DIGEST_NONE) { is_ok = true; } else if (AuthDigestPtr_) { #ifndef MOD_DISABLE_AUTH if (AuthKey_.empty() && !loadAuthKey()) { Log(Debug) << "Auth: Failed to load key with SPI=" << SPI_ << LogEnd; return false; } unsigned AuthInfoLen = getDigestSize(DigestType_); char *rcvdAuthInfo = new char[AuthInfoLen]; char *goodAuthInfo = new char[AuthInfoLen]; memmove(rcvdAuthInfo, AuthDigestPtr_, AuthInfoLen); memset(AuthDigestPtr_, 0, AuthInfoLen); switch (DigestType_) { case DIGEST_PLAIN: /// @todo: load plain text from a file memcpy(goodAuthInfo, "This is 32-byte plain testkey...", 32); break; case DIGEST_HMAC_MD5: hmac_md5(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo); break; case DIGEST_HMAC_SHA1: hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 1); break; case DIGEST_HMAC_SHA224: hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 224); break; case DIGEST_HMAC_SHA256: hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 256); break; case DIGEST_HMAC_SHA384: hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 384); break; case DIGEST_HMAC_SHA512: hmac_sha(buf, bufSize, (char*)&AuthKey_[0], AuthKey_.size(), goodAuthInfo, 512); break; default: break; } if (0 == memcmp(goodAuthInfo, rcvdAuthInfo, AuthInfoLen)) is_ok = true; Log(Debug) << "Auth:Checking using digest method: " << getDigestName(DigestType_) << LogEnd; PrintHex("Auth:received digest: ", (uint8_t*)rcvdAuthInfo, AuthInfoLen); PrintHex("Auth: proper digest: ", (uint8_t*)goodAuthInfo, AuthInfoLen); delete [] rcvdAuthInfo; delete [] goodAuthInfo; if (is_ok) Log(Info) << "Auth: Digest correct." << LogEnd; else { Log(Warning) << "Auth: Digest incorrect." << LogEnd; } #endif } else { Log(Error) << "Auth: Digest mode set to " << DigestType_ << ", but AUTH option not set." << LogEnd; return false; } return is_ok; }
void TMsg::calculateDigests(char* buffer, size_t len) { SPtr<TOptAuthentication> auth = (Ptr*)getOption(OPTION_AUTH); if (!auth) return; switch (auth->getProto()) { default: { Log(Error) << "AUTH: protocol " << auth->getProto() << " not supported yet." << LogEnd; return; } case AUTH_PROTO_DELAYED: { if (AuthKey_.empty()) { if (MsgType == SOLICIT_MSG) { return; // That's alright, no auth info in SOLICIT } Log(Error) << "AUTH: Can't sign delayed-auth option, key empty." << LogEnd; return; } if (auth->getAuthDataPtr()) { hmac_md5(buffer, len, (char*) &AuthKey_[0], AuthKey_.size() ,auth->getAuthDataPtr()); } return; } case AUTH_PROTO_RECONFIGURE_KEY: { if (AuthKey_.size() != RECONFIGURE_KEY_SIZE) { Log(Error) << "AUTH: Invalid size of reconfigure-key: expected " << RECONFIGURE_KEY_SIZE << ", actual size " << AuthKey_.size() << LogEnd; return; } if (auth->getAuthDataPtr()) { hmac_md5(buffer, len, (char*) &AuthKey_[0], AuthKey_.size() ,auth->getAuthDataPtr()); } return; } case AUTH_PROTO_NOT_SUPPORTED: case AUTH_PROTO_NONE: { // don't calculate anything return; } case AUTH_PROTO_DIBBLER: { DigestTypes UsedDigestType; // for AAAAUTH use only HMAC-SHA1 UsedDigestType = DigestType_; if (getSPI() && !loadAuthKey()) { return; } if (getSPI() && !AuthKey_.empty() && UsedDigestType != DIGEST_NONE) { Log(Debug) << "Auth: Used digest type is " << getDigestName(UsedDigestType) << LogEnd; switch (UsedDigestType) { case DIGEST_PLAIN: memcpy(AuthDigestPtr_, "This is 32-byte plain testkey...", getDigestSize(UsedDigestType)); break; case DIGEST_HMAC_MD5: hmac_md5(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_); break; case DIGEST_HMAC_SHA1: hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 1); break; case DIGEST_HMAC_SHA224: hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 224); break; case DIGEST_HMAC_SHA256: hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 256); break; case DIGEST_HMAC_SHA384: hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 384); break; case DIGEST_HMAC_SHA512: hmac_sha(buffer, len, (char*)&AuthKey_[0], AuthKey_.size(), (char *)AuthDigestPtr_, 512); break; default: break; } PrintHex(std::string("Auth: Sending digest ") + getDigestName(UsedDigestType) +" : ", (uint8_t*)AuthDigestPtr_, getDigestSize(UsedDigestType)); } } } }
size_t hmac_sha512(const hash_t *key, const hash_t *msg, hash_t *hash) { return hmac_sha(key, msg, hash, evp_sha512()); }
int main() { unsigned int i, j, k, key_len = 64; unsigned char mac[HMAC_MAX_OUTPUT_SIZE]; #ifdef SHA_1 for(i = 0; i < SHA1_TESTS; ++i) { hmac_sha(HMAC_SHA1, t_sha1[i].key, t_sha1[i].key_len, t_sha1[i].text, t_sha1[i].txt_len, mac, t_sha1[i].mac_len); printf("\nHMAC-SHA1 test %i, ", i + 1); printf("key %s", memcmp(t_sha1[i].mac, mac, t_sha1[i].mac_len) ? "is bad" : "is good"); printf("\n"); for(j = 0; j < t_sha1[i].mac_len; j += 4) printf("0x%02x%02x%02x%02x ", mac[j], mac[j + 1], mac[j + 2], mac[j + 3]); printf("\n"); } for(i = 0; i < SHA1_TESTS; ++i) { hmac_ctx cx[1]; hmac_sha_begin(HMAC_SHA1, cx); hmac_sha_key(t_sha1[i].key, t_sha1[i].key_len / 2, cx); hmac_sha_key(t_sha1[i].key + t_sha1[i].key_len / 2, t_sha1[i].key_len - t_sha1[i].key_len / 2, cx); hmac_sha_data(t_sha1[i].text, t_sha1[i].txt_len / 2, cx); hmac_sha_data(t_sha1[i].text + t_sha1[i].txt_len / 2, t_sha1[i].txt_len - t_sha1[i].txt_len / 2, cx); hmac_sha_end(mac, t_sha1[i].mac_len, cx); printf("\nHMAC-SHA1 test %i, ", i + 1); printf("mac %s", memcmp(t_sha1[i].mac, mac, t_sha1[i].mac_len) ? "is bad" : "is good"); printf("\n"); for(j = 0; j < t_sha1[i].mac_len; j += 4) printf("0x%02x%02x%02x%02x ", mac[j], mac[j + 1], mac[j + 2], mac[j + 3]); printf("\n"); } #endif #ifdef SHA_256 for(i = 0; i < SHA256_TESTS; ++i) { hmac_sha(HMAC_SHA256, t_sha256[i].key, t_sha256[i].key_len, t_sha256[i].text, t_sha256[i].txt_len, mac,t_sha256[i].mac_len); printf("\nHMAC-SHA256 test %i, ", i + 1); printf("mac %s", memcmp(t_sha256[i].mac, mac, t_sha256[i].mac_len) ? "is bad" : "is good"); for(j = 0; j < t_sha256[i].mac_len; j += 4) { if(j % 16 == 0) printf("\n"); printf("0x%02x%02x%02x%02x ", mac[j], mac[j + 1], mac[j + 2], mac[j + 3]); } printf("\n"); } for(i = 0; i < SHA256_TESTS; ++i) { hmac_ctx cx[1]; hmac_sha_begin(HMAC_SHA256, cx); hmac_sha_key(t_sha256[i].key, t_sha256[i].key_len / 2, cx); hmac_sha_key(t_sha256[i].key + t_sha256[i].key_len / 2, t_sha256[i].key_len - t_sha256[i].key_len / 2, cx); hmac_sha_data(t_sha256[i].text, t_sha256[i].txt_len / 2, cx); hmac_sha_data(t_sha256[i].text + t_sha256[i].txt_len / 2, t_sha256[i].txt_len - t_sha256[i].txt_len / 2, cx); hmac_sha_end(mac, t_sha256[i].mac_len, cx); printf("\nHMAC-SHA256 test %i, ", i + 1); printf("mac %s", memcmp(t_sha256[i].mac, mac, t_sha256[i].mac_len) ? "is bad" : "is good"); for(j = 0; j < t_sha256[i].mac_len; j += 4) { if(j % 16 == 0) printf("\n"); printf("0x%02x%02x%02x%02x ", mac[j], mac[j + 1], mac[j + 2], mac[j + 3]); } printf("\n"); } #endif #ifdef SHA_224 for(i = 0; i < SHA2_TESTS; ++i) { hmac_ctx cx[1]; hmac_sha_begin(HMAC_SHA224, cx); hmac_sha_key(t_s2[i].key, t_s2[i].key_len / 2, cx); hmac_sha_key(t_s2[i].key + t_s2[i].key_len / 2, t_s2[i].key_len - t_s2[i].key_len / 2, cx); hmac_sha_data(t_s2[i].text, t_s2[i].txt_len / 2, cx); hmac_sha_data(t_s2[i].text + t_s2[i].txt_len / 2, t_s2[i].txt_len - t_s2[i].txt_len / 2, cx); hmac_sha_end(mac, t_s2[i].mac_len[0], cx); printf("\nHMAC-SHA224 test %i, ", i + 1); printf("mac %s", memcmp(t_s2[i].r224, mac, t_s2[i].mac_len[0]) ? "is bad" : "is good"); for(k = 0; k < t_s2[i].mac_len[0]; k += 4) { if(k % 16 == 0) printf("\n"); printf("0x%02x%02x%02x%02x ", mac[k], mac[k + 1], mac[k + 2], mac[k + 3]); } printf("\n"); } #endif #ifdef SHA_256 for(i = 0; i < SHA2_TESTS; ++i) { hmac_ctx cx[1]; hmac_sha_begin(HMAC_SHA256, cx); hmac_sha_key(t_s2[i].key, t_s2[i].key_len / 2, cx); hmac_sha_key(t_s2[i].key + t_s2[i].key_len / 2, t_s2[i].key_len - t_s2[i].key_len / 2, cx); hmac_sha_data(t_s2[i].text, t_s2[i].txt_len / 2, cx); hmac_sha_data(t_s2[i].text + t_s2[i].txt_len / 2, t_s2[i].txt_len - t_s2[i].txt_len / 2, cx); hmac_sha_end(mac, t_s2[i].mac_len[1], cx); printf("\nHMAC-SHA256 test %i, ", i + 1); printf("mac %s", memcmp(t_s2[i].r256, mac, t_s2[i].mac_len[1]) ? "is bad" : "is good"); for(k = 0; k < t_s2[i].mac_len[1]; k += 4) { if(k % 16 == 0) printf("\n"); printf("0x%02x%02x%02x%02x ", mac[k], mac[k + 1], mac[k + 2], mac[k + 3]); } printf("\n"); } #endif #ifdef SHA_384 for(i = 0; i < SHA2_TESTS; ++i) { hmac_ctx cx[1]; hmac_sha_begin(HMAC_SHA384, cx); hmac_sha_key(t_s2[i].key, t_s2[i].key_len / 2, cx); hmac_sha_key(t_s2[i].key + t_s2[i].key_len / 2, t_s2[i].key_len - t_s2[i].key_len / 2, cx); hmac_sha_data(t_s2[i].text, t_s2[i].txt_len / 2, cx); hmac_sha_data(t_s2[i].text + t_s2[i].txt_len / 2, t_s2[i].txt_len - t_s2[i].txt_len / 2, cx); hmac_sha_end(mac, t_s2[i].mac_len[2], cx); printf("\nHMAC-SHA384 test %i, ", i + 1); printf("mac %s", memcmp(t_s2[i].r384, mac, t_s2[i].mac_len[2]) ? "is bad" : "is good"); for(k = 0; k < t_s2[i].mac_len[2]; k += 4) { if(k % 16 == 0) printf("\n"); printf("0x%02x%02x%02x%02x ", mac[k], mac[k + 1], mac[k + 2], mac[k + 3]); } printf("\n"); } #endif #ifdef SHA_512 for(i = 0; i < SHA2_TESTS; ++i) { hmac_ctx cx[1]; hmac_sha_begin(HMAC_SHA512, cx); hmac_sha_key(t_s2[i].key, t_s2[i].key_len / 2, cx); hmac_sha_key(t_s2[i].key + t_s2[i].key_len / 2, t_s2[i].key_len - t_s2[i].key_len / 2, cx); hmac_sha_data(t_s2[i].text, t_s2[i].txt_len / 2, cx); hmac_sha_data(t_s2[i].text + t_s2[i].txt_len / 2, t_s2[i].txt_len - t_s2[i].txt_len / 2, cx); hmac_sha_end(mac, t_s2[i].mac_len[3], cx); printf("\nHMAC-SHA512 test %i, ", i + 1); printf("mac %s", memcmp(t_s2[i].r512, mac, t_s2[i].mac_len[3]) ? "is bad" : "is good"); for(k = 0; k < t_s2[i].mac_len[3]; k += 4) { if(k % 16 == 0) printf("\n"); printf("0x%02x%02x%02x%02x ", mac[k], mac[k + 1], mac[k + 2], mac[k + 3]); } printf("\n"); } #endif printf("\n\n"); return 0; }
void main() { //variable about hmac_sha u8_t key[16] = {0x0}; u8_t key_len = 16; u8_t data[16] = {0x0}; u8_t data_len = 16; u8_t out[16] = {0x0}; u8_t out_len = 16; int i = 0 ; //def buff to storage encrypt data u8_t *buff = NULL; u8_t buff_len = 0; buff_len = sizeof(key) + sizeof(out); buff = (u8_t *)malloc(buff_len); memset(buff,0,buff_len); //initital key memset(key,0,16); memcpy(key,ip1,4); //initital data memset(data,0,16); memcpy(data,ip2,4); memcpy(data+4,ip3,4); memcpy(data+8,ip4,4); memcpy(data+12,ip5,4); hmac_sha(key,key_len,data,data_len,out,out_len); printf("key:\n"); for(i = 0;i<key_len;i++) { printf("%02x ",key[i]); } printf("\n"); //copy encrypt data memcpy(buff,ip2,4); memcpy(buff + 4,ip3,4); memcpy(buff + 8,ip4,4); memcpy(buff + 12,ip5,4); memcpy(buff + 16,out,16); //open output file FILE *fpd; if((fpd = fopen("output.txt","a+")) == NULL) { printf("open output file failure\n"); return 0; } printf("fwrite ret:%d\n",fwrite(buff,1,buff_len,fpd)); fclose(fpd); }