MTE Managed Key Encryption Add-On Code Samples
Purpose
Samples expand on our "Examples" by providing longer snippets of code demonstrating the entire processes. The objective of an MTE Managed Key Encryption Add-On "Samples" is to provide full samples of code of how to use the MTE Managed Key Encryption Encoder Add-On and MTE Managed Key Encryption Decoder Add-On.
The Managed Key Encryption (MKE) Add-On replaces the core encoder and decoder, which only do tokenization, with an encoder and decoder that combine standard encryption with tokenization. This allows much larger data to take advantage of the MTE technology without significantly increasing the data size.
In this example an input message is being encoded and decoded within a single program but in actual implementations the encoder and decoder would be on separate endpoints. By having both the Encoder and Decoder within one application it allows for the simplest working demonstration for interacting with the MTE. For more information, please see the official MTE developer guides.
MTE Managed Key Encryption (MKE)
MTE MKE Encode and Decode
This sample simply prompts for input and other MKE settings then encodes and then decodes the input using the settings that were selected.
- C
- C++
- CSharp
- Java
- Swift
- ObjC
- Python
- Go
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Callbacks. */
static mte_status ei_cb(void *, mte_drbg_ei_info *info);
static void n_cb(void *, mte_drbg_nonce_info *info);
static MTE_UINT64_T t_cb(void *context);
int main(int argc, char **argv)
{
int exitCode;
char input[128];
char personal[128];
MTE_SIZE_T input_bytes;
#if MTE_RUNTIME
MTE_SIZE_T i;
char line[80];
#endif
/* Status. */
mte_status status;
/* Options. */
mte_mke_enc_init_info e_info = MTE_MKE_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_mke_dec_init_info d_info = MTE_MKE_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_drbg_inst_info i_info = { &ei_cb, NULL, &n_cb, NULL, personal, 0 };
/* Encoder. */
char *encoded;
MTE_HANDLE encoder;
mte_enc_args e_args = MTE_ENC_ARGS_INIT(NULL, 0, NULL, &t_cb, NULL);
/* Decoder. */
char *decoded;
MTE_HANDLE decoder;
mte_dec_args d_args = MTE_DEC_ARGS_INIT(NULL, 0, NULL, &t_cb, NULL);
/* Licensing. */
const char *company;
const char *license;
/* Suppress unused args. */
(void)argc;
(void)argv;
/* Initialize MTE. */
if (!mte_init(NULL, NULL))
{
fputs("MTE init error.", stderr);
return -1;
}
/* Initialize MTE license. If a license code is not required (e.g., trial
mode), this can be skipped. This demo attempts to load the license info
from the environment if required. */
if (!mte_license_init("YOUR_COMPANY", "YOUR_LICENSE"))
{
company = getenv("MTE_COMPANY");
license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
!mte_license_init(company, license))
{
fprintf(stderr, "License init error (%s): %s\n",
mte_base_status_name(mte_status_license_error),
mte_base_status_description(mte_status_license_error));
return mte_status_license_error;
}
}
/* Get the input data. */
printf("Enter the data to encode> ");
fflush(stdout);
(void)!fgets(input, sizeof(input), stdin);
input[strlen(input) - 1] = '\0';
input_bytes = (MTE_SIZE_T)strlen(input);
/* Get the personalization string. */
printf("Enter the personalization> ");
fflush(stdout);
(void)!fgets(personal, sizeof(personal), stdin);
personal[strlen(personal) - 1] = '\0';
i_info.ps_bytes = (MTE_SIZE_T)strlen(personal);
/* Prompt for the options if this build has runtime options. */
#if MTE_RUNTIME
/* Get the DRBG. */
printf("DRBGs:");
for (i = 1; i < mte_base_drbgs_count(); ++i)
{
printf(" %s", mte_base_drbgs_name((mte_drbgs)i));
}
printf("\nEnter the DRBG> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
line[strlen(line) - 1] = '\0';
e_info.enc_params.drbg = d_info.dec_params.drbg = mte_base_drbgs_algo(line);
/* Get the token size. */
printf("Enter the token size in bytes> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
e_info.enc_params.tok_bytes = d_info.dec_params.tok_bytes =
(MTE_SIZE8_T)strtoul(line, NULL, 10);
/* Get the verifiers. */
printf("Verifiers:");
for (i = 0; i < mte_base_verifiers_count(); ++i)
{
printf(" %s", mte_base_verifiers_name((mte_verifiers)i));
}
printf("\nEnter the verifiers> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
line[strlen(line) - 1] = '\0';
e_info.enc_params.verifiers = d_info.dec_params.verifiers =
mte_base_verifiers_algo(line);
/* Get the cipher. */
printf("Ciphers:");
for (i = 1; i < mte_base_ciphers_count(); ++i)
{
printf(" %s", mte_base_ciphers_name((mte_ciphers)i));
}
printf("\nEnter the cipher> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
line[strlen(line) - 1] = '\0';
e_info.cipher = d_info.cipher = mte_base_ciphers_algo(line);
/* Get the hash. */
printf("Hashes:");
for (i = 1; i < mte_base_hashes_count(); ++i)
{
printf(" %s", mte_base_hashes_name((mte_hashes)i));
}
printf("\nEnter the hash> ");
fflush(stdout);
(void)!fgets(line, sizeof(line), stdin);
line[strlen(line) - 1] = '\0';
e_info.hash = d_info.hash = mte_base_hashes_algo(line);
#endif
/* Create the encoder. */
encoder = MTE_ALLOCA(mte_mke_enc_state_bytes(&e_info));
status = mte_mke_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_mke_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;
}
/* Allocate the buffer for encoding. */
encoded = MTE_ALLOCA(mte_mke_enc_buff_bytes_b64(encoder, input_bytes));
/* Encode the message. */
MTE_SET_ENC_IO(e_args, input, input_bytes, encoded);
status = mte_mke_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;
}
/* Display the encoded message. */
printf("Base64 message: %s\n", (const char *)e_args.encoded);
/* Create the decoder. */
decoder = MTE_ALLOCA(mte_mke_dec_state_bytes(&d_info));
status = mte_mke_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_mke_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;
}
/* Allocate the buffer for decoding. */
decoded = MTE_ALLOCA(mte_mke_dec_buff_bytes_b64(decoder, e_args.bytes));
/* Decode the message. */
MTE_SET_DEC_IO(d_args, e_args.encoded, e_args.bytes, decoded);
status = mte_mke_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));
}
/* Output the decoded data. */
printf("Decoded data: %s\n", (const char *)d_args.decoded);
/* Compare the decoded data against the original data. */
if (memcmp(d_args.decoded, input, input_bytes) == 0)
{
exitCode = 0;
puts("The original data and decoded data match.");
}
else
{
exitCode = -1;
puts("The original data and decoded data DO NOT match.");
}
/* Success. */
mte_mke_enc_uninstantiate(encoder);
mte_mke_dec_uninstantiate(decoder);
return exitCode;
}
static mte_status ei_cb(void *context, mte_drbg_ei_info *info)
{
/* Create all-zero entropy for this demo. This should never be done in real
applications. */
(void)context;
info->bytes = info->min_length;
memset(info->buff, 0, info->min_length);
return mte_status_success;
}
static void n_cb(void *context, mte_drbg_nonce_info *info)
{
/* Create all-zero nonce for this demo. This should never be done in real
applications. */
(void)context;
info->bytes = info->min_length;
memset(info->buff, 0, info->min_length);
}
static MTE_UINT64_T t_cb(void *context)
{
/* Return 0 for the timestamp. Real applications would request an actual
timestamp as appropriate for their system. */
(void)context;
return 0;
}
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
// The timestamp window and sequencing window are hard coded for this demo. */
static const uint64_t timestampWindow = 1;
static const int32_t sequenceWindow = 0;
int main(int /*argc*/, char ** /*argv*/)
{
size_t i;
std::string line;
std::string input;
std::string personal;
// Status.
mte_status status;
// Options.
mte_drbgs drbg = MteBase::getDefaultDrbg();
size_t tokBytes = MteBase::getDefaultTokBytes();
mte_verifiers verifiers = MteBase::getDefaultVerifiers();
mte_ciphers cipher = MteBase::getDefaultCipher();
mte_hashes hash = MteBase::getDefaultHash();
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped. This demo attempts to load the license info
// from the environment if required.
if (!MteBase::initLicense("YOUR_COMPANY", "YOUR_LICENSE"))
{
const char *company = getenv("MTE_COMPANY");
const char *license = getenv("MTE_LICENSE");
if (company == NULL || license == NULL ||
!MteBase::initLicense(company, license))
{
std::cerr << "License init error ("
<< MteBase::getStatusName(mte_status_license_error)
<< "): "
<< MteBase::getStatusDescription(mte_status_license_error)
<< std::endl;
return mte_status_license_error;
}
}
// Get the input data.
std::cout << "Enter the data to encode> " << std::flush;
std::cin >> input;
// Get the personalization string.
std::cout << "Enter the personalization> " << std::flush;
std::cin >> personal;
// Prompt for the options if available.
if (MteBase::hasRuntimeOpts())
{
// Get the DRBG.
std::cout << "DRBGs:";
for (i = 1; i < MteBase::getDrbgsCount(); ++i)
{
std::cout << ' ' << MteBase::getDrbgsName(static_cast<mte_drbgs>(i));
}
std::cout << "\nEnter the DRBG> " << std::flush;
std::cin >> line;
drbg = MteBase::getDrbgsAlgo(line.c_str());
// Get the token size.
std::cout << "Enter the token size in bytes> " << std::flush;
std::cin >> tokBytes;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Get the verifiers.
std::cout << "Verifiers:";
for (i = 0; i < MteBase::getVerifiersCount(); ++i)
{
std::cout << ' '
<< MteBase::getVerifiersName(static_cast<mte_verifiers>(i));
}
std::cout << "\nEnter the verifiers> " << std::flush;
std::cin >> line;
verifiers = MteBase::getVerifiersAlgo(line.c_str());
// Get the cipher.
std::cout << "Ciphers:";
for (i = 1; i < MteBase::getCiphersCount(); ++i)
{
std::cout << ' ' << MteBase::getCiphersName(static_cast<mte_ciphers>(i));
}
std::cout << "\nEnter the cipher> " << std::flush;
std::cin >> line;
cipher = MteBase::getCiphersAlgo(line.c_str());
// Get the hash.
std::cout << "Hashes:";
for (i = 1; i < MteBase::getHashesCount(); ++i)
{
std::cout << ' ' << MteBase::getHashesName(static_cast<mte_hashes>(i));
}
std::cout << "\nEnter the hash> " << std::flush;
std::cin >> line;
hash = MteBase::getHashesAlgo(line.c_str());
}
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
size_t entropyBytes = MteBase::getDrbgsEntropyMinBytes(drbg);
uint8_t *entropy = new uint8_t[entropyBytes];
memset(entropy, 0, entropyBytes);
// Create the encoder.
MteMkeEnc encoder(drbg, tokBytes, verifiers, cipher, hash);
encoder.setEntropy(entropy, entropyBytes);
encoder.setNonce(0);
status = encoder.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Encoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
delete[] entropy;
return status;
}
// Note that after the instantiate call, the entropy buffer will be zeroized.
// In this demo, the entropy buffer was set to all zeroes to begin with.
// Care should be taken to ensure that if the same entropy buffer is used
// again for a paired encoder/decoder, that buffer must be set identically
// before an instantiate call. Alternatively, two different entropy buffers
// with identical values may be used.
// Encode/encrypt the input.
const char *encoded = encoder.encodeB64(input, status);
if (status != mte_status_success)
{
std::cerr << "Encode error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Display the encoded message.
std::cout << "Base64 message: " << encoded << std::endl;
// Create the decoder.
MteMkeDec decoder(drbg,
tokBytes,
verifiers,
cipher,
hash,
timestampWindow,
sequenceWindow);
decoder.setEntropy(entropy, entropyBytes);
decoder.setNonce(0);
status = decoder.instantiate(personal);
if (status != mte_status_success)
{
std::cerr << "Decoder instantiate error ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Decode the message.
std::string decoded;
status = decoder.decodeB64(encoded, decoded);
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;
}
// Output the decoded data.
std::cout << "Decoded data: " << decoded << std::endl;
// Compare the decoded data against the original data.
if (decoded == input)
{
std::cout << "The original data and decoded data match." << std::endl;
}
else
{
std::cout << "The original data and decoded data DO NOT match."
<< std::endl;
return -1;
}
// Success.
delete[] entropy;
return 0;
}
using System;
using System.Text;
namespace MTE {
class demoCsMke {
// The timestamp window and sequencing window are hard coded for this
// demo.
private const UInt64 timestampWindow = 1;
private const Int32 sequenceWindow = 0;
static int Main(string[] args) {
// Status.
MteStatus status = MteStatus.mte_status_success;
// Options.
MteDrbgs drbg;
int tokBytes;
MteVerifiers verifiers;
MteCiphers cipher;
MteHashes hash;
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped. This demo attempts to load the license
// info from the environment if required.
MteBase baseObj = new MteBase();
if (!baseObj.InitLicense("YOUR_COMPANY", "YOUR_LICENSE")) {
string company = Environment.GetEnvironmentVariable("MTE_COMPANY");
string license = Environment.GetEnvironmentVariable("MTE_LICENSE");
if (company == null || license == null ||
!baseObj.InitLicense(company, license)) {
status = MteStatus.mte_status_license_error;
Console.Error.WriteLine("License init error ({0}): {1}",
baseObj.GetStatusName(status),
baseObj.GetStatusDescription(status));
return (int)status;
}
}
// Get the input data.
Console.Write("Enter the data to encode> ");
string input = Console.ReadLine();
// Get the personalization string.
Console.Write("Enter the personalization> ");
string personal = Console.ReadLine();
// Set up the options to use the buildtime options if the library is built
// for that; otherwise prompt for the options.
if (baseObj.HasRuntimeOpts()) {
// Get the DRBG.
Console.Write("DRBGs:");
for (int i = 1; i < baseObj.GetDrbgsCount(); ++i) {
Console.Write(" {0}", baseObj.GetDrbgsName((MteDrbgs)i));
}
Console.WriteLine();
Console.Write("Enter the DRBG> ");
drbg = baseObj.GetDrbgsAlgo(Console.ReadLine());
// Get the token size.
Console.Write("Enter the token size in bytes> ");
tokBytes = Convert.ToInt32(Console.ReadLine());
// Get the verifiers.
Console.Write("Verifiers:");
for (int i = 0; i < baseObj.GetVerifiersCount(); ++i) {
Console.Write(" {0}", baseObj.GetVerifiersName((MteVerifiers)i));
}
Console.WriteLine();
Console.Write("Enter the verifiers> ");
verifiers = baseObj.GetVerifiersAlgo(Console.ReadLine());
// Get the cipher.
Console.Write("Ciphers:");
for (int i = 1; i < baseObj.GetCiphersCount(); ++i) {
Console.Write(" {0}", baseObj.GetCiphersName((MteCiphers)i));
}
Console.WriteLine();
Console.Write("Enter the cipher> ");
cipher = baseObj.GetCiphersAlgo(Console.ReadLine());
// Get the hash.
Console.Write("Hashes:");
for (int i = 1; i < baseObj.GetHashesCount(); ++i) {
Console.Write(" {0}", baseObj.GetHashesName((MteHashes)i));
}
Console.WriteLine();
Console.Write("Enter the hash> ");
hash = baseObj.GetHashesAlgo(Console.ReadLine());
} else {
drbg = baseObj.GetDefaultDrbg();
tokBytes = baseObj.GetDefaultTokBytes();
verifiers = baseObj.GetDefaultVerifiers();
cipher = baseObj.GetDefaultCipher();
hash = baseObj.GetDefaultHash();
}
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
int entropyBytes = baseObj.GetDrbgsEntropyMinBytes(drbg);
byte[] entropy = new byte[entropyBytes];
// Create the Encoder.
MteMkeEnc encoder = new MteMkeEnc(drbg,
tokBytes,
verifiers,
cipher,
hash);
encoder.SetEntropy(entropy);
encoder.SetNonce(0);
status = encoder.Instantiate(personal);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Encoder instantiate error ({0}): " +
encoder.GetStatusDescription(status),
encoder.GetStatusName(status));
return (int)status;
}
// Encode the input.
string encoded = encoder.EncodeB64(input, out status);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Encode error ({0}): {1}",
encoder.GetStatusName(status),
encoder.GetStatusDescription(status));
return (int)status;
}
// Display the encoded message.
Console.WriteLine("Base64 message: {0}", encoded);
// Create the Decoder.
MteMkeDec decoder = new MteMkeDec(drbg,
tokBytes,
verifiers,
cipher,
hash,
timestampWindow,
sequenceWindow);
decoder.SetEntropy(entropy);
decoder.SetNonce(0);
status = decoder.Instantiate(personal);
if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decoder instantiate error ({0}): " +
decoder.GetStatusDescription(status),
decoder.GetStatusName(status));
return (int)status;
}
// Decode the message.
string decoded = decoder.DecodeStrB64(encoded, out status);
if (decoder.StatusIsError(status)) {
Console.Error.WriteLine("Decode error ({0}): {1}",
decoder.GetStatusName(status),
decoder.GetStatusDescription(status));
return (int)status;
} else if (status != MteStatus.mte_status_success) {
Console.Error.WriteLine("Decode warning ({0}): {1}",
decoder.GetStatusName(status),
decoder.GetStatusDescription(status));
}
// Output the decoded data.
Console.WriteLine("Decoded data: {0}", decoded);
// Compare the decoded data against the original data.
if (decoded == input) {
Console.WriteLine("The original data and decoded data match.");
} else {
Console.WriteLine("The original data and decoded data DO NOT match.");
return -1;
}
// Success.
return 0;
}
}
}
import com.eclypses.mte.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class demoJavaMke
{
// The timestamp window and sequencing window are hard coded for this demo.
private static final long timestampWindow = 1;
private static final int sequenceWindow = 0;
public static void main(String[] args) throws IOException
{
// Status.
MteStatus status;
// Options.
MteDrbgs drbg;
int tokBytes;
MteVerifiers verifiers;
MteCiphers cipher;
MteHashes hash;
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped. This demo attempts to load the license info
// from the environment if required.
if (!MteBase.initLicense("YOUR_COMPANY", "YOUR_LICENSE"))
{
String company = System.getenv("MTE_COMPANY");
String license = System.getenv("MTE_LICENSE");
if (company == null || license == null ||
!MteBase.initLicense(company, license))
{
status = MteStatus.mte_status_license_error;
System.err.println("Encode error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
}
// Buffered input.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// Get the input data.
System.out.print("Enter the data to encode> ");
String input = br.readLine();
// Get the personalization string.
System.out.print("Enter the personalization> ");
String personal = br.readLine();
// Set up the options to use the buildtime options if the library is built
// for that; otherwise prompt for the options.
if (MteBase.hasRuntimeOpts())
{
// Get the DRBG.
System.out.print("DRBGs:");
for (int i = 1; i < MteBase.getDrbgsCount(); ++i)
{
System.out.print(" " + MteBase.getDrbgsName(MteDrbgs.valueOf(i)));
}
System.out.println();
System.out.print("Enter the DRBG> ");
drbg = MteBase.getDrbgsAlgo(br.readLine());
// Get the token size.
System.out.print("Enter the token size in bytes> ");
tokBytes = Integer.parseInt(br.readLine());
// Get the verifiers.
System.out.print("Verifiers:");
for (int i = 0; i < MteBase.getVerifiersCount(); ++i)
{
System.out.print(" " +
MteBase.getVerifiersName(MteVerifiers.valueOf(i)));
}
System.out.println();
System.out.print("Enter the verifiers> ");
verifiers = MteBase.getVerifiersAlgo(br.readLine());
// Get the cipher.
System.out.print("Ciphers:");
for (int i = 1; i < MteBase.getCiphersCount(); ++i)
{
System.out.print(" " + MteBase.getCiphersName(MteCiphers.valueOf(i)));
}
System.out.println();
System.out.print("Enter the cipher> ");
cipher = MteBase.getCiphersAlgo(br.readLine());
// Get the hash.
System.out.print("Hashes:");
for (int i = 1; i < MteBase.getHashesCount(); ++i)
{
System.out.print(" " + MteBase.getHashesName(MteHashes.valueOf(i)));
}
System.out.println();
System.out.print("Enter the hash> ");
hash = MteBase.getHashesAlgo(br.readLine());
} else {
drbg = MteBase.getDefaultDrbg();
tokBytes = MteBase.getDefaultTokBytes();
verifiers = MteBase.getDefaultVerifiers();
cipher = MteBase.getDefaultCipher();
hash = MteBase.getDefaultHash();
}
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
int entropyBytes = MteBase.getDrbgsEntropyMinBytes(drbg);
byte[] entropy = new byte[entropyBytes];
// Create the Encoder.
MteMkeEnc encoder = new MteMkeEnc(drbg,
tokBytes,
verifiers,
cipher,
hash);
encoder.setEntropy(entropy);
encoder.setNonce(0);
status = encoder.instantiate(personal);
if (status != MteStatus.mte_status_success)
{
System.err.println("Encoder instantiate error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
// Encode the input.
MteBase.StrStatus encoded = encoder.encodeB64(input);
if (encoded.status != MteStatus.mte_status_success)
{
System.err.println("Encode error (" +
MteBase.getStatusName(encoded.status) + "): " +
MteBase.getStatusDescription(encoded.status));
System.exit(encoded.status.getValue());
}
// Display the encoded message.
System.out.println("Base64 message: " + encoded.str);
// Create the Decoder.
MteMkeDec decoder = new MteMkeDec(drbg,
tokBytes,
verifiers,
cipher,
hash,
timestampWindow,
sequenceWindow);
decoder.setEntropy(entropy);
decoder.setNonce(0);
status = decoder.instantiate(personal);
if (status != MteStatus.mte_status_success)
{
System.err.println("Decoder instantiate error (" +
MteBase.getStatusName(status) + "): " +
MteBase.getStatusDescription(status));
System.exit(status.getValue());
}
// Decode the message.
MteBase.StrStatus decoded = decoder.decodeStrB64(encoded.str);
if (MteBase.statusIsError(decoded.status))
{
System.err.println("Decode error (" +
MteBase.getStatusName(decoded.status) + "): " +
MteBase.getStatusDescription(decoded.status));
System.exit(decoded.status.getValue());
}
else if (decoded.status != MteStatus.mte_status_success)
{
System.err.println("Decode warning (" +
MteBase.getStatusName(decoded.status) + "): " +
MteBase.getStatusDescription(decoded.status));
}
// Output the decoded data.
System.out.println("Decoded data: " + decoded.str);
// Compare the decoded data against the original data.
if (decoded.str.equals(input))
{
System.out.println("The original data and decoded data match.");
}
else
{
System.out.println("The original data and decoded data DO NOT match.");
System.exit(-1);
}
// Success.
System.exit(0);
}
}
import Foundation
// Command line arguments. Default any that are not passed in:
// [1] = input data to be tokenized.
public func main() -> Int32 {
// Status.
var status: mte_status
// Input.
let input = CommandLine.argc > 1 ? CommandLine.arguments[1] : "hello"
// Personalization string.
let personal = "demo"
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped. This demo attempts to load the license info
// from the environment if required.
if !MteBase.initLicense("YOUR_COMPANY", "YOUR_LICENSE") {
let company = ProcessInfo.processInfo.environment["MTE_COMPANY"]
let license = ProcessInfo.processInfo.environment["MTE_LICENSE"];
if company == nil || license == nil ||
!MteBase.initLicense(company!, license!) {
status = mte_status_license_error
print("License init error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
}
// Output original data.
print("Original data: \(input)")
// Create the encoder and decoder.
let encoder = try! MteMkeEnc()
let decoder = try! MteMkeDec()
// Create all-zero entropy for this demo. The nonce will also be set to 0.
// This should never be done in real applications.
let entropyBytes = MteBase.getDrbgsEntropyMinBytes(encoder.getDrbg())
var entropy = [UInt8](repeating: 0, count: entropyBytes)
// Instantiate the encoder.
encoder.setEntropy(&entropy)
encoder.setNonce(0)
status = encoder.instantiate(personal)
if status != mte_status_success {
print("Encoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Encode the input.
var encoded: String
(encoded, status) = encoder.encodeB64(input)
if status != mte_status_success {
print("Encode error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Display the message.
print("Base64 message: \(encoded)")
// Instantiate the decoder.
decoder.setEntropy(&entropy)
decoder.setNonce(0)
status = decoder.instantiate(personal)
if status != mte_status_success {
print("Decoder instantiate error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Decode the message.
var decoded: String
(decoded, status) = decoder.decodeStrB64(encoded)
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))
}
// Output the decoded data.
print("Decoded data: \(decoded)")
// Compare the decoded data against the original data.
if decoded == input {
print("The original data and decoded data match.")
} else {
print("The original data and decoded data DO NOT match.")
return -1
}
// Success.
return 0
}
#import "MteMkeEnc.h"
#import "MteMkeDec.h"
int main() {
uint64 min = 999999999999;
uint64 max = UINT_MAX;
int entropySize = 32;
uint8_t *encoderEntropy[entropySize];
uint64 encoderNonce = 0;
NSString *encoderPersonalityString = @"";
uint8_t *decoderEntropy[entropySize];
uint64 decoderNonce = 0;
NSString *decoderPersonalityString = @"";
// Status.
mte_status status;
NSString *valueToEncode = @"hello";
// MARK: Options
mte_drbgs drbg;
NSInteger tokBytes;
mte_verifiers verifiers;
mte_ciphers cipher;
mte_hashes hash;
// For this Sample, we will hard-code these two Options
uint64 timestampWindow = 1;
int32_t sequenceWindow = 0;
@autoreleasepool {
puts("****** Simple Objective-C MKE Add-On Console Demo ******\n\n");
// Check License
if (![MteBase initLicense:@"YOUR_COMPANY" code:@"YOUR_LICENSE"]) {
status = mte_status_license_error;
fprintf(stderr, "License init error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// MARK: Initialize Initial Values
// Fill the entropy variables
if (SecRandomCopyBytes(kSecRandomDefault, entropySize, encoderEntropy) != 0) {
printf("%s", "Unable to generate Entropy");
}
memcpy(decoderEntropy, encoderEntropy, sizeof(encoderEntropy));
// Fill the nonce variables
encoderNonce = min + arc4random_uniform((uint32_t)(max - min + 1));
decoderNonce = encoderNonce;
// Fill the PersonalizationString variables
encoderPersonalityString = [[NSUUID UUID] UUIDString];
decoderPersonalityString = encoderPersonalityString;
// MARK: Initialize Options
// If Options were set at Buildtime, these must
// be used, otherwise they need to be set
if ([MteBase hasBuildtimeOpts]) {
drbg = [MteBase getBuildtimeDrbg];
tokBytes = [MteBase getBuildtimeTokBytes];
verifiers = [MteBase getBuildtimeVerifiers];
cipher = [MteBase getBuildtimeCipher];
hash = [MteBase getBuildtimeHash];
} else {
drbg = mte_drbgs_ctr_aes256_df;
tokBytes = 16;
verifiers = mte_verifiers_t64_crc32_seq;
cipher = mte_ciphers_aes256_ctr;
hash = mte_hashes_sha256;
}
// Create Encoder with Options
MteMkeEnc *encoder = MTE_AUTORELEASE([[MteMkeEnc alloc] initWithDrbg:drbg
tokBytes:tokBytes
verifiers:verifiers
cipher:cipher
hash:hash]);
[encoder setEntropy:encoderEntropy bytes:entropySize];
[encoder setNonce:encoderNonce];
status = [encoder instantiate:encoderPersonalityString];
if (status != mte_status_success)
{
fprintf(stderr, "Encoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
NSString *encoded = [encoder encodeB64:valueToEncode status:&status];
if (status != mte_status_success)
{
fprintf(stderr, "Encode error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Create Decoder with Options
MteMkeDec *decoder = MTE_AUTORELEASE([[MteMkeDec alloc] initWithDrbg:drbg
tokBytes:tokBytes
verifiers:verifiers
cipher:cipher
hash:hash
tWindow:timestampWindow
sWindow:sequenceWindow]);
[decoder setEntropy:decoderEntropy bytes:entropySize];
[decoder setNonce:decoderNonce];
[decoder instantiate:decoderPersonalityString];
if (status != mte_status_success)
{
fprintf(stderr, "Decoder instantiate error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
NSString *decoded = [decoder decodeB64:encoded status:&status];
if ([MteBase statusIsError:status])
{
fprintf(stderr, "Decode error (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
else if (status != mte_status_success)
{
fprintf(stderr, "Decode warning (%s): %s\n",
[[MteBase getStatusName:status] UTF8String],
[[MteBase getStatusDescription:status] UTF8String]);
return status;
}
// Compare the decoded data against the original data.
if ([decoded isEqualToString:valueToEncode])
{
puts("The original data and decoded data match.\n");
}
else
{
puts("The original data and decoded data DO NOT match.");
return -1;
}
puts("Closing the Application.\n");
}
return 0;
}
#!/usr/bin/env python3
# Import relevant modules for the program.
from MteCiphers import MteCiphers
from MteHashes import MteHashes
from MteDrbgs import MteDrbgs
from MteVerifiers import MteVerifiers
from MteStatus import MteStatus
from MteBase import MteBase
from MteMkeEnc import MteMkeEnc
from MteMkeDec import MteMkeDec
import os
import sys
# The timestamp window and sequencing window are hard coded for this demo.
timestamp_window = 1
sequence_window = 0
def main():
# Initialize MTE license. If a license code is not required (e.g., trial
# mode), this can be skipped. This demo attempts to load the license
# info from the environment if required.
if not MteBase.init_license("YOUR_COMPANY", "YOUR LICENSE"):
company = os.getenv("MTE_COMPANY")
license = os.getenv("MTE_LICENSE")
if company is None or \
license is None or \
not MteBase.init_license(company, license):
status = MteStatus.mte_status_license_error
print("License init error ({0}): {1}".format(MteBase.get_status_name(status),\
MteBase.get_status_description(status),\
file=sys.stderr))
return MteStatus.mte_status_license_error.value
# Get the input data.
input_data = input("Enter the data to encode\n> ")
# Get the personalization string.
personal_str = input("Enter personalization\n> ")
# Set up the options to use the buildtime options if the library is built
# for that; otherwise prompt for the options.
if MteBase.has_buildtime_opts():
drbg = MteBase.get_buildtime_drbg()
tok_bytes = MteBase.get_tok_bytes()
verifiers = MteBase.get_verifiers()
cipher = MteBase.get_buildtime_cipher()
hash_ = MteBase.get_buildtime_hash()
else:
# Get the DRBG.
drbg_list = []
print("DRBGs:",end="\n")
for i in range(1, MteBase.get_drbgs_count()):
print("{0}. {1}\n".format(i,MteBase.get_drbgs_name(MteDrbgs(i))), end="")
drbg_list.append(MteBase.get_drbgs_name(MteDrbgs(i)))
drbg = input("Enter the DRBG number\n> ")
drbg = MteBase.get_drbgs_algo(drbg_list[int(drbg)-1])
# Get the token size.
tok_bytes = int(input("Enter the token size in bytes\n> "))
# Get the verifiers.
verifiers_list = []
print("Verifiers:",end="\n")
for i in range(1, MteBase.get_verifiers_count()):
print("{0}. {1}\n".format(i,MteBase.get_verifiers_name(MteVerifiers(i))), end="")
verifiers_list.append(MteBase.get_verifiers_name(MteVerifiers(i)))
verifiers = input("Enter the verifier number\n> ")
verifiers = MteBase.get_verifiers_algo(verifiers_list[int(verifiers)-1])
# Get the cipher.
cipher_list = []
print("Ciphers:",end="\n")
for i in range(1, MteBase.get_ciphers_count()):
print("{0}. {1}\n".format(i,MteBase.get_ciphers_name(MteCiphers(i))), end="")
cipher_list.append(MteBase.get_ciphers_name(MteCiphers(i)))
cipher = input("Enter the cipher number\n> ")
cipher = MteBase.get_ciphers_algo(cipher_list[int(cipher)-1])
# Get the hashing algorithm.
hash_list = []
print("Hashes:", end="\n")
for i in range(1, MteBase.get_hashes_count()):
print("{0}. {1}\n".format(i,MteBase.get_hashes_name(MteHashes(i))), end="")
hash_list.append(MteBase.get_hashes_name(MteHashes(i)))
hash_ = input("Enter the hash number\n> ")
hash_ = MteBase.get_hashes_algo(hash_list[int(hash_)-1])
# Create all zero entropy for this demo. The nonce will also be set to zero.
# This should never be done in real applications.
entropy = "0"
entropy_min_bytes = MteBase.get_drbgs_entropy_min_bytes(drbg)
while len(entropy) < entropy_min_bytes:
entropy += "0"
entropy = bytearray(entropy,'utf-8')
# Create the Encoder.
encoder = MteMkeEnc(drbg,tok_bytes,verifiers,cipher,hash_)
encoder.set_entropy(entropy)
encoder.set_nonce(0)
status = encoder.instantiate(personal_str)
if status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(status),\
MteBase.get_status_description(status)
print("Encoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
# Encode the input.
(encoded, status) = encoder.encode_b64(input_data)
if status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(status),\
MteBase.get_status_description(status)
print("Encode error ({0}): {1}".format(\
status,message),file=sys.stderr)
# Display the encoded message.
print(f'Base64 message: {encoded}')
# Create the Decoder.
decoder = MteMkeDec(drbg, tok_bytes, verifiers, cipher,
hash_, timestamp_window, sequence_window)
decoder.set_entropy(entropy)
decoder.set_nonce(0)
status = decoder.instantiate(personal_str)
status = decoder.instantiate(personal_str)
if status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(status),\
MteBase.get_status_description(status)
print("Decoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
# Decode the message.
(decoded,status) = decoder.decode_str_b64(encoded)
if MteBase.status_is_error(status):
print("Decode error ({0}): {1}".format(\
MteBase.get_status_name(status),\
MteBase.get_status_description(status),\
file=sys.stderr))
elif status != MteStatus.mte_status_success:
print("Decode warning ({0}): {1}".format(\
MteBase.get_status_name(status),\
MteBase.get_status_description(status),\
file=sys.stderr))
# Compare the decoded data against the original data.
if decoded == input_data:
print("The original data and decoded data match.")
else:
print("The original data and decoded data DO NOT match.")
return -1
# Success.
return 0
package main
import (
"bufio"
"fmt"
"os"
"goMke/mte"
)
// The timestamp window and sequencing window are hard coded for this demo.
const (
timestampWindow = 1
sequenceWindow = 0
)
func doMain() int {
// Status.
var status mte.Status
// Options.
var drbg mte.Drbgs
var tokBytes int
var verifiers mte.Verifiers
var cipher mte.Ciphers
var hash mte.Hashes
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped. This demo attempts to load the license info
// from the environment if required.
if !mte.InitLicense("YOUR_COMPANY", "YOUR_LICENSE") {
company := os.Getenv("MTE_COMPANY")
license := os.Getenv("MTE_LICENSE")
if len(company) == 0 || len(license) == 0 ||
!mte.InitLicense(company, license) {
fmt.Fprintf(os.Stderr, "License init error (%v): %v\n",
mte.GetStatusName(mte.Status_mte_status_license_error),
mte.GetStatusDescription(mte.Status_mte_status_license_error))
return int(mte.Status_mte_status_license_error)
}
}
// Scanner input.
scanner := bufio.NewScanner(os.Stdin)
// Get the input data.
fmt.Print("Enter the data to encode> ")
scanner.Scan()
input := scanner.Text()
// Get the personalization string.
fmt.Print("Enter the personalization> ")
scanner.Scan()
personal := scanner.Text()
// Set up the options to use the buildtime options if the library is built
// for that; otherwise prompt for the options.
if mte.HasRuntimeOpts() {
// Get the DRBG.
fmt.Print("DRBGs:")
for i := 1; i < mte.GetDrbgsCount(); i++ {
fmt.Printf(" %v", mte.GetDrbgsName(mte.Drbgs(i)))
}
fmt.Print("\nEnter the DRBG> ")
scanner.Scan()
drbg = mte.GetDrbgsAlgo(scanner.Text())
// Get the token size.
fmt.Print("Enter the token size in bytes> ")
fmt.Scan(&tokBytes)
// Get the verifiers.
fmt.Print("Verifiers:")
for i := 0; i < mte.GetVerifiersCount(); i++ {
fmt.Printf(" %v", mte.GetVerifiersName(mte.Verifiers(i)))
}
fmt.Printf("\nEnter the verifiers> ")
scanner.Scan()
verifiers = mte.GetVerifiersAlgo(scanner.Text())
// Get the cipher.
fmt.Print("Ciphers:")
for i := 1; i < mte.GetCiphersCount(); i++ {
fmt.Printf(" %v", mte.GetCiphersName(mte.Ciphers(i)))
}
fmt.Print("\nEnter the cipher> ")
scanner.Scan()
cipher = mte.GetCiphersAlgo(scanner.Text())
// Get the hash.
fmt.Print("Hashes:")
for i := 1; i < mte.GetHashesCount(); i++ {
fmt.Printf(" %v", mte.GetHashesName(mte.Hashes(i)))
}
fmt.Print("\nEnter the hash> ")
scanner.Scan()
hash = mte.GetHashesAlgo(scanner.Text())
} else {
drbg = mte.GetDefaultDrbg()
tokBytes = mte.GetDefaultTokBytes()
verifiers = mte.GetDefaultVerifiers()
cipher = mte.GetDefaultCipher()
hash = mte.GetDefaultHash()
}
// 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(drbg)
entropy := make([]byte, entropyBytes)
// Create the Encoder.
encoder := mte.NewMkeEncOpt(drbg, tokBytes, verifiers, cipher, hash)
defer encoder.Destroy()
encoder.SetEntropy(entropy)
encoder.SetNonceInt(0)
status = encoder.InstantiateStr(personal)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
// Encode the input.
encoded, status := encoder.EncodeStrB64(input)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encode/encrypt error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
// Display the message.
fmt.Printf("Base64 message: %v\n", encoded)
// Create the Decoder.
decoder := mte.NewMkeDecOpt(drbg,
tokBytes,
verifiers,
cipher,
hash,
timestampWindow,
sequenceWindow)
defer decoder.Destroy()
decoder.SetEntropy(entropy)
decoder.SetNonceInt(0)
status = decoder.InstantiateStr(personal)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
}
// Decode the message.
decoded, status := decoder.DecodeStrB64(encoded)
if mte.StatusIsError(status) {
fmt.Fprintf(os.Stderr, "Decode error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
return int(status)
} else if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decode warning (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
}
// Output the decoded data.
fmt.Printf("Decoded data: %v\n", decoded)
// Compare the decoded data against the original data.
if decoded == input {
fmt.Println("The original data and decoded data match.")
} else {
fmt.Println("The original data and decoded data DO NOT match.")
return -1
}
// Success.
return 0
}
func main() {
os.Exit(doMain())
}
MTE MKE Encode Chunking
Here is a code sample of using the MKE Chunking methods to read in a file and encode the contents and write the contents to a different file.
Chunking mode of MKE is useful when you are securing a very large piece of data and don’t want to wait for the entire piece of data to be encoded before sending, or need to break up the data in order to send it. Chunking allows you to break a piece of data into smaller predetermined sized pieces and encode then systematically until the entire larger piece of data is encoded. For more information, please see the official MTE developer guides.
- C
- C++
- CSharp
- Java
- Swift
- Python
- Go
// Init the MTE.
if (!mte_init(NULL, NULL))
{
printf("There was an error attempting to initialize the MTE.\n");
return 1;
}
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped.
if (!mte_license_init("LicenseCompanyName", "LicenseKey"))
{
printf("There was an error attempting to initialize the MTE License.\n");
return 1;
}
// Check encrypt and decrypt chunk sizes.
size_t block_size = mte_base_ciphers_block_bytes(MTE_CIPHER_ENUM);
if (block_size > 1)
{
printf("The chunk size must be set to 1.");
return 1;
}
mte_status status;
// Set personalization string to demo for this sample.
const char* personal = "demo";
// Set nonce to the timestamp.
nonce = get_timestamp();
// Get minimum entropy amount of bytes.
size_t min_entropy_bytes = mte_base_drbgs_entropy_min_bytes(MTE_DRBG_ENUM);
if (min_entropy_bytes == 0)
{
min_entropy_bytes = 1;
}
entropy_size = min_entropy_bytes;
entropy_buff = malloc(min_entropy_bytes);
// Create byte array of random bytes to use as entropy.
int res = get_random(entropy_buff, entropy_size);
if (res != 0)
{
printf("There was an error attempting to create random entropy.\n");
return res;
}
// Create default MKE Encoder.
mte_mke_enc_init_info encoder_info = MTE_MKE_ENC_INIT_INFO_INIT(
MTE_DRBG_ENUM, MTE_TOKBYTES, MTE_VERIFIERS_ENUM, MTE_CIPHER_ENUM, MTE_HASH_ENUM, NULL, NULL, NULL, NULL, NULL, NULL);
static MTE_HANDLE encoder;
encoder = malloc(mte_mke_enc_state_bytes(&encoder_info));
// Initiate the Encoder state.
status = mte_mke_enc_state_init(encoder, &encoder_info);
if (status != mte_status_success)
{
printf("Encoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return 1;
}
// Set the Encoder instantiation information.
mte_drbg_inst_info enc_inst_info = { &entropy_input_callback, NULL, &nonce_callback, NULL, personal, strlen(personal) };
status = mte_mke_enc_instantiate(encoder, &enc_inst_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;
}
while (true)
{
char file_path[256];
printf("Please enter path to file (To end please type 'quit')\n");
fflush(stdout);
(void)fgets(file_path, sizeof(file_path), stdin);
file_path[strlen(file_path) - 1] = '\0';
if (strcasecmp(file_path, "quit") == 0)
{
break;
}
const char* base_file_name;
// Find last index of the path separator character.
char* path_char_index = strrchr(file_path, path_separator_char);
if (path_char_index == NULL) {
// No path characters in file name.
base_file_name = file_path;
}
else
{
// Get everything after path character.
base_file_name = path_char_index + 1;
}
// Get last index of period for file extension.
const char* file_extension;
char* file_extension_index = strrchr(base_file_name, '.');
if (file_extension_index == NULL)
{
// No extension in file name.
file_extension = "";
}
else
{
// Include the period in the file extension.
file_extension = file_extension_index;
}
// Create input file stream.
FILE* input_file;
size_t file_size = 0;
// Open the input file, for read mode "r" and binary "b".
input_file = fopen(file_path, "rb");
if (input_file == NULL)
{
fprintf(stderr, "Error reading file.");
break;
}
// Get the input file size.
fseek(input_file, 0, SEEK_END);
file_size = ftell(input_file);
// Close the input file.
fclose(input_file);
//=========================================////
//***** Begin MKE Encryption Process. *****////
//=========================================////
// Create encoded file name that includes the same extension.
char encoded_file_name[256] = "encoded";
strcat(encoded_file_name, file_extension);
// Delete any existing encoded file.
res = remove(encoded_file_name);
if (res == 0)
{
printf("Previous file %s deleted.\n", encoded_file_name);
}
// Create buffer to hold encrypt chunk size.
char* encrypt_chunk_buf;
encrypt_chunk_buf = malloc(encrypt_chunk_size);
// Get the chunk state size requirement.
size_t buff_bytes = mte_mke_enc_encrypt_state_bytes(encoder);
// Create buffer to hold MTE encryption.
unsigned char* enc_mke_buf;
enc_mke_buf = malloc(buff_bytes);
// Start chunking session.
status = mte_mke_enc_encrypt_start(encoder, enc_mke_buf);
if (status != mte_status_success)
{
fprintf(stderr, "Error starting encryption: (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
// Re-open input file, for read mode "r" and binary "b".
input_file = fopen(file_path, "rb");
// Open the encoded file, for write mode "w" and binary "b".
FILE* encoded_file;
encoded_file = fopen(encoded_file_name, "wb");
mte_enc_args encoding_args = MTE_ENC_ARGS_INIT(NULL, 0, NULL, ×tamp_callback, NULL);
// Go through until the end of the input file.
while (!feof(input_file))
{
// Set encrypt chunk to zero.
memset(encrypt_chunk_buf, '\0', encrypt_chunk_size);
// Read a portion of the input file of size encrypt_chunk_size to the encryption buffer.
size_t amount = fread(encrypt_chunk_buf, 1, encrypt_chunk_size, input_file);
// Check if the amount read is 0, the end of input file has been reached.
if (amount == 0)
{
continue;
}
// Encrypt the chunk buffer. Use the amount read from this pass.
// The same buffer can be used to encrypt in place, but is not necessary.
// This means the input buffer and the encrypted buffer can be the same.
MTE_SET_ENC_IO(encoding_args, encrypt_chunk_buf, amount, encrypt_chunk_buf);
status = mte_mke_enc_encrypt_chunk(encoder, enc_mke_buf, &encoding_args);
if (status != mte_status_success)
{
fprintf(stderr, "Error encrypting chunk: Status: %s/%s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return false;
}
if (encoding_args.bytes > 0)
{
// Write the chunk buffer to the encoded file.
fwrite(encoding_args.encoded, 1, encoding_args.bytes, encoded_file);
fflush(encoded_file);
}
}
// Close the input file.
fclose(input_file);
// Finish the encryption with the encryption buffer.
MTE_SET_ENC_IO(encoding_args, NULL, 0, NULL);
status = mte_mke_enc_encrypt_finish(encoder, enc_mke_buf, &encoding_args);
if (status != mte_status_success)
{
fprintf(stderr, "Error finishing encryption: (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
if (encoding_args.bytes > 0)
{
// Write the result bytes from encrypt finish.
fwrite(encoding_args.encoded, 1, encoding_args.bytes, encoded_file);
fflush(encoded_file);
}
// Free the encrypt buffer.
free(encrypt_chunk_buf);
// Close the encoded file.
fclose(encoded_file);
printf("Successfully encoded file %s\n", encoded_file_name);
mte_status status;
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped.
if (!MteBase::initLicense("LicenseCompanyName", "LicenseKey"))
{
status = mte_status_license_error;
std::cerr << "There was an error attempting to initialize the MTE License." << std::endl;
return status;
}
// Check encrypt and decrypt chunk sizes.
size_t blockSize = MteBase::getCiphersBlockBytes(MTE_CIPHER_ENUM);
if (blockSize > 1)
{
std::cerr << "The chunk size must be set to 1." << std::endl;
return 1;
}
// Set personalization string to demo for this sample.
std::string personal = "demo";
// Set nonce to the timestamp.
nonce = getTimestamp();
// Create the callbacks to get entropy, nonce, and timestamp.
Cbs cbs;
size_t minEntropySize = MteBase::getDrbgsEntropyMinBytes(MTE_DRBG_ENUM);
if (minEntropySize == 0)
{
minEntropySize = 1;
}
entropy = new uint8_t[minEntropySize];
// Populate entropy buffer with random bytes.
int res = getRandom(entropy, minEntropySize);
if (res != 0)
{
std::cerr << "There was an error attempting to create random entropy." << std::endl;
return mte_status_drbg_catastrophic;
}
// Create default MKE encoder.
MteMkeEnc 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;
}
while (true)
{
std::string filePath;
// Prompt for file path.
std::cout << "Please enter path to file (To end please type 'quit')" << std::endl;
std::getline(std::cin, filePath);
if (strcasecmp(filePath.c_str(), "quit") == 0)
{
break;
}
// Find the last index of the path separator character.
std::string baseFileName;
const char* pathIndexChar = strrchr(filePath.c_str(), path_separator_char);
if (pathIndexChar == nullptr)
{
// No path characters in file name.
baseFileName = filePath;
}
else
{
// Get everything after path character.
baseFileName = pathIndexChar + 1;
}
// Get last index of period for file extension.
std::string fileExtention;
const char* fileExtensionIndex = strrchr(baseFileName.c_str(), '.');
if (fileExtensionIndex == nullptr) {
// No extension in file name.
fileExtention = "";
}
else
{
// Include the period in the file extension.
fileExtention = fileExtensionIndex;
}
// Create input file stream for read and binary.
std::ifstream inputFile;
inputFile.open(filePath, std::ifstream::in | std::ifstream::binary);
if (!inputFile.good())
{
std::cerr << "Error opening file." << std::endl;
return -1;
}
// Get the input file size by seeking to the end, then return to beginning.
inputFile.seekg(0, inputFile.end);
size_t fileLength = inputFile.tellg();
inputFile.seekg(0, inputFile.beg);
//=========================================////
//***** Begin MKE Encryption Process. *****////
//=========================================////
// Create encoded file name that includes the same extension.
std::string encodedFileName = "encoded" + fileExtention;
// Open the encoded file stream for writing and binary.
std::ofstream encodedFile;
// Delete any existing encoded file.
if (std::remove(encodedFileName.c_str()) == 0)
{
std::cout << "Deleted existing file " << encodedFileName << std::endl;
}
encodedFile.open(encodedFileName, std::ofstream::out | std::ofstream::binary);
// Start chunking session.
status = encoder.startEncrypt();
if (status != mte_status_success)
{
std::cerr << "Error starting encryption: ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Go through until the end of the input file.
while (!inputFile.eof())
{
// Create buffer to hold encrypt chunk size.
char encryptChunkBuf[encryptChunkSize];
// Read a portion of the input file of size encryptChunkSize to the encryption buffer.
inputFile.read(encryptChunkBuf, encryptChunkSize);
// The amount read from the stream.
std::streamsize amountRead = inputFile.gcount();
// Encrypt the chunk buffer.
status = encoder.encryptChunk(encryptChunkBuf, amountRead);
if (status != mte_status_success)
{
std::cerr << "Error encrypting chunk: ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Write the chunk buffer to the encoded file.
encodedFile.write(encryptChunkBuf, amountRead);
encodedFile.flush();
}
// Close the input file.
inputFile.close();
// Finish the encryption with the encryption buffer.
size_t finishSize = 0;
const void* finishBuffer = encoder.finishEncrypt(finishSize, status);
if (status != mte_status_success)
{
std::cerr << "Error finishing encryption: ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Write the result bytes from encrypt finish.
if (finishSize > 0)
{
encodedFile.write(static_cast<const char*>(finishBuffer), finishSize);
encodedFile.flush();
}
// Close the encoded file.
encodedFile.close();
std::cout << "Successfully encoded file " << encodedFileName << std::endl;
//-----------------------
// Set encoded file name
//-----------------------
string encodedFileName = "encodedText";
//-----------------------------------
// Create default MTE MKE and Status
//-----------------------------------
MteMkeEnc mkeEncoder = new MteMkeEnc();
MteStatus encoderStatus;
//------------------------------------------------------------------------
// Set identifier
// These values should 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 identifier = "demo";
string fPath = string.Empty;
//--------------------------------------------------
// Prompt for path till we have one and it is valid
//--------------------------------------------------
while (string.IsNullOrWhiteSpace(fPath) || !File.Exists(fPath))
{
//------------------------------------
// Prompting message for file to copy
//------------------------------------
Console.WriteLine("Please enter path to file\n");
fPath = Console.ReadLine();
//-------------------------------
// Check to make sure file exits
//-------------------------------
if (!File.Exists(fPath))
{
Console.WriteLine($"File at the path '{fPath}' does not exist");
}
}
//----------------------------------------
// Set the correct extension for the file
//----------------------------------------
encodedFileName = $"{encodedFileName}{Path.GetExtension(fPath)}";
//---------------------------------------------------------------------
// Check how long entropy we need, set default all 0's
// should be treated like encryption keys - this is just example
//---------------------------------------------------------------------
int entropyMinBytes = mkeEncoder.GetDrbgsEntropyMinBytes(mkeEncoder.GetDrbg());
string entropy = (entropyMinBytes > 0) ? new String('0', entropyMinBytes) : entropy;
//--------------------------------
// Set MKE values for the Encoder
//--------------------------------
mkeEncoder.SetEntropy(Encoding.UTF8.GetBytes(entropy));
mkeEncoder.SetNonce(0);
//-------------------------
// Initialize MKE Encoder
//-------------------------
encoderStatus = mkeEncoder.Instantiate(identifier);
if (encoderStatus != MteStatus.mte_status_success)
{
throw new ApplicationException($"Failed to initialize the MTE encoder engine. Status: " +
$"{mkeEncoder.GetStatusName(encoderStatus)} / {mkeEncoder.GetStatusDescription(encoderStatus)}");
}
//-----------------------------
// Initialize chunking session
//-----------------------------
encoderStatus = mkeEncoder.StartEncrypt();
if(encoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to start encode chunk. Status: "
+ mkeEncoder.GetStatusName(encoderStatus)+ " / "
+ mkeEncoder.GetStatusDescription(encoderStatus));
}
//-------------------------------------------------------
// Before we start we want to delete any files
// that are already there in order to create new ones
//-------------------------------------------------------
if (File.Exists(encodedFileName))
{
File.Delete(encodedFileName);
}
//------------------------------------
// Read file in and encode using MKE
//------------------------------------
using (FileStream stream = File.OpenRead(fPath))
using (FileStream writeStream = File.OpenWrite(encodedFileName))
{
BinaryReader reader = new BinaryReader(stream);
BinaryWriter writer = new BinaryWriter(writeStream);
//-----------------------------------
// Create a buffer to hold the bytes
//-----------------------------------
byte[] buffer = new Byte[1024];
int bytesRead;
//------------------------------------------
// While the read method returns bytes
// Keep writing them to the output stream
//------------------------------------------
while ((bytesRead = stream.Read(buffer, 0, 1024)) > 0)
{
//-------------------------------
// Encode the data in place
// encoded data put back in buffer
//-------------------------------
MteStatus chunkStatus = mkeEncoder.EncryptChunk(buffer, 0, bytesRead);
if(chunkStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to encode chunk. Status: "
+ mkeEncoder.GetStatusName(chunkStatus)+ " / "
+ mkeEncoder.GetStatusDescription(chunkStatus));
}
writeStream.Write(buffer, 0, bytesRead);
}
//-----------------------------
// Finish the chunking session
//-----------------------------
byte[] finalEncodedChunk = mkeEncoder.FinishEncrypt(out MteStatus finishStatus);
if(finishStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to finish encode chunk. Status: "
+ mkeEncoder.GetStatusName(finishStatus)+ " / "
+ mkeEncoder.GetStatusDescription(finishStatus));
}
//-----------------------------------
// Append the final data to the file
//-----------------------------------
writeStream.Write(finalEncodedChunk, 0, finalEncodedChunk.Length);
}
private static final int BUFFER_SIZE = 1024; // 1KB
private static String _pathToEncodedFile = "src/encoded";
private static String _pathToDecodedFile = "src/decoded";
private static final String _defaultExtension = ".txt";
// -----------------
// Buffered input.
// -----------------
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String fPath = "";
// ----------------------
// Prompt for file path
// ----------------------
System.out.print("Enter full path to file: \n");
//----------------------------------------
// Loop till we get a valid file to encode
//----------------------------------------
while(true) {
//---------------------------------------------
// Ensure file exists, and update both output
// files with correct file extension
//---------------------------------------------
fPath = br.readLine();
File textFile = new File(fPath);
if(textFile.exists()){
String filename = textFile.getName();
String extension = "";
if (filename.contains(".")) {
extension = filename.substring(filename.lastIndexOf("."));
_pathToEncodedFile = _pathToEncodedFile + extension;
_pathToDecodedFile = _pathToDecodedFile + extension;
}else {
_pathToEncodedFile = _pathToEncodedFile + _defaultExtension;
_pathToDecodedFile = _pathToDecodedFile + _defaultExtension;
}
break;
}else {
System.out.print("Invalid file path, please type in full path to file.\n");
}
}
//--------------------
// Create MKE Encoder
//--------------------
MteMkeEnc mkeEncoder = new MteMkeEnc();
//-------------------------------------------------------------------------
// Set identifier
// These values should 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 identifier = "demo";
//---------------------------------------------------------------
// Check how long entropy we need, set default all 0's
// should be treated like encryption keys - this is just example
//---------------------------------------------------------------
int entropyMinBytes = MteBase.getDrbgsEntropyMinBytes(mkeEncoder.getDrbg());
String entropy = (entropyMinBytes > 0) ? new String('0', entropyMinBytes) : entropy;
//--------------------------------
// Set MKE values for the Encoder
//--------------------------------
mkeEncoder.setEntropy(entropy.getBytes());
mkeEncoder.setNonce(0);
//-------------------------
// Instantiate MKE Encoder
//-------------------------
MteStatus encoderStatus = mkeEncoder.instantiate(identifier);
if (encoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to initialize the MTE encoder engine. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
//-----------------------------
// Initialize chunking session
//-----------------------------
encoderStatus = mkeEncoder.startEncrypt();
if(encoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to start encode chunk. Status: "
+ MteBase.getStatusName(encoderStatus)+ " / "
+ MteBase.getStatusDescription(encoderStatus));
}
String inputFile = fPath;
String outputFile = _pathToEncodedFile;
//------------------------------------------------
// Delete file if exists so we can write new one
//------------------------------------------------
Path fileToDeletePathEN = Paths.get(outputFile);
Files.deleteIfExists(fileToDeletePathEN);
try (
InputStream inputStream = new FileInputStream(inputFile);
OutputStream outputStream = new FileOutputStream(outputFile);
) {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
//------------------------------------------------------------
// Encode the data in place - encoded data put back in buffer
//------------------------------------------------------------
MteStatus chunkStatus = mkeEncoder.encryptChunk(buffer, 0, bytesRead);
if(chunkStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to encode chunk. Status: "
+ MteBase.getStatusName(chunkStatus)+ " / "
+ MteBase.getStatusDescription(chunkStatus));
}
//------------------------------------
// Write the encoded text to the file
//------------------------------------
outputStream.write(buffer, 0, bytesRead);
}
//-----------------------------
// Finish the chunking session
//-----------------------------
MteBase.ArrStatus finalEncodedChunk = mkeEncoder.finishEncrypt();
if(finalEncodedChunk.status != MteStatus.mte_status_success)
{
throw new Exception("Failed to finish encode chunk. Status: "
+ MteBase.getStatusName(finalEncodedChunk.status)+ " / "
+ MteBase.getStatusDescription(finalEncodedChunk.status));
}
//-----------------------------------
// Append the final data to the file
//-----------------------------------
outputStream.write(finalEncodedChunk.arr);
} catch (IOException ex) {
ex.printStackTrace();
}
// Status.
var status: mte_status
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped.
if !MteBase.initLicense("LicenseCompanyName", "LicenseKey") {
let company = ProcessInfo.processInfo.environment["LicenseCompanyName"]
let license = ProcessInfo.processInfo.environment["LicenseKey"];
if company == nil || license == nil ||
!MteBase.initLicense(company!, license!) {
status = mte_status_license_error
print("License init error (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
}
// This sample works with the MKE add-on that uses a cipher block size of 1. Any other
// cipher block sizes are not guaranteed to work.
let blockSize = MteBase.getCiphersBlockBytes(MteBase.getDefaultCipher())
if (blockSize > 1)
{
print("The chunk size must be set to 1.")
return 1
}
// Set personalization string to demo for this sample.
let personal = "demo"
// Set nonce to the timestamp.
gNonce = getTimestamp()
// Create the callbacks to get entropy, nonce, and timestamp from stdin.
let cbs = Cbs()
// Get the minimum entropy size in bytes.
var minEntropySize = MteBase.getDrbgsEntropyMinBytes(MteBase.getDefaultDrbg())
if minEntropySize == 0 {
minEntropySize = 1
}
// Create entropy buffer.
gEntropy = [UInt8](repeating: 0, count: minEntropySize)
// Populate entropy buffer with random bytes.
let res = getRandom(&gEntropy)
if res != 0 {
print("There was an error attempting to create random entropy.")
return res
}
// Create default MKE encoder.
let encoder = try! MteMkeEnc()
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)
}
// Create default MKE decoder.
let decoder = try! MteMkeDec()
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)
}
while (true) {
var filePath: String
// Prompt for file path.
print("Please enter path to file (To end please type 'quit')")
filePath = readLine(strippingNewline: true) ?? ""
if filePath.isEmpty || filePath.lowercased() == "quit" {
break
}
// Find the base file name.
let baseFileName = NSURL(fileURLWithPath: filePath).lastPathComponent!
// Find the file extension.
let fileExtension = "." + (baseFileName as NSString).pathExtension
let inputFile: FileHandle
do {
inputFile = try FileHandle(forReadingFrom: URL.init(filePath: filePath))
} catch {
print ("Error reading file \(baseFileName)")
return -1
}
// Get the input file size.
do {
let attributes = try FileManager.default.attributesOfItem(atPath: filePath)
let fileLength = attributes[.size] as? Int ?? 0
if fileLength <= 0 {
print("Error opening file.")
return -1
}
} catch {
print("Error opening file.")
return -1
}
//=========================================////
//***** Begin MKE Encryption Process. *****////
//=========================================////
// Create encoded file name that includes the same extension.
let encodedFileName = "encoded" + fileExtension
// Delete any existing encoded file.
if FileManager.default.fileExists(atPath: encodedFileName) {
do {
try FileManager.default.removeItem(atPath: encodedFileName)
print("File \(encodedFileName) was deleted.")
} catch {
print ("Error deleting file \(encodedFileName)")
return -1
}
}
// Open the encoded file for writing.
FileManager.default.createFile(atPath: encodedFileName, contents: nil)
let encodedFile: FileHandle
do {
encodedFile = try FileHandle(forWritingTo: URL.init(filePath: encodedFileName))
} catch {
print ("Error creating file \(encodedFileName)")
return -1
}
// Start encrypt chunking session.
status = encoder.startEncrypt()
if status != mte_status_success {
print("Error starting encryption (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Go through until the end of the input file.
while (true) {
// Create buffer to hold encrypt chunk size.
let data = inputFile.readData(ofLength: encryptChunkSize)
var encryptChunkBuf = data.bytes
// Read a portion of the input file of size encryptChunkSize to the encryption buffer.
if (data.count == 0) {
break
}
// Encrypt the chunk buffer.
status = encoder.encryptChunk(&encryptChunkBuf)
if status != mte_status_success {
print("Error encrypting chunk (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Write the chunk buffer to the encoded file.
do {
try encodedFile.write(contentsOf: encryptChunkBuf)
} catch {
print ("Error writing to \(encodedFileName)")
return -1
}
}
// Close the input file.
do {
try inputFile.close()
} catch {
print ("Error closing \(baseFileName)")
}
// Finish the encryption with the encryption buffer.
let finishBuffer = encoder.finishEncrypt()
status = finishBuffer.status
if status != mte_status_success {
print("Error finishing encryption (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Write the result bytes from encrypt finish.
if finishBuffer.encoded.count > 0 {
do {
try encodedFile.write(contentsOf: finishBuffer.encoded)
} catch {
print ("Error writing to \(encodedFileName)")
return -1
}
}
// Close the encoded file.
do {
try encodedFile.close()
} catch {
print ("Error closing \(encodedFileName)")
}
print ("Successfully encoded file \(encodedFileName)")
#!/usr/bin/env python3
# Import relevant modules for the program.
from MteMkeEnc import MteMkeEnc
from MteStatus import MteStatus
from MteBase import MteBase
import os
import sys
def main():
# Create MKE Encoder.
mke_encoder = MteMkeEnc.fromdefault()
# Set identifier.
# These values should 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.
personal_str = "demo"
# Check how long entropy we need, set default all 0's.
# This should be treated like encryption keys - this is just an example.
entropy = "0"
entropy_min_bytes = MteBase.get_drbgs_entropy_min_bytes(mke_encoder.get_drbg())
while len(entropy) < entropy_min_bytes:
entropy += "0"
entropy = bytearray(entropy,'utf-8')
# Set mte values for the Encoder.
mke_encoder.set_entropy(entropy)
mke_encoder.set_nonce(0)
# Instantiate the MKE Encoder.
encoder_status = mke_encoder.instantiate(personal_str)
if encoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(encoder_status),\
MteBase.get_status_description(encoder_status)
print("Encoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
return encoder_status.value
# Initialize chunking session
encoder_status = mke_encoder.start_encrypt()
if encoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(encoder_status),\
MteBase.get_status_description(encoder_status)
print("Failed to start encode chunk ({0}): {1}".format(\
status,message),file=sys.stderr)
return encoder_status.value
# Open input file and create and open output file.
# Deletes output file if it exists.
in_file = "src/plaintext.txt"
out_file = "src/encoded.txt"
dir_ = "src"
try:
if os.path.exists(out_file):
os.remove(out_file)
except:
print("Error while deleting file ", out_file)
finally:
if not os.path.exists(dir_):
os.makedirs(dir_)
out_file = open(out_file, "wb")
in_file = open(in_file,"rb")
# While bytes read from file exist,
# continue to read them to encode.
bytes_read = bytearray()
chunk_size = 1024 ## Set buffer size
while True:
in_bytes = in_file.read(chunk_size)
bytes_read+=in_bytes
## Break if no bytes are left
if len(in_bytes) == 0:
break
# Read and encrypt chunks of the input file.
for byte_chunk in range(0, len(bytes_read)-1,chunk_size):
data = bytearray(chunk_size)
# Append chunks and extra bytes to an array for encoding.
for bytes_ in range(len(data)):
if (byte_chunk + bytes_) < len(bytes_read):
data[bytes_] = bytes_read[byte_chunk + bytes_]
# Add all bytes to be encrypted.
data_bytes = bytes(data)
# Encode data in place - encoded data put back in buffer.
encoder_status = mke_encoder.encrypt_chunk(data_bytes)
if encoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(encoder_status),\
MteBase.get_status_description(encoder_status)
print("Failed to encode chunk ({0}): {1}".format(\
status,message),file=sys.stderr)
return encoder_status.value
# Write bytes to output file.
if len(data_bytes) > 0:
out_file.write(data_bytes)
# Finish the chunking session.
encoded_chunk,encoder_status = mke_encoder.finish_encrypt()
if encoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(encoder_status),\
MteBase.get_status_description(encoder_status)
print("Failed to finish encode session.\n({0}): {1}".format(status,message),\
file=sys.stderr)
return encoder_status.value
# Append final result to output file.
if len(encoded_chunk) > 0:
out_file.write(encoded_chunk)
# Close the IO stream files.
in_file.close()
out_file.close()
# Success.
return 0
package main
import (
"bufio"
"fmt"
"goSocket/mte"
"io"
"os"
"path/filepath"
"strings"
)
//-----------------------
// Application constants
//-----------------------
const (
bufferSize = 1024
defaultExtension = ".txt"
nonce = 1
identifier = "mySecretIdentifier"
companyName = ""
companyLicense = ""
)
func main() {
//------------------------------------
// Prompting message for file to copy
//------------------------------------
fmt.Print("Please enter path to file\n")
reader := bufio.NewReader(os.Stdin)
fPath, _ := reader.ReadString('\n')
//---------------------------
// take off carriage return
//---------------------------
fPath = strings.Replace(fPath, "\n", "", -1)
fPath = strings.Replace(fPath, "\r", "", -1)
//--------------------------------
// Check to make sure file exists
//--------------------------------
_, err := os.Stat(fPath)
if err != nil {
fmt.Printf("Path does not exist! %s", err)
return
}
encodedFileName := "encodedFile"
decodedFileName := "decodedFile"
//-----------------------
// Get the file extension
//-----------------------
extension := defaultExtension
fExt := filepath.Ext(fPath)
if len(fExt) > 0 {
extension = fExt
}
encodedFileName = encodedFileName + extension
decodedFileName = decodedFileName + extension
//---------------
// Open the file
//---------------
f, err := os.Open(fPath)
if err != nil {
fmt.Printf("error opening %s: %s", fPath, err)
return
}
defer f.Close()
//-----------------------------------------
// Check if file we are creating is there
// If present delete file
//-----------------------------------------
_, err = os.Stat(encodedFileName)
if err == nil {
e := os.Remove(encodedFileName)
if e != nil {
fmt.Printf("Error trying to delete file %s", encodedFileName)
}
}
//--------------------------------
// Create MKE Encoder and Decoder
//--------------------------------
encoder := mte.NewMkeEncDef()
defer encoder.Destroy()
//----------------------------------------------------
// defer the exit so all other defer calls are called
//----------------------------------------------------
retcode := 0
defer func() { os.Exit(retcode) }()
//------------------------------------
// Check version and output to screen
//------------------------------------
mteVersion := mte.GetVersion()
fmt.Printf("Using Mte Version %s\n", mteVersion)
//--------------------------------
// Check license -- use constants
// If no license can be blank
//--------------------------------
if !mte.InitLicense(companyName, companyLicense) {
fmt.Println("There was an error attempting to initialize the MTE License.")
return
}
//----------------------------------------------------------------------------
// check how long entropy we need, set default
// Providing Entropy in this fashion is insecure. This is for demonstration
// purposes only and should never be done in practice.
//----------------------------------------------------------------------------
entropyBytes := mte.GetDrbgsEntropyMinBytes(encoder.GetDrbg())
entropy := make([]byte, entropyBytes)
//---------------
// Fill with 0's
//---------------
for i := 0; i < entropyBytes; i++ {
entropy[i] = '0'
}
//--------------------
// Initialize encoder
//--------------------
encoder.SetEntropy(entropy)
encoder.SetNonceInt(nonce)
status := encoder.InstantiateStr(identifier)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//---------------------
// Initialize Chunking
//---------------------
status = encoder.StartEncrypt()
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "MTE Encoder startDecrypt error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//-------------------------
// Create destination file
//-------------------------
destination, err := os.Create(encodedFileName)
if err != nil {
fmt.Printf("Error trying to create destination file %s, err: %s", encodedFileName, err)
}
defer destination.Close()
//-------------------------------------------------
// Iterate through file and write to new location
//-------------------------------------------------
for {
//------------------------------
// Create buffer for file parts
//------------------------------
buf := make([]byte, bufferSize)
amountRead, err := f.Read(buf)
if err != nil && err != io.EOF {
fmt.Printf("Error trying to read file %s, err: %s", fPath, err)
}
if amountRead == 0 {
//-----------------------------------------------
// Reached the end of the file, break out of loop
//-----------------------------------------------
break
}
//----------------------------------------------------------
// If the amount that was read is less than the buffer size,
// take a slice of the original buffer
//---------------------------------------------------------
if amountRead < bufferSize {
buf = buf[:amountRead]
}
//-----------------------------------------------------------
// Encrypt the chunk
//-----------------------------------------------------------
status = encoder.EncryptChunk(buf)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encode error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
break
}
//----------------------------------------
// Write the encoded bytes to destination
//----------------------------------------
if _, err := destination.Write(buf); err != nil {
fmt.Printf("Error trying to write to file %s, err: %s", encodedFileName, err)
}
}
//-----------------------------
// End of the file reached
// Finish the chunking session
//-----------------------------
finishEncode, status := encoder.FinishEncrypt()
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Encode finish error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
}
//-------------------------------------------------
// If there are bytes to write, write them to file
//-------------------------------------------------
if finishEncode != nil {
if _, err := destination.Write(finishEncode); err != nil {
fmt.Printf("Error trying to write to file %s, err: %s", encodedFileName, err)
}
}
destination.Close()
//---------------------------
// Print out success message
//---------------------------
fmt.Printf("Finished creating %s file\n", encodedFileName)
}
MTE MKE Decode Chunking
The decoding is slightly different than the encoding. Because each decoded chunk may not be the same size as the encoded chunk, the amount is returned instead of left in the same variable. Here is a code example of how to use the MKE Decode Chunking methods. This sample takes the contents of the file that was created above and decodes the text and saves it in a different file.
- C
- C++
- CSharp
- Java
- Swift
- Python
- Go
// Init the MTE.
if (!mte_init(NULL, NULL))
{
printf("There was an error attempting to initialize the MTE.\n");
return 1;
}
// Initialize MTE license. If a license code is not required (e.g., trial
// mode), this can be skipped.
if (!mte_license_init("LicenseCompanyName", "LicenseKey"))
{
printf("There was an error attempting to initialize the MTE License.\n");
return 1;
}
// Check encrypt and decrypt chunk sizes.
size_t block_size = mte_base_ciphers_block_bytes(MTE_CIPHER_ENUM);
if (block_size > 1)
{
printf("The chunk size must be set to 1.");
return 1;
}
mte_status status;
// Set personalization string to demo for this sample.
const char* personal = "demo";
// Set nonce to the timestamp.
nonce = get_timestamp();
// Get minimum entropy amount of bytes.
size_t min_entropy_bytes = mte_base_drbgs_entropy_min_bytes(MTE_DRBG_ENUM);
if (min_entropy_bytes == 0)
{
min_entropy_bytes = 1;
}
entropy_size = min_entropy_bytes;
entropy_buff = malloc(min_entropy_bytes);
// Create byte array of random bytes to use as entropy.
int res = get_random(entropy_buff, entropy_size);
if (res != 0)
{
printf("There was an error attempting to create random entropy.\n");
return res;
}
// Create default MKE Decoder.
mte_mke_dec_init_info decoder_info = MTE_MKE_DEC_INIT_INFO_INIT(
MTE_DRBG_ENUM, MTE_TOKBYTES, MTE_VERIFIERS_ENUM, MTE_CIPHER_ENUM, MTE_HASH_ENUM, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
static MTE_HANDLE decoder;
decoder = malloc(mte_mke_dec_state_bytes(&decoder_info));
// Initiate the Decoder state.
status = mte_mke_dec_state_init(decoder, &decoder_info);
if (status != mte_status_success)
{
printf("Decoder init error (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return 1;
}
// Set the Decoder instantiation information.
mte_drbg_inst_info dec_inst_info = { &entropy_input_callback, NULL, &nonce_callback, NULL, personal, strlen(personal) };
status = mte_mke_dec_instantiate(decoder, &dec_inst_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;
}
//=========================================////
//***** Begin MKE Decryption Process. *****////
//=========================================////
// Create decoded file name that includes the same extension.
char decoded_file_name[256] = "decoded";
strcat(decoded_file_name, file_extension);
// Delete any existing decoded file.
res = remove(decoded_file_name);
if (res == 0)
{
printf("Previous file %s deleted.\n", decoded_file_name);
}
// Get the chunk state size requirement.
buff_bytes = mte_mke_dec_decrypt_state_bytes(decoder);
// Create buffer to hold MTE decryption.
unsigned char* dec_mke_buf;
dec_mke_buf = malloc(buff_bytes);
// Start decrypt chunking session.
status = mte_mke_dec_decrypt_start(decoder, dec_mke_buf);
if (status != mte_status_success)
{
fprintf(stderr, "Error starting decryption: (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
// Re-open encoded file, for read mode "r" and binary "b".
encoded_file = fopen(encoded_file_name, "rb");
// Open the decoded file, for write mode "w" and binary "b".
FILE* decoded_file;
decoded_file = fopen(decoded_file_name, "wb");
// Create buffer to hold decrypt chunk size.
char* decrypt_chunk_buf;
decrypt_chunk_buf = malloc(decrypt_chunk_size);
// Create buffer to hold decoded data, to be the size of the decrypt chunk plus the block size.
char* decoded_data_buf;
decoded_data_buf = malloc(decrypt_chunk_size + block_size);
mte_dec_args decoding_args = MTE_DEC_ARGS_INIT(NULL, 0, NULL, ×tamp_callback, NULL);
while (!feof(encoded_file))
{
// Set decrypt chunk to zero.
memset(decrypt_chunk_buf, '\0', decrypt_chunk_size);
// Read a portion of the file of size decrypt_chunk_size to the decryption buffer.
size_t amount = fread(decrypt_chunk_buf, 1, decrypt_chunk_size, encoded_file);
// Check if the amount read is 0, the end of encoded file has been reached.
if (amount == 0)
{
continue;
}
// chunk size + block size new decoded buffer
// Decrypt the chunk buffer. Use the amount read from this pass.
// Contrary to encryption, decryption in place is not allowed. A separate input buffer
// and decrypted buffer will be needed.
MTE_SET_DEC_IO(decoding_args, decrypt_chunk_buf, amount, decoded_data_buf);
status = mte_mke_dec_decrypt_chunk(decoder, dec_mke_buf, &decoding_args);
if (status != mte_status_success)
{
fprintf(stderr, "Error decrypting chunk: Status: %s/%s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return false;
}
// Not all decrypt chunk calls will have data returned.
// If there is any data, write that to the file.
if (decoding_args.bytes > 0)
{
// Write the chunk buffer to the decoded file.
fwrite(decoding_args.decoded, 1, decoding_args.bytes, decoded_file);
fflush(decoded_file);
}
}
// Finish MKE decryption.
MTE_SET_DEC_IO(decoding_args, NULL, 0, decrypt_chunk_buf);
status = mte_mke_dec_decrypt_finish(decoder, dec_mke_buf, &decoding_args);
if (status != mte_status_success)
{
fprintf(stderr, "Error finishing decryption: (%s): %s\n",
mte_base_status_name(status),
mte_base_status_description(status));
return status;
}
if (decoding_args.bytes > 0)
{
// Write the result bytes from decrypt finish.
fwrite(decoding_args.decoded, 1, decoding_args.bytes, decoded_file);
fflush(decoded_file);
}
// Free the decrypt buffer.
free(decrypt_chunk_buf);
// Free the decoded data buffer.
free(decoded_data_buf);
// Close the decoded file.
fclose(decoded_file);
// Close the encoded file.
fclose(encoded_file);
printf("Successfully decoded file %s\n", decoded_file_name);
// Create default MKE decoder.
MteMkeDec 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;
}
//=========================================////
//***** Begin MKE Decryption Process. *****////
//=========================================////
// Create decoded file name that includes the same extension.
std::string decodedFileName = "decoded" + fileExtention;
// Open the decoded file stream for writing and binary.
std::ofstream decodedFile;
// Delete any existing decoded file.
if (std::remove(decodedFileName.c_str()) == 0)
{
std::cout << "Deleted existing file " << decodedFileName << std::endl;
}
decodedFile.open(decodedFileName, std::ofstream::out | std::ofstream::binary);
// Start decrypt chunking session.
status = decoder.startDecrypt();
if (status != mte_status_success)
{
std::cerr << "Error starting decryption: ("
<< MteBase::getStatusName(status)
<< "): "
<< MteBase::getStatusDescription(status)
<< std::endl;
return status;
}
// Re-open encoded file, for reading and binary.
std::ifstream encodedInputFile;
encodedInputFile.open(encodedFileName, std::ifstream::in | std::ifstream::binary);
// Go through until the end of the input file.
while (!encodedInputFile.eof())
{
// Create buffer to hold decrypt chunk size.
char decryptChunkBuf[decryptChunkSize];
// Read a portion of the encoded file of size decryptChunkSize to the decryption buffer.
encodedInputFile.read(decryptChunkBuf, decryptChunkSize);
// The amount read from the stream.
std::streamsize amountRead = encodedInputFile.gcount();
// Decrypt the chunk buffer.
size_t decryptedBytes = 0;
const void* decryptedChunk = decoder.decryptChunk(decryptChunkBuf, amountRead, decryptedBytes);
// If there are any bytes decrypted, write that to the decoded file.
if (decryptedBytes > 0)
{
// Write the chunk buffer to the decoded file.
decodedFile.write(static_cast<const char*>(decryptedChunk), decryptedBytes);
decodedFile.flush();
}
}
// Finish MKE decryption.
size_t decryptedBytes = 0;
const void* decryptedChunk = decoder.finishDecrypt(decryptedBytes, status);
// If there are any bytes decrypted, write that to the decoded file.
if (decryptedBytes > 0)
{
// Write the chunk buffer to the decoded file.
decodedFile.write(static_cast<const char*>(decryptedChunk), decryptedBytes);
decodedFile.flush();
}
// Close the encoded file.
encodedFile.close();
// Close the decoded file.
decodedFile.close();
std::cout << "Successfully decoded file " << decodedFileName << std::endl;
string encodedFileName = "encodedText";
string decodedFileName = "decodedText";
//-----------------------------------------
// Get fPath from prompt in encoded sample
//-----------------------------------------
encodedFileName = $"{encodedFileName}{Path.GetExtension(fPath)}";
decodedFileName = $"{decodedFileName}{Path.GetExtension(fPath)}";
//--------------------------------
// Create default MTE MKE Decoder
//--------------------------------
MteMkeDec mkeDecoder = new MteMkeDec();
//---------------------------------------------------------------------------
// Set identifier (must be same as encoder)
// These values should 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 identifier = "demo";
//---------------------------------------------------------------
// Check how long entropy we need, set default all 0's
// should be treated like encryption keys - this is just example
//---------------------------------------------------------------
int entropyMinBytes = mkeDecoder.GetDrbgsEntropyMinBytes(mkeDecoder.GetDrbg());
string entropy = (entropyMinBytes > 0) ? new String('0', entropyMinBytes) : entropy;
//---------------------------------
// Set MKE values for the Decoder
//---------------------------------
mkeDecoder.SetEntropy(Encoding.UTF8.GetBytes(entropy));
mkeDecoder.SetNonce(0);
//------------------------
// Initialize the Decoder
//------------------------
decoderStatus = mkeDecoder.Instantiate(identifier);
if (decoderStatus != MteStatus.mte_status_success)
{
throw new ApplicationException($"Failed to initialize the MTE decoder engine. "
+ $"Status: {mkeDecoder.GetStatusName(encoderStatus)} / "
+ $"{mkeDecoder.GetStatusDescription(encoderStatus)}");
}
//-----------------------------
// Initialize chunking session
//-----------------------------
MteStatus decoderStatus = mkeDecoder.StartDecrypt();
if(decoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to start decode chunk. Status: "
+ mkeDecoder.GetStatusName(decoderStatus)+ " / "
+ mkeDecoder.GetStatusDescription(decoderStatus));
}
//------------------------------------
// Read file in and decode using MKE
//------------------------------------
using (FileStream stream = File.OpenRead("encoded.txt"))
using (FileStream writeStream = File.OpenWrite("decoded.txt"))
{
BinaryReader reader = new BinaryReader(stream);
BinaryWriter writer = new BinaryWriter(writeStream);
//-----------------------------------
// Create a buffer to hold the bytes
//-----------------------------------
byte[] buffer = new Byte[1024];
int bytesRead;
//----------------------------------------
// While the read method returns bytes
// Keep writing them to the output stream
//----------------------------------------
while ((bytesRead = stream.Read(buffer, 0, 1024)) > 0)
{
//-------------------------------------------
// Ensure we are only decoding what was read
//-------------------------------------------
byte[] decodedData = new byte[0];
if (bytesRead == buffer.Length)
{
decodedData = _mkeDecoder.DecryptChunk(buffer);
}
else
{
//------------------------------------------
// Find out what the decoded length will be
//------------------------------------------
var cipherBlocks = _mkeDecoder.GetCiphersBlockBytes(_mkeDecoder.GetCipher());
int buffBytes = bytesRead - cipherBlocks;
//----------------------------------
// Allocate buffer for decoded data
//----------------------------------
decodedData = new byte[buffBytes];
int decryptError = _mkeDecoder.DecryptChunk(buffer, 0, bytesRead, decodedData, 0);
if (decryptError < 0)
{
throw new ApplicationException("Error decoding data.");
}
}
writeStream.Write(decodedData, 0, decodedData.Length);
}
//-----------------------------
// Finish the chunking session
//-----------------------------
byte[] finalDecodedChunk = mkeDecoder.FinishDecrypt(out MteStatus finishStatus);
if(finishStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to finish decode chunk. Status: "
+ mkeDecoder.GetStatusName(finishStatus)+ " / "
+ mkeDecoder.GetStatusDescription(finishStatus));
}
//-----------------------------------------------------------------------
// Check if there is additional bytes if not initialize empty byte array
//-----------------------------------------------------------------------
if(finalDecodedChunk.Length <=0) { finalDecodedChunk = new byte[0]; }
//------------------------------------
// Append the final data to the file
//------------------------------------
writeStream.Write(finalDecodedChunk, 0, finalDecodedChunk.Length);
}
private static final int BUFFER_SIZE = 1024; // 1KB
private static String _pathToEncodedFile = "src/encoded";
private static String _pathToDecodedFile = "src/decoded";
private static final String _defaultExtension = ".txt";
//------------------------
// Create default Decoder
//------------------------
MteMkeDec mkeDecoder = new MteMkeDec();
//----------------------------------------------------------------------
// Set identifier
// These values should 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 identifier = "demo";
//----------------------------------------------------------------------
// Check how long entropy we need, set default all 0's
// should be treated like encryption keys - this is just example
//----------------------------------------------------------------------
int entropyMinBytes = MteBase.getDrbgsEntropyMinBytes(mkeDecoder.getDrbg());
String entropy = "0";
entropy = entropy.repeat(entropyMinBytes);
//--------------------------------
// Set MKE values for the Decoder
//--------------------------------
mkeDecoder.setEntropy(entropy.getBytes());
mkeDecoder.setNonce(0);
//------------------------
// Initialize MKE Decoder
//------------------------
MteStatus decoderStatus = mkeDecoder.instantiate(identifier);
if(decoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to initialize decoder. Status: "
+ MteBase.getStatusName(decoderStatus)+ " / "
+ MteBase.getStatusDescription(decoderStatus));
}
//-----------------------------
// Initialize chunking session
//-----------------------------
decoderStatus = mkeDecoder.startDecrypt();
if(decoderStatus != MteStatus.mte_status_success)
{
throw new Exception("Failed to start decode chunk. Status: "
+ MteBase.getStatusName(decoderStatus)+ " / "
+ MteBase.getStatusDescription(decoderStatus));
}
//---------------------------------
// Clean up decoded file if exists
//---------------------------------
// Use decoded file created in encoded code
Path fileToDeletePathDC = Paths.get(_pathToDecodedFile);
Files.deleteIfExists(_pathToDecodedFile);
try (
//------------------------------------
// Read file in and decode using MKE
//------------------------------------
InputStream inputStream = new FileInputStream(outputFile);
OutputStream outputStream = new FileOutputStream(_pathToDecodedFile);
) {
byte[] buffer = new byte[BUFFER_SIZE];
int cipherBlock = mkeDecoder.getCiphersBlockBytes(mkeDecoder.getCipher());
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
//-------------------------------------------------------
// If bytesRead is equal to buffer do simple decodeChunk
//-------------------------------------------------------
byte[] decodedChunk = new byte[0];
if (bytesRead == buffer.length)
{
decodedChunk = _mkeDecoder.decryptChunk(buffer);
}
else
{
//------------------------------------------
// Find out what the decoded length will be
//------------------------------------------
int cipherBlock = _mkeDecoder.getCiphersBlockBytes(_mkeDecoder.getCipher());
int buffBytes = bytesRead - cipherBlock;
//----------------------------------
// Allocate buffer for decoded data
//----------------------------------
decodedChunk = new byte[buffBytes];
int decryptError = _mkeDecoder.decryptChunk(buffer, 0, bytesRead, decodedChunk, 0);
if (decryptError < 0)
{
throw new IllegalArgumentException("decrypt chunk error.");
}
}
//-----------------------------
// Write decoded chunk to file
//-----------------------------
outputStream.write(decodedChunk);
}
//-----------------------------
// Finish the chunking session
//-----------------------------
MteBase.ArrStatus finalEncodedChunk = mkeDecoder.finishDecrypt();
if(finalEncodedChunk.status != MteStatus.mte_status_success)
{
throw new Exception("Failed to finish decode chunk. Status: "
+ MteBase.getStatusName(finalEncodedChunk.status)+ " / "
+ MteBase.getStatusDescription(finalEncodedChunk.status));
}
//-----------------------------------------------------------------------
// Check if there is additional bytes if not initialize empty byte array
//-----------------------------------------------------------------------
if(finalEncodedChunk.arr.length <=0) { finalEncodedChunk.arr = new byte[0]; }
//-----------------------------------
// Append the final data to the file
//-----------------------------------
outputStream.write(finalEncodedChunk.arr);
} catch (IOException ex) {
ex.printStackTrace();
}
// Create default MKE decoder.
MteMkeDec 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;
}
//=========================================////
//***** Begin MKE Decryption Process. *****////
//=========================================////
// Create decoded file name that includes the same extension.
let decodedFileName = "decoded" + fileExtension
// Delete any existing decoded file.
if FileManager.default.fileExists(atPath: decodedFileName) {
try! FileManager.default.removeItem(atPath: decodedFileName)
print("File (\(decodedFileName) was deleted.")
}
// Open the decoded file for writing.
FileManager.default.createFile(atPath: decodedFileName, contents: nil)
let decodedFile: FileHandle
do {
decodedFile = try FileHandle(forWritingTo: URL.init(filePath: decodedFileName))
} catch {
print ("Error creating file \(decodedFileName)")
return -1
}
// Start decrypt chunking session.
status = decoder.startDecrypt()
if status != mte_status_success {
print("Error starting decryption (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// Re-open encoded file.
let encodedInputFile: FileHandle
do {
encodedInputFile = try FileHandle(forReadingFrom: URL.init(filePath: encodedFileName))
} catch {
print ("Error creating file \(encodedFileName)")
return -1
}
// Go through until the end of the input file.
while (true) {
// Create buffer to hold decrypt chunk size.
let data = encodedInputFile.readData(ofLength: decryptChunkSize)
let decryptChunkBuf = data.bytes
// Read a portion of the encoded file of size decryptChunkSize to the decryption buffer.
if (data.count == 0) {
break
}
// Decrypt the chunk buffer.
let decryptedResult = decoder.decryptChunk(decryptChunkBuf)
status = decryptedResult.status
if status != mte_status_success {
print("Error decrypting chunk (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// If there are any bytes decrypted, write that to the decoded file.
if decryptedResult.data.count > 0 {
// Write the chunk buffer to the decoded file.
do {
try decodedFile.write(contentsOf: decryptedResult.data)
} catch {
print ("Error attempting to write to file " + decodedFileName)
return -1
}
}
}
// Finish MTE decryption.
let decryptedResult = decoder.finishDecrypt()
status = decryptedResult.status
if status != mte_status_success {
print("Error finishing decryption (\(MteBase.getStatusName(status))): " +
MteBase.getStatusDescription(status))
return Int32(status.rawValue)
}
// If there are any bytes decrypted, write that to the decoded file.
if decryptedResult.data.count > 0 {
// Write the chunk buffer to the decoded file.
do {
try decodedFile.write(contentsOf: decryptedResult.data)
} catch {
print ("Error writing to \(decodedFileName)")
return -1
}
}
// Close the encoded fie.
do {
try encodedInputFile.close()
} catch {
print ("Error closing \(encodedFileName)")
}
// Close the decoded file.
do {
try decodedFile.close()
} catch {
print ("Error closing \(decodedFileName)")
}
print ("Successfully decoded file \(decodedFileName)")
#!/usr/bin/env python3
# Import relevant modules for the program.
from MteMkeDec import MteMkeDec
from MteStatus import MteStatus
from MteBase import MteBase
import os
import sys
def main():
# Create MKE Decoder.
mke_decoder = MteMkeDec.fromdefault()
# Set identifier (same as Encoder)
# These values should 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
personal_str = "demo"
# Check how long entropy we need, set default all 0's.
# This should be treated like encryption keys - this is just an example.
entropy = "0"
entropy_min_bytes = MteBase.get_drbgs_entropy_min_bytes(mke_decoder.get_drbg())
while len(entropy) < entropy_min_bytes:
entropy += "0"
entropy = bytearray(entropy,'utf-8')
# Set mte values for the Decoder.
mke_decoder.set_entropy(entropy)
mke_decoder.set_nonce(0)
# Instantiate the MKE Decoder.
decoder_status = mke_decoder.instantiate(personal_str)
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Decoder instantiate error ({0}): {1}".format(\
status,message),file=sys.stderr)
return decoder_status.value
# Initialize chunking session.
decoder_status = mke_decoder.start_decrypt()
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Failed to start decoding session ({0}): {1}".format(\
status,message),file=sys.stderr)
return decoder_status.value
# Open input file and create output file.
# Deletes output file if it exists.
decoded_file = "src/decoded.txt"
in_file = "src/encoded.txt"
try:
if os.path.exists(decoded_file):
os.remove(decoded_file)
except:
print("Error while deleting file ", decoded_file)
finally:
decoded_file = open(decoded_file,"wb")
in_file = open(in_file,"rb")
# While bytes read from file exist,
# continue to write them to output file.
bytes_decrypted = bytearray()
chunk_size = 1024 # Set buffer size.
while True:
in_bytes = in_file.read(chunk_size)
# Decrypt the chunk.
decrypted_chunk = mke_decoder.decrypt_chunk(in_bytes)
if len(decrypted_chunk) > 0:
bytes_decrypted += decrypted_chunk
# Remove white space null bytes from strings.
decrypted_str = decrypted_chunk.decode()
decoded_file.write(bytearray(decrypted_str.encode()))
elif len(in_bytes) == 0:
break
# Finish the chunking session.
decrypted_chunk,decoder_status = mke_decoder.finish_decrypt()
if decoder_status != MteStatus.mte_status_success:
(status,message) = MteBase.get_status_name(decoder_status),\
MteBase.get_status_description(decoder_status)
print("Failed to finish the decryption session.\n({0}): {1}".format(status,message),\
file=sys.stderr)
return decoder_status.value
# Check for additional bytes and append them.
while len(decrypted_chunk.decode()) > 0:
bytes_decrypted += decrypted_chunk
decrypted_str = decrypted_chunk.decode()
decoded_file.write(bytearray(decrypted_str.encode()))
# Close IO stream files.
decoded_file.close()
in_file.close()
# Success.
return 0
package main
import (
"bufio"
"fmt"
"goSocket/mte"
"io"
"os"
"path/filepath"
"strings"
)
//-----------------------
// Application constants
//-----------------------
const (
bufferSize = 1024
defaultExtension = ".txt"
nonce = 1
identifier = "mySecretIdentifier"
companyName = ""
companyLicense = ""
)
func main() {
//------------------------------------
// Prompting message for file to copy
//------------------------------------
fmt.Print("Please enter path to file\n")
reader := bufio.NewReader(os.Stdin)
fPath, _ := reader.ReadString('\n')
//---------------------------
// take off carriage return
//---------------------------
fPath = strings.Replace(fPath, "\n", "", -1)
fPath = strings.Replace(fPath, "\r", "", -1)
//--------------------------------
// Check to make sure file exists
//--------------------------------
_, err := os.Stat(fPath)
if err != nil {
fmt.Printf("Path does not exist! %s", err)
return
}
encodedFileName := "encodedFile"
decodedFileName := "decodedFile"
//-----------------------
// Get the file extension
//-----------------------
extension := defaultExtension
fExt := filepath.Ext(fPath)
if len(fExt) > 0 {
extension = fExt
}
encodedFileName = encodedFileName + extension
decodedFileName = decodedFileName + extension
//--------------------------------
// Create MKE Decoder
//--------------------------------
decoder := mte.NewMkeDecDef()
defer decoder.Destroy()
//----------------------------------------------------
// defer the exit so all other defer calls are called
//----------------------------------------------------
retcode := 0
defer func() { os.Exit(retcode) }()
//------------------------------------
// Check version and output to screen
//------------------------------------
mteVersion := mte.GetVersion()
fmt.Printf("Using Mte Version %s\n", mteVersion)
//--------------------------------
// Check license -- use constants
// If no license can be blank
//--------------------------------
if !mte.InitLicense(companyName, companyLicense) {
fmt.Println("There was an error attempting to initialize the MTE License.")
return
}
//----------------------------------------------------------------------------
// check how long entropy we need, set default
// Providing Entropy in this fashion is insecure. This is for demonstration
// purposes only and should never be done in practice.
//----------------------------------------------------------------------------
entropyBytes := mte.GetDrbgsEntropyMinBytes(encoder.GetDrbg())
entropy := make([]byte, entropyBytes)
//---------------
// Fill with 0's
//---------------
for i := 0; i < entropyBytes; i++ {
entropy[i] = '0'
}
//---------------------
// Initialize decoder
//---------------------
decoder.SetEntropy(entropy)
decoder.SetNonceInt(nonce)
status = decoder.InstantiateStr(identifier)
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "Decoder instantiate error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//---------------------------------------------------
// now read and decode file into new destination -->
//---------------------------------------------------
fRead, err := os.Open(encodedFileName)
if err != nil {
fmt.Printf("error opening %s: %s", encodedFileName, err)
return
}
defer fRead.Close()
//--------------------------------
// If the file is there delete it
//--------------------------------
_, err = os.Stat(decodedFileName)
if err == nil {
e := os.Remove(decodedFileName)
if e != nil {
fmt.Printf("Error trying to delete file %s", decodedFileName)
}
}
//-------------------------------------
// Initialize decrypt chunking session
//-------------------------------------
status = decoder.StartDecrypt()
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "MTE Decoder startDecrypt error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//--------------------------------
// Create final destination file
//--------------------------------
finalDest, err := os.Create(decodedFileName)
if err != nil {
fmt.Printf("Error trying to create final destination file %s, err: %s", decodedFileName, err)
}
defer finalDest.Close()
//----------------------------------
// Create buffer to read bytes into
//----------------------------------
//------------------------------------------
// Iterate through encoded file and decode
//------------------------------------------
for {
//------------------------------
// Create buffer for file parts
//------------------------------
buf := make([]byte, bufferSize)
amountRead, err := fRead.Read(buf)
if err != nil && err != io.EOF {
fmt.Printf("Error trying to read file %s, err: %s", encodedFileName, err)
}
//-----------------------------------------------------------
// If we reached the end of the file finish chunking session
//-----------------------------------------------------------
if amountRead == 0 {
//-----------------------------------------------
// Reached the end of the file, break out of loop
//-----------------------------------------------
break
}
//----------------------------------------------------------
// If the amount that was read is less than the buffer size,
// take a slice of the original buffer
//---------------------------------------------------------
if amountRead < bufferSize {
buf = buf[:amountRead]
}
decoded := decoder.DecryptChunk(buf)
if decoded == nil {
fmt.Fprintf(os.Stderr, "Decode error.\n")
break
}
if _, err := finalDest.Write(decoded); err != nil {
fmt.Printf("Error trying to write to file %s, err: %s", decodedFileName, err)
}
}
finishDecodeChunk, status := decoder.FinishDecrypt()
if status != mte.Status_mte_status_success {
fmt.Fprintf(os.Stderr, "MTE Decoder finishDecrypt error (%v): %v\n",
mte.GetStatusName(status), mte.GetStatusDescription(status))
retcode = int(status)
return
}
//---------------------------------------------------------
// if the return bytes are nil -- set to empty byte array
//---------------------------------------------------------
if finishDecodeChunk != nil {
if _, err := finalDest.Write(finishDecodeChunk); err != nil {
fmt.Printf("Error trying to write to file %s, err: %s", encodedFileName, err)
}
}
//---------------------------
// Print out success message
//---------------------------
fmt.Printf("Finished creating %s file\n", decodedFileName)
}
Full Chunking Sample Project
Eclypses has developed full sample projects demonstrating chunking.