yoncho`s blog
AUTOSAR IDS 본문
공식 문서 : https://www.autosar.org/fileadmin/standards/R20-11/FO/AUTOSAR_PRS_IntrusionDetectionSystem.pdf
코드
AUTOSAR IDS Message Format 에 맞는 랜덤 IDS Message 생성 코드 autosar_random_messge.js
더보기
const crypto = require('crypto');
const QSEV_MAX_BYTE_SIZE = 2147549199; // 8(EVENT) + 8(TIMESTAMP) + 2,147,483,648(CONTEXT) + 65,535(SIGNATURE)
const RESERVED_BYTE = '00000000'; //reserved 1byte (8bit)
const RESERVED_BIT = '0';
const CONTEXT_SHORT_TYPE = 0;
const CONTEXT_LONG_TYPE = 1;
//EVENT FRAME (total : 8byte)
class event_frame{
constructor(protocolVer, includeContextData, includeTimeStamp, includeSignature,idsAndSensorInstanceID, evenetDefinitionID, count, reserved)
{
this.protocolVer = protocolVer; //4bit
//protocl header = 4bit (reserved:1bit, include context, timestamp, signature 1bit)
this.protocolHeaderReserved = RESERVED_BIT;
this.includeContextData = includeContextData; //1bit
this.includeTimeStamp = includeTimeStamp; //1bit
this.includeSignature = includeSignature; //1bit
this.idsAndSensorInstanceID = idsAndSensorInstanceID; //16bit
this.evenetDefinitionID = evenetDefinitionID; //16bit
this.count = count; //16bit
this.reserved = reserved; //8bit
}
createBitData() {
return `${this.protocolVer
+this.protocolHeaderReserved
+this.includeSignature
+this.includeTimeStamp
+this.includeContextData
+this.idsAndSensorInstanceID
+this.evenetDefinitionID
+this.count
+this.reserved}`;
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//TIME STAMP (total : 8byte)
class time_stamp{
constructor(source, nanoSeconds, seconds, oemTimeStamp)
{
this.source = source; // [0 : AUTOSAR Standard CP - StbM - AP:ara::tsync | 1 : Auxiliary/OEM Specific timestamp]
this.reserved = RESERVED_BIT;
this.nanoSeconds = nanoSeconds; //30bit
this.seconds = seconds; //32bit
this.oemTimeStamp = oemTimeStamp; //63bit
}
createBitDataByAUTOSARTimeStamp() {
return `${this.source
+this.reserved
+this.nanoSeconds
+this.seconds}`;
}
createBitDataByOEMTimeStamp() {
return `${this.source
+this.oemTimeStamp}`;
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//CONTEXT DATA LONG (total : n byte [n = 5.. 2^31])
class context_data_long{
constructor(context_length_format, context_data_length, context_data_3byte_length, context_data)
{
this.context_length_format = context_length_format; //1bit
this.context_data_length = context_data_length; //7bit
this.context_data_3byte_length = context_data_3byte_length; //3byte
this.context_data = context_data; //1byte ~ 2^31 - 4byte
}
createFrame() {
return `${bitsToBytes(`${this.context_length_format
+this.context_data_length}`)
+this.context_data_3byte_length
+this.context_data}`;
}
}
//CONTEXT DATA SHORT (total : n byte [n = 2.. 127])
class context_data_short{
constructor(context_length_format, context_data_length, context_data)
{
this.context_length_format = context_length_format; //1bit
this.context_data_length = context_data_length; //7bit
this.context_data = context_data; //1byte ~ 126byte -> bit
}
createBitData() {
return `${this.context_length_format
+this.context_data_length
+this.context_data}`;
}
}
//CONTEXT DATA - BYTE INDEX '0' OF CONTEXT DATA LENGTH (total : 1 byte)
class context_data_length_encoding{
constructor(length_format, context_data_length){
this.length_format = length_format; //bit number 7 [ 0 : 7bit length info include data length code | 1 : 31bit length info include data length code ]
this.context_data_length = context_data_length; //bit number 6...0
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//SIGNATURE (total : n byte [ n : 3.. 65535])
class signature{
constructor(signature_length, signature_data){
this.signature_length = signature_length; //16bit
this.signature_data = signature_data; //1byte ~ 65,533byte -> bit
}
createBitData() {
return `${this.signature_length
+this.signature_data}`;
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
function createEventFrame()
{
//eventFrame
const eventFrameData = new event_frame();
eventFrameData.protocolVer = generateRandomBitString(4);
eventFrameData.includeContextData = generateRandomBitString(1);
eventFrameData.includeTimeStamp = generateRandomBitString(1);
eventFrameData.includeSignature = generateRandomBitString(1);
eventFrameData.idsAndSensorInstanceID = generateRandomBitString(16);
eventFrameData.evenetDefinitionID = generateRandomBitString(16);
eventFrameData.count = generateRandomBitString(16);
eventFrameData.reserved = RESERVED_BYTE; //reserved 8bit
return eventFrameData;
}
function createTimeStamp()
{
const timeStampData = new time_stamp();
timeStampData.source = generateRandomBitString(1);
if (timeStampData.source == '0') //AUTOSAR Standard
{
timeStampData.nanoSeconds = generateRandomBitString(30);
timeStampData.seconds = generateRandomBitString(32);
return timeStampData.createBitDataByAUTOSARTimeStamp();
}else{ //OEM
timeStampData.oemTimeStamp = generateRandomBitString(63);
return timeStampData.createBitDataByOEMTimeStamp();
}
}
function createContextData(contextDataType)
{
const contextDataLength = new context_data_length_encoding();
//only short
if(contextDataType == CONTEXT_SHORT_TYPE)
{
contextDataLength.length_format = CONTEXT_SHORT_TYPE;
}
else
{
contextDataLength.length_format = generateRandomBitString(1);
}
if(contextDataLength.length_format == CONTEXT_SHORT_TYPE) // 0 : 7bit length info include data length code
{
const shortContextData = new context_data_short();
shortContextData.context_length_format = contextDataLength.length_format;
shortContextData.context_data_length = generateRandomBitString(7);
let byteLength = parseInt(bitsToBytes(`${'0'+shortContextData.context_data_length}`.toString()), 16) - 1;
if (byteLength < 1) //최소 조건
{
byteLength = 1;
}
shortContextData.context_data = generateRandomBitString(byteLength * 8);
// crypto.randomBytes(byteLength).toString('hex'); //byte
return shortContextData.createBitData();
}else{ // 1 : 31bit length info include data length code ]
const longContextData = new context_data_long();
longContextData.context_length_format = contextDataLength.length_format;
longContextData.context_data_length = generateRandomBitString(7);
longContextData.context_data_3byte_length = crypto.randomBytes(3).toString('hex');
let byteLengthString = `${bitsToBytes(`${'0'+longContextData.context_data_length}`)+longContextData.context_data_3byte_length}`;
let byteLength = parseInt(byteLengthString, 16) - 4;
if (byteLength < 1)
{
byteLength = 1;
}
console.log(byteLength);
if (byteLength > 7)
{
longContextData.context_data = createLongContextData(byteLength);
}
else
{
longContextData.context_data = crypto.randomBytes(byteLength).toString('hex');
}
return longContextData.createFrame();
}
}
function createSignature()
{
const signatureData = new signature();
signatureData.signature_length = generateRandomBitString(16);
let byteLength = parseInt(bitsToBytes(signatureData.signature_length), 16) - 2;
signatureData.signature_data = generateRandomBitString(byteLength * 8);
return signatureData.createBitData();
}
function createAutosarIDSMessage(contextDataType)
{
let IDSMessage;
let eventFrame;
let timeStamp;
let contextData;
let signature;
//eventFrame
eventFrame = createEventFrame();
const eventFrameData = eventFrame.createBitData();
console.log(`EVENT FRAME : ${eventFrameData} [length : ${eventFrameData.length / 8} byte]`);
IDSMessage = eventFrameData;
//timeStamp
if(eventFrame.includeTimeStamp == '1')
{
timeStamp = createTimeStamp();
console.log(`TIME STAMP : ${timeStamp} [length : ${timeStamp.length / 8} byte]`);
IDSMessage += timeStamp;
}
//contextData
if(eventFrame.includeContextData == '1')
{
contextData = createContextData(contextDataType);
console.log(`CONTEXT DATA : ${contextData} [length : ${contextData.length / 8} byte]`);
IDSMessage += contextData;
}
//signature
if(eventFrame.includeSignature == '1')
{
signature = createSignature();
console.log('SIGNATURE : ', signature);
IDSMessage += signature;
}
const contextType = contextDataType == '0'? 'SHORT ONLY':'SHORT OR LONG';
// console.log("\nTOTAL :" ,IDSMessage);
console.log(`TOTAL LENGTH : ${(IDSMessage.length / 8)} byte`);
console.log(` - EVENT FRAME LENGTH : ${(eventFrameData.length / 8)} byte`);
if(eventFrame.includeTimeStamp == '1')
{
console.log(` - TIME STAMP LENGTH : ${(timeStamp.length / 8)} byte`);
}
if(eventFrame.includeContextData == '1')
{
console.log(` - CONTEXT DATA LENGTH : ${(contextData.length) / 8} byte | Data Type : ${contextType}`);
}
if(eventFrame.includeSignature == '1')
{
console.log(` - SIGNATURE LENGTH : ${(signature.length / 8)} byte`);
}
return IDSMessage;
}
createAutosarIDSMessage(0);
//+ export module
module.exports = {
createAutosarIDSMessage: createAutosarIDSMessage
}
//+ method
function generateRandomBitString(length)
{
let createBitString = '';
for(let i = 0; i < length; i++)
{
const randomDigit = Math.floor(Math.random() * 2); // 0 또는 1 중 랜덤한 값 생성
createBitString += randomDigit;
}
return createBitString;
}
function bitsToBytes(bitString) {
let length = bitString.length;
const bytes = [];
for (let i = 0; i < bitString.length; i += 8) {
const byte = bitString.slice(i, i + 8);
bytes.push(parseInt(byte, 2));
}
return Buffer.from(bytes).toString('hex');
}
function createLongContextData(byteLength)
{
let longContextData = '';
while(byteLength > 0)
{
let splitCount;
if (byteLength > 7)
{
splitCount = 7;
byteLength -= 7;
}
else
{
splitCount = byteLength;
byteLength -= splitCount;
}
longContextData += generateHex(splitCount);
}
return longContextData;
}
function generateHex(length) {
const characters = '0123456789abcdef';
let hexString = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
hexString += characters[randomIndex];
}
return hexString;
}
단, Context long data의 경우 createFrame() 함수에서 return값이 byte type이다.
나머지 Event frame, Time stamp, Signature, Context_short는 bit string을 return한다.
Comments