1263320Sdim/*
2263320Sdim * Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved.
3263320Sdim *
4263320Sdim * Licensed under the Apache License 2.0 (the "License").  You may not use
5263320Sdim * this file except in compliance with the License.  You can obtain a copy
6263320Sdim * in the file LICENSE in the source distribution or at
7263320Sdim * https://www.openssl.org/source/license.html
8263320Sdim */
9263320Sdim
10263320Sdim/*
11263320Sdim * Simple ARIA CBC encryption demonstration program.
12263320Sdim */
13263320Sdim
14263320Sdim#include <stdio.h>
15263320Sdim#include <openssl/err.h>
16263320Sdim#include <openssl/bio.h>
17263320Sdim#include <openssl/evp.h>
18263320Sdim#include <openssl/crypto.h>
19263320Sdim#include <openssl/core_names.h>
20263320Sdim
21263320Sdim/* ARIA key */
22263320Sdimstatic const unsigned char cbc_key[] = {
23263320Sdim    0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66,
24263320Sdim    0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69,
25263320Sdim    0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f
26263320Sdim};
27263320Sdim
28263320Sdim/* Unique initialisation vector */
29263320Sdimstatic const unsigned char cbc_iv[] = {
30263320Sdim    0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84,
31263320Sdim    0x99, 0xaa, 0x3e, 0x68,
32263320Sdim};
33263320Sdim
34263320Sdim/* Example plaintext to encrypt */
35263320Sdimstatic const unsigned char cbc_pt[] = {
36263320Sdim    0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea,
37263320Sdim    0xcc, 0x2b, 0xf2, 0xa5
38263320Sdim};
39263320Sdim
40263320Sdim/* Expected ciphertext value */
41263320Sdimstatic const unsigned char cbc_ct[] = {
42263320Sdim    0x9a, 0x44, 0xe6, 0x85, 0x94, 0x26, 0xff, 0x30, 0x03, 0xd3, 0x7e, 0xc6,
43263320Sdim    0xb5, 0x4a, 0x09, 0x66, 0x39, 0x28, 0xf3, 0x67, 0x14, 0xbc, 0xe8, 0xe2,
44263320Sdim    0xcf, 0x31, 0xb8, 0x60, 0x42, 0x72, 0x6d, 0xc8
45263320Sdim};
46263320Sdim
47263320Sdim/*
48263320Sdim * A library context and property query can be used to select & filter
49263320Sdim * algorithm implementations. If they are NULL then the default library
50263320Sdim * context and properties are used.
51263320Sdim */
52263320SdimOSSL_LIB_CTX *libctx = NULL;
53263320Sdimconst char *propq = NULL;
54263320Sdim
55int 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;
103err:
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
113int 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;
159err:
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
169int 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