Home | History | Annotate | Line # | Download | only in cipher
      1 /*
      2  * Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 /*
     11  * Simple ARIA CBC encryption demonstration program.
     12  */
     13 
     14 #include <stdio.h>
     15 #include <openssl/err.h>
     16 #include <openssl/bio.h>
     17 #include <openssl/evp.h>
     18 #include <openssl/crypto.h>
     19 #include <openssl/core_names.h>
     20 
     21 /* ARIA key */
     22 static const unsigned char cbc_key[] = {
     23     0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66,
     24     0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69,
     25     0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f
     26 };
     27 
     28 /* Unique initialisation vector */
     29 static const unsigned char cbc_iv[] = {
     30     0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84,
     31     0x99, 0xaa, 0x3e, 0x68,
     32 };
     33 
     34 /* Example plaintext to encrypt */
     35 static const unsigned char cbc_pt[] = {
     36     0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea,
     37     0xcc, 0x2b, 0xf2, 0xa5
     38 };
     39 
     40 /* Expected ciphertext value */
     41 static const unsigned char cbc_ct[] = {
     42     0x9a, 0x44, 0xe6, 0x85, 0x94, 0x26, 0xff, 0x30, 0x03, 0xd3, 0x7e, 0xc6,
     43     0xb5, 0x4a, 0x09, 0x66, 0x39, 0x28, 0xf3, 0x67, 0x14, 0xbc, 0xe8, 0xe2,
     44     0xcf, 0x31, 0xb8, 0x60, 0x42, 0x72, 0x6d, 0xc8
     45 };
     46 
     47 /*
     48  * A library context and property query can be used to select & filter
     49  * algorithm implementations. If they are NULL then the default library
     50  * context and properties are used.
     51  */
     52 OSSL_LIB_CTX *libctx = NULL;
     53 const char *propq = NULL;
     54 
     55 int aria_cbc_encrypt(void)
     56 {
     57     int ret = 0;
     58     EVP_CIPHER_CTX *ctx;
     59     EVP_CIPHER *cipher = NULL;
     60     int outlen, tmplen;
     61     size_t cbc_ivlen = sizeof(cbc_iv);
     62     unsigned char outbuf[1024];
     63     unsigned char outtag[16];
     64 
     65     printf("ARIA CBC Encrypt:\n");
     66     printf("Plaintext:\n");
     67     BIO_dump_fp(stdout, cbc_pt, sizeof(cbc_pt));
     68 
     69     /* Create a context for the encrypt operation */
     70     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
     71         goto err;
     72 
     73     /* Fetch the cipher implementation */
     74     if ((cipher = EVP_CIPHER_fetch(libctx, "ARIA-256-CBC", propq)) == NULL)
     75         goto err;
     76 
     77     /*
     78      * Initialise an encrypt operation with the cipher/mode, key and IV.
     79      * We are not setting any custom params so let params be just NULL.
     80      */
     81     if (!EVP_EncryptInit_ex2(ctx, cipher, cbc_key, cbc_iv, /* params */ NULL))
     82         goto err;
     83 
     84     /* Encrypt plaintext */
     85     if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, cbc_pt, sizeof(cbc_pt)))
     86         goto err;
     87 
     88     /* Finalise: there can be some additional output from padding */
     89     if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen))
     90         goto err;
     91     outlen += tmplen;
     92 
     93     /* Output encrypted block */
     94     printf("Ciphertext (outlen:%d):\n", outlen);
     95     BIO_dump_fp(stdout, outbuf, outlen);
     96 
     97     if (sizeof(cbc_ct) == outlen && !CRYPTO_memcmp(outbuf, cbc_ct, outlen))
     98         printf("Final ciphertext matches expected ciphertext\n");
     99     else
    100         printf("Final ciphertext differs from expected ciphertext\n");
    101 
    102     ret = 1;
    103 err:
    104     if (!ret)
    105         ERR_print_errors_fp(stderr);
    106 
    107     EVP_CIPHER_free(cipher);
    108     EVP_CIPHER_CTX_free(ctx);
    109 
    110     return ret;
    111 }
    112 
    113 int aria_cbc_decrypt(void)
    114 {
    115     int ret = 0;
    116     EVP_CIPHER_CTX *ctx;
    117     EVP_CIPHER *cipher = NULL;
    118     int outlen, tmplen, rv;
    119     size_t cbc_ivlen = sizeof(cbc_iv);
    120     unsigned char outbuf[1024];
    121 
    122     printf("ARIA CBC Decrypt:\n");
    123     printf("Ciphertext:\n");
    124     BIO_dump_fp(stdout, cbc_ct, sizeof(cbc_ct));
    125 
    126     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
    127         goto err;
    128 
    129     /* Fetch the cipher implementation */
    130     if ((cipher = EVP_CIPHER_fetch(libctx, "ARIA-256-CBC", propq)) == NULL)
    131         goto err;
    132 
    133     /*
    134      * Initialise an encrypt operation with the cipher/mode, key and IV.
    135      * We are not setting any custom params so let params be just NULL.
    136      */
    137     if (!EVP_DecryptInit_ex2(ctx, cipher, cbc_key, cbc_iv, /* params */ NULL))
    138         goto err;
    139 
    140     /* Decrypt plaintext */
    141     if (!EVP_DecryptUpdate(ctx, outbuf, &outlen, cbc_ct, sizeof(cbc_ct)))
    142         goto err;
    143 
    144     /* Finalise: there can be some additional output from padding */
    145     if (!EVP_DecryptFinal_ex(ctx, outbuf + outlen, &tmplen))
    146         goto err;
    147     outlen += tmplen;
    148 
    149     /* Output decrypted block */
    150     printf("Plaintext (outlen:%d):\n", outlen);
    151     BIO_dump_fp(stdout, outbuf, outlen);
    152 
    153     if (sizeof(cbc_pt) == outlen && !CRYPTO_memcmp(outbuf, cbc_pt, outlen))
    154         printf("Final plaintext matches original plaintext\n");
    155     else
    156         printf("Final plaintext differs from original plaintext\n");
    157 
    158     ret = 1;
    159 err:
    160     if (!ret)
    161         ERR_print_errors_fp(stderr);
    162 
    163     EVP_CIPHER_free(cipher);
    164     EVP_CIPHER_CTX_free(ctx);
    165 
    166     return ret;
    167 }
    168 
    169 int main(int argc, char **argv)
    170 {
    171     if (!aria_cbc_encrypt())
    172        return 1;
    173 
    174     if (!aria_cbc_decrypt())
    175         return 1;
    176 
    177     return 0;
    178 }
    179