she_encrypt
Version:
Cryptographic function for ciphering SHE commands args (M1-M3/M4-M5)
210 lines (181 loc) • 7.5 kB
JavaScript
/** @fileOverview
* Script for generating scripts to make key prov
*
*
*/
(function(root) {
"use strict";
// script generator
var SHEenc = require('../SHE_encrypt.js');
// getopt
const getopt_module = require('posix-getopt');
const path = require('path');
const printf = require('printf');
const fs = require('fs');
const GENSHE_ERROR = 0xFFFFFFFF;
const GENSHE_MISSING_ARG = 0xFFFFFFF0;
const GENSHE_INVALID_ARG = 0xFFFFFFF8;
var print_usage = () => {
/** Implem of print_usage */
console.info("%s: Usage: %s [<OPTIONS>] <COMMAND> [<ARGUMENTS>]",
flags.cmdname, flags.cmdname);
console.info(" This command aims at generating SHE messages for MAC keys provisi-");
console.info(" onning. ");
console.info(" OPTIONS: ");
console.info(" -v|--verbose be more verbose when running. Use sev- ");
console.info(" eral times in order to raise verbosity.");
console.info(" COMMANDS: ");
console.info(" -h|--help display this help message. ");
console.info(" ");
console.info(" ARGUMENTS: ");
console.info(" -K|--iskmac generate a Kmac instead of Kmaster. ");
console.info(" -k|--key[=]<kmac> Key to be provisionned. ");
console.info(" -m|--master[=]<kmaster> Kmaster to cipher message. Default is ");
console.info(" the default Kmaster. ");
console.info(" -c|--cid[=]<cid> the CID to be used. ");
console.info(" -C|--channel[=]<channel> the channel to be used for Kmac. ");
console.info(" ");
console.info("Copyright © 2023 RENAULT GROUP / Rémi COHEN SCALI <remi.cohen-scali@renault.com> ");
};
var flags = {
cmdname: (path.basename(process.argv[0]) === "node" ||
path.basename(process.argv[0]) === "node.exe" ?
path.basename(process.argv[1]) :
path.basename(process.argv[0])),
cidFlag: false,
cid: 0x2000001,
keyFlag: false,
key: undefined,
masterFlag: false,
master: Buffer.from('0153F7000099ED9F320451AA8A7D9707', 'hex'),
iskmacFlag: false,
iskmac: false,
channelFlag: false,
channel: 1,
helpFlag: false,
verboseFlag: 0
};
/*jslint indent: 2, bitwise: false, nomen: false, plusplus: false, white: false, regexp: false */
/*global document, window, escape, unescape, module, require, Uint32Array */
var option;
/* Instanciate option parser for processing all command line arguments for getting options */
var parser =
new getopt_module.BasicParser(
'v(verbose)h(help)K(iskmac)k:(key)m:(master)c:(cid)C:(channel)',
process.argv
);
/* Processing all command line arguments */
while ((option = parser.getopt()) !== undefined && !option.error)
{
switch (option.option)
{
// --help/-h: display help
case 'h':
flags.helpFlag = true;
if (flags.verboseFlag)
console.info("%s: info: Help requested.", flags.cmdname);
break;
// --verbose/-v: Increase verbosity
case 'v':
flags.verboseFlag++;
if (flags.verboseFlag)
console.info("%s: info: verbosity (-v) increased to %s", flags.cmdname, flags.verboseFlag);
break;
// --iskmac/-K: generate a Kmac she msg
case 'K':
flags.iskmacFlag = true;
flags.iskmac = true;
if (flags.verboseFlag)
console.info("%s: info: iskmac (-K) option selected", flags.cmdname);
break;
// --key/-k: key to be provisionned
case 'k':
flags.keyFlag = true;
flags.key = option.optarg;
if (flags.verboseFlag)
console.info("%s: info: provisionned key (-k) set to '%s'", flags.cmdname, flags.key.toUpperCase());
break;
// --master/-m: kmaster to be used
case 'm':
flags.masterFlag = true;
flags.master = option.optarg;
if (flags.verboseFlag)
console.info("%s: info: ciphering key (-m) set to '%s'", flags.cmdname, flags.master.toUpperCase());
break;
// --cid/-c: CID for which to gen script
case 'c':
flags.cidFlag = true;
flags.cid = (option.optarg[1] === 'x' ? Number.parseInt(option.optarg, 16) : Number.parseInt(option.optarg));
if (flags.verboseFlag)
console.info("%s: info: CID (-c) set to '%s'.", flags.cmdname, flags.cid);
break;
// --channel/-C: channel for the Kmac key (slot id #4 to #8)
case 'C':
var channelNb = Number.parseInt(option.optarg);
if (channelNb >= 1 && channelNb <= 5)
{
flags.channelFlag = true;
flags.channel = channelNb;
if (flags.verboseFlag)
console.info("%s: info: channel (-C) set to '%s'.", flags.cmdname, flags.channel);
}
else
{
console.error("%s: info: invalid channel number (-C) provided '%s'.", flags.cmdname, channelNb);
}
break;
// Unknown option arg
case '?':
print_usage();
process.exit(-1);
default:
break;
}
}
/*
* Print help & exit
*/
if (flags.helpFlag)
{
print_usage();
process.exit(0);
}
else if (!flags.iskmacFlag && flags.channelFlag)
{
console.error("%s: error: you cannot specify channel (-C) with Kmaster key (missing -K)", flags.cmdname);
print_usage();
process.exit(GENSHE_ERROR && GENSHE_INVALID_ARG);
}
/*
* Generate message
*
*/
else if (flags.keyFlag)
{
var she = new SHEenc(flags.iskmac, Buffer.from(flags.master, 'hex'), Buffer.from(flags.key, 'hex'), flags.cid, flags.channel);
console.info("CID = %s (0x%s)", flags.cid, printf("%x", flags.cid));
console.info("M1 = %s", she.M1.toString('hex'));
console.info("M2 = %s", she.M2.toString('hex'));
console.info("M3 = %s", she.M3.toString('hex'));
console.info("M4 = %s", she.M4.toString('hex'));
console.info("M5 = %s", she.M5.toString('hex'));
console.info("M1|M2|M3 = %s %s %s", she.M1.toString('hex'), she.M2.toString('hex'), she.M3.toString('hex'));
console.info("M4|M5 = %s %s", she.M4.toString('hex'), she.M5.toString('hex'));
process.exit(0);
}
/*
* Missing a key or both
*
*/
else
{
console.error("%s: error: missing mandatory option (-k)", flags.cmdname);
print_usage();
process.exit(GENSHE_ERROR && GENSHE_MISSING_ARG);
}
})(this);
/*
* vim: et:ts=4:sw=4:sts=4
* -*- mode: JavaScript; coding: utf-8-unix; tab-width: 4 -*-
*/