MTE Core Code Examples
Purpose
The objective of an MTE Core "Examples" is to provide short examples of how to use the MTE Core Encoder and MTE Core Decoder.
MTE Core Encoder
Create MTE Core Encoder
The MTE Core Encoder will be created using default options. The default options will set preferred security options recommended by Eclypses. Custom options should only be used in special circumstances and after reading and understanding how to select the best options for a given situation. More information about how to select these options can be found in the official MTE Developer Guides.
Create Default Encoder
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
/* Create the encoder. */
MTE_HANDLE encoder;
mte_enc_init_info e_info = MTE_ENC_INIT_INFO_INIT(
MTE_DRBG_ENUM, MTE_TOKBYTES, MTE_VERIFIERS_ENUM,
MTE_CIPHER_ENUM, MTE_HASH_ENUM, NULL, NULL, NULL, NULL, NULL, NULL);
mte_enc_args e_args = MTE_ENC_ARGS_INIT(NULL, 0, NULL, &t_cb, NULL);
encoder = MTE_ALLOCA(mte_enc_state_bytes(&e_info));
status = mte_enc_state_init(encoder, &e_info);
if (status != mte_status_success)
{
fprintf(stderr, "Encoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
status = mte_enc_instantiate(encoder, &i_info);
if (status != mte_status_success)
{
fprintf(stderr, "Encoder instantiate error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
The entropy and nonce callbacks.
static mte_status ei_cb(void* context, mte_drbg_ei_info* info)
{
MTE_SIZE_T input_bytes;
(void)context;
/* Get the entropy. */
printf("Enter %u-%lu bytes of entropy> ",
(unsigned)info->min_length,
(unsigned long)info->max_length);
fflush(stdout);
(void)!fgets(ei_buff, sizeof(ei_buff), stdin);
input_bytes = (MTE_SIZE_T)(strlen(ei_buff) - 1);
/* If the entropy is less than the minimum required, we must return an
error. */
if (input_bytes < info->min_length)
{
return mte_status_drbg_catastrophic;
}
else if (input_bytes > info->bytes)
{
/* If the entropy is longer than the provided buffer, point at our buffer
instead. */
info->buff = (MTE_UINT8_T*)ei_buff;
}
else
{
/* Otherwise copy the entropy to the provided buffer. */
memcpy(info->buff, ei_buff, input_bytes);
}
/* Set the actual entropy length. */
info->bytes = input_bytes;
/* We got it successfully. */
return mte_status_success;
}
static void n_cb(void* context, mte_drbg_nonce_info* info)
{
MTE_SIZE8_T i;
MTE_UINT64_T u64;
char line[80];
(void)context;
/* Get the nonce. */
printf("Enter the nonce (decimal digits only)> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
u64 = strtoul(line, NULL, 10);
/* Copy the nonce in little-endian format to the nonce buffer. */
for (i = 0; i < info->max_length && i < sizeof(u64); ++i)
{
info->buff[i] = (MTE_UINT8_T)(u64 >> (i * 8));
}
/* If the minimum length is greater than the size of the nonce we got, fill
up to that length with zeros. */
for (; i < info->min_length; ++i)
{
info->buff[i] = 0;
}
/* Set the actual nonce length. */
info->bytes = i;
}
// Create the encoder.
MteEnc encoder;
encoder.setEntropyCallback(&cbs);
encoder.setNonceCallback(&cbs);
encoder.setTimestampCallback(&cbs);
status = encoder.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Encoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
The entropy and nonce callbacks.
mte_status Cbs::entropyCallback(mte_drbg_ei_info& info)
{
// Display a prompt.
std::cout << "Enter "
<< static_cast<size_t>(info.min_length) << '-' << info.max_length
<< " bytes of entropy> " << std::flush;
// Get a line of input.
std::string line;
std::cin >> line;
// If the input was less than the minimum required, we must return an error.
if (line.size() < info.min_length)
{
return mte_status_drbg_catastrophic;
}
// Set the actual entropy length. It cannot exceed the maximum required.
size_t buffBytes = info.bytes;
info.bytes = std::min(static_cast<MTE_SIZE_T>(line.size()), info.max_length);
// If the length is greater than the length of the provided buffer, we have
// to create our own buffer instead.
if (info.bytes > buffBytes)
{
delete [] myEntropy;
myEntropy = new uint8_t[info.bytes];
info.buff = myEntropy;
}
// Copy the entropy to the buffer and we got it successfully.
memcpy(info.buff, line.data(), info.bytes);
return mte_status_success;
}
void Cbs::nonceCallback(mte_drbg_nonce_info& info)
{
// Display a prompt.
std::cout << "Enter the nonce (decimal digits only)> " << std::flush;
// Get the nonce and ignore the rest of the line.
MTE_UINT64_T u64;
std::cin >> u64;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Copy the nonce in little-endian format to the nonce buffer.
size_t i;
for (i = 0; i < info.max_length && i < sizeof(u64); ++i)
{
info.buff[i] = static_cast<MTE_UINT8_T>(u64 >> (i * 8));
}
// If the minimum length is greater than the size of the nonce we got, fill
// up to that length with zeros.
for (; i < info.min_length; ++i)
{
info.buff[i] = 0;
}
// Set the actual nonce length.
info.bytes = static_cast<MTE_SIZE8_T>(i);
}
// Create MTE Core Encoder with defaults
MteEnc mteEncoder = new MteEnc();
// Need entropy, nonce and personalization string
// These values should be unique and entropy must be treated like encryption keys!
// The following personalization string and nonce values are for
// demonstration only and should not be used in a production environment
string personalizationString = "MySecretPersonalizationStringGoesHere";
long nonce = 12345678;
// *** IMPORTANT NOTE ***
// Entropy is critical to security and should be created and handled like encryption keys.
// To permit decoding of encoded value, Encoder and Decoder must use identical Entropy, Nonce and
// Personalization String as well as Options . See Developer Guides for more information.
// Check how long of entropy we need.
// This example fills entropy with at string of zeros
// this should NOT be used in a production environment
int entropyMinBytes = mteEncoder.GetDrbgsEntropyMinBytes(mteEncoder.GetDrbg());
string entropy = (entropyMinBytes > 0)
? new String('0', entropyMinBytes)
: string.Empty;
// Set encoder entropy and nonce
mteEncoder.SetEntropy(Encoding.UTF8.GetBytes(entropy));
mteEncoder.SetNonce(nonce);
// Initialize MTE encoder
MteStatus encoderStatus = mteEncoder.Instantiate(personalizationString);
if(encoderStatus !=MteStatus.mte_status_success)
{
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new ApplicationException($"Failed to initialize the MTE encoder engine." +
$"Status: {mteEncoder.GetStatusName(encoderStatus)} / " +
$"{mteEncoder.GetStatusDescription(encoderStatus)}");
}
// Create the MTE encoder
MteEnc mteEncoder = new MteEnc();
// Need entropy, nonce and personalization string
// These values should be unique and entropy must be treated like encryption keys!
// The following personalization string and nonce values are for
// demonstration only and should not be used in a production environment
String personalizationString = "MySecretPersonalizationStringGoesHere";
long nonce = 12345678;
// *** IMPORTANT NOTE ***
// Entropy is critical to security and should be created and handled like encryption keys.
// To permit decoding of encoded value, Encoder and Decoder must use identical Entropy, Nonce and
// Personalization String as well as Options . See Developer Guides for more information.
// Check how long of entropy we need.
// This example fills entropy with at string of zeros
// this should NOT be used in a production environment
int entropyMinBytes = MteBase.getDrbgsEntropyMinBytes(mteEncoder.getDrbg());
String entropy = "0";
entropy = entropy.repeat(entropyMinBytes);
// Set encoder entropy and nonce
mteEncoder.setEntropy(entropy.getBytes());
mteEncoder.setNonce(nonce);
// Initialize MTE encoder
MteStatus encoderStatus = mteEncoder.instantiate(personalizationString.getBytes());
if (encoderStatus != MteStatus.mte_status_success)
{
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new Exception("Failed to initialize the MTE encoder engine. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
import { MteEnc } from "mte-wasm-browser";
// Note: mteWasm must already be declared and instantiated
// assign module variable to be an encoder
const mteEncoder = MteEnc.fromdefault(mteWasm);
// set encoder entropy
// see Best Practice guides for generating secure entropy values
mteEncoder.setEntropyStr("SecretEntropyStringHere");
// set encoder nonce
mteEncoder.setNonce(12345678);
// instantiate using personalization token
const encoderStatus = mteEncoder.instantiate("SecretPersonalizationStringHere");
// check instantiation was successful
if (encoderStatus !== MteStatus.mte_status_success) {
const status = mteBase.getStatusName(encoderStatus);
const message = mteBase.getStatusDescription(encoderStatus);
throw new Error(`Error instantiating MTE Encoder.\n${status}: ${message}`);
}
// Create the encoder.
let encoder = try! MteEnc()
encoder.setEntropyCallback(cbs)
encoder.setNonceCallback(cbs)
encoder.setTimestampCallback(cbs)
status = encoder.instantiate(personal)
if status != mte_status_success {
print("Encoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
The entropy and nonce callbacks.
class Cbs: MteEntropyCallback, MteNonceCallback, MteTimestampCallback {
func entropyCallback(_ minEntropy: Int,
_ minLength: Int,
_ maxLength: UInt64,
_ entropyInput: inout [UInt8],
_ eiBytes: inout UInt64,
_ entropyLong: inout UnsafeMutableRawPointer?) -> mte_status {
// Display a prompt.
print("Enter \(minLength)-\(maxLength) bytes of entropy> ", terminator: "")
// Get a line of input.
let line = readLine()!
// If the input was less than the minimum required, we must return an error.
if line.utf8.count < minLength {
return mte_status_drbg_catastrophic
}
// Set the actual entropy length. It cannot exceed the maximum required.
let buffBytes = eiBytes
eiBytes = min(UInt64(line.utf8.count), maxLength)
// If the length is greater than the length of the provided buffer, we have
// to create our own buffer instead.
if eiBytes > buffBytes {
// Get the entropy input as an array.
let ei = [UInt8](line.utf8)
// If there is previous raw entropy, deallocate it.
if myEntropyRaw != nil {
myEntropyRaw!.deallocate()
}
// Allocate unsafe memory for the entropy.
myEntropyRaw =
UnsafeMutableRawPointer.allocate(byteCount: ei.count, alignment: 16)
// Copy from the entropy array to the unsafe memory.
ei.withUnsafeBytes { buff in
let raw = myEntropyRaw!.assumingMemoryBound(to: UInt8.self)
let ei = buff.bindMemory(to: UInt8.self)
raw.assign(from: ei.baseAddress!, count: ei.count)
}
// Set the raw pointer to point at the unsafe memory.
entropyLong = myEntropyRaw
}
else {
// Copy the entropy to the buffer.
entropyInput.replaceSubrange(Range(uncheckedBounds: (0, Int(eiBytes))),
with: line.utf8.prefix(Int(eiBytes)))
}
// Success.
return mte_status_success
}
func nonceCallback(_ minLength: Int,
_ maxLength: Int,
_ nonce: inout [UInt8],
_ nBytes: inout Int) {
// Display a prompt.
print("Enter the nonce (decimal digits only)> ", terminator: "")
// Get the nonce and ignore the rest of the line.
let u64 = UInt64(readLine()!)!
// Copy the nonce in little-endian format to the nonce buffer.
let nCopied = min(nonce.count, MemoryLayout.size(ofValue: u64))
for i in 0..<nCopied {
nonce[i] = UInt8(UInt64(u64 >> (i * 8)) & 0xFF)
}
// If the minimum length is greater than the size of the nonce we got, fill
// up to that length with zeros.
if nCopied < minLength {
for i in nCopied..<minLength {
nonce[i] = 0
}
nBytes = minLength
}
else {
nBytes = nCopied
}
}
# Create MTE Core Encoder with defaults.
mte_encoder = MteEnc.fromdefault()
# Need entropy, nonce and personalization string.
# *** IMPORTANT NOTE ***
# Entropy is critical to security and should be created and
# handled like encryption keys. To permit decoding of encoded
# value, Encoder and Decoder must use identical Entropy, Nonce and
# Personalization String as well as Options . See Developer Guides for more information.
#-----------------------------------------------------------------
# The following personalization string and nonce values are for
# demonstration only and should not be used in a production environment.
personalization_string = "MySecretPersonalizationStringGoesHere"
nonce = 12345678
# Check how long of entropy we need.
# This example fills entropy with at string of zeros.
# This should NOT be used in a production environment.
entropy_min_bytes = MteBase.get_drbgs_entropy_min_bytes(mte_encoder.get_drbg())
entropy = bytes("0" * entropy_min_bytes, 'utf-8')
# Set encoder entropy and nonce.
mte_encoder.set_entropy(entropy)
mte_encoder.set_nonce(nonce)
# Initialize MTE encoder.
encoder_status = mte_encoder.instantiate(personalization_string)
if encoder_status != MteStatus.mte_status_success:
# MTE cannot continue so handle failure appropriately.
# Below is an Example.
raise Exception("Failed to initialize the MTE encoder engine. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
// Create Encoder with default options
// In practice, you will create an encoder this way, create a custom encoder,
// or create MKE or FLEN encoder. See developer guide for more information
mteEncoder := mte.NewEncDef()
defer mteEncoder.Destroy()
// Need entropy, nonce and personalization string.
// These values should be unique and treated like encryption keys!
// The following personalization string and nonce values are for demonstration purposes
// and should NOT be used in production environments
personalizationString := "MySecretPersonalizationStringGoesHere"
nonce := 12345678
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
entropyBytes := mte.GetDrbgsEntropyMinBytes(mteEncoder.GetDrbg())
entropy := make([]byte, entropyBytes)
// Set entropy and nonce
mteEncoder.SetEntropy(entropy)
mteEncoder.SetNonceInt(nonce)
// Instantiate the encoder.
encoderStatus := mteEncoder.InstantiateStr(personalizationString)
if encoderStatus != mte.Status_mte_status_success {
// Handle an error here -- below is a sample
fmt.Fprintf(os.Stderr, "Encoder instantiate error (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
<?php
// Create Encoder with default options
// In practice, you will create an encoder this way, create a custom encoder,
// or create MKE or FLEN encoder. See developer guide for more information
$mteEncoder = new mteEnc();
// Need entropy, nonce and personalization string.
// These values should be unique and treated like encryption keys!
// The following personalization string and nonce values are for demonstration purposes
// and should NOT be used in production environments
$personalizationString = "MySecretPersonalizationStringGoesHere";
$nonce = 12345678;
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
$entropyBytes = $mteEncoder->getDrbgEntropyMinBytes(constant($mteEncoder->getDrbg()));
$entropy = "";
$entropy = str_pad($entropy, $entropyBytes);
// Set entropy and nonce
$mteEncoder->setEntropy($entropy);
$mteEncoder->setNonce($nonce);
// Instantiate the Encoder.
$encoded = $mteEncoder->instantiate($personalizationString);
if (constant($encoded["status"])==mte_status_success) {
// Handle an error here -- below is a sample
echo "Encoder instantiate error: ".$mteEncoder->getStatusName(constant($encoded["status"])).":"
.$mteEncoder->getStatusDescription(constant($encoded["status"]));
return $mteEncoder->getStatusCode(constant($encoded["status"]));
}
?>
Encoding to a base64 string or byte[]
Use the following methods to encode a string or a byte[]. The samples below display all the options that can be used to encode, only one method needs to be used to encode the data. The developer should select the method that works with the type of data that is used.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
/* There are different functions available to use depending on program needs.
* The versions with b64 in the function name involve base 64 conversion,
* suitable for protocols requiring a string representation.
* Otherwise the default will use raw bytes.
*/
/* Allocate the buffer for encoding. */
char* encoded = MTE_ALLOCA(mte_enc_buff_bytes_b64(encoder));
/* Encode the message. */
MTE_SET_ENC_IO(e_args, input, input_bytes, encoded);
status = mte_enc_encode_b64(encoder, &e_args);
if (status != mte_status_success)
{
fprintf(stderr, "Encode error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
The timestamp callback.
static MTE_UINT64_T t_cb(void* context)
{
char line[80];
(void)context;
/* Get the timestamp. */
printf("Enter the timestamp (decimal digits only)> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
return strtoul(line, NULL, 10);
}
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
size_t encodedBytes = 0;
// Encode the message.
const void* encoded = encoder.encode(input, inputBytes, encodedBytes, status);
if (status != mte_status_success)
{
std::cerr << "Encode error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
The timestamp callback.
MTE_UINT64_T Cbs::timestampCallback()
{
// Display a prompt.
std::cout << "Enter the timestamp (decimal digits only)> " << std::flush;
// Get the timestamp and ignore the rest of the line.
MTE_UINT64_T u64;
std::cin >> u64;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return u64;
}
// Example value to be encoded
string inputString = "What I want to be encoded goes here";
byte[] bytesToBeEncoded = Encoding.ASCII.GetBytes(inputString);
// initialize status
MteStatus encoderStatus;
// Below are 4 different examples of how to encode
// ONLY ONE needs to be used!!!
// Encode byte[] to a base64 string
string encodedBytesAsString = mteEncoder.EncodeB64(bytesToBeEncoded, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
// Encode string to a base64 string
string encodedStringAsString = mteEncoder.EncodeStrB64(inputString, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
// Encode byte[] to a byte[]
byte[] encodedBytesAsBytes = mteEncoder.Encode(bytesToBeEncoded, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
// Encode string to a byte[]
byte[] encodedStringAsBytes = mteEncoder.EncodeStr(inputString, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
// Example value to be encoded
String inputString = "What I want to be encoded goes here";
byte[] bytesToBeEncoded = inputString.getBytes(StandardCharsets.UTF_16);
// initialize status
MteStatus encoderStatus;
// Below are 4 different examples of how to encode
// ONLY ONE needs to be used!!!
// Encode byte[] to a base64 string
String encodedBytesAsString = mteEncoder.encodeB64(bytesToBeEncoded, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
// Encode string to a base64 string
String encodedStringAsString = mteEncoder.encodeStrB64(inputString, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
// Encode byte[] to a byte[]
byte[] encodedBytesAsBytes = mteEncoder.encode(bytesToBeEncoded, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
// Encode string to a byte[]
byte[] encodedStringAsBytes = mteEncoder.encodeStr(inputString, out encoderStatus);
if(encoderStatus != MteStatus.mte_status_success)
{
// Handle encode failure appropriately
// Below is only an example
throw new Exception("Failed to encode. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
// encode string and return as B64 string
const str = "A sensitive string.";
const encoderResult = mteEncoder.encodeStrB64(str);
if (encoderResult.status !== MteStatus.mte_status_success) {
const status = mteBase.getStatusName(encoderResult);
const message = mteBase.getStatusDescription(encoderResult);
throw new Error(`Failed to encode. Status ${status}: ${message}\n`);
}
// encoderResult.str contains encoded result
// encode string and return as Uint8Array
const str = "A sensitive string.";
const encoderResult = mteEncoder.encoderStr(str);
if (encoderResult.status !== MteStatus.mte_status_success) {
const status = mteBase.getStatusName(encoderResult);
const message = mteBase.getStatusDescription(encoderResult);
throw new Error(`Failed to encode. Status ${status}: ${message}\n`);
}
// encoderResult.arr contains encoded result
// encode Uint8Array and return as b64 string
const arr = new Uint8Array([9, 19, 89]);
const encoderResult = mteEncoder.encodeB64(arr);
if (encoderResult.status !== MteStatus.mte_status_success) {
const status = mteBase.getStatusName(encoderResult);
const message = mteBase.getStatusDescription(encoderResult);
throw new Error(`Failed to encode. Status ${status}: ${message}\n`);
}
// encoderResult.str contains encoded result
// encode Uint8Array and return as Uint8Array
const arr = new Uint8Array([9, 19, 89]);
const encoderResult = mteEncoder.encode(arr);
if (encoderResult.status !== MteStatus.mte_status_success) {
const status = mteBase.getStatusName(encoderResult);
const message = mteBase.getStatusDescription(encoderResult);
throw new Error(`Failed to encode. Status ${status}: ${message}\n`);
}
// encoderResult.arr contains encoded result
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
// Encode the message.
let encodedRes = encoder.encode(input)
status = encodedRes.status
if (status != mte_status_success) {
print("Encode error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
The timestamp callback.
func timestampCallback() -> UInt64 {
// Display a prompt.
print("Enter the timestamp (decimal digits only)> ", terminator: "")
// Get the timestamp and ignore the rest of the line.
return UInt64(readLine()!)!
}
# Example values to be encoded.
input_string = "What I want to be encoded goes here"
bytes_to_be_encoded = bytes(input_string,'utf-8')
# Below are 4 different examples of how to encode.
# ONLY ONE needs to be used.
# Encode byte[] to a base64 string.
(encoded_bytes_as_string, encoder_status) = mte_encoder.encode_b64(bytes_to_be_encoded)
if encoder_status != MteStatus.mte_status_success:
# Handle encode failure appropriately.
# Below is only an example.
raise Exception("Failed to encode. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
# Encode string to a base64 string.
(encoded_string_as_string, encoder_status) = mte_encoder.encode_b64(input_string)
if encoder_status != MteStatus.mte_status_success:
# Handle encode failure appropriately.
# Below is only an example.
raise Exception("Failed to encode. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
# Encode byte[] to a byte[].
(encoded_bytes_as_string, encoder_status) = mte_encoder.encode(bytes_to_be_encoded)
if encoder_status != MteStatus.mte_status_success:
# Handle encode failure appropriately.
# Below is only an example.
raise Exception("Failed to encode. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
# Encode string to a byte[].
(encoded_string_as_bytes, encoder_status) = mte_encoder.encode(input_string)
if encoder_status != MteStatus.mte_status_success:
# Handle encode failure appropriately.
# Below is only an example.
raise Exception("Failed to encode. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
// Example values to be encoded
inputString := "Message we are going to encode"
inputBytes := []byte(inputString)
// initialize status
var encoderStatus mte.Status
// Encode string to a base64 string
encodedString, encoderStatus := mteEncoder.EncodeStrB64(inputString)
if(encoderStatus != mte.Status_mte_status_success){
// Handle error -- example below
fmt.Fprintf(os.Stderr, "Failed to encode. Status (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
// Encode byte[] to a base64 string
encodedString, encoderStatus := mteEncoder.EncodeB64(inputBytes)
if(encoderStatus != mte.Status_mte_status_success){
// Handle error -- example below
fmt.Fprintf(os.Stderr, "Failed to encode. Status (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
// Encode string to a byte array
encodedBytes, encoderStatus := mteEncoder.EncodeStr(inputString)
if(encoderStatus != mte.Status_mte_status_success){
// Handle error -- example below
fmt.Fprintf(os.Stderr, "Failed to encode. Status (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
// Encode bytes to a byte array
encodedBytes, encoderStatus := mteEncoder.Encode(inputBytes)
if(encoderStatus != mte.Status_mte_status_success){
// Handle error -- example below
fmt.Fprintf(os.Stderr, "Failed to encode. Status (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
<?php
// Example value to be encoded
$inputString = "What I want to be encoded goes here";
// Below are 2 different examples of how to encode
// ONLY ONE needs to be used!!!
?>
<?php
// Encode String to String
$encoded = $mteEnc->encode($inputString);
// Check the status
if (constant($encoded["status"])!=mte_status_success){
// Handle an error here -- below is a sample
throw new Exception("Failed to encode. Status "
.$mteEncoder->getStatusName(constant($encoded["status"])).":"
.$mteEncoder->getStatusDescription(constant($encoded["status"])));
}
?>
<?php
// Encode string to Base64 String
$base64encoded = $mteEnc->encodeB64($inputString);
// Check the status
if (constant($base64encoded["status"])!=mte_status_success){
// Handle an error here -- below is a sample
throw new Exception("Failed to encode. Status "
.$mteEncoder->getStatusName(constant($base64encoded["status"])).":"
.$mteEncoder->getStatusDescription(constant($base64encoded["status"])));
}
?>
Encoder State
The encoder state can be saved and restored with either byte[] or a base64 string using the following methods. Below are several examples of how to use it, based on your data type you only need to use one of the following examples.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
Save state.
/* There are different functions available to use depending on program needs.
* The versions with b64 in the function name involve base 64 conversion,
* suitable for protocols requiring a string representation.
* Otherwise the default will use raw bytes.
*/
/* Save the encoder state. */
MTE_UINT8_T* e_saved = MTE_ALLOCA(mte_enc_save_bytes(encoder));
status = mte_enc_state_save(encoder, e_saved);
if (status != mte_status_success)
{
fputs("Encoder state save error.", stderr);
return mte_status_unsupported;
}
Restore state.
/* Restore the encoder state. */
status = mte_enc_state_restore(encoder, e_saved);
if (status != mte_status_success)
{
fprintf(stderr, "Encoder state restore error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
Save state.
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
// Save the encoder state.
size_t eSavedBytes = 0;
const void* esaved = encoder.saveState(eSavedBytes);
if (esaved == NULL)
{
std::cerr << "Encoder state save error." << std::endl;
return mte_status_unsupported;
}
Restore state.
// Restore the encoder state.
status = encoder.restoreState(esaved);
if (status != mte_status_success)
{
std::cerr << "Encoder state restore error." << std::endl;
return status;
}
// Save and restore Encoder state with bytes
// Get byte[] of encoder state
byte[] encoderByteState = mteEncoder.SaveState();
// Restore Encoder with byte[] state
MteStatus encoderStatus = mteEncoder.RestoreState(encoderByteState);
if(encoderStatus != MteStatus.mte_status_success)
{
// Encoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore Encoder state. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
// Save and restore Encoder state with string
// Get string of Encoder state
string encoderStrState = mteEncoder.SaveStateB64();
// Restore Encoder with string state
MteStatus encoderStatus = mteEncoder.RestoreStateB64(encoderStrState);
if(encoderStatus != MteStatus.mte_status_success)
{
// Encoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore encoder state. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
// Save and restore Encoder state with bytes
// Get byte[] of Encoder state
byte[] encoderByteState = mteEncoder.saveState();
// Restore Encoder with byte[] state
MteStatus encoderStatus = mteEncoder.restoreState(encoderByteState);
if(encoderStatus != MteStatus.mte_status_success)
{
// Encoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore Encoder state. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
// Save and restore Encoder state with string
// Get string of Encoder state
String encoderStrState = mteEncoder.saveStateB64();
// Restore Encoder with string state
MteStatus encoderStatus = mteEncoder.restoreStateB64(encoderStrState);
if(encoderStatus != MteStatus.mte_status_success)
{
// Encoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore Encoder state. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
// save Encoder state as Uint8Array
const state = mteEncoder.saveState();
// restore Encoder from Uint8Array
mteEncoder.restoreState(state);
// save Encoder state as Base64 String
const state = mteEncoder.saveStateB64();
// restore Encoder from Base64 state
mteEncoder.restoreStateB64(state);
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
// Save the encoder state.
let esaved = encoder.saveState()
if esaved == nil {
print("Encoder state save error.")
return Int32(mte_status_unsupported.rawValue)
}
# Save and restore Encoder state with bytes.
# Get byte[] of Encoder state.
encoder_byte_state = mte_encoder.save_state()
# Restore Encoder with byte[] state.
encoder_status = mte_encoder.restore_state(encoder_byte_state)
if encoder_status != MteStatus.mte_status_success:
# Mte cannot continue, handle restore failure appropriately.
# Below is only an example.
raise Exception("Failed to restore Encoder state. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
# Save and restore Encoder state with string.
# Get string of Encoder state.
encoder_str_state = mte_encoder.save_state_b64()
# Restore Encoder with string state.
encoder_status = mte_encoder.restore_state_b64(encoder_str_state)
if encoder_status != MteStatus.mte_status_success:
# Mte cannot continue, handle restore failure appropriately.
# Below is only an example.
raise Exception("Failed to restore Encoder state. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
// Save and restore Encoder state with bytes
// Get byte[] of encoder state
encoderByteState := mteEncoder.SaveState()
encoderStatus := mteEncoder.RestoreState(encoderByteState);
if(encoderStatus != mte.Status_mte_status_success){
// Encoder restore failed, handle appropriately.
// Below is only an example
fmt.Fprintf(os.Stderr, "Restore Encoder state error (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
// Save and restore Encoder state with bytes
// Get byte[] of Encoder state
encoderStrState := mteEncoder.SaveStateB64()
encoderStatus := mteEncoder.RestoreStateB64(encoderStrState);
if(encoderStatus != mte.Status_mte_status_success){
// Encoder restore failed, handle appropriately
// Below is only an example
fmt.Fprintf(os.Stderr, "Restore Encoder state error (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
<?php
$encoderStrState = $mteEncoder->saveState();
$restoreStatus = $mteEncoder->restoreState($encoderStrState);
if (constant($restoreStatus)!=mte_status_success){
// Handle an error here -- below is a sample
echo "Encoder restore state error: "
.$mteEncoder->getStatusName(constant($restoreStatus)).":"
.$mteEncoder->getStatusDescription(constant($restoreStatus));
return $mteEncoder->getStatusCode(constant($restoreStatus));
}
?>
<?php
$encoderB64State = $mteEncoder->saveStateB64();
$restoreStatus = $mteEncoder->restoreStateB64($encoderB64State);
if (constant($restoreStatus)!=mte_status_success){
// Handle an error here -- below is a sample
echo "Encoder restore base64 state error: "
.$mteEncoder->getStatusName(constant($restoreStatus)).":"
.$mteEncoder->getStatusDescription(constant($restoreStatus));
return $mteEncoder->getStatusCode(constant($restoreStatus));
}
?>
Additional options for Encoder State
The Core MTE encoder state and the MTE MKE encoder state are interchangeable. This means, the encoder state can be restored to a MTE Core OR an MTE MKE. The MTE used should be created using the same options for this to work correctly. The security of the MTE Core can be used for a password then the MTE MKE can be used on larger data in the same application without having to create multiple instances of the MTE.
Reseeding Interval
There are a limited amount of random numbers a DRBG can produce before it must be reseeded. This is called the reseed interval. The DRBG will stop functioning in order to protect the security of the application. When the MTE reaches it's reseed interval the MTE will return a status of "mte_status_drbg_seedlife_reached".
The developer can use the reseed count and the reseed interval to determine if the seed life is ending. We recommend reseeding the MTE before the seed life ends in order to prevent the loss of any data. Reseeding the MTE can be done by re-initializing the MTE with a new entropy value and new nonce. Both sides, the Encoder and Decoder, must be re-initialized at the same time to stay in sync.
The example below checks for 90% usage before re-initializing. For DRBGs with large reseed interval, 90% is a good number. To determine a good percentage the size of the data transmission should be used. For small data transmissions a value much closer to 100% can be used; for larger data transmissions or smaller reseed intervals, a smaller percentage should be used to ensure the end of the seed life is not hit.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Go
- PHP
// Get the Encoder DRBG reseed counter.
// This is the MTE's current seed count.
uint64_t current_seed = mte_enc_reseed_counter(encoder);
// Get the Encoder DRBG max reseed interval.
uint64_t max_seed = mte_base_drbgs_reseed_interval(MTE_DRBG_ENUM);
// For example, if the current seed is greater than 90% of the max seed,
// uninstantiate the MTE then Reinitialize the MTE.
// with a new entropy and nonce to reseed.
if (current_seed > (max_seed * 0.9))
{
// Uninstantiate the Encoder.
mte_status encoder_status = mte_enc_uninstantiate(encoder);
if (encoder_status != mte_status_success)
{
fprintf(stderr, "Failed to uninstantiate Encoder (%s): %s\n",
mte_base_status_name(encoder_status),
mte_base_status_description(encoder_status));
return encoder_status;
}
// Now the Encoder and matching Decoder must be re-paired with a new entropy and nonce.
//=============================================================
// TODO: Developer adds code to re-pair with entropy and nonce.
//=============================================================
}
// Get the Encoder DRBG reseed counter.
// This is the MTE's current seed count.
uint64_t currentSeed = encoder.getReseedCounter();
// Get the Encoder DRBG max reseed interval.
uint64_t maxSeed = MteBase::getDrbgsReseedInterval(MTE_DRBG_ENUM);
// For example, if the current seed is greater than 90% of the max seed,
// uninstantiate the MTE then Reinitialize the MTE.
// with a new entropy and nonce to reseed.
if (currentSeed > (maxSeed * 0.9))
{
// Uninstantiate the Encoder.
mte_status encoderStatus = encoder.uninstantiate();
if (encoderStatus != mte_status_success)
{
std::cerr << "Encoder uninstantiate error ("
<< MteBase::getStatusName(encoderStatus)
<< "): "
<< MteBase::getStatusDescription(encoderStatus)
<< std::endl;
return encoderStatus;
}
// Now the Encoder and matching Decoder must be re-paired with a new entropy and nonce.
//=============================================================
// TODO: Developer adds code to re-pair with entropy and nonce.
//=============================================================
}
//--------------------------------------
// Get the Encoder DRBG reseed counter
// This is the MTE's current seed count
ulong currentSeed = mteEncoder.GetReseedCounter();
//------------------------------------------
// Get the Encoder DRBG max reseed interval
ulong maxSeed = mteBase.GetDrbgsReseedInterval(mteEncoder.GetDrbg());
//---------------------------------------------------------
// If the current seed is greater than 90% of the max seed
// Uninstantiate the MTE then Reinitialize the MTE
// with a new entropy and nonce to reseed
if (currentSeed > (maxSeed * 0.9)){
//---------------------------
// Uninstantiate the Encoder
MteStatus encoderStatus = mteEncoder.Uninstantiate();
if(encoderStatus != MteStatus.mte_status_success) {
//-------------------------------------------------
// MTE was not uninstantiated as desired so handle
// failure appropriately, below is only an example
throw new Exception("Failed to uninstantiate Encoder. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
HandshakeModel handshake = MethodToHandshake();
//-------------------------------
// Set Encoder entropy and nonce
mteEncoder.SetEntropy(Encoding.UTF8.GetBytes(handshake.NewEncoderEntropy));
mteEncoder.SetNonce(handshake.NewNonce);
//------------------------
// Initialize MTE Encoder
MteStatus encoderStatus = mteEncoder.Instantiate(personalizationString);
if(encoderStatus !=MteStatus.mte_status_success) {
//-----------------------------------------------------
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new ApplicationException($"Failed to initialize the MTE Encoder engine." +
$"Status: {mteEncoder.GetStatusName(encoderStatus)} / " +
$"{mteEncoder.GetStatusDescription(encoderStatus)}");
}
}
//--------------------------------------
// Get the Encoder DRBG reseed counter
// This is the MTE's current seed count
long currentSeed = mteEncoder.getReseedCounter();
//------------------------------------------
// Get the Encoder DRBG max reseed interval
long maxSeed = MteBase.getDrbgsReseedInterval(mteEncoder.getDrbg());
//---------------------------------------------------------
// If the current seed is greater than 90% of the max seed
// Uninstantiate the MTE then Reinitialize the MTE
// with a new entropy and nonce to reseed
if(currentSeed > (_maxSeed * .9)) {
// Uninstantiate the Encoder
MteStatus encoderStatus = mkeEncoder.uninstantiate();
if(encoderStatus != MteStatus.mte_status_success) {
// MTE was not uninstantiated as desired so handle failure appropriately
// Below is only an example
throw new Exception("Failed to uninstantiate Encoder. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
HandshakeResponse handshake = MethodToHandshake();
//-------------------------------
// Set Encoder entropy and nonce
mteEncoder.setEntropy(handshake.NewEncoderEntropy.getBytes()));
mteEncoder.setNonce(handshake.NewNonce);
//------------------------
// Initialize MTE Encoder
MteStatus encoderStatus = mteEncoder.instantiate(personalizationString);
if(encoderStatus !=MteStatus.mte_status_success) {
//-----------------------------------------------------
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new Exception("Error creating Encoder: Status: "
+ MteBase.getStatusName(encoderStatus) + " / "
+ MteBase.getStatusDescription(encoderStatus);
}
}
JavaScript works a little differently than other languages due to having to use a different type once it reaches 16 digits. You can get more info on BigInts on MDN. Because of this, we specifically cast to Number, only grab 15 digits of precision, and reseed at 80% of the max seed instead of 90%.
//--------------------------------------
// Get the Encoder DRBG reseed counter
// This is the MTE's current seed count
const currentSeed = Number(
String(mteEncoder.getReseedCounter()).substring(0, 15),
);
//------------------------------------------
// Get the Encoder DRBG max reseed interval
const maxSeed = Number(
String(mteEncoder.getDrbgsReseedInterval(drbg)).substring(0, 15),
);
//---------------------------------------------------------
// If the current seed is greater than 80% of the max seed
// Uninstantiate the MTE then Reinitialize the MTE
// with a new entropy and nonce to reseed
if (Number(currentSeed) > Number(maxSeed) * 0.8) {
//---------------------------
// Uninstantiate the Encoder
const encoderStatus = mteEncoder.uninstantiate();
if (encoderStatus !== MteStatus.mte_status_success) {
//-------------------------------------------------
// MTE was not uninstantiated as desired so handle
// failure appropriately, below is only an example
throw new Error(
`Failed to uninstantiate Encoder. ` +
`Status: ${mteEncoder.getStatusName(encoderStatus)} ` +
`/ ${mteEncoder.getStatusDescription(encoderStatus)}`,
);
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
const handshake = methodToHandshake();
//-------------------------------
// Set Encoder entropy and nonce
mteEncoder.setEntropy(handshake.newEncoderEntropy);
mteEncoder.setNonce(handshake.newNonce);
//------------------------
// Initialize MTE Encoder
const encoderStatus = mteEncoder.instantiate(personalizationString);
if (encoderStatus !== MteStatus.mte_status_success) {
//-----------------------------------------------------
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new Error(
`Failed to initialize the MTE Encoder engine.` +
`Status: ${mteEncoder.getStatusName(encoderStatus)} / ` +
`${mteEncoder.getStatusDescription(encoderStatus)}`,
);
}
}
// Get the Encoder DRBG reseed counter.
// This is the MTE's current seed count.
let currentSeed:UInt64 = encoder.getReseedCounter()
// Get the Encoder DRBG max reseed interval.
let maxSeed:UInt64 = MteBase.getDrbgsReseedInterval(encoder.getDrbg())
// For example, if the current seed is greater than 90% of the max seed,
// uninstantiate the MTE then Reinitialize the MTE.
// with a new entropy and nonce to reseed.
if (currentSeed > (maxSeed * UInt64(0.9))) {
// Uninstantiate the Encoder.
let encoderStatus:mte_status = encoder.uninstantiate()
if (encoderStatus != mte_status_success) {
print("Encoder uninstantiate error (\(MteBase.getStatusName(encoderStatus))): " +
MteBase.getStatusDescription(encoderStatus))
return Int32(encoderStatus.rawValue)
}
// Now the Encoder and matching Decoder must be re-paired with a new entropy and nonce.
//=============================================================
// TODO: Developer adds code to re-pair with entropy and nonce.
//=============================================================
}
//--------------------------------------
// Get the Encoder DRBG reseed counter
// This is the MTE's current seed count
currentSeed := mteEncoder.getReseedCounter()
//------------------------------------------
// Get the Encoder DRBG max reseed interval
maxSeed := mteEncoder.getDrbgReseedInterval(mteEncoder.getDrbg())
if currentSeed > (maxSeed * .9) {
//---------------------------
// Uninstantiate the Encoder
encoderStatus := mteEncoder.Uninstantiate()
if encoderStatus != mte.Status_mte_status_success {
//----------------------------------------------------
// Handle Encoder uninstantiate failure appropriately
// Below is only an example
fmt.Fprintf(os.Stderr, "Encoder uninstantiate error (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
handshake := MethodToHandshake();
//--------------------
// Initialize Encoder
//--------------------
mteEncoder.SetEntropy(handshake.newEncoderEntropy)
mteEncoder.SetNonceInt(handshake.newNonce)
encoderStatus := mteEncoder.InstantiateStr(personalizationString)
if encoderStatus != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encoder instantiate error (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return (int)encoderStatus
}
}
<?php
//--------------------------------------
// Get the Encoder DRBG reseed counter
// This is the MTE's current seed count
$currentSeed = $mteEncoder->getReseedCounter();
//------------------------------------------
// Get the Encoder DRBG max reseed interval
$maxSeed = $mteEncoder->getDrbgReseedInterval(constant($mteEncoder->getDrbg()));
if ($currentSeed > ($maxSeed * .9)) {
//---------------------------
// Uninstantiate the Encoder
$encoderStatus = $mteEncoder->uninstantiate();
if (constant($encoderStatus) != mte_status_success) {
//----------------------------------------------------
// Handle Encoder uninstantiate failure appropriately
// Below is only an example
echo "Encoder uninstantiate error: "
.$mteEncoder->getStatusName(constant($encoderStatus)).":"
.$mteEncoder->getStatusDescription(constant($encoderStatus));
return $mteEncoder->getStatusCode(constant($encoderStatus));
}
unset($mteEncoder);
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
$handshake = MethodToHandshake();
//--------------------
// Initialize Encoder
//--------------------
$mteEncoder = new MteEnc();
$mteEncoder->setEntropy($handshake["newEncoderEntropy"]);
$mteEncoder->setNonce($handshake["newNonce"]);
$encoderStatus = $mteEncoder->instantiate($personalizationString);
if (constant($encoderStatus) != mte_status_success) {
//----------------------------------------------------
// Handle Encoder instantiate failure appropriately
// Below is only an example
echo "Encoder instantiate error: "
.$mteEncoder->getStatusName(constant($encoderStatus)).":"
.$mteEncoder->getStatusDescription(constant($encoderStatus));
return $mteEncoder->getStatusCode(constant($encoderStatus));
}
}
?>
Uninstantiate Encoder
Uninstantiate encoder, this will zeroize the DRBG state and returns the status.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
status = mte_enc_uninstantiate(encoder);
if (status != mte_status_success)
{
fprintf(stderr, "Failed to uninstantiate encoder (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
status = encoder.uninstantiate();
if (status != mte_status_success)
{
std::cerr << "Encoder uninstantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Uninstantiate the Encoder
MteStatus encoderStatus = mteEncoder.Uninstantiate();
if(encoderStatus != MteStatus.mte_status_success)
{
// MTE was not uninstantiated as desired so handle failure appropriately
// Below is only an example
throw new Exception("Failed to uninstantiate Encoder. Status: "
+ mteEncoder.GetStatusName(encoderStatus)+ " / "
+ mteEncoder.GetStatusDescription(encoderStatus));
}
// Uninstantiate the Encoder
MteStatus encoderStatus = mteEncoder.uninstantiate();
if(encoderStatus != MteStatus.mte_status_success)
{
// MTE was not uninstantiated as desired so handle failure appropriately
// Below is only an example
throw new Exception("Failed to uninstantiate Encoder. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
// Uninstantiate the Encoder
mteEncoder.uninstantiate();
// free WASM memory
mteEncoder.destroy();
// Uninstantiate the Encoder
let status: mte_status = encoder.uninstantiate()
if status != mte_status_success {
// MTE was not uninstantiated as desired so handle failure appropriately
print("Encoder Uninstantiate error: \(MteBase.getStatusName(status))." +
"Description: \(MteBase.getStatusDescription(status))"
}
# Uninstantiate the Encoder.
encoder_status = mte_encoder.uninstantiate()
if encoder_status != MteStatus.mte_status_success:
# MTE was not uninstantiated as desired so handle failure appropriately.
# Below is only an example.
raise Exception("Failed to uninstantiate Encoder. Status: {0} / {1}\n".format(MteBase.get_status_name(encoder_status),
MteBase.get_status_description(encoder_status)))
// Uninstantiate the Encoder
encoderStatus := mteEncoder.Uninstantiate();
if(encoderStatus != mte.Status_mte_status_success){
// Handle Encoder uninstatiate failure appropriately
// Below is only an example
fmt.Fprintf(os.Stderr, "Encoder uninstantiate error (%v): %v\n",
mte.GetStatusName(encoderStatus), mte.GetStatusDescription(encoderStatus))
return int(encoderStatus)
}
<?php
// Uninstantiate the Encoder
$encoderStatus = $mteEncoder->uninstantiate();
if (constant($encoderStatus) != mte_status_success) {
//----------------------------------------------------
// Handle Encoder uninstantiate failure appropriately
// Below is only an example
echo "Encoder uninstantiate error: ".$mteEncoder->getStatusName(constant($encoderStatus)).":"
.$mteEncoder->getStatusDescription(constant($encoderStatus));
return $mteEncoder->getStatusCode(constant($encoderStatus));
}
// Clear out $mteEncoder variable
unset($mteEncoder);
?>
MTE Core Decoder
Create MTE Core Decoder
The MTE Core Decoder will be created using default options. The default options will set preferred security options recommended by Eclypses. Custom options should only be used in special circumstances and after reading and understanding how to select the best options for a given situation. More information about how to select these options can be found in the official MTE Developer Guides.
Create Default Decoder
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
/* Create the decoder. */
MTE_HANDLE decoder;
mte_dec_init_info d_info = MTE_DEC_INIT_INFO_INIT(
MTE_DRBG_ENUM, MTE_TOKBYTES, MTE_VERIFIERS_ENUM,
MTE_CIPHER_ENUM, MTE_HASH_ENUM, 1, 0, NULL, NULL, NULL, NULL, NULL, NULL);
mte_dec_args d_args = MTE_DEC_ARGS_INIT(NULL, 0, NULL, &t_cb, NULL);
decoder = MTE_ALLOCA(mte_dec_state_bytes(&d_info));
status = mte_dec_state_init(decoder, &d_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
status = mte_dec_instantiate(decoder, &i_info);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
The entropy and nonce callbacks.
static mte_status ei_cb(void* context, mte_drbg_ei_info* info)
{
MTE_SIZE_T input_bytes;
(void)context;
/* Get the entropy. */
printf("Enter %u-%lu bytes of entropy> ",
(unsigned)info->min_length,
(unsigned long)info->max_length);
fflush(stdout);
(void)!fgets(ei_buff, sizeof(ei_buff), stdin);
input_bytes = (MTE_SIZE_T)(strlen(ei_buff) - 1);
/* If the entropy is less than the minimum required, we must return an
error. */
if (input_bytes < info->min_length)
{
return mte_status_drbg_catastrophic;
}
else if (input_bytes > info->bytes)
{
/* If the entropy is longer than the provided buffer, point at our buffer
instead. */
info->buff = (MTE_UINT8_T*)ei_buff;
}
else
{
/* Otherwise copy the entropy to the provided buffer. */
memcpy(info->buff, ei_buff, input_bytes);
}
/* Set the actual entropy length. */
info->bytes = input_bytes;
/* We got it successfully. */
return mte_status_success;
}
static void n_cb(void* context, mte_drbg_nonce_info* info)
{
MTE_SIZE8_T i;
MTE_UINT64_T u64;
char line[80];
(void)context;
/* Get the nonce. */
printf("Enter the nonce (decimal digits only)> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
u64 = strtoul(line, NULL, 10);
/* Copy the nonce in little-endian format to the nonce buffer. */
for (i = 0; i < info->max_length && i < sizeof(u64); ++i)
{
info->buff[i] = (MTE_UINT8_T)(u64 >> (i * 8));
}
/* If the minimum length is greater than the size of the nonce we got, fill
up to that length with zeros. */
for (; i < info->min_length; ++i)
{
info->buff[i] = 0;
}
/* Set the actual nonce length. */
info->bytes = i;
}
// Create the decoder.
MteDec decoder;
decoder.setEntropyCallback(&cbs);
decoder.setNonceCallback(&cbs);
decoder.setTimestampCallback(&cbs);
status = decoder.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Decoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
The entropy and nonce callbacks.
mte_status Cbs::entropyCallback(mte_drbg_ei_info& info)
{
// Display a prompt.
std::cout << "Enter "
<< static_cast<size_t>(info.min_length) << '-' << info.max_length
<< " bytes of entropy> " << std::flush;
// Get a line of input.
std::string line;
std::cin >> line;
// If the input was less than the minimum required, we must return an error.
if (line.size() < info.min_length)
{
return mte_status_drbg_catastrophic;
}
// Set the actual entropy length. It cannot exceed the maximum required.
size_t buffBytes = info.bytes;
info.bytes = std::min(static_cast<MTE_SIZE_T>(line.size()), info.max_length);
// If the length is greater than the length of the provided buffer, we have
// to create our own buffer instead.
if (info.bytes > buffBytes)
{
delete [] myEntropy;
myEntropy = new uint8_t[info.bytes];
info.buff = myEntropy;
}
// Copy the entropy to the buffer and we got it successfully.
memcpy(info.buff, line.data(), info.bytes);
return mte_status_success;
}
void Cbs::nonceCallback(mte_drbg_nonce_info& info)
{
// Display a prompt.
std::cout << "Enter the nonce (decimal digits only)> " << std::flush;
// Get the nonce and ignore the rest of the line.
MTE_UINT64_T u64;
std::cin >> u64;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Copy the nonce in little-endian format to the nonce buffer.
size_t i;
for (i = 0; i < info.max_length && i < sizeof(u64); ++i)
{
info.buff[i] = static_cast<MTE_UINT8_T>(u64 >> (i * 8));
}
// If the minimum length is greater than the size of the nonce we got, fill
// up to that length with zeros.
for (; i < info.min_length; ++i)
{
info.buff[i] = 0;
}
// Set the actual nonce length.
info.bytes = static_cast<MTE_SIZE8_T>(i);
}
// Create MTE Core Decoder with defaults
MteDec mteDecoder = new MteDec();
// Need entropy, nonce and personalization string
// These values should be unique and entropy must be treated like encryption keys!
// The following personalization string and nonce values are for
// demonstration only and should not be used in a production environment
string personalizationString = "MySecretPersonalizationStringGoesHere";
long nonce = 12345678;
// *** IMPORTANT NOTE ***
// Entropy is critical to security and should be created and handled like encryption keys.
// To permit decoding of encoded value, Encoder and Decoder must use identical Entropy, Nonce and
// Personalization String as well as Options . See Developer Guides for more information.
// Check how long of entropy we need.
// This example fills entropy with at string of zeros
// this should NOT be used in a production environment
int entropyMinBytes = mteDecoder.GetDrbgsEntropyMinBytes(mteDecoder.GetDrbg());
string entropy = (entropyMinBytes > 0)
? new String('0', entropyMinBytes)
: string.Empty;
// Set Decoder entropy and nonce
mteDecoder.SetEntropy(Encoding.UTF8.GetBytes(entropy));
mteDecoder.SetNonce(nonce);
// Initialize MTE Decoder
MteStatus decoderStatus = mteDecoder.Instantiate(personalizationString);
if(decoderStatus != MteStatus.mte_status_success)
{
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new ApplicationException($"Failed to initialize the MTE Decoder engine." +
$"Status: {mteDecoder.GetStatusName(decoderStatus)} / " +
$"{mteDecoder.GetStatusDescription(decoderStatus)}");
}
// Create the MTE Decoder
MteDec mteDecoder = new MteDec();
// Need entropy, nonce and personalization string
// These values should be unique and entropy must be treated like encryption keys!
// The following personalization string and nonce values are for
// demonstration only and should not be used in a production environment
String personalizationString = "MySecretPersonalizationStringGoesHere";
long nonce = 12345678;
// *** IMPORTANT NOTE ***
// Entropy is critical to security and should be created and handled like encryption keys.
// To permit decoding of encoded value, Encoder and Decoder must use identical Entropy, Nonce and
// Personalization String as well as Options . See Developer Guides for more information.
// Check how long of entropy we need.
// This example fills entropy with at string of zeros
// this should NOT be used in a production environment
int entropyMinBytes = MteBase.getDrbgsEntropyMinBytes(mte_decoder.getDrbg());
String entropy = "0";
entropy = entropy.repeat(entropyMinBytes);
mte_decoder.set_entropy(entropy)
mte_decoder.set_nonce(nonce)
# Initialize MTE Decoder.
decoder_status = mte_decoder.instantiate(personalization_string)
if decoder_status != MteStatus.mte_status_success:
# MTE cannot continue so handle failure appropriately.
# Below is an Example.
raise Exception("Failed to initialize the MTE Decoder engine. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
import { MteDec } from "mte-wasm-browser";
// Note: mteWasm must already be declared and instantiated
// create Decoder from default
const mteDecoder = MteDec.fromdefault(mteWasm);
// set Decoder entropy
// see Best Practice guides for generating secure entropy values
mteDecoder.setEntropyStr("SecretEntropyStringHere");
// set Decoder nonce
mteDecoder.setNonce(12345678);
// instantiate using personalization token
const decoderStatus = mteDecoder.instantiate("SecretPersonalizationStringHere");
// check instantiation was successful
if (decoderStatus !== MteStatus.mte_status_success) {
const status = mteBase.getStatusName(decoderStatus);
const message = mteBase.getStatusDescription(decoderStatus);
throw new Error(`Error instantiating MTE Decoder.\n${status}: ${message}`);
}
// Create the decoder.
let decoder = try! MteDec()
decoder.setEntropyCallback(cbs)
decoder.setNonceCallback(cbs)
decoder.setTimestampCallback(cbs)
status = decoder.instantiate(personal)
if status != mte_status_success {
print("decoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
The entropy and nonce callbacks.
class Cbs: MteEntropyCallback, MteNonceCallback, MteTimestampCallback {
func entropyCallback(_ minEntropy: Int,
_ minLength: Int,
_ maxLength: UInt64,
_ entropyInput: inout [UInt8],
_ eiBytes: inout UInt64,
_ entropyLong: inout UnsafeMutableRawPointer?) -> mte_status {
// Display a prompt.
print("Enter \(minLength)-\(maxLength) bytes of entropy> ", terminator: "")
// Get a line of input.
let line = readLine()!
// If the input was less than the minimum required, we must return an error.
if line.utf8.count < minLength {
return mte_status_drbg_catastrophic
}
// Set the actual entropy length. It cannot exceed the maximum required.
let buffBytes = eiBytes
eiBytes = min(UInt64(line.utf8.count), maxLength)
// If the length is greater than the length of the provided buffer, we have
// to create our own buffer instead.
if eiBytes > buffBytes {
// Get the entropy input as an array.
let ei = [UInt8](line.utf8)
// If there is previous raw entropy, deallocate it.
if myEntropyRaw != nil {
myEntropyRaw!.deallocate()
}
// Allocate unsafe memory for the entropy.
myEntropyRaw =
UnsafeMutableRawPointer.allocate(byteCount: ei.count, alignment: 16)
// Copy from the entropy array to the unsafe memory.
ei.withUnsafeBytes { buff in
let raw = myEntropyRaw!.assumingMemoryBound(to: UInt8.self)
let ei = buff.bindMemory(to: UInt8.self)
raw.assign(from: ei.baseAddress!, count: ei.count)
}
// Set the raw pointer to point at the unsafe memory.
entropyLong = myEntropyRaw
}
else {
// Copy the entropy to the buffer.
entropyInput.replaceSubrange(Range(uncheckedBounds: (0, Int(eiBytes))),
with: line.utf8.prefix(Int(eiBytes)))
}
// Success.
return mte_status_success
}
func nonceCallback(_ minLength: Int,
_ maxLength: Int,
_ nonce: inout [UInt8],
_ nBytes: inout Int) {
// Display a prompt.
print("Enter the nonce (decimal digits only)> ", terminator: "")
// Get the nonce and ignore the rest of the line.
let u64 = UInt64(readLine()!)!
// Copy the nonce in little-endian format to the nonce buffer.
let nCopied = min(nonce.count, MemoryLayout.size(ofValue: u64))
for i in 0..<nCopied {
nonce[i] = UInt8(UInt64(u64 >> (i * 8)) & 0xFF)
}
// If the minimum length is greater than the size of the nonce we got, fill
// up to that length with zeros.
if nCopied < minLength {
for i in nCopied..<minLength {
nonce[i] = 0
}
nBytes = minLength
}
else {
nBytes = nCopied
}
}
# Create MTE Core Decoder with defaults.
mte_decoder = MteDec.fromdefault()
# Need entropy, nonce and personalization string.
# These values should be unique and entropy must be treated like encryption keys!
# The following personalization string and nonce values are for
# demonstration only and should not be used in a production environment.
personalization_string = "MySecretPersonalizationStringGoesHere"
nonce = 12345678
# *** IMPORTANT NOTE ***
# Entropy is critical to security and should be created and handled like encryption keys.
# To permit decoding of encoded value, Encoder and Decoder must use identical Entropy, Nonce and
# Personalization String as well as Options . See Developer Guides for more information.
# Check how long of entropy we need.
# This example fills entropy with at string of zeros,
# this should NOT be used in a production environment.
entropy_min_bytes = MteBase.get_drbgs_entropy_min_bytes(mte_decoder.get_drbg())
entropy = bytes(entropy_min_bytes)
# Set Decoder entropy and nonce.
mte_decoder.set_entropy(entropy)
mte_decoder.set_nonce(nonce)
# Initialize MTE Decoder.
decoder_status = mte_decoder.instantiate(personalization_string)
if decoder_status != MteStatus.mte_status_success:
# MTE cannot continue so handle failure appropriately.
# Below is an Example.
raise Exception("Failed to initialize the MTE Decoder engine. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
// Create Decoder with default options
mteDecoder := mte.NewDecDef()
defer mteDecoder.Destroy()
// Need entropy, nonce and personalization string
// These values should be unique and entropy must be treated like encryption keys!
// The following personalization string and nonce values are for
// demonstration only and should not be used in a production environment
personalizationString := "MySecretPersonalizationStringGoesHere";
nonce := 12345678;
// *** IMPORTANT NOTE ***
// Entropy is critical to security and should be created and handled like encryption keys.
// To permit decoding of encoded value, Encoder and Decoder must use identical Entropy, Nonce and
// Personalization String as well as Options . See Developer Guides for more information.
entropy_min_bytes = mte_decoder.get_drbgs_entropy_min_bytes(mte_decoder.get_drbg())
entropy = bytes("0" * entropy_min_bytes, 'utf-8')
// Check how long of entropy we need.
// This example fills entropy with at string of zeros
// this should NOT be used in a production environment
entropyBytes := mte.GetDrbgsEntropyMinBytes(mteDecoder.GetDrbg())
entropy := make([]byte, entropyBytes)
// Set entropy and nonce
mteDecoder.SetEntropy(entropy)
mteDecoder.SetNonceInt(nonce)
// Instantiate the Decoder.
decoderStatus := mteDecoder.InstantiateStr(personalizationString)
if status != mte.Status_mte_status_success {
// Handle an error here -- below is a sample
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(decoderStatus), mte.GetStatusDescription(decoderStatus))
return int(decoderStatus)
}
<?php
// Create Decoder with default options
// In practice, you will create a decoder this way, create a custom decoder,
// or create MKE or FLEN decoder. See developer guide for more information
$mteDecoder = new mteDec();
// Need entropy, nonce and personalization string.
// These values should be unique and treated like encryption keys!
// The following personalization string and nonce values are for demonstration purposes
// and should NOT be used in production environments
$personalizationString = "MySecretPersonalizationStringGoesHere";
$nonce = 12345678;
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
$entropyBytes = $mteDecoder->getDrbgEntropyMinBytes(constant($mteDecoder->getDrbg()));
$entropy = "";
$entropy = str_pad($entropy, $entropyBytes);
// Set entropy and nonce
$mteDecoder->setEntropy($entropy);
$mteDecoder->setNonce($nonce);
// Instantiate the Decoder.
$decoded = $mteDecoder->instantiate($personalizationString);
if (constant($decoded["status"])==mte_status_success) {
// Handle an error here -- below is a sample
echo "Decoder instantiate error: ".$mteDecoder->getStatusName(constant($decoded["status"])).":"
.$mteDecoder->getStatusDescription(constant($decoded["status"]));
return $mteDecoder->getStatusCode(constant($decoded["status"]));
}
?>
Decoding string or byte[]
Use the following methods to decode a string or a byte[] to the original value. The samples below display all the options that can be used to decode, only one method needs to be used to decode the data. The developer should select the method that works with the type of data that is used.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
/* There are different functions available to use depending on program needs.
* The versions with b64 in the function name involve base 64 conversion,
* suitable for protocols requiring a string representation.
* Otherwise the default will use raw bytes.
*/
/* Decode the message. */
MTE_SET_DEC_IO(d_args, e_args.encoded, e_args.bytes, decoded);
status = mte_dec_decode_b64(decoder, &d_args);
if (mte_base_status_is_error(status))
{
fprintf(stderr, "Decode error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
else if (status != mte_status_success)
{
fprintf(stderr, "Decode warning (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
}
The timestamp callback.
static MTE_UINT64_T t_cb(void* context)
{
char line[80];
(void)context;
/* Get the timestamp. */
printf("Enter the timestamp (decimal digits only)> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
return strtoul(line, NULL, 10);
}
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
size_t decodedBytes = 0;
// Decode the message.
const void* decoded = decoder.decode(encoded, encodedBytes, decodedBytes, status);
if (MteBase::statusIsError(status))
{
std::cerr << "Decode error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
else if (status != mte_status_success)
{
std::cerr << "Decode warning ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
}
The timestamp callback.
MTE_UINT64_T Cbs::timestampCallback()
{
// Display a prompt.
std::cout << "Enter the timestamp (decimal digits only)> " << std::flush;
// Get the timestamp and ignore the rest of the line.
MTE_UINT64_T u64;
std::cin >> u64;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return u64;
}
// initialize status
MteStatus decoderStatus;
// Below are 4 different examples of how to decode
// ONLY ONE needs to be used!!!
// Decode byte[] to a base64 string
string decodedBytesAsString = mteDecoder.DecodeStr(encodedBytes, out decoderStatus);
if (mteDecoder.StatusIsError(decoderStatus)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
Console.Error.WriteLine("Decode error ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
return (int)status;
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
} else if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decode warning ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
}
// Decode string to a base64 string
string decodedStringAsString = mteDecoder.DecodeStrB64(encodedBase64String, out decoderStatus);
if (mteDecoder.StatusIsError(decoderStatus)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
Console.Error.WriteLine("Decode error ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
return (int)status;
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
} else if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decode warning ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
// Decode byte[] to a byte[]
byte[] decodedBytes = mteDecoder.Decode(encodedBytes, out decoderStatus);
if (mteDecoder.StatusIsError(decoderStatus)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
Console.Error.WriteLine("Decode error ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
return (int)status;
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
} else if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decode warning ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
// Decode string to a byte[]
byte[] decodedStringAsBytes = mteDecoder.DecodeB64(encodedBase64String, out decoderStatus);
if (mteDecoder.StatusIsError(decoderStatus)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
Console.Error.WriteLine("Decode error ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
return (int)status;
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
} else if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decode warning ({0}): {1}",
mteDecoder.GetStatusName(decoderStatus),
mteDecoder.GetStatusDescription(decoderStatus));
// Initiaze status
MteStatus decoderStatus;
// Below are 4 different examples of how to decode
// ONLY ONE needs to be used!!!
// Decode byte[] to a base64 string
MteBase.StrStatus decoded = mteDecoder.decodeStr(encodedBytes);
if (MteBase.statusIsError(decoded.status))
{
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
throw new Exception("Failed to decode. Status: "
+ MteBase.getStatusName(decoded.status)+ " / "
+ MteBase.getStatusDescription(decoded.status));
}
else if (decoded.status != MteStatus.mte_status_success)
{
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
System.err.println("Decode warning ("
+ MteBase.getStatusName(decoded.status) + "): "
+ MteBase.getStatusDescription(decoded.status));
}
String decodedBytesAsString = decoded.str;
// Decode string to a base64 string
MteBase.StrStatus decoded = mteDecoder.decodeStrB64(encodedBase64String);
if (MteBase.statusIsError(decoded.status))
{
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
throw new Exception("Failed to decode. Status: "
+ MteBase.getStatusName(decoded.status)+ " / "
+ MteBase.getStatusDescription(decoded.status));
}
else if (decoded.status != MteStatus.mte_status_success)
{
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
System.err.println("Decode warning ("
+ MteBase.getStatusName(decoded.status) + "): "
+ MteBase.getStatusDescription(decoded.status));
}
String decodedBytesAsString = decoded.str;
// Decode byte[] to a byte[]
MteBase.ArrStatus decoded = mteDecoder.decode(encodedBytes);
if (MteBase.statusIsError(decoded.status))
{
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
throw new Exception("Failed to decode. Status: "
+ MteBase.getStatusName(decoded.status)+ " / "
+ MteBase.getStatusDescription(decoded.status));
}
else if (decoded.status != MteStatus.mte_status_success)
{
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
System.err.println("Decode warning ("
+ MteBase.getStatusName(decoded.status) + "): "
+ MteBase.getStatusDescription(decoded.status));
}
byte[] decodedBytesAsBytes = decoded.arr;
// Decode string to a byte[]
MteBase.ArrStatus decoded = mteDecoder.(encodedBase64String);
if (MteBase.statusIsError(decoded.status))
{
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
throw new Exception("Failed to decode. Status: "
+ MteBase.getStatusName(decoded.status)+ " / "
+ MteBase.getStatusDescription(decoded.status));
}
else if (decoded.status != MteStatus.mte_status_success)
{
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
System.err.println("Decode warning ("
+ MteBase.getStatusName(decoded.status) + "): "
+ MteBase.getStatusDescription(decoded.status));
}
byte[] decodedStringAsBytes = decoded.arr;
// decode string and return as B64 string
const decoderResult = mteDecoder.decodeStrB64(str);
if (mteDecoder.statusIsError(decoderResult.status)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
const status = mteDecoder.getStatusName(decoderResult.status);
const message = mteDecoder.getStatusDescription(decoderResult.status);
throw new Error(`Error when MTE decoding data.\n${status}: ${message}`);
return;
} else if (decoderResult.status != MteStatus.mte_status_success) {
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
alert(
"Decode warning (" +
mteDecoder.getStatusName(decoderResult.status) +
"): " +
mteDecoder.getStatusDescription(decoderResult.status),
);
}
console.log(`Decode result is: ${decoderResult.str}`);
// decode string and return as Uint8Array
const decoderResult = mteDecoder.decoderStr(str);
if (mteDecoder.statusIsError(decoderResult.status)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
const status = mteDecoder.getStatusName(decoderResult.status);
const message = mteDecoder.getStatusDescription(decoderResult.status);
throw new Error(`Error when MTE decoding data.\n${status}: ${message}`);
return;
} else if (decoderResult.status != MteStatus.mte_status_success) {
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
alert(
"Decode warning (" +
mteDecoder.getStatusName(decoderResult.status) +
"): " +
mteDecoder.getStatusDescription(decoderResult.status),
);
}
console.log(`Decode result is: ${decoderResult.arr}`);
// decode Uint8Array and return as b64 string
const decoderResult = mteDecoder.decodeB64(arr);
if (mteDecoder.statusIsError(decoderResult.status)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
const status = mteDecoder.getStatusName(decoderResult.status);
const message = mteDecoder.getStatusDescription(decoderResult.status);
throw new Error(`Error when MTE decoding data.\n${status}: ${message}`);
return;
} else if (decoderResult.status != MteStatus.mte_status_success) {
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
alert(
"Decode warning (" +
mteDecoder.getStatusName(decoderResult.status) +
"): " +
mteDecoder.getStatusDescription(decoderResult.status),
);
}
console.log(`Decode result is: ${decoderResult.str}`);
// decode Uint8Array and return as Uint8Array
const decoderResult = mteDecoder.decode(arr);
if (mteDecoder.statusIsError(decoderResult.status)) {
// Unable to decode, this checks for errors, handle failure appropriately
// Below is only an example
const status = mteDecoder.getStatusName(decoderResult.status);
const message = mteDecoder.getStatusDescription(decoderResult.status);
throw new Error(`Error when MTE decoding data.\n${status}: ${message}`);
return;
} else if (decoderResult.status != MteStatus.mte_status_success) {
// This catches Decoder warnings, the decode process was successful
// But depending on the type of security needed these may be ignored
// Please see Developer Guide for more details.
alert(
"Decode warning (" +
mteDecoder.getStatusName(decoderResult.status) +
"): " +
mteDecoder.getStatusDescription(decoderResult.status),
);
}
console.log(`Decode result is: ${decoderResult.arr}`);
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
// Decode the message.
let decoded = decoder.decode(Array(encodedRes.encoded))
status = decoded.status
if (MteBase.statusIsError(status)) {
print("Decode error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
} else if (status != mte_status_success) {
print("Decode warning (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
}
The timestamp callback.
func timestampCallback() -> UInt64 {
// Display a prompt.
print("Enter the timestamp (decimal digits only)> ", terminator: "")
// Get the timestamp and ignore the rest of the line.
return UInt64(readLine()!)!
}
# Below are 4 different examples of how to decode.
# ONLY ONE needs to be used.
# Decode byte[] to a base64 string.
(decoded_bytes_as_string, decoder_status) = mte_decoder.decode_str(encoded_bytes)
if MteBase.status_is_error(decoder_status):
# Handle decode failure appropriately.
# Below is only an example.
raise Exception("Failed to decode. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
elif decoder_status != MteStatus.mte_status_success:
# This catches Decoder warnings, the decode process was successful
# But depending on the type of security needed these may be ignored
# Please see Developer Guide for more details.
print("Decode warning ({0}): {1}".format(
MteBase.get_status_name(status),
MteBase.get_status_description(status)),
file=sys.stderr)
# Decode string to a base64 string.
(decoded_string_as_string, decoder_status) = mte_decoder.decode_str_b64(encoded_base64_string)
if MteBase.status_is_error(decoder_status):
# Handle decode failure appropriately.
# Below is only an example.
raise Exception("Failed to decode. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
elif decoder_status != MteStatus.mte_status_success:
# This catches Decoder warnings, the decode process was successful
# But depending on the type of security needed these may be ignored
# Please see Developer Guide for more details.
print("Decode warning ({0}): {1}".format(
MteBase.get_status_name(status),
MteBase.get_status_description(status)),
file=sys.stderr)
# Decode byte[] to a byte[].
(decoded_bytes, decoder_status) = mte_decoder.decode(encoded_bytes)
if MteBase.status_is_error(decoder_status):
# Handle decode failure appropriately.
# Below is only an example.
raise Exception("Failed to decode. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
elif decoder_status != MteStatus.mte_status_success:
# This catches Decoder warnings, the decode process was successful
# But depending on the type of security needed these may be ignored
# Please see Developer Guide for more details.
print("Decode warning ({0}): {1}".format(
MteBase.get_status_name(status),
MteBase.get_status_description(status)),
file=sys.stderr)
# Decode string to a byte[].
(decoded_string_as_bytes, decoder_status) = mte_decoder.decode_b64(encoded_base64_string)
if MteBase.status_is_error(decoder_status):
# Handle decode failure appropriately.
# Below is only an example.
raise Exception("Failed to decode. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
elif decoder_status != MteStatus.mte_status_success:
# This catches Decoder warnings, the decode process was successful
# But depending on the type of security needed these may be ignored
# Please see Developer Guide for more details.
print("Decode warning ({0}): {1}".format(
MteBase.get_status_name(status),
MteBase.get_status_description(status)),
file=sys.stderr)
// initialize status
var decoderStatus mte.Status
// Below are 4 different examples of how to decode
// ONLY ONE needs to be used!!!
// decode byte[] to base64 string
decodedBytesAsString, decodedStatus := mteDecoder.DecodeStr(encodedBytes)
if mte.StatusIsError(decodedStatus) {
// Handle error correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode error (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
return int(status)
} else if decodedStatus != mte.Status_mte_status_success {
// Handle warning correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode warning (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
}
// decode string to base64 string
decodedStringAsString, decodedStatus := mteDecoder.DecodeStrB64(encodedString)
if mte.StatusIsError(decodedStatus) {
// Handle error correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode error (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
return int(status)
} else if decodedStatus != mte.Status_mte_status_success {
// Handle warning correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode warning (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
}
// decode bytes to byte
decodedBytes, decodedStatus := mteDecoder.Decode(encodedBytes)
if mte.StatusIsError(decodedStatus) {
// Handle error correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode error (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
return int(status)
} else if decodedStatus != mte.Status_mte_status_success {
// Handle warning correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode warning (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
}
// decode string to bytes
decodedBytes, decodedStatus := mteDecoder.DecodeB64(encodedString)
if mte.StatusIsError(decodedStatus) {
// Handle error correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode error (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
return int(status)
} else if decodedStatus != mte.Status_mte_status_success {
// Handle warning correctly
// Below is an example
fmt.Fprintf(os.Stderr, "Decode warning (%v): %v\n",
mte.GetStatusName(decodedStatus), mte.GetStatusDescription(decodedStatus))
}
<?php
// Decode String to String
$decoded = $mteDecoder->decode($encoded["str"]);
// Check the status
if (constant($decoded["status"])!=mte_status_success){
// Handle an error here -- below is a sample
throw new Exception("Decoder decode error: "
.$mteDecoder->getStatusName(constant($decoded["status"])).":"
.$mteDecoder->getStatusDescription(constant($decoded["status"])));
}
?>
<?php
// Decode Base64 string to string
$decoded = $mteDecoder->decodeB64($encoded["str"]);
// Check the status
if (constant($decoded["status"])!=mte_status_success){
// Handle an error here -- below is a sample
throw new Exception("Decoder decode error: "
.$mteDecoder->getStatusName(constant($decoded["status"])).":"
.$mteDecoder->getStatusDescription(constant($decoded["status"])));
}
?>
Decoder State
The decoder state can be saved and restored with either byte[] or a base64 string using the following methods. Below are several examples of how to use it, based on your data type you only need to use one of the following examples.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
Save state.
/* There are different functions available to use depending on program needs.
* The versions with b64 in the function name involve base 64 conversion,
* suitable for protocols requiring a string representation.
* Otherwise the default will use raw bytes.
*/
/* Save the decoder state. */
/* Saved state. */
MTE_UINT8_T* d_saved = MTE_ALLOCA(mte_dec_save_bytes(decoder));
status = mte_dec_state_save(decoder, d_saved);
if (status != mte_status_success)
{
fputs("Decoder state save error.", stderr);
return mte_status_unsupported;
}
Restore state.
/* Restore the decoder state. */
status = mte_dec_state_restore(decoder, d_saved);
if (status != mte_status_success)
{
fprintf(stderr, "Decoder state restore error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
Save state.
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
// Save the decoder state.
size_t dSavedBytes = 0;
const void* dsaved = decoder.saveState(dSavedBytes);
if (dsaved == NULL)
{
std::cerr << "Decoder state save error." << std::endl;
return mte_status_unsupported;
}
Restore state.
// Restore the decoder state.
status = decoder.restoreState(dsaved);
if (status != mte_status_success)
{
std::cerr << "Decoder state restore error." << std::endl;
return status;
}
// Save and restore Decoder state with bytes
// Get byte[] of decoder state
byte[] decoderByteState = mteDecoder.SaveState();
// Restore Decoder with byte[] state
MteStatus decoderStatus = mteDecoder.RestoreState(decoderByteState);
if(decoderStatus != MteStatus.mte_status_success)
{
// Decoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore Decoder state. Status: "
+ mteDecoder.GetStatusName(decoderStatus)+ " / "
+ mteDecoder.GetStatusDescription(decoderStatus));
}
// save and restore Decoder state with string
// Get string of Decoder state
string decoderStrState = mteDecoder.SaveStateB64();
// Restore Decoder with string state
MteStatus decoderStatus = mteDecoder.RestoreStateB64(decoderStrState);
if(decoderStatus != MteStatus.mte_status_success)
{
// Decoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore Decoder state. Status: "
+ mteDecoder.GetStatusName(decoderStrStatus)+ " / "
+ mteDecoder.GetStatusDescription(decoderStrStatus));
}
// Save and restore Decoder state with bytes
// Get byte[] of decoder state
byte[] decoderByteState = mteDecoder.saveState();
// Restore Decoder with byte[] state
MteStatus decoderStatus = mteDecoder.restoreState(decoderByteState);
if(decoderStatus != MteStatus.mte_status_success)
{
// Decoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore Decoder state. Status: "
+ MteBase.getStatusName(decoderStatus)+ " / "
+ MteBase.getStatusDescription(decoderStatus));
}
// save and restore Decoder state with string
// Get string of decoder state
string decoderStrState = mteDecoder.saveStateB64();
// Restore Decoder with string state
MteStatus decoderStatus = mteDecoder.restoreStateB64(decoderStrState);
if(decoderStatus != MteStatus.mte_status_success)
{
// Decoder restore failed, handle appropriately
// Below is only an example
throw new Exception("Failed to restore Decoder state. Status: "
+ MteBase.getStatusName(decoderStrStatus)+ " / "
+ MteBase.getStatusDescription(decoderStrStatus));
}
// save Decoder state as Uint8Array
let state = mteDecoder.saveState();
// restore Decoder from Uint8Array
mteDecoder.restoreState(state);
// save Decoder state as Base64 String
const state = mteDecoder.saveStateB64();
// restore Decoder from Base64 state
mteDecoder.restoreStateB64(state);
// There are different functions available to use depending on program needs.
// The versions with b64 in the function name involve base 64 conversion,
// suitable for protocols requiring a string representation.
// Otherwise the default will use raw bytes.
// Save the decoder state.
let dsaved = decoder.saveState()
if dsaved == nil {
print("Decoder state save error.")
return Int32(mte_status_unsupported.rawValue)
}
# Save and restore Decoder state with bytes.
decoder_byte_state = mte_decoder.save_state()
# Restore Decoder with byte[] state.
decoder_status = mte_decoder.restore_state(decoder_byte_state)
if decoder_status != MteStatus.mte_status_success:
# Mte cannot continue, handle restore failure appropriately.
# Below is only an example.
raise Exception("Failed to restore Decoder state. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
# Save and restore Decoder state with string.
# Get string of Decoder state.
decoder_str_state = mte_decoder.save_state_b64()
# Restore Decoder with string state.
decoder_status = mte_decoder.restore_state_b64(decoder_str_state)
if decoder_status != MteStatus.mte_status_success:
# Mte cannot continue, handle restore failure appropriately.
# Below is only an example.
raise Exception("Failed to restore Decoder state. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
// Save and restore Decoder state with bytes
// Get byte[] of decoder state
decoderByteState := mteDecoder.SaveState()
decoderStatus := mteDecoder.RestoreState(decoderByteState);
if(decoderStatus != mte.Status_mte_status_success){
// Handle Decoder restore failure appropriately
// Below is only an example
fmt.Fprintf(os.Stderr, "Restore Decoder state error (%v): %v\n",
mte.GetStatusName(decoderStatus), mte.GetStatusDescription(decoderStatus))
return int(decoderStatus)
}
// Save and restore Decoder state with bytes
// Get byte[] of decoder state
decoderStrState := mteDecoder.SaveStateB64()
decoderStatus := mteDecoder.RestoreStateB64(decoderStrState);
if(decoderStatus != mte.Status_mte_status_success){
// Handle Decoder restore failure appropriately
// Below is only an example
fmt.Fprintf(os.Stderr, "Restore Decoder state error (%v): %v\n",
mte.GetStatusName(decoderStatus), mte.GetStatusDescription(decoderStatus))
return int(decoderStatus)
}
<?php
$decoderStrState = $mteDecoder->saveState();
$restoreStatus = $mteDecoder->restoreState($decoderStrState);
if (constant($restoreStatus)!=mte_status_success){
// Handle an error here -- below is a sample
echo "Decoder restore state error: "
.$mteDecoder->getStatusName(constant($restoreStatus)).":"
.$mteDecoder->getStatusDescription(constant($restoreStatus));
return $mteDecoder->getStatusCode(constant($restoreStatus));
}
?>
<?php
$decoderB64State = $mteDecoder->saveStateB64();
$restoreStatus = $mteDecoder->restoreStateB64($decoderB64State);
if (constant($restoreStatus)!=mte_status_success){
// Handle an error here -- below is a sample
echo "Decoder restore base64 state error: "
.$mteDecoder->getStatusName(constant($restoreStatus)).":"
.$mteDecoder->getStatusDescription(constant($restoreStatus));
return $mteDecoder->getStatusCode(constant($restoreStatus));
}
?>
Additional options for Decoder State
The Core MTE decoder state and the MTE MKE decoder state are interchangeable. This means, the decoder state can be restored to a MTE Core OR an MTE MKE. The MTE used should be created using the same options for this to work correctly. The security of the MTE Core can be used for a password then the MTE MKE can be used on larger data in the same application without having to create multiple instances of the MTE.
Reseeding Interval
There are a limited amount of random numbers a DRBG can produce before it must be reseeded. This is called the reseed interval. The DRBG will stop functioning in order to protect the security of the application. When the MTE reaches it's reseed interval the MTE will return a status of "mte_status_drbg_seedlife_reached".
The developer can use the reseed count and the reseed interval to determine if the seed life is ending. We recommend reseeding the MTE before the seed life ends in order to prevent the loss of any data. Reseeding the MTE can be done by re-initializing the MTE with a new entropy value and new nonce. Both sides, the Encoder and Decoder, must be re-initialized at the same time to stay in sync.
The example below checks for 90% usage before re-initializing. For DRBGs with large reseed interval, 90% is a good number. To determine a good percentage the size of the data transmission should be used. For small data transmissions a value much closer to 100% can be used; for larger data transmissions or smaller reseed intervals, a smaller percentage should be used to ensure the end of the seed life is not hit.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Go
- PHP
// Get the Decoder DRBG reseed counter.
// This is the MTE's current seed count.
uint64_t current_seed = mte_dec_reseed_counter(decoder);
// Get the Decoder DRBG max reseed interval.
uint64_t max_seed = mte_base_drbgs_reseed_interval(MTE_DRBG_ENUM);
// For example, if the current seed is greater than 90% of the max seed,
// uninstantiate the MTE then Reinitialize the MTE.
// with a new entropy and nonce to reseed.
if (current_seed > (max_seed * 0.9))
{
// Uninstantiate the Decoder.
mte_status decoder_status = mte_dec_uninstantiate(decoder);
if (decoder_status != mte_status_success)
{
fprintf(stderr, "Failed to uninstantiate Decoder (%s): %s\n",
mte_base_status_name(decoder_status),
mte_base_status_description(decoder_status));
return decoder_status;
}
// Now the Decoder and matching Encoder must be re-paired with a new entropy and nonce.
//=============================================================
// TODO: Developer adds code to re-pair with entropy and nonce.
//=============================================================
}
// Get the Decoder DRBG reseed counter.
// This is the MTE's current seed count.
uint64_t currentSeed = decoder.getReseedCounter();
// Get the Decoder DRBG max reseed interval.
uint64_t maxSeed = MteBase::getDrbgsReseedInterval(MTE_DRBG_ENUM);
// For example, if the current seed is greater than 90% of the max seed,
// uninstantiate the MTE then Reinitialize the MTE.
// with a new entropy and nonce to reseed.
if (currentSeed > (maxSeed * 0.9))
{
// Uninstantiate the Decoder.
mte_status decoderStatus = decoder.uninstantiate();
if (decoderStatus != mte_status_success)
{
std::cerr << "Decoder uninstantiate error ("
<< MteBase::getStatusName(decoderStatus)
<< "): "
<< MteBase::getStatusDescription(decoderStatus)
<< std::endl;
return decoderStatus;
}
// Now the Decoder and matching Encoder must be re-paired with a new entropy and nonce.
//=============================================================
// TODO: Developer adds code to re-pair with entropy and nonce.
//=============================================================
}
//--------------------------------------
// Get the Decoder DRBG reseed counter
// This is the MTE's current seed count
ulong currentSeed = mteDecoder.GetReseedCounter();
//------------------------------------------
// Get the Decoder DRBG max reseed interval
ulong maxSeed = mteBase.GetDrbgsReseedInterval(mteDecoder.GetDrbg());
//---------------------------------------------------------
// If the current seed is greater than 90% of the max seed
// Uninstantiate the MTE then Reinitialize the MTE
// with a new entropy and nonce to reseed
if (currentSeed > (maxSeed * 0.9)) {
//---------------------------
// Uninstantiate the Decoder
MteStatus decoderStatus = mteDecoder.Uninstantiate();
if(decoderStatus != MteStatus.mte_status_success) {
//-------------------------------------------------
// MTE was not uninstantiated as desired so handle
// failure appropriately, below is only an example
throw new Exception("Failed to uninstantiate Decoder. Status: "
+ mteDecoder.GetStatusName(decoderStatus)+ " / "
+ mteDecoder.GetStatusDescription(decoderStatus));
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
HandshakeModel handshake = MethodToHandshake();
//-------------------------------
// Set Decoder entropy and nonce
mteDecoder.SetEntropy(Encoding.UTF8.GetBytes(handshake.NewEncoderEntropy));
mteDecoder.SetNonce(handshake.NewNonce);
//------------------------
// Initialize MTE Decoder
MteStatus decoderStatus = mteDecoder.Instantiate(personalizationString);
if(decoderStatus !=MteStatus.mte_status_success) {
//-----------------------------------------------------
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new ApplicationException($"Failed to initialize the MTE Decoder engine." +
$"Status: {mteDecoder.GetStatusName(decoderStatus)} / " +
$"{mteDecoder.GetStatusDescription(decoderStatus)}");
}
}
//--------------------------------------
// Get the Decoder DRBG reseed counter
// This is the MTE's current seed count
long currentSeed = mteDecoder.getReseedCounter();
//------------------------------------------
// Get the Decoder DRBG max reseed interval
long maxSeed = MteBase.getDrbgsReseedInterval(mteDecoder.getDrbg());
//---------------------------------------------------------
// If the current seed is greater than 90% of the max seed
// Uninstantiate the MTE then Reinitialize the MTE
// with a new entropy and nonce to reseed
if(currentSeed > (_maxSeed * .9)) {
// Uninstantiate the Decoder
MteStatus decoderStatus = mkeDecoder.uninstantiate();
if(decoderStatus != MteStatus.mte_status_success) {
// MTE was not uninstantiated as desired so handle failure appropriately
// Below is only an example
throw new Exception("Failed to uninstantiate Decoder. Status: "
+ MteBase.getStatusName(decoderStatus)+ " / "
+ MteBase.getStatusDescription(decoderStatus));
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
HandshakeResponse handshake = MethodToHandshake();
//-------------------------------
// Set Encoder entropy and nonce
mteDecoder.setEntropy(handshake.NewEncoderEntropy.getBytes()));
mteDecoder.setNonce(handshake.NewNonce);
//------------------------
// Initialize MTE Encoder
MteStatus decoderStatus = mteDecoder.instantiate(personalizationString);
if(decoderStatus !=MteStatus.mte_status_success) {
//-----------------------------------------------------
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new Exception("Error creating Decoder: Status: "
+ MteBase.getStatusName(decoderStatus) + " / "
+ MteBase.getStatusDescription(decoderStatus);
}
}
JavaScript works a little differently than other languages due to having to use a different type once it reaches 16 digits. You can get more info on BigInts on MDN. Because of this, we specifically cast to Number, only grab 15 digits of precision, and reseed at 80% of the max seed instead of 90%.
//--------------------------------------
// Get the Decoder DRBG reseed counter
// This is the MTE's current seed count
const currentSeed = Number(
String(mteDecoder.getReseedCounter()).substring(0, 15),
);
//------------------------------------------
// Get the Decoder DRBG max reseed interval
const maxSeed = Number(
String(mteDecoder.getDrbgsReseedInterval(drbg)).substring(0, 15),
);
//---------------------------------------------------------
// If the current seed is greater than 90% of the max seed
// Uninstantiate the MTE then Reinitialize the MTE
// with a new entropy and nonce to reseed
if (currentSeed > maxSeed * 0.8) {
//---------------------------
// Uninstantiate the Decoder
const decoderStatus = mteDecoder.uninstantiate();
if (decoderStatus !== MteStatus.mte_status_success) {
//-------------------------------------------------
// MTE was not uninstantiated as desired so handle
// failure appropriately, below is only an example
throw new Error(
`Failed to uninstantiate Decoder. ` +
`Status: ${mteDecoder.getStatusName(decoderStatus)} ` +
`/ ${mteDecoder.getStatusDescription(decoderStatus)}`,
);
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
const handshake = methodToHandshake();
//-------------------------------
// Set Decoder entropy and nonce
mteDecoder.setEntropy(handshake.newEncoderEntropy);
mteDecoder.setNonce(handshake.newNonce);
//------------------------
// Initialize MTE Decoder
const decoderStatus = mteDecoder.instantiate(personalizationString);
if (decoderStatus !== MteStatus.mte_status_success) {
//-----------------------------------------------------
// MTE cannot continue so handle failure appropriately
// Below is just an example
throw new Error(
`Failed to initialize the MTE Decoder engine.` +
`Status: ${mteDecoder.getStatusName(decoderStatus)} / ` +
`${mteDecoder.getStatusDescription(decoderStatus)}`,
);
}
}
// Get the Decoder DRBG reseed counter.
// This is the MTE's current seed count.
let currentSeed:UInt64 = decoder.getReseedCounter()
// Get the Decoder DRBG max reseed interval.
let maxSeed:UInt64 = MteBase.getDrbgsReseedInterval(decoder.getDrbg())
// For example, if the current seed is greater than 90% of the max seed,
// uninstantiate the MTE then Reinitialize the MTE.
// with a new entropy and nonce to reseed.
if (currentSeed > (maxSeed * UInt64(0.9))) {
// Uninstantiate the Decoder.
let decoderStatus:mte_status = decoder.uninstantiate()
if (decoderStatus != mte_status_success) {
print("Decoder uninstantiate error (\(MteBase.getStatusName(decoderStatus))): " +
MteBase.getStatusDescription(decoderStatus))
return Int32(decoderStatus.rawValue)
}
// Now the Decoder and matching Encoder must be re-paired with a new entropy and nonce.
//=============================================================
// TODO: Developer adds code to re-pair with entropy and nonce.
//=============================================================
}
//--------------------------------------
// Get the Decoder DRBG reseed counter
// This is the MTE's current seed count
currentSeed := mteDecoder.getReseedCounter()
//------------------------------------------
// Get the Decoder DRBG max reseed interval
maxSeed := mteDecoder.getDrbgReseedInterval(mteDecoder.getDrbg())
if currentSeed > (maxSeed * .9) {
// Uninstantiate the Decoder
decoderStatus := mteDecoder.Uninstantiate()
if decoderStatus != mte.Status_mte_status_success {
// Handle Decoder uninstantiate failure appropriately
// Below is only an example
fmt.Fprintf(os.Stderr, "Decoder uninstantiate error (%v): %v\n",
mte.GetStatusName(decoderStatus),
mte.GetStatusDescription(decoderStatus))
return int(decoderStatus)
}
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
handshake := MethodToHandshake();
//--------------------
// Initialize Decoder
//--------------------
mteDecoder.SetEntropy(handshake.newDecoderEntropy)
mteDecoder.SetNonceInt(handshake.newNonce)
decoderStatus := mteDecoder.InstantiateStr(personalizationString)
if decoderStatus != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(decoderStatus),
mte.GetStatusDescription(decoderStatus))
return (int)decoderStatus
}
}
<?php
//--------------------------------------
// Get the Decoder DRBG reseed counter
// This is the MTE's current seed count
$currentSeed = $mteDecoder->getReseedCounter();
//------------------------------------------
// Get the Decoder DRBG max reseed interval
$maxSeed = $mteDecoder->getDrbgReseedInterval(constant($mteDecoder->getDrbg()));
if ($currentSeed > ($maxSeed * .9)) {
//---------------------------
// Uninstantiate the Decoder
$decoderStatus = $mteDecoder->uninstantiate();
if (constant($decoderStatus) != mte_status_success) {
//----------------------------------------------------
// Handle Decoder uninstantiate failure appropriately
// Below is only an example
echo "Decoder uninstantiate error: "
.$mteDecoder->getStatusName(constant($decoderStatus)).":"
.$mteDecoder->getStatusDescription(constant($decoderStatus));
return $mteDecoder->getStatusCode(constant($decoderStatus));
}
unset($mteDecoder);
//---------------------------------------
// Re-handshake to get new entropy value
// AND new nonce value
// Full code sample not here, to see example
// please see Diffie-Hellman Key Exchange
$handshake = MethodToHandshake();
//--------------------
// Initialize Decoder
//--------------------
$mteDecoder = new MteDec();
$mteDecoder->setEntropy($handshake["newEncoderEntropy"]);
$mteDecoder->setNonce($handshake["newNonce"]);
$decoderStatus = $mteDecoder->instantiate($personalizationString);
if (constant($decoderStatus) != mte_status_success) {
//----------------------------------------------------
// Handle Decoder instantiate failure appropriately
// Below is only an example
echo "Decoder instantiate error: "
.$mteDecoder->getStatusName(constant($decoderStatus)).":"
.$mteDecoder->getStatusDescription(constant($decoderStatus));
return $mteDecoder->getStatusCode(constant($decoderStatus));
}
}
?>
Get Timestamps from Decoder
After an MTE packet has been sent, the MTE decoder has the encoded timestamp value as well as the decoded timestamp value. They can be retrieved using the following code:
- C
- C++
- CSharp
- Java
- Swift
- Python
- Go
- PHP
// Get the Encode timestamp.
uint64_t encoder_ts = d_args.enc_ts;
// Get the Decode timestamp.
uint64_t decoder_ts = d_args.dec_ts;
// Get the Encode timestamp.
uint64_t encoderTs = decoder.getEncTs();
// Get the Decode timestamp.
uint64_t decoderTs = decoder.getDecTs();
// Get the Encode timestamp
ulong encoderTs = mteDecoder.GetEncTs();
// Get the Decode timestamp
ulong decoderTs = mteDecoder.GetDecTs();
// Get the Encode timestamp
long encoderTs = mteDecoder.getEncTs();
// Get the Decode timestamp
long decoderTs = mteDecoder.getDecTs();
// Get the Encode timestamp.
let encoderTs: UInt64 = decoder.getEncTs()
// Get the Decode timestamp.
let decoderTs: UInt64 = decoder.getDecTs()
# Get the Encode timestamp.
encoder_ts = mte_decoder.get_enc_ts()
# Get the Decode timestamp.
decoder_ts = mte_decoder.get_dec_ts()
// Get the Encode timestamp
encoderTs := mteDecoder.GetEncTs()
// Get the Decode timestamp
decoderTs := mteDecoder.GetDecTs()
<?php
// Get the Encode timestamp
$encoderTs = $mteDecoder->getEncTs();
?>
<?php
// Get the Decode timestamp
$decoderTs = $mteDecoder->getDecTs();
?>
Get Messages Skipped from Decoder
After an MTE packet has been sent, the MTE decoder has the number of messages that were skipped. This can be retrieved using the following code:
- C
- C++
- Swift
// Get the number of messages skipped.
uint32_t decoder_msg_skipped = d_args.msg_skipped;
// Get the number of messages skipped.
uint32_t decoderMsgSkipped = decoder.getMsgSkipped();
// Get the number of messages skipped.
let decoderMsgSkipped: UInt32 = decoder.getMsgSkipped()
Uninstantiate Decoder
Uninstantiate decoder, this will zeroize the DRBG state and returns the status.
- C
- C++
- CSharp
- Java
- JavaScript
- Swift
- Python
- Go
- PHP
status = mte_dec_uninstantiate(decoder);
if (status != mte_status_success)
{
fprintf(stderr, "Failed to uninstantiate decoder (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
status = decoder.uninstantiate();
if (status != mte_status_success)
{
std::cerr << "Decoder uninstantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Uninstantiate the Decoder
MteStatus decoderStatus = mteDecoder.Uninstantiate();
if(decoderStatus != MteStatus.mte_status_success)
{
// MTE was not uninstantiated as desired so handle failure appropriately
// Below is only an example
throw new Exception("Failed to uninstantiate Decoder. Status: "
+ mteDecoder.GetStatusName(decoderStatus)+ " / "
+ mteDecoder.GetStatusDescription(decoderStatus));
}
// Uninstantiate the Decoder
MteStatus decoderStatus = mteDecoder.uninstantiate();
if(decoderStatus != MteStatus.mte_status_success)
{
// MTE was not uninstantiated as desired so handle failure appropriately
// Below is only an example
throw new Exception("Failed to uninstantiate Decoder. Status: "
+ MteBase.getStatusName(decoderStatus)+ " / "
+ MteBase.getStatusDescription(decoderStatus));
}
// Uninstantiate the Decoder
mteDecoder.uninstantiate();
// free WASM memory
mteDecoder.destroy();
// Uninstantiate the Decoder
let status: mte_status = decoder.uninstantiate()
if status != mte_status_success {
// MTE was not uninstantiated as desired so handle failure appropriately
print("Decoder Uninstantiate error: \(MteBase.getStatusName(status))." +
"Description: \(MteBase.getStatusDescription(status))"
}
# Uninstantiate the Decoder.
decoder_status = mte_decoder.uninstantiate()
if decoder_status != MteStatus.mte_status_success:
# MTE was not uninstantiated as desired so handle failure appropriately.
# Below is only an example.
raise Exception("Failed to uninstantiate Decoder. Status: {0} / {1}\n".format(MteBase.get_status_name(decoder_status),
MteBase.get_status_description(decoder_status)))
// Uninstantiate the Decoder
decoderStatus := mteDecoder.Uninstantiate();
if(decoderStatus != mte.Status_mte_status_success){
// Handle Decoder uninstantiate failure appropriately
// Below is only an example
fmt.Fprintf(os.Stderr, "Decoder uninstantiate error (%v): %v\n",
mte.GetStatusName(decoderStatus), mte.GetStatusDescription(decoderStatus))
return int(decoderStatus)
}
<?php
// Uninstantiate the Decoder
$decoderStatus = $mteDecoder->uninstantiate();
if (constant($decoderStatus) != mte_status_success) {
//----------------------------------------------------
// Handle Decoder uninstantiate failure appropriately
// Below is only an example
echo "Decoder uninstantiate error: "
.$mteDecoder->getStatusName(constant($decoderStatus)).":"
.$mteDecoder->getStatusDescription(constant($decoderStatus));
return $mteDecoder->getStatusCode(constant($decoderStatus));
}
// Clear out $mteDecoder variable
unset($mteDecoder);
?>