blob: a2d52bfd7a20b3b20760fc7d677624a5542c0f03 [file] [log] [blame]
Reut Zysmanff6bab92016-02-09 14:06:31 +02001/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
Amit Blay6281ebc2015-01-11 14:44:08 +02002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <dev/fbcon.h>
31#include <target.h>
32#include <mmc.h>
33#include <partition_parser.h>
34#include <platform.h>
35#include <crypto_hash.h>
36#include <malloc.h>
37#include <sha.h>
38#include <string.h>
39#include <rand.h>
40#include <stdlib.h>
Amit Blay4aa292f2015-04-28 21:55:59 +030041#include <boot_verifier.h>
42#include <image_verify.h>
Amit Blay6281ebc2015-01-11 14:44:08 +020043#include "scm.h"
44#include "mdtp.h"
Reut Zysmanff6bab92016-02-09 14:06:31 +020045#include "mdtp_fs.h"
46
Amit Blay6281ebc2015-01-11 14:44:08 +020047
Amit Blay4aa292f2015-04-28 21:55:59 +030048#define DIP_ENCRYPT (0)
49#define DIP_DECRYPT (1)
50#define MAX_CIPHER_DIP_SCM_CALLS (3)
Amit Blay6281ebc2015-01-11 14:44:08 +020051
Amit Blay8e2731c2015-04-28 21:54:55 +030052#define MDTP_MAJOR_VERSION (0)
53#define MDTP_MINOR_VERSION (2)
54
Reut Zysmand7138622016-01-18 14:43:59 +020055#define MDTP_CORRECT_PIN_DELAY_MSEC (1000)
56
Amit Blay8e2731c2015-04-28 21:54:55 +030057/** Extract major version number from complete version. */
58#define MDTP_GET_MAJOR_VERSION(version) ((version) >> 16)
59
Amit Blaydf42d2f2015-02-03 16:37:09 +020060static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified);
61static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip);
Amit Blay4aa292f2015-04-28 21:55:59 +030062static void mdtp_tzbsp_disallow_cipher_DIP(void);
Amit Blay6281ebc2015-01-11 14:44:08 +020063
Amit Blay8e2731c2015-04-28 21:54:55 +030064uint32_t g_mdtp_version = (((MDTP_MAJOR_VERSION << 16) & 0xFFFF0000) | (MDTP_MINOR_VERSION & 0x0000FFFF));
Amit Blay4aa292f2015-04-28 21:55:59 +030065static int is_mdtp_activated = -1;
Amit Blay8e2731c2015-04-28 21:54:55 +030066
Amit Blay8e2731c2015-04-28 21:54:55 +030067int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
Amit Blay4aa292f2015-04-28 21:55:59 +030068int scm_random(uint32_t * rbuf, uint32_t r_len);
Reut Zysmand7138622016-01-18 14:43:59 +020069extern void mdelay(unsigned msecs);
Rami Butsteinfaecf7f2015-06-04 16:39:30 +030070void free_mdtp_image(void);
Amit Blay8e2731c2015-04-28 21:54:55 +030071
Amit Blay6281ebc2015-01-11 14:44:08 +020072/********************************************************************************/
73
74/* Read the DIP from EMMC */
Amit Blaydf42d2f2015-02-03 16:37:09 +020075static int read_DIP(DIP_t *dip)
Amit Blay6281ebc2015-01-11 14:44:08 +020076{
77 unsigned long long ptn = 0;
78 uint32_t actual_partition_size;
Amit Blaydf42d2f2015-02-03 16:37:09 +020079 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +020080
81 int index = INVALID_PTN;
82
83 ASSERT(dip != NULL);
84
85 index = partition_get_index("dip");
86 ptn = partition_get_offset(index);
87
88 if(ptn == 0)
89 {
90 return -1;
91 }
92
93 actual_partition_size = ROUNDUP(sizeof(DIP_t), block_size);
94
95 if(mmc_read(ptn, (void *)dip, actual_partition_size))
96 {
97 dprintf(CRITICAL, "mdtp: read_DIP: ERROR, cannot read DIP info\n");
98 return -1;
99 }
100
Reut Zysman18411272015-02-09 13:47:27 +0200101 dprintf(SPEW, "mdtp: read_DIP: SUCCESS, read %d bytes\n", actual_partition_size);
Amit Blay6281ebc2015-01-11 14:44:08 +0200102
103 return 0;
104}
105
106/* Store the DIP into the EMMC */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200107static int write_DIP(DIP_t *dip)
Amit Blay6281ebc2015-01-11 14:44:08 +0200108{
109 unsigned long long ptn = 0;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200110 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +0200111
112 int index = INVALID_PTN;
113
114 ASSERT(dip != NULL);
115
116 index = partition_get_index("dip");
117 ptn = partition_get_offset(index);
Reut Zysman18411272015-02-09 13:47:27 +0200118
Amit Blay6281ebc2015-01-11 14:44:08 +0200119 if(ptn == 0)
120 {
121 return -1;
122 }
123
Reut Zysman18411272015-02-09 13:47:27 +0200124 if(mmc_write(ptn, ROUNDUP(sizeof(DIP_t), block_size), (void *)dip))
Amit Blay6281ebc2015-01-11 14:44:08 +0200125 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300126 dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot write DIP info\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200127 return -1;
128 }
129
Reut Zysman18411272015-02-09 13:47:27 +0200130 dprintf(SPEW, "mdtp: write_DIP: SUCCESS, write %d bytes\n", ROUNDUP(sizeof(DIP_t), block_size));
131
Amit Blay6281ebc2015-01-11 14:44:08 +0200132 return 0;
133}
134
Reut Zysman18411272015-02-09 13:47:27 +0200135/* Deactivate MDTP by storing the default DIP into the EMMC */
136static void write_deactivated_DIP()
Amit Blay6281ebc2015-01-11 14:44:08 +0200137{
Amit Blaydf42d2f2015-02-03 16:37:09 +0200138 DIP_t *enc_dip;
139 DIP_t *dec_dip;
Amit Blay6281ebc2015-01-11 14:44:08 +0200140 int ret;
141
142 enc_dip = malloc(sizeof(DIP_t));
143 if (enc_dip == NULL)
144 {
Reut Zysman18411272015-02-09 13:47:27 +0200145 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot allocate DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200146 return;
147 }
148
149 dec_dip = malloc(sizeof(DIP_t));
150 if (dec_dip == NULL)
151 {
Reut Zysman18411272015-02-09 13:47:27 +0200152 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot allocate DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200153 free(enc_dip);
154 return;
155 }
156
157 memset(dec_dip, 0, sizeof(DIP_t));
158
159 dec_dip->status = DIP_STATUS_DEACTIVATED;
Amit Blay8e2731c2015-04-28 21:54:55 +0300160 dec_dip->version = g_mdtp_version;
Amit Blay6281ebc2015-01-11 14:44:08 +0200161
162 ret = mdtp_tzbsp_enc_hash_DIP(dec_dip, enc_dip);
163 if(ret < 0)
164 {
Reut Zysman18411272015-02-09 13:47:27 +0200165 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot cipher DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200166 goto out;
167 }
168
169 ret = write_DIP(enc_dip);
170 if(ret < 0)
171 {
Reut Zysman18411272015-02-09 13:47:27 +0200172 dprintf(CRITICAL, "mdtp: write_deactivated_DIP: ERROR, cannot write DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200173 goto out;
174 }
175
176out:
177 free(enc_dip);
178 free(dec_dip);
179}
180
181/* Validate a hash calculated on entire given partition */
Amit Blay8e2731c2015-04-28 21:54:55 +0300182static int verify_partition_single_hash(char *name, uint64_t size, DIP_hash_table_entry_t *hash_table)
Amit Blay6281ebc2015-01-11 14:44:08 +0200183{
Amit Blay8e2731c2015-04-28 21:54:55 +0300184 unsigned char digest[HASH_LEN]={0};
Amit Blay6281ebc2015-01-11 14:44:08 +0200185 unsigned long long ptn = 0;
186 int index = INVALID_PTN;
Amit Blay4aa292f2015-04-28 21:55:59 +0300187 unsigned char *buf = (unsigned char *)target_get_scratch_address() + MDTP_SCRATCH_OFFSET;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200188 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay8e2731c2015-04-28 21:54:55 +0300189 uint64_t actual_partition_size = ROUNDUP(size, block_size);
Amit Blay6281ebc2015-01-11 14:44:08 +0200190
Amit Blay8e2731c2015-04-28 21:54:55 +0300191 dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %llu\n", name, size);
Amit Blay6281ebc2015-01-11 14:44:08 +0200192
193 ASSERT(name != NULL);
194 ASSERT(hash_table != NULL);
Amit Blay8e2731c2015-04-28 21:54:55 +0300195 ASSERT(size > 0);
Amit Blay6281ebc2015-01-11 14:44:08 +0200196
197 index = partition_get_index(name);
198 ptn = partition_get_offset(index);
199
200 if(ptn == 0) {
201 dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: partition was not found\n", name);
202 return -1;
203 }
204
Amit Blay6281ebc2015-01-11 14:44:08 +0200205 if (mmc_read(ptn, (void *)buf, actual_partition_size))
206 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300207 dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: mmc_read() fail.\n", name);
Amit Blay6281ebc2015-01-11 14:44:08 +0200208 return -1;
209 }
210
Amit Blayfe649212015-01-25 11:21:10 +0200211 /* calculating the hash value using HW crypto */
212 target_crypto_init_params();
Reut Zysmanff6bab92016-02-09 14:06:31 +0200213
214 if(strcmp(name, "mdtp") == 0){
215 buf[0] = 0; // removes first byte
216 dprintf(INFO, "mdtp: verify_partition_single_hash: removes 1st byte\n");
217 }
218
Amit Blay8e2731c2015-04-28 21:54:55 +0300219 hash_find(buf, size, digest, CRYPTO_AUTH_ALG_SHA256);
Amit Blay6281ebc2015-01-11 14:44:08 +0200220
Amit Blay8e2731c2015-04-28 21:54:55 +0300221 if (memcmp(digest, hash_table->hash, HASH_LEN))
Amit Blay6281ebc2015-01-11 14:44:08 +0200222 {
223 dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: Failed partition hash verification\n", name);
224
225 return -1;
226 }
227
Reut Zysman18411272015-02-09 13:47:27 +0200228 dprintf(SPEW, "verify_partition_single_hash: %s: VERIFIED!\n", name);
Amit Blay6281ebc2015-01-11 14:44:08 +0200229
230 return 0;
231}
232
233/* Validate a hash table calculated per block of a given partition */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200234static int verify_partition_block_hash(char *name,
Amit Blay8e2731c2015-04-28 21:54:55 +0300235 uint64_t size,
Amit Blay6281ebc2015-01-11 14:44:08 +0200236 uint32_t verify_num_blocks,
Amit Blaydf42d2f2015-02-03 16:37:09 +0200237 DIP_hash_table_entry_t *hash_table,
Amit Blay8e2731c2015-04-28 21:54:55 +0300238 uint8_t *force_verify_block)
Amit Blay6281ebc2015-01-11 14:44:08 +0200239{
Amit Blay8e2731c2015-04-28 21:54:55 +0300240 unsigned char digest[HASH_LEN]={0};
Amit Blay6281ebc2015-01-11 14:44:08 +0200241 unsigned long long ptn = 0;
242 int index = INVALID_PTN;
Amit Blay4aa292f2015-04-28 21:55:59 +0300243 unsigned char *buf = (unsigned char *)target_get_scratch_address() + MDTP_SCRATCH_OFFSET;
Amit Blay6281ebc2015-01-11 14:44:08 +0200244 uint32_t bytes_to_read;
245 uint32_t block_num = 0;
Amit Blay8e2731c2015-04-28 21:54:55 +0300246 uint32_t total_num_blocks = ((size - 1) / MDTP_FWLOCK_BLOCK_SIZE) + 1;
247 uint32_t rand_int;
248 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay6281ebc2015-01-11 14:44:08 +0200249
Amit Blay8e2731c2015-04-28 21:54:55 +0300250 dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %llu\n", name, size);
Amit Blay6281ebc2015-01-11 14:44:08 +0200251
252 ASSERT(name != NULL);
253 ASSERT(hash_table != NULL);
Amit Blay8e2731c2015-04-28 21:54:55 +0300254 ASSERT(size > 0);
255 ASSERT(force_verify_block != NULL);
Amit Blay6281ebc2015-01-11 14:44:08 +0200256
257 index = partition_get_index(name);
258 ptn = partition_get_offset(index);
259
260 if(ptn == 0) {
261 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: partition was not found\n", name);
262 return -1;
263 }
264
Amit Blayfe649212015-01-25 11:21:10 +0200265 /* initiating parameters for hash calculation using HW crypto */
266 target_crypto_init_params();
Amit Blay8e2731c2015-04-28 21:54:55 +0300267 if (check_aboot_addr_range_overlap((uint32_t)buf, ROUNDUP(MDTP_FWLOCK_BLOCK_SIZE, block_size)))
268 {
269 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: image buffer address overlaps with aboot addresses.\n", name);
270 return -1;
271 }
Amit Blayfe649212015-01-25 11:21:10 +0200272
Amit Blay6281ebc2015-01-11 14:44:08 +0200273 while (MDTP_FWLOCK_BLOCK_SIZE * block_num < size)
274 {
275 if (*force_verify_block == 0)
276 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300277 if(scm_random((uint32_t *)&rand_int, sizeof(rand_int)))
278 {
279 dprintf(CRITICAL,"mdtp: scm_call for random failed\n");
280 return -1;
281 }
282
Amit Blay6281ebc2015-01-11 14:44:08 +0200283 /* Skip validation of this block with probability of verify_num_blocks / total_num_blocks */
Amit Blay8e2731c2015-04-28 21:54:55 +0300284 if ((rand_int % total_num_blocks) >= verify_num_blocks)
Amit Blay6281ebc2015-01-11 14:44:08 +0200285 {
286 block_num++;
287 hash_table += 1;
288 force_verify_block += 1;
289 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: skipped verification of block %d\n", name, block_num);
290 continue;
291 }
292 }
293
Amit Blay6281ebc2015-01-11 14:44:08 +0200294 if ((size - (MDTP_FWLOCK_BLOCK_SIZE * block_num) < MDTP_FWLOCK_BLOCK_SIZE))
295 {
296 bytes_to_read = size - (MDTP_FWLOCK_BLOCK_SIZE * block_num);
297 } else
298 {
299 bytes_to_read = MDTP_FWLOCK_BLOCK_SIZE;
300 }
301
Amit Blay8e2731c2015-04-28 21:54:55 +0300302 if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, ROUNDUP(bytes_to_read, block_size)))
Amit Blay6281ebc2015-01-11 14:44:08 +0200303 {
304 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: mmc_read() fail.\n", name);
305 return -1;
306 }
307
Amit Blayfe649212015-01-25 11:21:10 +0200308 /* calculating the hash value using HW */
Amit Blay8e2731c2015-04-28 21:54:55 +0300309 hash_find(buf, bytes_to_read, digest, CRYPTO_AUTH_ALG_SHA256);
Amit Blay6281ebc2015-01-11 14:44:08 +0200310
Amit Blay8e2731c2015-04-28 21:54:55 +0300311 if (memcmp(digest, hash_table->hash, HASH_LEN))
Amit Blay6281ebc2015-01-11 14:44:08 +0200312 {
313 dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: Failed partition hash[%d] verification\n", name, block_num);
314 return -1;
315 }
316
317 block_num++;
318 hash_table += 1;
319 force_verify_block += 1;
320 }
321
Reut Zysman18411272015-02-09 13:47:27 +0200322 dprintf(SPEW, "verify_partition_block_hash: %s: VERIFIED!\n", name);
Amit Blay6281ebc2015-01-11 14:44:08 +0200323
324 return 0;
325}
326
Amit Blay8e2731c2015-04-28 21:54:55 +0300327/* Validate the partition parameters read from DIP */
328static int validate_partition_params(uint64_t size,
Amit Blay6281ebc2015-01-11 14:44:08 +0200329 mdtp_fwlock_mode_t hash_mode,
Amit Blay8e2731c2015-04-28 21:54:55 +0300330 uint32_t verify_ratio)
Amit Blay6281ebc2015-01-11 14:44:08 +0200331{
Amit Blay8e2731c2015-04-28 21:54:55 +0300332 if (size == 0 || size > (uint64_t)MDTP_FWLOCK_BLOCK_SIZE * (uint64_t)MAX_BLOCKS ||
333 hash_mode >= MDTP_FWLOCK_MODE_SIZE || verify_ratio > 100)
Amit Blay6281ebc2015-01-11 14:44:08 +0200334 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300335 dprintf(CRITICAL, "mdtp: validate_partition_params: error, size=%llu, hash_mode=%d, verify_ratio=%d\n",
336 size, hash_mode, verify_ratio);
Amit Blay6281ebc2015-01-11 14:44:08 +0200337 return -1;
338 }
339
340 return 0;
341}
342
Amit Blay8e2731c2015-04-28 21:54:55 +0300343/* Verify a given partitinon */
344static int verify_partition(char *name,
345 uint64_t size,
346 mdtp_fwlock_mode_t hash_mode,
347 uint32_t verify_num_blocks,
348 DIP_hash_table_entry_t *hash_table,
349 uint8_t *force_verify_block)
350{
351 if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
352 {
353 return verify_partition_single_hash(name, size, hash_table);
354 } else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
355 {
356 return verify_partition_block_hash(name, size, verify_num_blocks, hash_table, force_verify_block);
357 }
358
359 /* Illegal value of hash_mode */
360 return -1;
361}
362
363static int validate_dip(DIP_t *dip)
364{
365 uint8_t *dip_p;
366
367 ASSERT(dip != NULL);
368
369 /* Make sure DIP version is supported by current SW */
370 if (MDTP_GET_MAJOR_VERSION(dip->version) != MDTP_MAJOR_VERSION)
371 {
372 dprintf(CRITICAL, "mdtp: validate_dip: Wrong DIP version 0x%x\n", dip->version);
373 return -1;
374 }
375
376 /* Make sure that deactivated DIP content is as expected */
377 if (dip->status == DIP_STATUS_DEACTIVATED)
378 {
379 dip_p = (uint8_t*)&dip->mdtp_cfg;
380 while (dip_p < dip->hash)
381 {
382 if (*dip_p != 0)
383 {
384 dprintf(CRITICAL, "mdtp: validate_dip: error in deactivated DIP\n");
385 return -1;
386 }
387 dip_p++;
388 }
389 }
390
391 return 0;
392}
393
Reut Zysmanff6bab92016-02-09 14:06:31 +0200394/* Display the recovery UI in case mdtp image is corrupted */
395static void display_mdtp_fail_recovery_ui(){
396 display_error_msg_mdtp();
397}
398
Reut Zysman18411272015-02-09 13:47:27 +0200399/* Display the recovery UI to allow the user to enter the PIN and continue boot */
Amit Blay4aa292f2015-04-28 21:55:59 +0300400static void display_recovery_ui(mdtp_cfg_t *mdtp_cfg)
Reut Zysman18411272015-02-09 13:47:27 +0200401{
402 uint32_t pin_length = 0;
403 char entered_pin[MDTP_MAX_PIN_LEN+1] = {0};
404 uint32_t i;
Amit Blay8e2731c2015-04-28 21:54:55 +0300405 char pin_mismatch = 0;
Reut Zysman18411272015-02-09 13:47:27 +0200406
Amit Blay4aa292f2015-04-28 21:55:59 +0300407 if (mdtp_cfg->enable_local_pin_authentication)
Reut Zysman18411272015-02-09 13:47:27 +0200408 {
409 dprintf(SPEW, "mdtp: display_recovery_ui: Local deactivation enabled\n");
410
Amit Blay4aa292f2015-04-28 21:55:59 +0300411 pin_length = strlen(mdtp_cfg->mdtp_pin.mdtp_pin);
Reut Zysman18411272015-02-09 13:47:27 +0200412
413 if (pin_length > MDTP_MAX_PIN_LEN || pin_length < MDTP_MIN_PIN_LEN)
414 {
415 dprintf(CRITICAL, "mdtp: display_recovery_ui: Error, invalid PIN length\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300416 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200417 }
418
419 // Set entered_pin to initial '0' string + null terminator
420 for (i=0; i<pin_length; i++)
421 {
422 entered_pin[i] = '0';
423 }
424
425 // Allow the user to enter the PIN as many times as he wishes
426 // (with INVALID_PIN_DELAY_MSECONDS after each failed attempt)
427 while (1)
428 {
Amit Blay8e2731c2015-04-28 21:54:55 +0300429 get_pin_from_user(entered_pin, pin_length);
Reut Zysman18411272015-02-09 13:47:27 +0200430
Amit Blay8e2731c2015-04-28 21:54:55 +0300431 // Go over the entire PIN in any case, to prevent side-channel attacks
432 for (i=0; i<pin_length; i++)
433 {
Amit Blay4aa292f2015-04-28 21:55:59 +0300434 pin_mismatch |= mdtp_cfg->mdtp_pin.mdtp_pin[i] ^ entered_pin[i];
Amit Blay8e2731c2015-04-28 21:54:55 +0300435 }
Reut Zysman18411272015-02-09 13:47:27 +0200436
Amit Blay8e2731c2015-04-28 21:54:55 +0300437 if (0 == pin_mismatch)
438 {
439 // Valid PIN - deactivate and continue boot
440 dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
441 write_deactivated_DIP();
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300442 goto out;
Amit Blay8e2731c2015-04-28 21:54:55 +0300443 }
444 else
445 {
446 // Invalid PIN - display an appropriate message (which also includes a wait
447 // for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
448 dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
449 display_invalid_pin_msg();
Reut Zysman18411272015-02-09 13:47:27 +0200450
Amit Blay8e2731c2015-04-28 21:54:55 +0300451 pin_mismatch = 0;
452 }
Reut Zysman18411272015-02-09 13:47:27 +0200453 }
454 }
455 else
456 {
457 dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300458 display_error_msg(); /* This will never return */
Reut Zysman18411272015-02-09 13:47:27 +0200459 }
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300460
461 out:
Amit Blay54849152015-11-09 15:51:40 +0200462 display_image_on_screen();
Rami Butsteinfaecf7f2015-06-04 16:39:30 +0300463 free_mdtp_image();
Reut Zysmand7138622016-01-18 14:43:59 +0200464 mdelay(MDTP_CORRECT_PIN_DELAY_MSEC);
Reut Zysman18411272015-02-09 13:47:27 +0200465}
466
Amit Blay4aa292f2015-04-28 21:55:59 +0300467/* Verify the boot or recovery partitions using boot_verifier. */
468static int verify_ext_partition(mdtp_ext_partition_verification_t *ext_partition)
469{
470 int ret = 0;
471 bool restore_to_orange = false;
472 unsigned long long ptn = 0;
473 int index = INVALID_PTN;
474
475 /* If image was already verified in aboot, return its status */
476 if (ext_partition->integrity_state == MDTP_PARTITION_STATE_INVALID)
477 {
478 dprintf(CRITICAL, "mdtp: verify_ext_partition: image %s verified externally and failed.\n",
479 ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
480 return -1;
481 }
482 else if (ext_partition->integrity_state == MDTP_PARTITION_STATE_VALID)
483 {
484 dprintf(CRITICAL, "mdtp: verify_ext_partition: image %s verified externally succesfully.\n",
485 ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
486 return 0;
487 }
488
489 /* If image was not verified in aboot, verify it ourselves using boot_verifier. */
490
491 /* 1) Initialize keystore. We don't care about return value which is Verified Boot's state machine state. */
492 boot_verify_keystore_init();
493
494 /* 2) If boot_verifier is ORANGE, it will prevent verifying an image. So
495 * temporarly change boot_verifier state to BOOT_INIT.
496 */
497 if (boot_verify_get_state() == ORANGE)
498 restore_to_orange = true;
499 boot_verify_send_event(BOOT_INIT);
500
501 switch (ext_partition->partition)
502 {
503 case MDTP_PARTITION_BOOT:
504 case MDTP_PARTITION_RECOVERY:
505
506 /* 3) Signature may or may not be at the end of the image. Read the signature if needed. */
507 if (!ext_partition->sig_avail)
508 {
509 if (check_aboot_addr_range_overlap((uint32_t)(ext_partition->image_addr + ext_partition->image_size), ext_partition->page_size))
510 {
511 dprintf(CRITICAL, "ERROR: Signature read buffer address overlaps with aboot addresses.\n");
512 return -1;
513 }
514
515 index = partition_get_index(ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
516 ptn = partition_get_offset(index);
517 if(ptn == 0) {
518 dprintf(CRITICAL, "ERROR: partition %s not found\n",
519 ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
520 return -1;
521 }
522
523 if(mmc_read(ptn + ext_partition->image_size, (void *)(ext_partition->image_addr + ext_partition->image_size), ext_partition->page_size))
524 {
525 dprintf(CRITICAL, "ERROR: Cannot read %s image signature\n",
526 ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
527 return -1;
528 }
529 }
530
531 /* 4) Verify the image using its signature. */
532 ret = boot_verify_image((unsigned char *)ext_partition->image_addr,
533 ext_partition->image_size,
Amit Blay59fad252015-05-17 17:27:17 +0300534 ext_partition->partition == MDTP_PARTITION_BOOT ? "/boot" : "/recovery");
Amit Blay4aa292f2015-04-28 21:55:59 +0300535 break;
536
537 default:
538 /* Only boot and recovery are legal here */
539 dprintf(CRITICAL, "ERROR: wrong partition %d\n", ext_partition->partition);
540 return -1;
541 }
542
543 if (ret)
544 {
545 dprintf(INFO, "mdtp: verify_ext_partition: image %s verified succesfully in MDTP.\n",
546 ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
547 }
548 else
549 {
550 dprintf(CRITICAL, "mdtp: verify_ext_partition: image %s verification failed in MDTP.\n",
551 ext_partition->partition == MDTP_PARTITION_BOOT ? "boot" : "recovery");
552 }
553
554 /* 5) Restore the right boot_verifier state upon exit. */
555 if (restore_to_orange)
556 {
557 boot_verify_send_event(DEV_UNLOCK);
558 }
559
560 return ret ? 0 : -1;
561}
562
Amit Blay6281ebc2015-01-11 14:44:08 +0200563/* Verify all protected partitinons according to the DIP */
Amit Blay4aa292f2015-04-28 21:55:59 +0300564static void verify_all_partitions(DIP_t *dip,
565 mdtp_ext_partition_verification_t *ext_partition,
566 verify_result_t *verify_result)
Amit Blay6281ebc2015-01-11 14:44:08 +0200567{
568 int i;
Amit Blay4aa292f2015-04-28 21:55:59 +0300569 int verify_failure = 0;
Reut Zysmanff6bab92016-02-09 14:06:31 +0200570 int verify_temp_result = 0;
Amit Blay4aa292f2015-04-28 21:55:59 +0300571 int ext_partition_verify_failure = 0;
Amit Blay6281ebc2015-01-11 14:44:08 +0200572 uint32_t total_num_blocks;
573
574 ASSERT(dip != NULL);
575 ASSERT(verify_result != NULL);
576
577 *verify_result = VERIFY_FAILED;
578
Amit Blay8e2731c2015-04-28 21:54:55 +0300579 if (validate_dip(dip))
580 {
581 dprintf(CRITICAL, "mdtp: verify_all_partitions: failed DIP validation\n");
582 return;
583 }
584
Amit Blay6281ebc2015-01-11 14:44:08 +0200585 if (dip->status == DIP_STATUS_DEACTIVATED)
586 {
587 *verify_result = VERIFY_SKIPPED;
Amit Blay8e2731c2015-04-28 21:54:55 +0300588 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200589 }
Amit Blay8e2731c2015-04-28 21:54:55 +0300590 else
Amit Blay6281ebc2015-01-11 14:44:08 +0200591 {
Amit Blay8a510302015-08-17 09:20:01 +0300592 if (ext_partition->partition != MDTP_PARTITION_NONE)
Amit Blay6281ebc2015-01-11 14:44:08 +0200593 {
Amit Blay8a510302015-08-17 09:20:01 +0300594 for(i=0; i<MAX_PARTITIONS; i++)
Amit Blay6281ebc2015-01-11 14:44:08 +0200595 {
Reut Zysmanff6bab92016-02-09 14:06:31 +0200596 verify_temp_result = 0;
Amit Blay8a510302015-08-17 09:20:01 +0300597 if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
Amit Blay8e2731c2015-04-28 21:54:55 +0300598 {
Amit Blay8a510302015-08-17 09:20:01 +0300599 total_num_blocks = ((dip->partition_cfg[i].size - 1) / MDTP_FWLOCK_BLOCK_SIZE);
600 if (validate_partition_params(dip->partition_cfg[i].size,
601 dip->partition_cfg[i].hash_mode,
602 dip->partition_cfg[i].verify_ratio))
603 {
604 dprintf(CRITICAL, "mdtp: verify_all_partitions: Wrong partition parameters\n");
605 verify_failure = TRUE;
606 break;
607 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200608
Reut Zysmanff6bab92016-02-09 14:06:31 +0200609 verify_temp_result |= (verify_partition(dip->partition_cfg[i].name,
Amit Blay8a510302015-08-17 09:20:01 +0300610 dip->partition_cfg[i].size,
611 dip->partition_cfg[i].hash_mode,
612 (dip->partition_cfg[i].verify_ratio * total_num_blocks) / 100,
613 dip->partition_cfg[i].hash_table,
614 dip->partition_cfg[i].force_verify_block) != 0);
Reut Zysmanff6bab92016-02-09 14:06:31 +0200615
616 if((verify_temp_result) && (strcmp("mdtp",dip->partition_cfg[i].name) == 0)){
617 *verify_result = VERIFY_MDTP_FAILED;
618 }
619
620 verify_failure |= verify_temp_result;
Amit Blay8a510302015-08-17 09:20:01 +0300621 }
622 }
623
624 ext_partition_verify_failure = verify_ext_partition(ext_partition);
625
626 if (verify_failure || ext_partition_verify_failure)
627 {
628 dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
629 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200630 }
631 }
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200632 is_mdtp_activated = 1;
Amit Blay6281ebc2015-01-11 14:44:08 +0200633 }
634
635 *verify_result = VERIFY_OK;
Amit Blay8e2731c2015-04-28 21:54:55 +0300636 return;
Amit Blay6281ebc2015-01-11 14:44:08 +0200637}
638
639/* Verify the DIP and all protected partitions */
Amit Blay4aa292f2015-04-28 21:55:59 +0300640static void validate_DIP_and_firmware(mdtp_ext_partition_verification_t *ext_partition)
Amit Blay6281ebc2015-01-11 14:44:08 +0200641{
642 int ret;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200643 DIP_t *enc_dip;
644 DIP_t *dec_dip;
Amit Blay6281ebc2015-01-11 14:44:08 +0200645 uint32_t verified = 0;
646 verify_result_t verify_result;
Amit Blaydf42d2f2015-02-03 16:37:09 +0200647 uint32_t block_size = mmc_get_device_blocksize();
Amit Blay4aa292f2015-04-28 21:55:59 +0300648 mdtp_cfg_t mdtp_cfg;
Amit Blay6281ebc2015-01-11 14:44:08 +0200649
650 enc_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
651 if (enc_dip == NULL)
652 {
Reut Zysman18411272015-02-09 13:47:27 +0200653 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300654 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200655 }
656
657 dec_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
658 if (dec_dip == NULL)
659 {
Reut Zysman18411272015-02-09 13:47:27 +0200660 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200661 free(enc_dip);
Amit Blay8e2731c2015-04-28 21:54:55 +0300662 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200663 }
664
665 /* Read the DIP holding the MDTP Firmware Lock state from the DIP partition */
666 ret = read_DIP(enc_dip);
667 if(ret < 0)
668 {
669 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot read DIP\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300670 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200671 }
672
673 /* Decrypt and verify the integrity of the DIP */
674 ret = mdtp_tzbsp_dec_verify_DIP(enc_dip, dec_dip, &verified);
675 if(ret < 0)
676 {
677 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify DIP\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300678 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200679 }
680
681 /* In case DIP integrity verification fails, notify the user and halt */
682 if(!verified)
683 {
684 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted DIP\n");
Amit Blay8e2731c2015-04-28 21:54:55 +0300685 display_error_msg(); /* This will never return */
Amit Blay6281ebc2015-01-11 14:44:08 +0200686 }
687
Amit Blay4aa292f2015-04-28 21:55:59 +0300688 /* Verify the integrity of the partitions which are protected, according to the content of the DIP */
689 verify_all_partitions(dec_dip, ext_partition, &verify_result);
690
691 mdtp_cfg = dec_dip->mdtp_cfg;
Amit Blay8e2731c2015-04-28 21:54:55 +0300692
693 /* Clear decrypted DIP since we don't need it anymore */
694 memset(dec_dip, 0, sizeof(DIP_t));
Amit Blay6281ebc2015-01-11 14:44:08 +0200695
Amit Blay4aa292f2015-04-28 21:55:59 +0300696
Amit Blay6281ebc2015-01-11 14:44:08 +0200697 if (verify_result == VERIFY_OK)
698 {
Reut Zysman18411272015-02-09 13:47:27 +0200699 dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify OK\n");
Amit Blay6281ebc2015-01-11 14:44:08 +0200700 }
Amit Blay8e2731c2015-04-28 21:54:55 +0300701 else if (verify_result == VERIFY_SKIPPED)
702 {
703 dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
Reut Zysmanff6bab92016-02-09 14:06:31 +0200704 }
705 else if(verify_result == VERIFY_MDTP_FAILED)
706 {
707 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted mdtp image\n");
708 display_mdtp_fail_recovery_ui();
709 }
710 else /* VERIFY_FAILED */
Amit Blay6281ebc2015-01-11 14:44:08 +0200711 {
712 dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted firmware\n");
Amit Blay4aa292f2015-04-28 21:55:59 +0300713 display_recovery_ui(&mdtp_cfg);
Amit Blay6281ebc2015-01-11 14:44:08 +0200714 }
715
Amit Blay4aa292f2015-04-28 21:55:59 +0300716 memset(&mdtp_cfg, 0, sizeof(mdtp_cfg));
717
Amit Blay6281ebc2015-01-11 14:44:08 +0200718 free(enc_dip);
719 free(dec_dip);
720
721 return;
722}
723
Reut Zysmanff6bab92016-02-09 14:06:31 +0200724
Amit Blay6281ebc2015-01-11 14:44:08 +0200725/********************************************************************************/
726
Amit Blay4aa292f2015-04-28 21:55:59 +0300727/** Entry point of the MDTP Firmware Lock.
728 * If needed, verify the DIP and all protected partitions.
729 * Allow passing information about partition verified using an external method
730 * (either boot or recovery). For boot and recovery, either use aboot's
731 * verification result, or use boot_verifier APIs to verify internally.
732 **/
733void mdtp_fwlock_verify_lock(mdtp_ext_partition_verification_t *ext_partition)
Amit Blay6281ebc2015-01-11 14:44:08 +0200734{
Amit Blaydf42d2f2015-02-03 16:37:09 +0200735 int ret;
736 bool enabled;
Amit Blay6281ebc2015-01-11 14:44:08 +0200737
Reut Zysmanff6bab92016-02-09 14:06:31 +0200738 if(mdtp_fs_init() != 0){
739 dprintf(CRITICAL, "mdtp: mdtp_img: ERROR, image file could not be loaded\n");
740 display_error_msg_mdtp(); /* This will never return */
741 }
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200742 /* sets the default value of this global to be MDTP not activated */
743 is_mdtp_activated = 0;
744
Amit Blay4aa292f2015-04-28 21:55:59 +0300745 do {
746 if (ext_partition == NULL)
747 {
748 dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, external partition is NULL\n");
749 display_error_msg(); /* This will never return */
750 break;
751 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200752
Amit Blay4aa292f2015-04-28 21:55:59 +0300753 ret = mdtp_fuse_get_enabled(&enabled);
754 if(ret)
755 {
756 dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
757 display_error_msg(); /* This will never return */
758 }
759
760 /* Continue with Firmware Lock verification only if enabled by eFuse */
761 if (enabled)
762 {
763 /* This function will handle firmware verification failure via UI */
764 validate_DIP_and_firmware(ext_partition);
765 }
766 } while (0);
767
768 /* Disallow CIPHER_DIP SCM call from this point, unless we are in recovery */
769 /* The recovery image will disallow CIPHER_DIP SCM call by itself. */
Amit Blay8a510302015-08-17 09:20:01 +0300770 if (ext_partition->partition == MDTP_PARTITION_BOOT)
Amit Blay6281ebc2015-01-11 14:44:08 +0200771 {
Amit Blay4aa292f2015-04-28 21:55:59 +0300772 mdtp_tzbsp_disallow_cipher_DIP();
Amit Blay6281ebc2015-01-11 14:44:08 +0200773 }
Amit Blay6281ebc2015-01-11 14:44:08 +0200774}
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200775/********************************************************************************/
776
777/** Indicates whether the MDTP is currently in ACTIVATED state **/
778int mdtp_activated(bool * activated){
779 if(is_mdtp_activated < 0){
780 /* mdtp_fwlock_verify_lock was not called before, the value is not valid */
781 return is_mdtp_activated;
782 }
783
784 *activated = is_mdtp_activated;
785 return 0;
786}
Amit Blay6281ebc2015-01-11 14:44:08 +0200787
788/********************************************************************************/
789
Amit Blay6281ebc2015-01-11 14:44:08 +0200790/* Decrypt a given DIP and verify its integrity */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200791static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified)
Amit Blay6281ebc2015-01-11 14:44:08 +0200792{
Amit Blay6281ebc2015-01-11 14:44:08 +0200793 unsigned char hash[HASH_LEN];
794 SHA256_CTX sha256_ctx;
795 int ret;
796
797 ASSERT(enc_dip != NULL);
798 ASSERT(dec_dip != NULL);
799 ASSERT(verified != NULL);
800
Amit Blay4418fb42015-05-05 08:45:13 +0300801 arch_clean_invalidate_cache_range((addr_t)enc_dip, sizeof(DIP_t));
802 arch_invalidate_cache_range((addr_t)dec_dip, sizeof(DIP_t));
803
Amit Blay6281ebc2015-01-11 14:44:08 +0200804 ret = mdtp_cipher_dip_cmd((uint8_t*)enc_dip, sizeof(DIP_t),
805 (uint8_t*)dec_dip, sizeof(DIP_t),
806 DIP_DECRYPT);
807 if (ret)
808 {
809 dprintf(CRITICAL, "mdtp: mdtp_tzbsp_dec_verify_DIP: ERROR, cannot cipher DIP\n");
810 *verified = 0;
Amit Blay8e2731c2015-04-28 21:54:55 +0300811 memset(dec_dip, 0, sizeof(DIP_t));
Amit Blay6281ebc2015-01-11 14:44:08 +0200812 return -1;
813 }
814
Amit Blay4418fb42015-05-05 08:45:13 +0300815 arch_invalidate_cache_range((addr_t)dec_dip, sizeof(DIP_t));
816
Amit Blay6281ebc2015-01-11 14:44:08 +0200817 SHA256_Init(&sha256_ctx);
818 SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
819 SHA256_Final(hash, &sha256_ctx);
820
Amit Blay8e2731c2015-04-28 21:54:55 +0300821 if (memcmp(hash, dec_dip->hash, HASH_LEN))
Amit Blay6281ebc2015-01-11 14:44:08 +0200822 {
823 *verified = 0;
Amit Blay8e2731c2015-04-28 21:54:55 +0300824 memset(dec_dip, 0, sizeof(DIP_t));
Amit Blay6281ebc2015-01-11 14:44:08 +0200825 }
826 else
827 {
828 *verified = 1;
829 }
830
831 return 0;
832}
833
Amit Blay4aa292f2015-04-28 21:55:59 +0300834/* Encrypt a given DIP and calculate its integrity information */
Amit Blaydf42d2f2015-02-03 16:37:09 +0200835static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
Amit Blay6281ebc2015-01-11 14:44:08 +0200836{
Amit Blay6281ebc2015-01-11 14:44:08 +0200837 SHA256_CTX sha256_ctx;
838 int ret;
839
840 ASSERT(dec_dip != NULL);
841 ASSERT(enc_dip != NULL);
842
Amit Blay6281ebc2015-01-11 14:44:08 +0200843 SHA256_Init(&sha256_ctx);
844 SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
Amit Blay8e2731c2015-04-28 21:54:55 +0300845 SHA256_Final(dec_dip->hash, &sha256_ctx);
Amit Blay6281ebc2015-01-11 14:44:08 +0200846
Amit Blay4418fb42015-05-05 08:45:13 +0300847 arch_clean_invalidate_cache_range((addr_t)dec_dip, sizeof(DIP_t));
848 arch_invalidate_cache_range((addr_t)enc_dip, sizeof(DIP_t));
849
Amit Blay6281ebc2015-01-11 14:44:08 +0200850 ret = mdtp_cipher_dip_cmd((uint8_t*)dec_dip, sizeof(DIP_t),
851 (uint8_t*)enc_dip, sizeof(DIP_t),
852 DIP_ENCRYPT);
853 if (ret)
854 {
855 dprintf(CRITICAL, "mdtp: mdtp_tzbsp_enc_hash_DIP: ERROR, cannot cipher DIP\n");
856 return -1;
857 }
858
Amit Blay4418fb42015-05-05 08:45:13 +0300859 arch_invalidate_cache_range((addr_t)enc_dip, sizeof(DIP_t));
860
Amit Blay6281ebc2015-01-11 14:44:08 +0200861 return 0;
862}
Amit Blay4aa292f2015-04-28 21:55:59 +0300863
864/* Disallow the CIPHER_DIP SCM call */
865static void mdtp_tzbsp_disallow_cipher_DIP(void)
866{
867 DIP_t *dip;
868 int i;
869
870 dip = malloc(sizeof(DIP_t));
871 if (dip == NULL)
872 {
873 dprintf(CRITICAL, "mdtp: mdtp_tzbsp_disallow_cipher_DIP: ERROR, cannot allocate DIP\n");
874 return;
875 }
876
877 /* Disallow the CIPHER_DIP SCM by calling it MAX_CIPHER_DIP_SCM_CALLS times */
878 for (i=0; i<MAX_CIPHER_DIP_SCM_CALLS; i++)
879 {
880 mdtp_tzbsp_enc_hash_DIP(dip, dip);
881 }
882
883 free(dip);
884}