| /* |
| * 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 <stdint.h> |
| |
| #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; |
| } |