blob: 1d90922ad923d2289f813f86af2e7f0b69d150e8 [file] [log] [blame]
#
# Copyright 2018-2020 NXP
# SPDX-License-Identifier: Apache-2.0
#
#
"""License text"""
import ctypes
import logging
from .util import status_to_str
from .session import Session
from . import sss_api as apis
from .keyobject import KeyObject
log = logging.getLogger(__name__)
class KeyStore:
"""
Key Store operation
"""
# session is instance of Session
def __init__(self, session_obj):
"""
Key store context initialization
:param session_obj: Instance of Session
"""
if not isinstance(session_obj, Session):
log.error("%s must be instance of Session", str(session_obj))
self.keystore = None
return
self.keystore = apis.sss_key_store_t()
self.session = session_obj.session_ctx
self._keystore_id = ctypes.c_uint32(155)
if self.session is None:
self.keystore = None
return
status = apis.sss_key_store_context_init(
ctypes.byref(self.keystore), ctypes.byref(self.session))
if status != apis.kStatus_SSS_Success:
log.error("sss_key_store_context_init %s", status_to_str(status))
self.keystore = None
return
log.debug("sss_key_store_context_init %s", status_to_str(status))
if session_obj.subsystem == apis.kType_SSS_SE_A71CH:
self._sscp_session = apis.sss_sscp_session_t()
status = apis.sscp_a71ch_init(
ctypes.byref(self._sscp_session), ctypes.byref(self.keystore))
if status != apis.kStatus_SSS_Success:
log.error("sscp_a71ch_init %s", (status_to_str(status)))
self.keystore = None
return
log.debug("sscp_a71ch_init %s", (status_to_str(status)))
status = apis.sss_key_store_allocate(ctypes.byref(self.keystore),
self._keystore_id)
if status != apis.kStatus_SSS_Success:
log.error("sss_key_store_allocate %s", status_to_str(status))
self.keystore = None
return
log.debug("sss_key_store_allocate %s", status_to_str(status))
def set_key(self, key_object, data, data_len, key_bit_len, opt, opt_len): # pylint: disable=too-many-arguments
"""
Inject key or certificate
:param key_object: Instance of key object
:param data: Value to inject
:param data_len: Length of the value
:param key_bit_len: Key bit length
:param opt: Option. Eg: Policy
:param opt_len: Option length
:return: Status
"""
if not isinstance(key_object, KeyObject):
log.error("%s must be an instance of KeyObject", str(key_object))
return apis.kStatus_SSS_Fail
if key_object.keyobject is None:
log.error("set_key %s", status_to_str(apis.kStatus_SSS_Fail))
return apis.kStatus_SSS_Fail
status = apis.sss_key_store_set_key(
ctypes.byref(self.keystore),
ctypes.byref(key_object.keyobject),
ctypes.byref(data),
data_len, key_bit_len, opt, opt_len)
if status != apis.kStatus_SSS_Success:
log.error("sss_key_store_set_key %s", status_to_str(status))
return status
log.debug("sss_key_store_set_key %s", status_to_str(status))
return status
def save_key_store(self):
"""
Save key store
:return: Status
"""
if self.keystore is None:
log.error("save_key_store %s", status_to_str(apis.kStatus_SSS_Fail))
return status_to_str(apis.kStatus_SSS_Fail)
status = apis.sss_key_store_save(ctypes.byref(self.keystore))
if status != apis.kStatus_SSS_Success:
log.error("sss_key_store_save %s", status_to_str(status))
return status_to_str(status)
log.debug("sss_key_store_save %s", status_to_str(status))
return status
def generate_key(self, key_object, key_len, opt):
"""
Generate ECC or RSA key
:param key_object: Instance of key object
:param key_len: Key length to generate
:param opt: Options to set. Eg: Policy
:return: Status
"""
if not isinstance(key_object, KeyObject):
log.error("%s must be an instance of KeyObject", str(key_object))
return apis.kStatus_SSS_Fail
if key_object.keyobject is None:
log.error("generate_key %s", status_to_str(apis.kStatus_SSS_Fail))
return apis.kStatus_SSS_Fail
status = apis.sss_key_store_generate_key(
ctypes.byref(self.keystore), ctypes.byref(key_object.keyobject), key_len, opt)
if status != apis.kStatus_SSS_Success:
log.error("sss_key_store_generate_key %s", status_to_str(status))
return status
log.debug("sss_key_store_generate_key %s", status_to_str(status))
return status
def get_key(self, key_object, data, data_len, key_bit_len):
"""
Retrieve key from secure element
:param key_object: Instance of key object
:param data: Output data
:param data_len: Output data length
:param key_bit_len: Out put key bit length
:return: Status
"""
if not isinstance(key_object, KeyObject):
log.error("%s must be an instance of KeyObject", str(key_object))
return apis.kStatus_SSS_Fail
if key_object.keyobject is None:
log.error("get_key %s", status_to_str(apis.kStatus_SSS_Fail))
return apis.kStatus_SSS_Fail
status = apis.sss_key_store_get_key(
ctypes.byref(self.keystore), ctypes.byref(key_object.keyobject), ctypes.byref(data),
ctypes.byref(data_len), ctypes.byref(key_bit_len))
if status != apis.kStatus_SSS_Success:
log.error("sss_key_store_get_key %s", status_to_str(status))
return status
log.debug("sss_key_store_get_key %s", status_to_str(status))
return status
def erase_key(self, key_object):
"""
Erase key from secure element
:param key_object: Instance of key object
:return: Status
"""
if not isinstance(key_object, KeyObject):
log.error("%s must be an instance of KeyObject", str(key_object))
return apis.kStatus_SSS_Fail
if key_object.keyobject is None:
log.error("erase_key %s", status_to_str(apis.kStatus_SSS_Fail))
return apis.kStatus_SSS_Fail
status = apis.sss_key_store_erase_key(
ctypes.byref(self.keystore), ctypes.byref(key_object.keyobject))
if status != apis.kStatus_SSS_Success:
log.error("sss_key_store_erase_key %s", status_to_str(status))
return status
log.debug("sss_key_store_erase_key %s", status_to_str(status))
return status
def free(self):
"""
Release allocated key store
:return: None
"""
if self.keystore:
apis.sss_key_store_context_free(ctypes.byref(self.keystore))
self.keystore = None