1 /* 2 * Copyright 2014, Staubli Faverges 3 * Pierre Aubert 4 * 5 * eMMC- Replay Protected Memory Block 6 * According to JEDEC Standard No. 84-A441 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <config.h> 12 #include <common.h> 13 #include <memalign.h> 14 #include <mmc.h> 15 #include <u-boot/sha256.h> 16 #include "mmc_private.h" 17 18 /* Request codes */ 19 #define RPMB_REQ_KEY 1 20 #define RPMB_REQ_WCOUNTER 2 21 #define RPMB_REQ_WRITE_DATA 3 22 #define RPMB_REQ_READ_DATA 4 23 #define RPMB_REQ_STATUS 5 24 25 /* Response code */ 26 #define RPMB_RESP_KEY 0x0100 27 #define RPMB_RESP_WCOUNTER 0x0200 28 #define RPMB_RESP_WRITE_DATA 0x0300 29 #define RPMB_RESP_READ_DATA 0x0400 30 31 /* Error codes */ 32 #define RPMB_OK 0 33 #define RPMB_ERR_GENERAL 1 34 #define RPMB_ERR_AUTH 2 35 #define RPMB_ERR_COUNTER 3 36 #define RPMB_ERR_ADDRESS 4 37 #define RPMB_ERR_WRITE 5 38 #define RPMB_ERR_READ 6 39 #define RPMB_ERR_KEY 7 40 #define RPMB_ERR_CNT_EXPIRED 0x80 41 #define RPMB_ERR_MSK 0x7 42 43 #define SHA256_BLOCK_SIZE 64 44 45 /* Error messages */ 46 static const char * const rpmb_err_msg[] = { 47 "", 48 "General failure", 49 "Authentication failure", 50 "Counter failure", 51 "Address failure", 52 "Write failure", 53 "Read failure", 54 "Authentication key not yet programmed", 55 }; 56 57 static int mmc_rpmb_request(struct mmc *mmc, const void *s, 58 unsigned int count, bool is_rel_write) 59 { 60 struct mmc_cmd cmd = {0}; 61 struct mmc_data data; 62 int ret; 63 64 ret = mmc_set_blockcount(mmc, count, is_rel_write); 65 if (ret) { 66 #ifdef CONFIG_MMC_RPMB_TRACE 67 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret); 68 #endif 69 return 1; 70 } 71 72 cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; 73 cmd.cmdarg = 0; 74 cmd.resp_type = MMC_RSP_R1; 75 76 data.src = (const char *)s; 77 data.blocks = count; 78 data.blocksize = MMC_MAX_BLOCK_LEN; 79 data.flags = MMC_DATA_WRITE; 80 81 ret = mmc_send_cmd(mmc, &cmd, &data); 82 if (ret) { 83 #ifdef CONFIG_MMC_RPMB_TRACE 84 printf("%s:mmc_send_cmd-> %d\n", __func__, ret); 85 #endif 86 return 1; 87 } 88 return 0; 89 } 90 static int mmc_rpmb_response(struct mmc *mmc, struct s_rpmb *s, 91 unsigned short expected, unsigned short cnt) 92 { 93 struct mmc_cmd cmd = {0}; 94 struct mmc_data data; 95 int ret; 96 97 ret = mmc_set_blockcount(mmc, cnt, false); 98 if (ret) { 99 #ifdef CONFIG_MMC_RPMB_TRACE 100 printf("%s:mmc_set_blockcount-> %d\n", __func__, ret); 101 #endif 102 return -1; 103 } 104 cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK; 105 cmd.cmdarg = 0; 106 cmd.resp_type = MMC_RSP_R1; 107 108 data.dest = (char *)s; 109 data.blocks = cnt; 110 data.blocksize = MMC_MAX_BLOCK_LEN; 111 data.flags = MMC_DATA_READ; 112 113 ret = mmc_send_cmd(mmc, &cmd, &data); 114 if (ret) { 115 #ifdef CONFIG_MMC_RPMB_TRACE 116 printf("%s:mmc_send_cmd-> %d\n", __func__, ret); 117 #endif 118 return -1; 119 } 120 /* Check the response and the status */ 121 if (be16_to_cpu(s->request) != expected) { 122 #ifdef CONFIG_MMC_RPMB_TRACE 123 printf("%s:response= %x\n", __func__, 124 be16_to_cpu(s->request)); 125 #endif 126 return -1; 127 } 128 ret = be16_to_cpu(s->result); 129 if (ret) { 130 printf("%s %s\n", rpmb_err_msg[ret & RPMB_ERR_MSK], 131 (ret & RPMB_ERR_CNT_EXPIRED) ? 132 "Write counter has expired" : ""); 133 } 134 135 /* Return the status of the command */ 136 return ret; 137 } 138 static int mmc_rpmb_status(struct mmc *mmc, unsigned short expected) 139 { 140 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1); 141 142 memset(rpmb_frame, 0, sizeof(struct s_rpmb)); 143 rpmb_frame->request = cpu_to_be16(RPMB_REQ_STATUS); 144 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false)) 145 return -1; 146 147 /* Read the result */ 148 return mmc_rpmb_response(mmc, rpmb_frame, expected, 1); 149 } 150 static void rpmb_hmac(unsigned char *key, unsigned char *buff, int len, 151 unsigned char *output) 152 { 153 sha256_context ctx; 154 int i; 155 unsigned char k_ipad[SHA256_BLOCK_SIZE]; 156 unsigned char k_opad[SHA256_BLOCK_SIZE]; 157 158 sha256_starts(&ctx); 159 160 /* According to RFC 4634, the HMAC transform looks like: 161 SHA(K XOR opad, SHA(K XOR ipad, text)) 162 163 where K is an n byte key. 164 ipad is the byte 0x36 repeated blocksize times 165 opad is the byte 0x5c repeated blocksize times 166 and text is the data being protected. 167 */ 168 169 for (i = 0; i < RPMB_SZ_MAC; i++) { 170 k_ipad[i] = key[i] ^ 0x36; 171 k_opad[i] = key[i] ^ 0x5c; 172 } 173 /* remaining pad bytes are '\0' XOR'd with ipad and opad values */ 174 for ( ; i < SHA256_BLOCK_SIZE; i++) { 175 k_ipad[i] = 0x36; 176 k_opad[i] = 0x5c; 177 } 178 sha256_update(&ctx, k_ipad, SHA256_BLOCK_SIZE); 179 sha256_update(&ctx, buff, len); 180 sha256_finish(&ctx, output); 181 182 /* Init context for second pass */ 183 sha256_starts(&ctx); 184 185 /* start with outer pad */ 186 sha256_update(&ctx, k_opad, SHA256_BLOCK_SIZE); 187 188 /* then results of 1st hash */ 189 sha256_update(&ctx, output, RPMB_SZ_MAC); 190 191 /* finish up 2nd pass */ 192 sha256_finish(&ctx, output); 193 } 194 int mmc_rpmb_get_counter(struct mmc *mmc, unsigned long *pcounter) 195 { 196 int ret; 197 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1); 198 199 /* Fill the request */ 200 memset(rpmb_frame, 0, sizeof(struct s_rpmb)); 201 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WCOUNTER); 202 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false)) 203 return -1; 204 205 /* Read the result */ 206 ret = mmc_rpmb_response(mmc, rpmb_frame, RPMB_RESP_WCOUNTER, 1); 207 if (ret) 208 return ret; 209 210 *pcounter = be32_to_cpu(rpmb_frame->write_counter); 211 return 0; 212 } 213 int mmc_rpmb_set_key(struct mmc *mmc, void *key) 214 { 215 ALLOC_CACHE_ALIGN_BUFFER(struct s_rpmb, rpmb_frame, 1); 216 /* Fill the request */ 217 memset(rpmb_frame, 0, sizeof(struct s_rpmb)); 218 rpmb_frame->request = cpu_to_be16(RPMB_REQ_KEY); 219 memcpy(rpmb_frame->mac, key, RPMB_SZ_MAC); 220 221 if (mmc_rpmb_request(mmc, rpmb_frame, 1, true)) 222 return -1; 223 224 /* read the operation status */ 225 return mmc_rpmb_status(mmc, RPMB_RESP_KEY); 226 } 227 int mmc_rpmb_read(struct mmc *mmc, void *addr, unsigned short blk, 228 unsigned short cnt, unsigned char *key) 229 { 230 ALLOC_CACHE_ALIGN_BUFFER 231 (char, rpmb_frame_data, 232 sizeof(struct s_rpmb) * cnt); 233 ALLOC_CACHE_ALIGN_BUFFER 234 (char, rpmb_frame_data_verify, 235 sizeof(struct s_rpmb_verify) * cnt); 236 struct s_rpmb *rpmb_frame; 237 struct s_rpmb_verify *rpmb_frame_vrify; 238 int i; 239 240 memset(rpmb_frame_data, 0, sizeof(struct s_rpmb) * cnt); 241 memset(rpmb_frame_data_verify, 0, sizeof(struct s_rpmb_verify) * cnt); 242 rpmb_frame = (struct s_rpmb *)rpmb_frame_data; 243 rpmb_frame->address = cpu_to_be16(blk); 244 rpmb_frame->request = cpu_to_be16(RPMB_REQ_READ_DATA); 245 if (mmc_rpmb_request(mmc, rpmb_frame, 1, false)) { 246 printf("mmc_rpmb_read request error\n"); 247 return -1; 248 } 249 250 if (mmc_rpmb_response 251 (mmc, 252 (struct s_rpmb *)rpmb_frame_data, 253 RPMB_RESP_READ_DATA, cnt)) { 254 printf("mmc_rpmb_read response error\n"); 255 return -1; 256 } 257 258 for (i = 0; i < cnt; i++) { 259 rpmb_frame = (struct s_rpmb *) 260 (rpmb_frame_data + 261 i * sizeof(struct s_rpmb)); 262 263 rpmb_frame_vrify = (struct s_rpmb_verify *) 264 (rpmb_frame_data_verify + 265 i * sizeof(struct s_rpmb_verify)); 266 memcpy(addr + i * RPMB_SZ_DATA, rpmb_frame->data, RPMB_SZ_DATA); 267 memcpy(rpmb_frame_vrify->data, rpmb_frame->data, 284); 268 } 269 270 if (key) { 271 unsigned char ret_hmac[RPMB_SZ_MAC]; 272 rpmb_hmac 273 (key, (unsigned char *)rpmb_frame_data_verify, 274 284 * cnt, ret_hmac); 275 if (memcmp(ret_hmac, rpmb_frame->mac, RPMB_SZ_MAC)) { 276 printf("MAC error on block #%d\n", i); 277 return -1; 278 } 279 } 280 281 return cnt; 282 } 283 int mmc_rpmb_write(struct mmc *mmc, void *addr, unsigned short blk, 284 unsigned short cnt, unsigned char *key) 285 { 286 struct s_rpmb *rpmb_frame; 287 struct s_rpmb_verify *rpmb_frame_vrify; 288 ALLOC_CACHE_ALIGN_BUFFER 289 (char, rpmb_frame_data, 290 sizeof(struct s_rpmb) * cnt); 291 ALLOC_CACHE_ALIGN_BUFFER 292 (char, rpmb_frame_data_verify, 293 sizeof(struct s_rpmb_verify) * cnt); 294 295 unsigned long wcount; 296 unsigned short i; 297 unsigned short temp; 298 299 temp = cnt - 1; 300 memset(rpmb_frame_data, 0, sizeof(struct s_rpmb) * cnt); 301 memset(rpmb_frame_data_verify, 0, sizeof(struct s_rpmb_verify) * cnt); 302 for (i = 0; i < cnt; i++) { 303 if (i == 0) { 304 if (mmc_rpmb_get_counter(mmc, &wcount)) { 305 printf("Cannot read RPMB write counter\n"); 306 break; 307 } 308 } 309 310 rpmb_frame = (struct s_rpmb *) 311 (rpmb_frame_data + 312 i * sizeof(struct s_rpmb)); 313 rpmb_frame_vrify = (struct s_rpmb_verify *) 314 (rpmb_frame_data_verify + 315 i * sizeof(struct s_rpmb_verify)); 316 memcpy(rpmb_frame->data, addr + i * RPMB_SZ_DATA, RPMB_SZ_DATA); 317 memcpy(rpmb_frame_vrify->data, addr + 318 i * RPMB_SZ_DATA, RPMB_SZ_DATA); 319 rpmb_frame->address = cpu_to_be16(blk); 320 rpmb_frame_vrify->address = cpu_to_be16(blk); 321 rpmb_frame->block_count = cpu_to_be16(cnt); 322 rpmb_frame_vrify->block_count = cpu_to_be16(cnt); 323 rpmb_frame->write_counter = cpu_to_be32(wcount); 324 rpmb_frame_vrify->write_counter = cpu_to_be32(wcount); 325 rpmb_frame->request = cpu_to_be16(RPMB_REQ_WRITE_DATA); 326 rpmb_frame_vrify->request = cpu_to_be16(RPMB_REQ_WRITE_DATA); 327 if (i == temp) { 328 rpmb_hmac 329 (key, (unsigned char *)rpmb_frame_data_verify, 330 284 * cnt, rpmb_frame->mac); 331 } 332 } 333 if (mmc_rpmb_request(mmc, rpmb_frame_data, cnt, true)) 334 return -1; 335 336 if (mmc_rpmb_status(mmc, RPMB_RESP_WRITE_DATA)) 337 return -1; 338 return cnt; 339 } 340 341 int read_counter(struct mmc *mmc, struct s_rpmb *requestpackets) 342 { 343 if (mmc_rpmb_request(mmc, requestpackets, 1, false)) 344 return -1; 345 346 if (mmc_rpmb_response(mmc, requestpackets, RPMB_RESP_WCOUNTER, 1)) 347 return -1; 348 349 return 0; 350 } 351 352 int program_key(struct mmc *mmc, struct s_rpmb *requestpackets) 353 { 354 if (mmc_rpmb_request(mmc, requestpackets, 1, true)) 355 return -1; 356 357 memset(requestpackets, 0, sizeof(struct s_rpmb)); 358 359 requestpackets->request = cpu_to_be16(RPMB_REQ_STATUS); 360 361 if (mmc_rpmb_request(mmc, requestpackets, 1, false)) 362 return -1; 363 364 return mmc_rpmb_response(mmc, requestpackets, RPMB_RESP_KEY, 1); 365 } 366 367 int authenticated_read(struct mmc *mmc, 368 struct s_rpmb *requestpackets, uint16_t block_count) 369 { 370 if (mmc_rpmb_request(mmc, requestpackets, 1, false)) 371 return -1; 372 373 if (mmc_rpmb_response 374 (mmc, requestpackets, RPMB_RESP_READ_DATA, block_count)) 375 return -1; 376 377 return 0; 378 } 379 380 int authenticated_write(struct mmc *mmc, struct s_rpmb *requestpackets) 381 { 382 if (mmc_rpmb_request(mmc, requestpackets, 1, true)) 383 return -1; 384 385 memset(requestpackets, 0, sizeof(struct s_rpmb)); 386 387 requestpackets->request = cpu_to_be16(RPMB_REQ_STATUS); 388 389 if (mmc_rpmb_request(mmc, requestpackets, 1, false)) 390 return -1; 391 392 return mmc_rpmb_response(mmc, requestpackets, RPMB_RESP_WRITE_DATA, 1); 393 } 394 395