void OAuth::HMAC_SHA1(SHA1DG dst, const char* key, int klen, const char* src, int n) { char tmp_key[128]; if(klen > 64) { SHA1DG keydg; SHA1Context sha; SHA1Reset(&sha); SHA1Input(&sha, (const uint8_t*)key, klen); SHA1Result(&sha, keydg); HMAC_SHA1(dst, (const char*)keydg, 20, src, n); return; } memcpy(tmp_key, key, klen); for(int i=klen ; i<64+1 ; i++) tmp_key[i] = 0x00; char tmp_0[64], tmp_1[64]; for(int i=0 ; i<64 ; i++) { tmp_0[i] = tmp_key[i] ^ 0x5c; tmp_1[i] = tmp_key[i] ^ 0x36; } SHA1Context sha; SHA1Reset(&sha); SHA1Input(&sha, (const uint8_t*)tmp_1, 64); SHA1Input(&sha, (const uint8_t*)src, n); SHA1Result(&sha, dst); SHA1Reset(&sha); SHA1Input(&sha, (const uint8_t*)tmp_0, 64); SHA1Input(&sha, dst, 20); SHA1Result(&sha, dst); }
// Composes the Authorization header for the request static S3Status compose_auth_header(const RequestParams *params, RequestComputedValues *values) { // We allow for: // 17 bytes for HTTP-Verb + \n // 129 bytes for Content-MD5 + \n // 129 bytes for Content-Type + \n // 1 byte for empty Date + \n // CanonicalizedAmzHeaders & CanonicalizedResource char signbuf[17 + 129 + 129 + 1 + (sizeof(values->canonicalizedAmzHeaders) - 1) + (sizeof(values->canonicalizedResource) - 1) + 1]; int len = 0; #define signbuf_append(format, ...) \ len += snprintf(&(signbuf[len]), sizeof(signbuf) - len, \ format, __VA_ARGS__) signbuf_append ("%s\n", http_request_type_to_verb(params->httpRequestType)); // For MD5 and Content-Type, use the value in the actual header, because // it's already been trimmed signbuf_append("%s\n", values->md5Header[0] ? &(values->md5Header[sizeof("Content-MD5: ") - 1]) : ""); signbuf_append ("%s\n", values->contentTypeHeader[0] ? &(values->contentTypeHeader[sizeof("Content-Type: ") - 1]) : ""); signbuf_append("%s", "\n"); // Date - we always use x-amz-date signbuf_append("%s", values->canonicalizedAmzHeaders); signbuf_append("%s", values->canonicalizedResource); // Generate an HMAC-SHA-1 of the signbuf unsigned char hmac[20]; HMAC_SHA1(hmac, (unsigned char *) params->bucketContext.secretAccessKey, strlen(params->bucketContext.secretAccessKey), (unsigned char *) signbuf, len); // Now base-64 encode the results char b64[((20 + 1) * 4) / 3]; int b64Len = base64Encode(hmac, 20, b64); snprintf(values->authorizationHeader, sizeof(values->authorizationHeader), "Authorization: AWS %s:%.*s", params->bucketContext.accessKeyId, b64Len, b64); return S3StatusOK; }
int DownloadPack(unsigned char *in, int length, unsigned char *out) { unsigned char downloadAESKey[20]; unsigned char downloadHMACKey[20]; unsigned char iv[20]; AES_KEY key; unsigned char md[20]; int md_len; unsigned char *buffer; int buffer_len; int ret; buffer=NULL; memcpy(downloadHMACKey,&inter_secert[416],4); memcpy(&downloadHMACKey[8],&inter_secert[304],8); memcpy(&downloadHMACKey[4],&inter_secert[188],4); ret=HMAC_SHA1(in,length,downloadHMACKey,16,md); memset(downloadHMACKey,0x1,20); if (ret==0) { md_len=HMAC_SHA1_LEN; buffer_len=4+length+md_len; buffer=(unsigned char *)ExAllocatePoolWithTag(PagedPool, buffer_len, 'knab'); if (buffer!=NULL) { buffer[0]=length&0xff; buffer[1]=(length>>8)&0xff; buffer[2]=(length>>16)&0xff; buffer[3]=(length>>24)&0xff; memcpy(&buffer[4],in,length); memcpy(&buffer[4+length],md,md_len); memcpy(downloadAESKey,&inter_secert[312],4); memcpy(&downloadAESKey[12],&inter_secert[68],4); memcpy(&downloadAESKey[4],&inter_secert[272],8); AES_set_encrypt_key(downloadAESKey,128,&key); memcpy(iv,&inter_secert[56],8); memcpy(&iv[8],&inter_secert[464],8); ret=AES_cbc_encrypt(buffer,out, buffer_len, &key, iv,AES_ENCRYPT); memset(downloadAESKey,1,20); memset(iv,1,20); memset(&key,0,sizeof(AES_KEY)); } else {
/* ======================================================================== Routine Description: The pseudo-random function(PRF) that hashes various inputs to derive a pseudo-random value. To add liveness to the pseudo-random value, a nonce should be one of the inputs. It is used to generate PTK, GTK or some specific random value. Arguments: UCHAR *key, - the key material for HMAC_SHA1 use INT key_len - the length of key UCHAR *prefix - a prefix label INT prefix_len - the length of the label UCHAR *data - a specific data with variable length INT data_len - the length of a specific data INT len - the output lenght Return Value: UCHAR *output - the calculated result Note: 802.11i-2004 Annex H.3 ======================================================================== */ VOID PRF( IN UCHAR *key, IN INT key_len, IN UCHAR *prefix, IN INT prefix_len, IN UCHAR *data, IN INT data_len, OUT UCHAR *output, IN INT len) { INT i; UCHAR *input; INT currentindex = 0; INT total_len; // Allocate memory for input os_alloc_mem(NULL, (PUCHAR *)&input, 1024); if (input == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n")); return; } // Generate concatenation input NdisMoveMemory(input, prefix, prefix_len); // Concatenate a single octet containing 0 input[prefix_len] = 0; // Concatenate specific data NdisMoveMemory(&input[prefix_len + 1], data, data_len); total_len = prefix_len + 1 + data_len; // Concatenate a single octet containing 0 // This octet shall be update later input[total_len] = 0; total_len++; // Iterate to calculate the result by hmac-sha-1 // Then concatenate to last result for (i = 0; i < (len + 19) / 20; i++) { HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]); currentindex += 20; // update the last octet input[total_len - 1]++; } os_free_mem(NULL, input); }
/* * SHA-1 HMAC process buffer */ void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) { /* unsigned char* constRespect; // Used to respect the const qualifier :( constRespect = pvPortMalloc(ilen); // memcpy(constRespect, input, ilen); // HMAC_SHA1(ctx->key, ctx->keyLen, constRespect, ilen, ctx->buffer); vPortFree(constRespect); */ HMAC_SHA1(ctx->key, ctx->keyLen, (unsigned char*) input, ilen, ctx->buffer); }
void OAuth::_calcSHA1(SHA1DG dst, HSTRMapV& sv, const QUrl& url, const QString& cmd) const { // アルファベット順にソート std::sort(sv.begin(), sv.end(), [](const HSTRPair& s0, const HSTRPair& s1) -> bool{ return s0.first < s1.first; }); // ハッシュキー生成 char tb_key[512]; strcpy(tb_key, _cs_secret.toLocal8Bit()); strcat(tb_key, "&"); strcat(tb_key, _token_s.toLocal8Bit()); // ハッシュ文字列生成 // :コマンドとURL const int BUFF_SIZE = 16384; char tb_bstr[BUFF_SIZE]; char *tb_ptr = tb_bstr, *tb_end = tb_bstr+BUFF_SIZE; QByteArray cmd8 = cmd.toUtf8(); tb_ptr += UrlEncode_OAUTH(tb_ptr, tb_end-tb_ptr, cmd8.data(), cmd8.size()); *tb_ptr++ = '&'; QByteArray url8 = url.toString(QUrl::RemoveQuery).toUtf8(); tb_ptr += UrlEncode_OAUTH(tb_ptr, tb_end-tb_ptr, url8.data(), url8.size()); *tb_ptr++ = '&'; // :パラメタ char tb_tmp[4096]; QByteArray tmp; QTextStream ss(&tmp); int nA = sv.size(); for(int i=0 ; i<nA ; i++) { if(i!=0) ss << '&'; HSTRPair& sp = sv[i]; ss << sp.first.toUtf8() << '='; QByteArray ba = sp.second.toUtf8(); size_t n = UrlEncode_OAUTH(tb_tmp, sizeof(tb_tmp), ba.data(), ba.size()); Q_ASSERT(n < sizeof(tb_tmp)-1); tb_tmp[n] = '\0'; ss << tb_tmp; } ss.flush(); tb_ptr += UrlEncode_OAUTH(tb_ptr, tb_end-tb_ptr, tmp.data(), tmp.size()); Q_ASSERT(tb_ptr <= tb_end); tb_ptr[0] = '\0'; tb_key[strlen(tb_key)] = '\0'; HMAC_SHA1(dst, tb_key, strlen(tb_key), tb_bstr, tb_ptr-tb_bstr); }
void OpenPGPCryptoHashHMAC::reset(void) { std::string key(m_keyBuf.rawBuffer(), m_keyLen); switch (m_hashType) { case (XSECCryptoHash::HASH_SHA1) : mp_md.reset(HMAC_SHA1(key)); break; case (XSECCryptoHash::HASH_MD5) : mp_md.reset(HMAC_MD5(key)); break; case (XSECCryptoHash::HASH_SHA224) : mp_md.reset(HMAC_SHA224(key)); break; case (XSECCryptoHash::HASH_SHA256) : mp_md.reset(HMAC_SHA256(key)); break; case (XSECCryptoHash::HASH_SHA384) : mp_md.reset(HMAC_SHA384(key)); break; case (XSECCryptoHash::HASH_SHA512) : mp_md.reset(HMAC_SHA512(key)); break; default : mp_md.reset(); } if(!mp_md) { throw XSECCryptoException(XSECCryptoException::MDError, "OpenPGP:HashHMAC - Error loading Message Digest"); } }
/* ======================================================================== Routine Description: Calcaulate MIC. It is used during 4-ways handsharking. Arguments: pAd - pointer to our pAdapter context PeerWepStatus - indicate the encryption type Return Value: Note: ======================================================================== */ VOID CalculateMIC( IN PRTMP_ADAPTER pAd, IN UCHAR PeerWepStatus, IN UCHAR *PTK, OUT PEAPOL_PACKET pMsg) { UCHAR *OutBuffer; ULONG FrameLen = 0; UCHAR mic[LEN_KEY_DESC_MIC]; UCHAR digest[80]; // allocate memory for MIC calculation os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512); if (OutBuffer == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n")); return; } // make a frame for calculating MIC. MakeOutgoingFrame(OutBuffer, &FrameLen, pMsg->Body_Len[1] + 4, pMsg, END_OF_ARGS); NdisZeroMemory(mic, sizeof(mic)); // Calculate MIC if (PeerWepStatus == Ndis802_11Encryption3Enabled) { HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest); NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); } else { hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic); } // store the calculated MIC NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); os_free_mem(pAd, OutBuffer); }
std::string TaskBase::compose_auth_header( const std::string& http_method, StringMap& amz_date, const std::string& resource, const std::string& date, const std::string& content_type, const std::string& content_md5 ) { unsigned char hmac[20]; char b64[((20 + 1) * 4) / 3]; std::string signbuf; signbuf += http_method; signbuf += "\n"; signbuf += content_md5; signbuf += "\n"; signbuf += content_type; signbuf += "\n"; signbuf += date; signbuf += "\n"; // date StringMap::iterator it = _amz_data.begin(); for (; it != _amz_data.end(); ++ it) { signbuf += it->first; signbuf += ":"; signbuf += it->second; signbuf += "\n"; } signbuf += resource; // Generate an HMAC-SHA-1 of the signbuf HMAC_SHA1(hmac, (unsigned char *) _s_secret_key.c_str(), _s_secret_key.length(), (unsigned char *) signbuf.c_str(), signbuf.length()); // Now base-64 encode the results int b64Len = base64Encode(hmac, 20, b64); char auth_val_buf[128]; sprintf_s(auth_val_buf, 128, "SINA %s:%.*s", _s_access_key.c_str(), 10, &b64[5]); return auth_val_buf; }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. */ /* USART configuration */ USART_Config(); /* Enable HASH clock */ RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_HASH, ENABLE); /* Display the original message */ Display_MainMessage(); /*============================================================================= HMAC SHA-1 Digest Computation ==============================================================================*/ /* HMAC SHA-1 Digest Computation */ HMAC_SHA1((uint8_t*)Key, KEY_TAB_SIZE, (uint8_t*)Input, INPUT_TAB_SIZE, Sha1output); /* Display the HMAC SHA1 digest */ Display_SHA1Digest(); /*============================================================================= HMAC MD5 Digest Computation ==============================================================================*/ /* HMAC MD5 Digest Computation */ HMAC_MD5((uint8_t*)Key, KEY_TAB_SIZE, (uint8_t*)Input, INPUT_TAB_SIZE, Md5output); /* Display the HMAC MD5 digest */ Display_MD5Digest(); while(1); }
VOID WpaMicFailureReportFrame( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PUCHAR pOutBuffer = NULL; UCHAR Header802_3[14]; ULONG FrameLen = 0; EAPOL_PACKET Packet; UCHAR Mic[16]; BOOLEAN bUnicast; DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n")); bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE); pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER); // init 802.3 header and Fill Packet MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); NdisZeroMemory(&Packet, sizeof(Packet)); Packet.ProVer = EAPOL_VER; Packet.ProType = EAPOLKey; Packet.KeyDesc.Type = WPA1_KEY_DESC; // Request field presented Packet.KeyDesc.KeyInfo.Request = 1; if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { Packet.KeyDesc.KeyInfo.KeyDescVer = 2; } else // TKIP { Packet.KeyDesc.KeyInfo.KeyDescVer = 1; } Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY); // KeyMic field presented Packet.KeyDesc.KeyInfo.KeyMic = 1; // Error field presented Packet.KeyDesc.KeyInfo.Error = 1; // Update packet length after decide Key data payload SET_UINT16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG) // Key Replay Count NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); inc_byte_array(pAd->StaCfg.ReplayCounter, 8); // Convert to little-endian format. *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo)); MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory if(pOutBuffer == NULL) { return; } // Prepare EAPOL frame for MIC calculation // Be careful, only EAPOL frame is counted for MIC calculation MakeOutgoingFrame(pOutBuffer, &FrameLen, CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, &Packet, END_OF_ARGS); // Prepare and Fill MIC value NdisZeroMemory(Mic, sizeof(Mic)); if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { // AES UCHAR digest[20] = {0}; HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); } else { // TKIP HMAC_MD5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE); } NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); // copy frame to Tx ring and send MIC failure report frame to authenticator RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID], Header802_3, LENGTH_802_3, (PUCHAR)&Packet, CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, FALSE); MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n")); }
S3Status S3_generate_authenticated_query_string (char *buffer, const S3BucketContext *bucketContext, const char *key, int64_t expires, const char *resource) { #define MAX_EXPIRES (((int64_t) 1 << 31) - 1) // S3 seems to only accept expiration dates up to the number of seconds // representably by a signed 32-bit integer if (expires < 0) { expires = MAX_EXPIRES; } else if (expires > MAX_EXPIRES) { expires = MAX_EXPIRES; } // xxx todo: rework this so that it can be incorporated into shared code // with request_perform(). It's really unfortunate that this code is not // shared with request_perform(). // URL encode the key char urlEncodedKey[S3_MAX_KEY_SIZE * 3]; if (key) { urlEncode(urlEncodedKey, key, strlen(key)); } else { urlEncodedKey[0] = 0; } // Compute canonicalized resource char canonicalizedResource[MAX_CANONICALIZED_RESOURCE_SIZE]; canonicalize_resource(bucketContext->bucketName, resource, urlEncodedKey, canonicalizedResource); // We allow for: // 17 bytes for HTTP-Verb + \n // 1 byte for empty Content-MD5 + \n // 1 byte for empty Content-Type + \n // 20 bytes for Expires + \n // 0 bytes for CanonicalizedAmzHeaders // CanonicalizedResource char signbuf[17 + 1 + 1 + 1 + 20 + sizeof(canonicalizedResource) + 1]; int len = 0; #define signbuf_append(format, ...) \ len += snprintf(&(signbuf[len]), sizeof(signbuf) - len, \ format, __VA_ARGS__) signbuf_append("%s\n", "GET"); // HTTP-Verb signbuf_append("%s\n", ""); // Content-MD5 signbuf_append("%s\n", ""); // Content-Type signbuf_append("%llu\n", (unsigned long long) expires); signbuf_append("%s", canonicalizedResource); // Generate an HMAC-SHA-1 of the signbuf unsigned char hmac[20]; HMAC_SHA1(hmac, (unsigned char *) bucketContext->secretAccessKey, strlen(bucketContext->secretAccessKey), (unsigned char *) signbuf, len); // Now base-64 encode the results char b64[((20 + 1) * 4) / 3]; int b64Len = base64Encode(hmac, 20, b64); // Now urlEncode that char signature[sizeof(b64) * 3]; urlEncode(signature, b64, b64Len); // Finally, compose the uri, with params: // ?AWSAccessKeyId=xxx[&Expires=]&Signature=xxx char queryParams[sizeof("AWSAccessKeyId=") + 20 + sizeof("&Expires=") + 20 + sizeof("&Signature=") + sizeof(signature) + 1]; sprintf(queryParams, "AWSAccessKeyId=%s&Expires=%ld&Signature=%s", bucketContext->accessKeyId, (long) expires, signature); return compose_uri(buffer, S3_MAX_AUTHENTICATED_QUERY_STRING_SIZE, bucketContext, urlEncodedKey, resource, queryParams); }
static uint32_t _tpm_wrap_unseal(uint32_t locality, const uint8_t *in_data, uint32_t *secret_size, uint8_t *secret) { uint32_t ret; tpm_nonce_t odd_osap, even_osap; tpm_nonce_t nonce_even, nonce_odd, nonce_even_d, nonce_odd_d; tpm_authhandle_t hauth, hauth_d; tpm_authdata_t shared_secret; tpm_authdata_t pub_auth, res_auth, pub_auth_d, res_auth_d; uint8_t cont_session = false, cont_session_d = false; tpm_key_handle_t hkey = TPM_KH_SRK; uint32_t offset; uint32_t ordinal = TPM_ORD_UNSEAL; tpm_digest_t digest; /* skip generate nonce for odd_osap, just use the random value in stack */ /* establish a osap session */ ret = tpm_osap(locality, TPM_ET_SRK, TPM_KH_SRK, &odd_osap, &hauth, &nonce_even, &even_osap); if ( ret != TPM_SUCCESS ) return ret; /* calculate the shared secret shared-secret = HMAC(auth, even_osap || odd_osap) */ offset = 0; UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &even_osap); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &odd_osap); HMAC_SHA1((uint8_t *)&srk_authdata, sizeof(srk_authdata), WRAPPER_IN_BUF, offset, (uint8_t *)&shared_secret); /* establish a oiap session */ ret = tpm_oiap(locality, &hauth_d, &nonce_even_d); if ( ret != TPM_SUCCESS ) return ret; /* skip generate nonce_odd & nonce_odd_d, just use the random values */ /* calculate authdata */ /* in_param_digest = sha1(1S ~ 6S) */ offset = 0; UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ordinal); UNLOAD_STORED_DATA12(WRAPPER_IN_BUF, offset, in_data); sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest); /* authdata1 = hmac(key, in_param_digest || auth_params1) */ offset = 0; UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd); UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session); HMAC_SHA1((uint8_t *)&shared_secret, sizeof(shared_secret), WRAPPER_IN_BUF, offset, (uint8_t *)&pub_auth); /* authdata2 = hmac(key, in_param_digest || auth_params2) */ offset = 0; UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even_d); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd_d); UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session_d); HMAC_SHA1((uint8_t *)&blob_authdata, sizeof(blob_authdata), WRAPPER_IN_BUF, offset, (uint8_t *)&pub_auth_d); /* call the simple seal function */ ret = _tpm_unseal(locality, hkey, in_data, hauth, &nonce_odd, &cont_session, (const tpm_authdata_t *)&pub_auth, hauth_d, &nonce_odd_d, &cont_session_d, (const tpm_authdata_t *)&pub_auth_d, secret_size, secret, &nonce_even, &res_auth, &nonce_even_d, &res_auth_d); /* skip check for res_auth */ return ret; }
static uint32_t _tpm_wrap_seal(uint32_t locality, const tpm_pcr_info_long_t *pcr_info, uint32_t in_data_size, const uint8_t *in_data, uint32_t *sealed_data_size, uint8_t *sealed_data) { uint32_t ret; tpm_nonce_t odd_osap, even_osap, nonce_even, nonce_odd; tpm_authhandle_t hauth; tpm_authdata_t shared_secret, pub_auth, res_auth; tpm_encauth_t enc_auth; uint8_t cont_session = false; tpm_key_handle_t hkey = TPM_KH_SRK; uint32_t pcr_info_size = sizeof(*pcr_info); uint32_t offset; uint32_t ordinal = TPM_ORD_SEAL; tpm_digest_t digest; /* skip generate nonce for odd_osap, just use the random value in stack */ /* establish a osap session */ ret = tpm_osap(locality, TPM_ET_SRK, TPM_KH_SRK, &odd_osap, &hauth, &nonce_even, &even_osap); if ( ret != TPM_SUCCESS ) return ret; /* calculate the shared secret shared-secret = HMAC(srk_auth, even_osap || odd_osap) */ offset = 0; UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &even_osap); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &odd_osap); HMAC_SHA1((uint8_t *)&srk_authdata, sizeof(srk_authdata), WRAPPER_IN_BUF, offset, (uint8_t *)&shared_secret); /* generate ecrypted authdata for data enc_auth = XOR(authdata, sha1(shared_secret || last_even_nonce)) */ offset = 0; UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &shared_secret); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even); sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest); memcpy(&enc_auth, &blob_authdata, sizeof(blob_authdata)); XOR_BLOB_TYPE(&enc_auth, &digest); /* skip generate nonce for nonce_odd, just use the random value in stack */ /* calculate authdata */ /* in_param_digest = sha1(1S ~ 6S) */ offset = 0; UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, ordinal); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &enc_auth); UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, pcr_info_size); UNLOAD_PCR_INFO_LONG(WRAPPER_IN_BUF, offset, pcr_info); UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, in_data_size); UNLOAD_BLOB(WRAPPER_IN_BUF, offset, in_data, in_data_size); sha1_buffer(WRAPPER_IN_BUF, offset, (uint8_t *)&digest); /* authdata = hmac(key, in_param_digest || auth_params) */ offset = 0; UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &digest); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_even); UNLOAD_BLOB_TYPE(WRAPPER_IN_BUF, offset, &nonce_odd); UNLOAD_INTEGER(WRAPPER_IN_BUF, offset, cont_session); HMAC_SHA1((uint8_t *)&shared_secret, sizeof(shared_secret), WRAPPER_IN_BUF, offset, (uint8_t *)&pub_auth); /* call the simple seal function */ ret = _tpm_seal(locality, hkey, (const tpm_encauth_t *)&enc_auth, pcr_info_size, pcr_info, in_data_size, in_data, hauth, &nonce_odd, &cont_session, (const tpm_authdata_t *)&pub_auth, sealed_data_size, sealed_data, &nonce_even, &res_auth); /* skip check for res_auth */ return ret; }