Home | History | Annotate | Line # | Download | only in cipher
      1 /*
      2  * Copyright 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 aes wrap 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 /* aes key */
     22 static const unsigned char wrap_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 wrap_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 wrap_pt[] = {
     36     0xad, 0x4f, 0xc9, 0xfc, 0x77, 0x69, 0xc9, 0xea, 0xfc, 0xdf, 0x00, 0xac,
     37     0x34, 0xec, 0x40, 0xbc, 0x28, 0x3f, 0xa4, 0x5e, 0xd8, 0x99, 0xe4, 0x5d,
     38     0x5e, 0x7a, 0xc4, 0xe6, 0xca, 0x7b, 0xa5, 0xb7,
     39 };
     40 
     41 /* Expected ciphertext value */
     42 static const unsigned char wrap_ct[] = {
     43     0x97, 0x99, 0x55, 0xca, 0xf6, 0x3e, 0x95, 0x54, 0x39, 0xd6, 0xaf, 0x63, 0xff, 0x2c, 0xe3, 0x96,
     44     0xf7, 0x0d, 0x2c, 0x9c, 0xc7, 0x43, 0xc0, 0xb6, 0x31, 0x43, 0xb9, 0x20, 0xac, 0x6b, 0xd3, 0x67,
     45     0xad, 0x01, 0xaf, 0xa7, 0x32, 0x74, 0x26, 0x92,
     46 };
     47 
     48 /*
     49  * A library context and property query can be used to select & filter
     50  * algorithm implementations. If they are NULL then the default library
     51  * context and properties are used.
     52  */
     53 OSSL_LIB_CTX *libctx = NULL;
     54 const char *propq = NULL;
     55 
     56 int aes_wrap_encrypt(void)
     57 {
     58     int ret = 0;
     59     EVP_CIPHER_CTX *ctx;
     60     EVP_CIPHER *cipher = NULL;
     61     int outlen, tmplen;
     62     unsigned char outbuf[1024];
     63 
     64     printf("aes wrap Encrypt:\n");
     65     printf("Plaintext:\n");
     66     BIO_dump_fp(stdout, wrap_pt, sizeof(wrap_pt));
     67 
     68     /* Create a context for the encrypt operation */
     69     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
     70         goto err;
     71 
     72     EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
     73 
     74     /* Fetch the cipher implementation */
     75     if ((cipher = EVP_CIPHER_fetch(libctx, "AES-256-WRAP", propq)) == NULL)
     76         goto err;
     77 
     78     /*
     79      * Initialise an encrypt operation with the cipher/mode, key and IV.
     80      * We are not setting any custom params so let params be just NULL.
     81      */
     82     if (!EVP_EncryptInit_ex2(ctx, cipher, wrap_key, wrap_iv, /* params */ NULL))
     83         goto err;
     84 
     85     /* Encrypt plaintext */
     86     if (!EVP_EncryptUpdate(ctx, outbuf, &outlen, wrap_pt, sizeof(wrap_pt)))
     87         goto err;
     88 
     89     /* Finalise: there can be some additional output from padding */
     90     if (!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen))
     91         goto err;
     92     outlen += tmplen;
     93 
     94     /* Output encrypted block */
     95     printf("Ciphertext (outlen:%d):\n", outlen);
     96     BIO_dump_fp(stdout, outbuf, outlen);
     97 
     98     if (sizeof(wrap_ct) == outlen && !CRYPTO_memcmp(outbuf, wrap_ct, outlen))
     99         printf("Final ciphertext matches expected ciphertext\n");
    100     else
    101         printf("Final ciphertext differs from expected ciphertext\n");
    102 
    103     ret = 1;
    104 err:
    105     if (!ret)
    106         ERR_print_errors_fp(stderr);
    107 
    108     EVP_CIPHER_free(cipher);
    109     EVP_CIPHER_CTX_free(ctx);
    110 
    111     return ret;
    112 }
    113 
    114 int aes_wrap_decrypt(void)
    115 {
    116     int ret = 0;
    117     EVP_CIPHER_CTX *ctx;
    118     EVP_CIPHER *cipher = NULL;
    119     int outlen, tmplen;
    120     unsigned char outbuf[1024];
    121 
    122     printf("aes wrap Decrypt:\n");
    123     printf("Ciphertext:\n");
    124     BIO_dump_fp(stdout, wrap_ct, sizeof(wrap_ct));
    125 
    126     if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
    127         goto err;
    128 
    129     EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
    130 
    131     /* Fetch the cipher implementation */
    132     if ((cipher = EVP_CIPHER_fetch(libctx, "aes-256-wrap", propq)) == NULL)
    133         goto err;
    134 
    135     /*
    136      * Initialise an encrypt operation with the cipher/mode, key and IV.
    137      * We are not setting any custom params so let params be just NULL.
    138      */
    139     if (!EVP_DecryptInit_ex2(ctx, cipher, wrap_key, wrap_iv, /* params */ NULL))
    140         goto err;
    141 
    142     /* Decrypt plaintext */
    143     if (!EVP_DecryptUpdate(ctx, outbuf, &outlen, wrap_ct, sizeof(wrap_ct)))
    144         goto err;
    145 
    146     /* Finalise: there can be some additional output from padding */
    147     if (!EVP_DecryptFinal_ex(ctx, outbuf + outlen, &tmplen))
    148         goto err;
    149     outlen += tmplen;
    150 
    151     /* Output decrypted block */
    152     printf("Plaintext (outlen:%d):\n", outlen);
    153     BIO_dump_fp(stdout, outbuf, outlen);
    154 
    155     if (sizeof(wrap_pt) == outlen && !CRYPTO_memcmp(outbuf, wrap_pt, outlen))
    156         printf("Final plaintext matches original plaintext\n");
    157     else
    158         printf("Final plaintext differs from original plaintext\n");
    159 
    160     ret = 1;
    161 err:
    162     if (!ret)
    163         ERR_print_errors_fp(stderr);
    164 
    165     EVP_CIPHER_free(cipher);
    166     EVP_CIPHER_CTX_free(ctx);
    167 
    168     return ret;
    169 }
    170 
    171 int main(int argc, char **argv)
    172 {
    173     if (!aes_wrap_encrypt())
    174        return 1;
    175 
    176     if (!aes_wrap_decrypt())
    177         return 1;
    178 
    179     return 0;
    180 }
    181 
    182