168 lines
5.2 KiB
C
168 lines
5.2 KiB
C
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|||
|
|
/*
|
|||
|
|
* Copyright (C) 2015-2019 Intel Corp. All rights reserved
|
|||
|
|
* Copyright (C) 2021-2022 Linaro Ltd
|
|||
|
|
*/
|
|||
|
|
#ifndef __RPMB_H__
|
|||
|
|
#define __RPMB_H__
|
|||
|
|
|
|||
|
|
#include <linux/device.h>
|
|||
|
|
#include <linux/types.h>
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* enum rpmb_type - type of underlying storage technology
|
|||
|
|
*
|
|||
|
|
* @RPMB_TYPE_EMMC : emmc (JESD84-B50.1)
|
|||
|
|
* @RPMB_TYPE_UFS : UFS (JESD220)
|
|||
|
|
* @RPMB_TYPE_NVME : NVM Express
|
|||
|
|
*/
|
|||
|
|
enum rpmb_type {
|
|||
|
|
RPMB_TYPE_EMMC,
|
|||
|
|
RPMB_TYPE_UFS,
|
|||
|
|
RPMB_TYPE_NVME,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* struct rpmb_descr - RPMB description provided by the underlying block device
|
|||
|
|
*
|
|||
|
|
* @type : block device type
|
|||
|
|
* @route_frames : routes frames to and from the RPMB device
|
|||
|
|
* @dev_id : unique device identifier read from the hardware
|
|||
|
|
* @dev_id_len : length of unique device identifier
|
|||
|
|
* @reliable_wr_count: number of sectors that can be written in one access
|
|||
|
|
* @capacity : capacity of the device in units of 128K
|
|||
|
|
*
|
|||
|
|
* @dev_id is intended to be used as input when deriving the authenticaion key.
|
|||
|
|
*/
|
|||
|
|
struct rpmb_descr {
|
|||
|
|
enum rpmb_type type;
|
|||
|
|
int (*route_frames)(struct device *dev, u8 *req, unsigned int req_len,
|
|||
|
|
u8 *resp, unsigned int resp_len);
|
|||
|
|
u8 *dev_id;
|
|||
|
|
size_t dev_id_len;
|
|||
|
|
u16 reliable_wr_count;
|
|||
|
|
u16 capacity;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* struct rpmb_dev - device which can support RPMB partition
|
|||
|
|
*
|
|||
|
|
* @dev : device
|
|||
|
|
* @id : device_id
|
|||
|
|
* @list_node : linked list node
|
|||
|
|
* @descr : RPMB description
|
|||
|
|
*/
|
|||
|
|
struct rpmb_dev {
|
|||
|
|
struct device dev;
|
|||
|
|
int id;
|
|||
|
|
struct list_head list_node;
|
|||
|
|
struct rpmb_descr descr;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
#define to_rpmb_dev(x) container_of((x), struct rpmb_dev, dev)
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* struct rpmb_frame - RPMB frame structure for authenticated access
|
|||
|
|
*
|
|||
|
|
* @stuff : stuff bytes, a padding/reserved area of 196 bytes at the
|
|||
|
|
* beginning of the RPMB frame. They don’t carry meaningful
|
|||
|
|
* data but are required to make the frame exactly 512 bytes.
|
|||
|
|
* @key_mac : The authentication key or the message authentication
|
|||
|
|
* code (MAC) depending on the request/response type.
|
|||
|
|
* The MAC will be delivered in the last (or the only)
|
|||
|
|
* block of data.
|
|||
|
|
* @data : Data to be written or read by signed access.
|
|||
|
|
* @nonce : Random number generated by the host for the requests
|
|||
|
|
* and copied to the response by the RPMB engine.
|
|||
|
|
* @write_counter: Counter value for the total amount of the successful
|
|||
|
|
* authenticated data write requests made by the host.
|
|||
|
|
* @addr : Address of the data to be programmed to or read
|
|||
|
|
* from the RPMB. Address is the serial number of
|
|||
|
|
* the accessed block (half sector 256B).
|
|||
|
|
* @block_count : Number of blocks (half sectors, 256B) requested to be
|
|||
|
|
* read/programmed.
|
|||
|
|
* @result : Includes information about the status of the write counter
|
|||
|
|
* (valid, expired) and result of the access made to the RPMB.
|
|||
|
|
* @req_resp : Defines the type of request and response to/from the memory.
|
|||
|
|
*
|
|||
|
|
* The stuff bytes and big-endian properties are modeled to fit to the spec.
|
|||
|
|
*/
|
|||
|
|
struct rpmb_frame {
|
|||
|
|
u8 stuff[196];
|
|||
|
|
u8 key_mac[32];
|
|||
|
|
u8 data[256];
|
|||
|
|
u8 nonce[16];
|
|||
|
|
__be32 write_counter;
|
|||
|
|
__be16 addr;
|
|||
|
|
__be16 block_count;
|
|||
|
|
__be16 result;
|
|||
|
|
__be16 req_resp;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
#define RPMB_PROGRAM_KEY 0x1 /* Program RPMB Authentication Key */
|
|||
|
|
#define RPMB_GET_WRITE_COUNTER 0x2 /* Read RPMB write counter */
|
|||
|
|
#define RPMB_WRITE_DATA 0x3 /* Write data to RPMB partition */
|
|||
|
|
#define RPMB_READ_DATA 0x4 /* Read data from RPMB partition */
|
|||
|
|
#define RPMB_RESULT_READ 0x5 /* Read result request (Internal) */
|
|||
|
|
|
|||
|
|
#if IS_ENABLED(CONFIG_RPMB)
|
|||
|
|
struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev);
|
|||
|
|
void rpmb_dev_put(struct rpmb_dev *rdev);
|
|||
|
|
struct rpmb_dev *rpmb_dev_find_device(const void *data,
|
|||
|
|
const struct rpmb_dev *start,
|
|||
|
|
int (*match)(struct device *dev,
|
|||
|
|
const void *data));
|
|||
|
|
int rpmb_interface_register(struct class_interface *intf);
|
|||
|
|
void rpmb_interface_unregister(struct class_interface *intf);
|
|||
|
|
struct rpmb_dev *rpmb_dev_register(struct device *dev,
|
|||
|
|
struct rpmb_descr *descr);
|
|||
|
|
int rpmb_dev_unregister(struct rpmb_dev *rdev);
|
|||
|
|
|
|||
|
|
int rpmb_route_frames(struct rpmb_dev *rdev, u8 *req,
|
|||
|
|
unsigned int req_len, u8 *resp, unsigned int resp_len);
|
|||
|
|
|
|||
|
|
#else
|
|||
|
|
static inline struct rpmb_dev *rpmb_dev_get(struct rpmb_dev *rdev)
|
|||
|
|
{
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static inline void rpmb_dev_put(struct rpmb_dev *rdev) { }
|
|||
|
|
|
|||
|
|
static inline struct rpmb_dev *
|
|||
|
|
rpmb_dev_find_device(const void *data, const struct rpmb_dev *start,
|
|||
|
|
int (*match)(struct device *dev, const void *data))
|
|||
|
|
{
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static inline int rpmb_interface_register(struct class_interface *intf)
|
|||
|
|
{
|
|||
|
|
return -EOPNOTSUPP;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static inline void rpmb_interface_unregister(struct class_interface *intf)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static inline struct rpmb_dev *
|
|||
|
|
rpmb_dev_register(struct device *dev, struct rpmb_descr *descr)
|
|||
|
|
{
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static inline int rpmb_dev_unregister(struct rpmb_dev *dev)
|
|||
|
|
{
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static inline int rpmb_route_frames(struct rpmb_dev *rdev, u8 *req,
|
|||
|
|
unsigned int req_len, u8 *resp,
|
|||
|
|
unsigned int resp_len)
|
|||
|
|
{
|
|||
|
|
return -EOPNOTSUPP;
|
|||
|
|
}
|
|||
|
|
#endif /* CONFIG_RPMB */
|
|||
|
|
|
|||
|
|
#endif /* __RPMB_H__ */
|