Security/Tizen 3.X Key Manager initial value setting
- 1 Overview
- 2 Files
- 3 System database
- 4 Parser
- 5 Initial values tool
- 6 Initial values security
- 7 Hardware backend
- 8 Testing
- 9 Integration with installer (use case)
- 10 See also
The initial values feature allows key-manager service to import items like keys, certificates or binary data into its database after device booting. The feature is intended for loading initial keys required for system to work. Key-manager module, after startup, scans directories for existence of specially-crafted XML files. The XML files contain encoded information on data that will be added to the system database the first time key-manager will recognize given XML file. To protect the imported initial values the XML files should be either encrypted with a device key or removed immediately after import.
The file format is XML. Document structure will be validated with the following schema: initial_values.xsd
Initial value files should be placed at:
Initial values file example: example.xml
XML validation and parsing is implemented using libxml2.
Encrypted initial values are intended to be stored on read-only partition – so that in case of a device factory reset, the key-manager DB will be loaded again with these data. Initial values in read-write location will be removed after import. To trigger initial value import from RO location a flag must be placed at /opt/data/ckm/initial_values/ro_import. After importing the data from RO location key-manager will delete the flag. Initial values from RW location is processed after RO ones possibly overwriting existing values.
All initial values will be stored in system database. That is a database reserved for system processes. System database features:
- System processes are identified using uid range <0,5000) (according to ). All system processes have full access rights to the system database.
- System users don't log in so database is not protected with a password. Therefore, it's not safe unless hardware backend is used for storage. Also, it's not possible to change the database password for a system user.
- System process can still provide a custom password to additionally encrypt a single row in database.
- The system database is not removed when a system user is removed.
- By default non-system users will have no access to system database (objects will be invisible to the client). However, a system user can grant read-only permissions to specific application running as a non-system user: <source lang="c">ckmc_set_permission(“/System data1”, “pkg1”, “r”);</source>. In such case the the access is granted to an application running as any non-system user.
- There's no such thing as application in system database. All objects exist in a common namespace. Therefore, the label column in NAMES table will be hardcoded to /System and common for all system database objects.
- Object names interpretation:
- pkg1 object1 refers to an object in users database owned by pkg1 named object1.
- /System object2 refers to an object in system database in common namespace "/System" named object2 ("/System" is used to not clutter the app identifier namespace). Non-system user can use this format to perform read-only operations using system database objects via API: <source lang="c">ckmc_get_key(“/System key1”, NULL, &key);</source>
- Parser - a generic class wrapping a SAX XML interface. Allows XML validation and parsing. Custom objects can be registered as listeners for specific events.
- ElementHandler - a base class for custom xml element handlers. The object is notified when an element starts, ends or some characters appear within it.
- InitialValuesFile - a class responsible for processing of single XML file with initial values. The class registers itself for document events and holds InitialValueLogic.
- InitialValuesLogic - a class providing different element handlers. It is registered in Parser. When new element starts, the InitialValuesLogic is asked to provide a handler object. It then returns custom ElementHandler derived class, which is again notified about XML events. Upon element end, after ElementHandler is notified the InitialValuesLogic is notified so that it can set the release the element handler. The class holds a connection to Database and passes it to current InitialValueHandler upon creation.
- InitialValueHandler - base class for key, cert and data elements. It holds the buffer and permissions handlers.
- KeyHandler - class for handling keys. When key element is finished an object of this class has all required information to save the key and permissions in database.
- CertHandler - class for handling certificates. When certificate element is finished an object of this class has all required information to save the certificate and permissions in database.
- DataHandler - class for handling data. When data element is finished an object of this class has all required information to save the data and permissions in database.
- BufferHandler - class for handling actual data.
- PermissionHandler - class for handling permissions to objects.
[NOTE] Diagram does not include a handler for main InitialValues element for clarity.
Example sequence for following initial values document: <source lang="xml"> <InitialValues version="0">
<Key name="key1" type="RSA_PRV" password="123"> <PEM> -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2b1bXDa+S8/MGWnMkru4 T4tUddtZNi0NVjQn9RFH1NMa220GsRhRO56F77FlSVFKfSfVZKIiWg6C+DVCkcLf zXJ/Z0pvwOQYBAqVMFjV6efQGN0JzJ1Unu7pPRiZl7RKGEI+cyzzrcDyrLLrQ2W7 0ZySkNEOv6Frx9JgC5NExuYY4lk2fQQa38JXiZkfyzif2em0px7mXbyf5LjccsKq v1e+XLtMsL0ZefRcqsP++NzQAI8fKX7WBT+qK0HJDLiHrKOTWYzx6CwJ66LD/vvf j55xtsKDLVDbsotvf8/m6VLMab+vqKk11TP4tq6yo0mwyTADvgl1zowQEO9I1W6o zQIDAQAB -----END PUBLIC KEY----- </PEM> </Key>
</InitialValues> </source> [NOTE] For clarity, the diagram does not include a InitialValues element parsing sequence.
Initial values tool
The initial values file creation can be done manually, but since version 0.1.27, there is a binary tool prepared that allows to alter a skeleton XML file by adding individual items. The tool name is ckm_initial_values. Tool can be built using two different methods:
- Building key-manager’s repository with gbs will produce an RPM package key-manager-initial-values containing the tool.
- Building the tool locally using cmake and make in tools/ckm_initial_values subdirectory of key-manager’s repository (the tool requires openssl and libxml2).
Its usage options are following:
Usage: ckm_initial_values <options> Mandatory options: -d|--data <dataFile> Path to file containing initial value to be added. Supported formats: - Key: - raw binary (symmetric keys) - DER (asymmetric keys) - Data: raw binary - Cert: DER -n|--name <name> Name, under which the initial value will be saved. -t|--type <type> Initial value type. One of: Key, Data, Cert. -s|--subtype <subtype> Initial value subtype. For 'Key' type allowed values are: RSA_PRV, RSA_PUB, DSA_PRV, DSA_PUB, ECDSA_PRV, ECDSA_PUB, AES. For other types this option should not be used. Optional: -x|--xml <xmlFile> Path to XML file that should be modified. If not provided output will be printed to stdout. -k|--key <keyFile> Path to file containing AES key in binary form used for initial value encryption. -p|--password <password> Password used to encrypt the initial value. -e|--exportable If present the stored value can be later extracted via key-manager API. -a|--accessors <accessor1>[,<accessor2>[,...]] A list of key-manager clients allowed to access given initial value separated by commas. -b|--backend <backend> A key-manager's backed to use when saving the initial values.
The result of tool work is a modified (in-place) or created XML file given as “-xml” argument. Alternatively the produced XML can be printed to stdout.
Initial values security
There are few aspects to consider regarding initial values security:
Initial values can be stored in one of 2 backends. A userspace database called “software backend” or a TrustZone OS storage managed by key-manager-ta called “hardware backend”. Whenever possible the data is stored in a hardware backend. Software backend is used as a fall back. The default backend can be enforced in some cases using “--backend" tool option.
Items stored in hardware backend are encrypted with device key and as such are protected against an offline attack.
See https://wiki.tizen.org/Security/Tizen_5.X_Key_Manager_backends for more information about key-manager backends.
XML level encryption
Initial value can be stored in plain (only base64-encoded) or encrypted form in the XML file. XML with plain data is susceptible to an offline attack. The risk of an attack can be reduced by removing the XML files after successful import.
To encrypt an initial value on XML level an encryption key has to passed to the tool via the "--key" option. The tool will store the item in encrypted form (AES GCM) in the XML. The key used for encryption has to be embedded into key-manager-ta at build stage so that it is able to decrypt the item during import. This option works only with hardware backend. See Hardware backend section for details.
RO vs. RW location
Unlike initial values from RW location, the ones from RO location won't be removed after being imported. If they are stored in plain form they will be permanently susceptible to an offline attack.
Database level encryption
System database is not protected with a password. Therefore, the data stored in it is susceptible to an offline attack. Imported data can be additionally encrypted in the database using a password (provided as tool argument “--password"). The password is stored in XML file so it is advised to use RW location so that the file is removed afterwards.
The password will be later required to access the item via key manager's API.
An "exportable" flag is used to determine whether given item can be retrieved from the key-manager's database and passed to the client in plain form. To protect secret data against online attack it is advised to forbid it by setting the flag to "false". Note that hardware backend does not allow storing exportable keys in it. If such key is to be stored the software backend will be selected.
Hardware backend is implemented by a trusted application key-manager-ta running in TrustZone and communicating with key-manager. It can be used to safely store key-manager data. It's also able to safely transfer encrypted initial values from an XML file to TrustZone encrypted storage. To do that, an encryption key has to be embedded into key-manager-ta at build stage.
Embedding initial values encryption key in key-manager-ta
During key-manager-ta build depending on flags set in spec file and passed to gbs the embedded key can be handled in three different ways:
- Not handled at all. In this mode the encrypted initial values feature will be disabled. This is the default mode.
- In test build (--define "test_key ON" passed as gbs option) a hardcoded test key will be used. This key MUST NOT be used on products.
- In product build (%define attach_product_key ON) the rpm will expect a macro secret_ta_key_delivery_method that will provide a file containing the key encoded in base64 form in ta/include/ subdirectory of key-manager-ta source directory. During build the rpm will evaluate this macro and embed the key in key-manager-ta’s code. If key is not present the encrypted initial values feature will be disabled.
To safely use commercial keys in key-manager-ta, it MUST be ensured that the TA image itself is encrypted with key known only to TrustZone OS, capable of unpacking & running the TA – DO NOT USE commercial keys for debug builds of the platform.
Currently supported item types
Currently, as of key-manager-ta release 0.1.25 and key-manager release version 0.1.27, only symmetric keys & binary data can be stored in hardware backend with “--key” protection option. Additionally only data (not keys) can be stored in it with exportable flag enabled.
If “--key” option provided with other type of item, OR, key-manager-ta is unavailable, key-manager will use software backend. In such case, importing encrypted initial values items to DB will not be possible. Such items will be ignored and proper error logs will be printed by key-manager to your default system logger (usually dlog).
To enable the hardware backend, following option need to be passed to gbs when building key-manager and security-tests:
--define "tz_backend ON"
To enable usage of a test initial values encryption key (testing purposes ONLY), following option need to be passed to gbs when building key-manager-ta:
--define "test_key ON"
The key used for testing is located in key-manager-ta repository under path: data/secret_key.h. DO NOT USE this key for production releases. However, you can use this key for testing the feature in debug builds.
Automatic tests are available at https://review.tizen.org/gerrit/#/admin/projects/platform/core/test/security-tests include a group of tests dedicated for initial values testing
The test "T7000_Encrypted_initial_values" covers the whole process of creating and encrypted initial values XML, importing them into key-manager (hardware backend) and using an imported key to decrypt a ciphertext sample.
Integration with installer (use case)
Preloaded application example (based on Web_App_Encryption_Support):
- Wrt-installer running as root during image creation installs preloaded a application PKG1.
- It generates APP_DEK and stores it in initial values file as an AES key under a name APP_DEK_PKG1.
- It encrypts the application with specific AES algorithm with specific configuration.
- It stores the algorithm type and configuration (like initialization vector) by itself.
- It gives PKG1 permission to access APP_DEK_PKG1.
- Wrt-launcher running as an ordinary logged in user during normal system operation launches the application PKG1.
- Webappenc gets AES key APP_DEK_PKG1 from system database.
- Webappenc uses the key and previously stored decryption parameters to decrypt the web application in runtime.