uboot/lib/aes/aes-encrypt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2019,Softathome
   4 */
   5
   6#define OPENSSL_API_COMPAT 0x10101000L
   7
   8#include "mkimage.h"
   9#include <stdio.h>
  10#include <string.h>
  11#include <image.h>
  12#include <time.h>
  13#include <openssl/bn.h>
  14#include <openssl/rsa.h>
  15#include <openssl/pem.h>
  16#include <openssl/err.h>
  17#include <openssl/ssl.h>
  18#include <openssl/evp.h>
  19#include <openssl/engine.h>
  20#include <uboot_aes.h>
  21
  22#if OPENSSL_VERSION_NUMBER >= 0x10000000L
  23#define HAVE_ERR_REMOVE_THREAD_STATE
  24#endif
  25
  26int image_aes_encrypt(struct image_cipher_info *info,
  27                      unsigned char *data, int size,
  28                      unsigned char **cipher, int *cipher_len)
  29{
  30        EVP_CIPHER_CTX *ctx;
  31        unsigned char *buf = NULL;
  32        int buf_len, len, ret = 0;
  33
  34        /* create and initialise the context */
  35        ctx = EVP_CIPHER_CTX_new();
  36        if (!ctx) {
  37                printf("Can't create context\n");
  38                return -1;
  39        }
  40
  41        /* allocate a buffer for the result */
  42        buf = malloc(size + AES_BLOCK_LENGTH);
  43        if (!buf) {
  44                printf("Can't allocate memory to encrypt\n");
  45                ret = -1;
  46                goto out;
  47        }
  48
  49        if (EVP_EncryptInit_ex(ctx, info->cipher->calculate_type(),
  50                               NULL, info->key, info->iv) != 1) {
  51                printf("Can't init encryption\n");
  52                ret = -1;
  53                goto out;
  54        }
  55
  56        if (EVP_EncryptUpdate(ctx, buf, &len, data, size) != 1) {
  57                printf("Can't encrypt data\n");
  58                ret = -1;
  59                goto out;
  60        }
  61
  62        buf_len = len;
  63
  64        if (EVP_EncryptFinal_ex(ctx, buf + len, &len) != 1) {
  65                printf("Can't finalise the encryption\n");
  66                ret = -1;
  67                goto out;
  68        }
  69
  70        buf_len += len;
  71
  72        *cipher = buf;
  73        *cipher_len = buf_len;
  74
  75 out:
  76        EVP_CIPHER_CTX_free(ctx);
  77        return ret;
  78}
  79
  80int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest,
  81                              void *fit, int node_noffset)
  82{
  83        int parent, node;
  84        char name[128];
  85        int ret = 0;
  86
  87        /* Either create or overwrite the named cipher node */
  88        parent = fdt_subnode_offset(keydest, 0, FIT_CIPHER_NODENAME);
  89        if (parent == -FDT_ERR_NOTFOUND) {
  90                parent = fdt_add_subnode(keydest, 0, FIT_CIPHER_NODENAME);
  91                if (parent < 0) {
  92                        ret = parent;
  93                        if (ret != -FDT_ERR_NOSPACE) {
  94                                fprintf(stderr,
  95                                        "Couldn't create cipher node: %s\n",
  96                                        fdt_strerror(parent));
  97                        }
  98                }
  99        }
 100        if (ret)
 101                goto done;
 102
 103        /* Either create or overwrite the named key node */
 104        if (info->ivname)
 105                snprintf(name, sizeof(name), "key-%s-%s-%s",
 106                         info->name, info->keyname, info->ivname);
 107        else
 108                snprintf(name, sizeof(name), "key-%s-%s",
 109                         info->name, info->keyname);
 110
 111        node = fdt_subnode_offset(keydest, parent, name);
 112        if (node == -FDT_ERR_NOTFOUND) {
 113                node = fdt_add_subnode(keydest, parent, name);
 114                if (node < 0) {
 115                        ret = node;
 116                        if (ret != -FDT_ERR_NOSPACE) {
 117                                fprintf(stderr,
 118                                        "Could not create key subnode: %s\n",
 119                                        fdt_strerror(node));
 120                        }
 121                }
 122        } else if (node < 0) {
 123                fprintf(stderr, "Cannot select keys parent: %s\n",
 124                        fdt_strerror(node));
 125                ret = node;
 126        }
 127
 128        if (ret)
 129                goto done;
 130
 131        if (info->ivname)
 132                /* Store the IV in the u-boot device tree */
 133                ret = fdt_setprop(keydest, node, "iv",
 134                                  info->iv, info->cipher->iv_len);
 135        else
 136                /* Store the IV in the FIT image */
 137                ret = fdt_setprop(fit, node_noffset, "iv",
 138                                  info->iv, info->cipher->iv_len);
 139
 140        if (!ret)
 141                ret = fdt_setprop(keydest, node, "key",
 142                                  info->key, info->cipher->key_len);
 143
 144        if (!ret)
 145                ret = fdt_setprop_u32(keydest, node, "key-len",
 146                                      info->cipher->key_len);
 147
 148done:
 149        if (ret)
 150                ret = ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
 151
 152        return ret;
 153}
 154