/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include "rpmb.h" /* For struct rpmb_key */ #define MMC_READ_MULTIPLE_BLOCK 18 #define MMC_WRITE_MULTIPLE_BLOCK 25 #define MMC_RELIABLE_WRITE_FLAG (1 << 31) #define MMC_RSP_PRESENT (1 << 0) #define MMC_RSP_CRC (1 << 2) #define MMC_RSP_OPCODE (1 << 4) #define MMC_CMD_ADTC (1 << 5) #define MMC_RSP_SPI_S1 (1 << 7) #define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) #define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1) struct rpmb_nonce { uint8_t byte[16]; }; struct rpmb_u16 { uint8_t byte[2]; }; struct rpmb_u32 { uint8_t byte[4]; }; #define RPMB_PACKET_DATA_SIZE (256) #define RPMB_WRITE_COUNTER_EXPIRED_VALUE (~0U) struct rpmb_packet { uint8_t pad[196]; struct rpmb_key key_mac; uint8_t data[RPMB_PACKET_DATA_SIZE]; struct rpmb_nonce nonce; struct rpmb_u32 write_counter; struct rpmb_u16 address; struct rpmb_u16 block_count; struct rpmb_u16 result; struct rpmb_u16 req_resp; }; enum rpmb_request { RPMB_REQ_PROGRAM_KEY = 0x0001, RPMB_REQ_GET_COUNTER = 0x0002, RPMB_REQ_DATA_WRITE = 0x0003, RPMB_REQ_DATA_READ = 0x0004, RPMB_REQ_RESULT_READ = 0x0005, }; enum rpmb_response { RPMB_RESP_PROGRAM_KEY = 0x0100, RPMB_RESP_GET_COUNTER = 0x0200, RPMB_RESP_DATA_WRITE = 0x0300, RPMB_RESP_DATA_READ = 0x0400, }; enum rpmb_result { RPMB_RES_OK = 0x0000, RPMB_RES_GENERAL_FAILURE = 0x0001, RPMB_RES_AUTH_FAILURE = 0x0002, RPMB_RES_COUNT_FAILURE = 0x0003, RPMB_RES_ADDR_FAILURE = 0x0004, RPMB_RES_WRITE_FAILURE = 0x0005, RPMB_RES_READ_FAILURE = 0x0006, RPMB_RES_NO_AUTH_KEY = 0x0007, RPMB_RES_WRITE_COUNTER_EXPIRED = 0x0080, }; static inline struct rpmb_u16 rpmb_u16(uint16_t val) { struct rpmb_u16 ret = {{ (uint8_t)(val >> 8), (uint8_t)(val >> 0), }}; return ret; } static inline struct rpmb_u32 rpmb_u32(uint32_t val) { struct rpmb_u32 ret = {{ (uint8_t)(val >> 24), (uint8_t)(val >> 16), (uint8_t)(val >> 8), (uint8_t)(val >> 0), }}; return ret; } static inline uint16_t rpmb_get_u16(struct rpmb_u16 u16) { size_t i; uint16_t val; val = 0; for (i = 0; i < sizeof(u16.byte); i++) val = val << 8 | u16.byte[i]; return val; } static inline uint32_t rpmb_get_u32(struct rpmb_u32 u32) { size_t i; uint32_t val; val = 0; for (i = 0; i < sizeof(u32.byte); i++) val = val << 8 | u32.byte[i]; return val; }