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