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