void onSecretChangeAck(){ // Quando il nodo CONTROLLO riceve la frame di ACK (guarda l��� ID frame): // SE Check_ACK_By_IDsource==1 (ovvero �� la prima volta che ricevo questo tipo di frame da questo SOURCE) // Verifica dell���HMAC(attraverso la verify con il vecchio segreto) // SE la verifica �� OK // allora ClearAckBy_IdSource, azzero il bit nella tabella // SE Is_LastAck()==SI // allora prepara la frame di AckRESET_RETE if(checkAckByID(&wl, frame.sourceID)==1){ if(SEC_HMAC_verify(&shh,&frame,HMAC_LENGTH,frame.digest)==SEC_STATE_HMAC_VERIFY_OK){ clearAckByID(&wl, frame.sourceID); if(checkAllzeroAck(&wl)==1){ // preparo la Frame di AckRESET_NETWORK: // Frame AckRESET_RETE: // ID Frame=0xAC // ID Source=ID NODO CONTROLLO // Msg = contiene il timestamp cifrato con la chiave di ogni nodo // NON �� Firmato(perche' i nodi router potrebbero ottenere per primi // il nuovo segreto e non inoltrare i pacchetti in caso di ritrasmissione) //genarazione nuovo segreto per HMAC SEC_RVG_handle srgvh; SEC_GenarateRandomValue_CustomLength(&srgvh,secret,SECRETLEN/4); int i=0; for(i=0;i<N;i++){ if(*(wl[i].id) != 0){ frame.ID=SEC_SECRETCHANGE_OK; sch.key = wl[i].key; sch.iv = sch.key; memcpy(frame.sourceID, STM32_UUID, IDLEN); memcpy(frame.timestamp, ×tamp,TIMESTAMPLEN); uint32 ciphertextLen; SEC_Encrypt(&sch, (uint8_t*)(×tamp), TIMESTAMPLEN, frame.msg, &ciphertextLen); timestamp++; send((uint8*) &frame); } } } }else{ /*hmac non verificato*/} }else{ // il flag di ack �� a zero quindi ho gi�� ricevuto questo tipo di frame } }
/*funzione di invio della prima frame da parte del nodo operativo * per connettersi alla retefunzione per creare il messaggio cifrato da inserire * nella prima frame*/ void joinRequest() { frame.ID=SEC_JOIN_REQ; memcpy(frame.sourceID, STM32_UUID, IDLEN); // creazione del msg cifrato con all'interno l'ID della scheda uint32 ciplen; SEC_Encrypt(&sch,frame.sourceID,IDLEN,frame.msg,&ciplen); BSP_LED_On(LED6); send_segment_best_effort((uint8*) &frame, sizeof(frame)); }
/************************************************* * Function: PCT_SendMsgToCloud * Description: * Author: cxy * Returns: * Parameter: * History: *************************************************/ u32 PCT_SendMsgToCloud(ZC_SecHead *pstruSecHead, u8 *pu8PlainData) { u32 u32Index; u32 u32RetVal; u16 u16Len; u16 u16PaddingLen; u32RetVal = SEC_PaddingCheck(pstruSecHead->u8SecType, ZC_HTONS(pstruSecHead->u16TotalMsg), &u16PaddingLen); if (ZC_RET_ERROR == u32RetVal) { return ZC_RET_ERROR; } u16Len = ZC_HTONS(pstruSecHead->u16TotalMsg) + sizeof(ZC_SecHead) + u16PaddingLen; if (u16Len > MSG_BUFFER_MAXLEN) { return ZC_RET_ERROR; } for (u32Index = 0; u32Index < MSG_BUFFER_SEND_MAX_NUM; u32Index++) { if (MSG_BUFFER_IDLE == g_struSendBuffer[u32Index].u8Status) { u16Len = ZC_HTONS(pstruSecHead->u16TotalMsg) + u16PaddingLen; /*first check padding,then Encrypt, final copy sechead*/ u32RetVal = SEC_Encrypt(pstruSecHead, g_struSendBuffer[u32Index].u8MsgBuffer + sizeof(ZC_SecHead), pu8PlainData, &u16Len); if (ZC_RET_ERROR == u32RetVal) { return ZC_RET_ERROR; } pstruSecHead->u16TotalMsg = ZC_HTONS(u16Len); /*copy sechead*/ memcpy(g_struSendBuffer[u32Index].u8MsgBuffer, (u8*)pstruSecHead, sizeof(ZC_SecHead)); g_struSendBuffer[u32Index].u32Len = u16Len + sizeof(ZC_SecHead); g_struSendBuffer[u32Index].u8Status = MSG_BUFFER_FULL; MSG_PushMsg(&g_struSendQueue, (u8*)&g_struSendBuffer[u32Index]); return ZC_RET_OK; } } return ZC_RET_ERROR; }
void onJoinRequest() { /* all'atto di una richiesta: * - in base al mittente prelevo la chiave in tabella * - decifro il messaggio con la chiave prelevata * - costruisco il pacchetto di risposta col segreto cifrato * - invio il pacchetto cifrato e firmato */ if (!checkAckByID(&wl, frame.sourceID)) { sch.key = SearchKeyByID(&wl, frame.sourceID); sch.iv = sch.key; //il messaggio conterra' l'id che e' di 12 byte ma AES lavora con blocchi da 16 uint32 ciplen = 16; uint8 plain[16]; uint32 plainlen; SEC_StateTypeDef stato; stato = SEC_Decrypt(&sch, frame.msg, ciplen, plain, &plainlen); int result = memcmp(plain, frame.sourceID, IDLEN); if (result == 0) { //Costruisco il pacchetto di risposta della JOIN cleanVector((uint8*) &frame, sizeof(frame)); uint32 ciphertextLen; SEC_Encrypt(&sch, secret, SECRETLEN, frame.msg, &ciphertextLen); frame.ID = SEC_JOIN_RES; memcpy(frame.sourceID, STM32_UUID, IDLEN); memcpy(frame.timestamp, ×tamp,TIMESTAMPLEN); timestamp++; SEC_HMAC(&shh, (uint8*) &frame, HMAC_LENGTH, frame.digest); send((uint8*) &frame); } } else { /* utente gi������ presente in rete (gi������ ������ stato ricevuto l'ack) oppure non in whitelist. * invia un alert all'amministratore che deve controllare se il nodo ������ fidato e, quindi, * pu������ riattivarlo (mettendo il campo 'ack' a 0) oppure si tratta di un tentativo * malevolo di accedere alla rete */ } }
/************************************************* * Function: PCT_SendMsgToCloud * Description: * Author: cxy * Returns: * Parameter: * History: *************************************************/ u32 PCT_SendMsgToCloud(ZC_SecHead *pstruSecHead, u8 *pu8PlainData) { //u32 u32Index; u32 u32RetVal; u16 u16Len; u16 u16PaddingLen; ZC_SendParam struParam; u32RetVal = SEC_PaddingCheck(pstruSecHead->u8SecType, ZC_HTONS(pstruSecHead->u16TotalMsg), &u16PaddingLen); if (ZC_RET_ERROR == u32RetVal) { return ZC_RET_ERROR; } u16Len = ZC_HTONS(pstruSecHead->u16TotalMsg) + sizeof(ZC_SecHead) + u16PaddingLen; if (u16Len > MSG_BUFFER_MAXLEN) { return ZC_RET_ERROR; } #if 1 if (MSG_BUFFER_IDLE == g_struSendBuffer[0].u8Status) { u16Len = ZC_HTONS(pstruSecHead->u16TotalMsg) + u16PaddingLen; /*first check padding,then Encrypt, final copy sechead*/ u32RetVal = SEC_Encrypt(pstruSecHead, g_struSendBuffer[0].u8MsgBuffer + sizeof(ZC_SecHead), pu8PlainData, &u16Len); if (ZC_RET_ERROR == u32RetVal) { return ZC_RET_ERROR; } pstruSecHead->u16TotalMsg = ZC_HTONS(u16Len); /*copy sechead*/ memcpy(g_struSendBuffer[0].u8MsgBuffer, (u8*)pstruSecHead, sizeof(ZC_SecHead)); g_struSendBuffer[0].u32Len = u16Len + sizeof(ZC_SecHead); g_struSendBuffer[0].u8Status = MSG_BUFFER_FULL; //MSG_PushMsg(&g_struSendQueue, (u8*)&g_struSendBuffer[0]); /* ·¢ËÍ */ struParam.u8NeedPoll = 0; g_struProtocolController.pstruMoudleFun->pfunSendTcpData(g_struProtocolController.struCloudConnection.u32Socket, g_struSendBuffer[0].u8MsgBuffer, g_struSendBuffer[0].u32Len, &struParam); //ZC_Printf("send data len = %d\n", u16DataLen); g_struSendBuffer[0].u8Status = MSG_BUFFER_IDLE; g_struSendBuffer[0].u32Len = 0; return ZC_RET_OK; } #else for (u32Index = 0; u32Index < MSG_BUFFER_SEND_MAX_NUM; u32Index++) { if (MSG_BUFFER_IDLE == g_struSendBuffer[u32Index].u8Status) { u16Len = ZC_HTONS(pstruSecHead->u16TotalMsg) + u16PaddingLen; /*first check padding,then Encrypt, final copy sechead*/ u32RetVal = SEC_Encrypt(pstruSecHead, g_struSendBuffer[u32Index].u8MsgBuffer + sizeof(ZC_SecHead), pu8PlainData, &u16Len); if (ZC_RET_ERROR == u32RetVal) { return ZC_RET_ERROR; } pstruSecHead->u16TotalMsg = ZC_HTONS(u16Len); /*copy sechead*/ memcpy(g_struSendBuffer[u32Index].u8MsgBuffer, (u8*)pstruSecHead, sizeof(ZC_SecHead)); g_struSendBuffer[u32Index].u32Len = u16Len + sizeof(ZC_SecHead); g_struSendBuffer[u32Index].u8Status = MSG_BUFFER_FULL; MSG_PushMsg(&g_struSendQueue, (u8*)&g_struSendBuffer[u32Index]); return ZC_RET_OK; } } #endif return ZC_RET_ERROR; }