Skip to content

CNTR Sample Application for Encryption

Pablo de Lara edited this page Mar 1, 2021 · 2 revisions

API Overview

Based off the MPEG CENC in CBCS mode sample application (https://github.com/intel/intel-ipsec-mb/wiki/MPEG-CENC-in-CBCS-mode) but reworked for AES Counter mode.

API Information

Below is a sample application to demonstrate how to use CNTR cipher for encryption. In the example below we are expanding keys into AES round keys, CTR uses only encryption keys for both encrypt and decrypt operations.

NULL_HASH is defined here so no authentication takes place.

encrypt_key 128-bit encryption key.

plain_text plain text for encryption.

cipher_text expected cipher text output, i.e. encrypted plain text with use of encrypt_key and iv.

iv is the initialisation vector.

Sample Application

#include <stdio.h> 
#include <stdint.h> 
#include "intel-ipsec-mb.h" 
#include <string.h>  

int main(int argc, char **argv) 

{ 
    IMB_MGR *p_mgr = NULL; 
    IMB_JOB *job = NULL; 
    IMB_ARCH arch; 
    uint64_t flags = 0; 
    uint32_t enc_keys[11*4] __attribute__((aligned(16))); /* 16 byte keys * 11 rounds */ 
    uint32_t dec_keys[11*4] __attribute__((aligned(16))); /* unused for AES-CTR */ 
    uint8_t buf[1024]; 

    /* Test vector for AES-CTR-128 */ 
    const uint8_t encrypt_key[16] = { 
        0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, 
        0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E 
    }; 

    const uint8_t plain_text[16] = { 
        0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, 
        0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 
    }; 

    const uint8_t cipher_text[16] = { 
        0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, 
        0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 
    }; 

    const uint8_t iv[16] = { 
        0x00, 0x00, 0x00, 0x30,	/* nonce */ 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
    }; 

    int j, res; 
 
    /* allocate multi-buffer manager */ 
    p_mgr = alloc_mb_mgr(flags); 
    if (p_mgr == NULL){ 
        printf("Error allocating MB_MGR structure!\n"); 
        return EXIT_FAILURE; 
    } 

    /* initialize mb_mgr */ 
    init_mb_mgr_auto(p_mgr, &arch);
    switch(arch) { 
    case IMB_ARCH_NOAESNI: 
            printf("Using NOAESNI interface\n"); 
            break; 
    case IMB_ARCH_SSE: 
            printf("Using SSE interface\n"); 
            break; 
    case IMB_ARCH_AVX: 
            printf("Using AVX interface\n"); 
            break; 
    case IMB_ARCH_AVX2: 
            printf("Using AVX2 interface\n"); 
            break; 
    case IMB_ARCH_AVX512: 
            printf("Using AVX512 interface\n"); 
            break; 
    default: 
            printf("Error: No supported interface detected!\n"); 
            return EXIT_FAILURE; 
    } 

    /* expand aes-128 key into round keys */ 
    IMB_AES_KEYEXP_128(p_mgr, encrypt_key, enc_keys ,dec_keys); 

    /* submit jobs */ 
    printf("Submitting job...\n"); 
    job = IMB_GET_NEXT_JOB(p_mgr); 
    job->cipher_direction = IMB_DIR_ENCRYPT; /* or IMB_DIR_DECRYPT */ 
    job->chain_order = IMB_ORDER_CIPHER_HASH; /* HASH_CIPHER for DECRYPT */ 
    job->src = plain_text; 
    job->dst = buf; 
    job->cipher_mode = IMB_CIPHER_CNTR; 
    job->enc_keys = enc_keys; 
    job->dec_keys = enc_keys; 
    job->key_len_in_bytes = 16; 
    job->iv = iv; 
    job->iv_len_in_bytes = 12; 
    job->cipher_start_src_offset_in_bytes = 0; 
    job->msg_len_to_cipher_in_bytes = sizeof(plain_text); 
    job->hash_alg = IMB_AUTH_NULL; 

    job = IMB_SUBMIT_JOB(p_mgr); 
    if (job == NULL) 
            printf("Received NULL\n"); 
    else 
            printf("Received job!\n"); 
      
    /* flush the scheduler - may be required if manager is to be re-used */ 
     while ((job = IMB_FLUSH_JOB(p_mgr)) != NULL) 
         ; 
     free_mb_mgr(p_mgr); 
}

Application Output

Using AVX512 interface 
Submitting job... 
Received job!