Cisco IOx Secure Storage Service
Introduction
Secure Storage Service (SSS) offers a secure way of storing certificates, keys, and confidential user data in a device. It uses data encryption with a key stored within Cisco's Anti Counterfeit Technology v2 (ACT2) chip, which is part of Cisco's Hardware-Anchored Secure Boot and Trust Anchor module (TAm) to Verify Hardware and Software Integrity.

IOx applications can only access the Secure Storage Service (SSS) running in the host through REST based APIs, and the encrypted content will be placed in the application disk space.
There is no way for the running application, or even the gateway operating system, at any level of privilege, to retrieve the encryption key. This function is offloaded to the hardware ACT2 chip.
Warning: If the IOx application is deleted, so is the allocated disk space and with it all the secure storage content. The IOx 'upgrade' function will preserve the secure storage content.
Availability
Secure Storage Service (SSS) is a Cisco IOx core service available on the following Cisco platforms:
- Cisco IR809 and IR829
- Cisco IC3000
Using SSS is particularly recommended when removable disks such as mSATA is being used, as the media can be removed physically and unencrypted content can be easily accessed without any difficulty.
Note: This service is not supported on USB storage. It only supported on internal flash disk, or Cisco's removable media such as IR829's mSATA hard disk.
Accessing Secure Storage API
IOx Secure Storage requires an application to communicate with the host system by using a HTTP REST API to the Secure Storage Service.
The API's IP address and port number that an application requires to access the SSS is available:
- in the
/data/.envfile for LXC-based platforms such as IR8x9. Load those environement variables first inshby runningsource /data/env - in Docker's environment variable for native Docker platforms such as IC3000. In this case no action is required, the environment variables are directly available.
${CAF_SS_IP_ADDR} is an IPv4 or IPv6 address through which the application can access the SSS.
${CAF_SS_PORT} is the port through which the SSS can be accessed.
The base URL to access Secure Storage API is therefore going to be:
http://$CAF_SS_IP_ADDR:$CAF_SS_PORT/...
A KVM application must have a shared mount of the disk volume, so the Cisco application-hosting framework can inject the above variables.
Secure Storage Services
SSS offers two of the following key functionalities to applications:
- Secure storage
- Media encryption
SSS supports only managed mode. In this mode, the keys that an application uses for encryption and decryption come from the host system hardware trust anchor.
Functionality
The SSS feature allows you to upload and download user objects. The objects are stored in a software-based trust anchor module (SW-TAM) repository.
Supported SSS Operations
- Upload operation: Uploads an object to the SW-TAM repository.
- Retrieve operation: Retrieves an object from the SW-TAM repository.
- List operation: Lists objects that are contained in the SW-TAM repository.
- Delete operation: Permanently removes an object from the SW-TAM repository.
Media Encryption (Crypt Container(CC)/ Encrypted Disk)
The CC feature offers a set of REST based APIs through which an application can carve out encrypted disk/media.
Supported CC Operations
- CC create: Encrypted disk file that contains application objects.
- Upload operation: Uploads an object to the CC.
- Retrieve operation: Downloads an object from the CC.
- List operation: Lists objects that are contained in the CC.
- Delete operation: Removes an object contained from in the CC.
Supported SSS REST APIs With curl-based API Usage
This section provides a sample of the externally visible REST based APIs that are available to IOx applications.
In the sample usage:
- APPID refers to the CAF_APP_ID environment variable.
- App-UUID refers to the CAF_SYSTEM_UUID environment variable.
- IP address refers to the CAF_SS_IP_ADDR environment variable.
- PORT refers to CAF_SS_PORT environment variable.
- $OBJNAME is the object file name.
- $OBJCONTENT is the payload (contents to be stored in an object file).
- $TOKEN= is the response obtained for the token request REST API.
The following response classifier variables are used in the examples:
- $RETCODE: numerical code 2xX or 4yY
- $RETSTR: response text
Example
run_curl () {
CMD=$
T2=$(timestamp)
if [[ $2 -eq $RETCODE ]] ; then
response=`curl --write-out %{http_code} --silent --output /dev/null ${CMD}`
else
response=`curl --silent ${CMD}`
fi
T1=$(timestamp)
echo "response [$response] took [$(( T1 - T2))] ms"
}
REST API Set
[GET] /TOKEN/${APPID}/${APP-UUID}
Obtain a token for an application.
IN: AppId, App-UUID
OUT: JSON response with token# data | 4yY Failure
An app should be able to get the token any time and any number of times.
run_curl "-X GET http://$IP:$PORT/SS/TOKEN/${APPID}/${APP-UUID}“ $RETSTR
Returns $TOKEN: You must preserve and use the token in subsequent REST API calls.
See the "Application Workflow To Make Use of Any SSS" section.
[POST] /${APPID}/Object
Create a secure object or create a crypt-container.
IN: token#, Object-type [Crypt-Container(CC) | SS-Object], object-name, object-file/content
CC: size, Object-Attrit-Type
OUT: 2xX ok | 4yY Failure
If the Object-type is CC, CC size is mandatory.
Object-Attrit-Type: (optional) By default, objects are treated as RAW objects.
Object attribute list (N = 1 to 9; 7 alone is not supported)
OBJECT_RAW = 1,
/* Generic object identifier */
OBJECT_SYM_KEY = 2,
/* Symmetric key identifier */
OBJECT_RSA_KEYPAIR = 3,
/* RSA key identifier */
OBJECT_CERT = 4,
/* X.509 certificate identifier */
OBJECT_CERTCHAIN = 5,
/* chain of certificates up to root */
OBJECT_ECC_KEYPAIR = 6,
/* ECC Key identifier */
OBJECT_VUDI = 7,
/* Virtual UDI [not supported] */
OBJECT_RSA_PEM_KEYPAIR = 8,
/* PEM encoded RSA key identifier */
OBJECT_ECC_PEM_KEYPAIR = 9,
/* PEM encoded ECC key identifier */
[1] Upload object from file to file
run_curl "-X POST http://$IP:$PORT/SS/${APPID}/Object -H 'content-type:/ multipart/form-data;' -F ss-Token=${TOKEN} -F Object-type=Object -F object-Name=${OBJNAME} -F ss-Content=@${OBJNAME}" $RETSTR
[2] Upload object payload to file
run_curl "-X POST http://$IP:$PORT/SS/${APPID}/Object -H 'content-type:/ multipart/form-data;' -F ss-Token=${TOKEN} -F Object-type=Object -F object-Name=${OBJNAME} -F ss-Content=${OBJCONTENT}" $RETSTR "
For To specifying object-attribute. one need to make use of -F object-attribute=
[3] Crypt C-container creation
run_curl “-X POST http://$IP:9443/SS/${APPID}/Crypt-Container -H 'content-type: multipart/form-data' -F ss-Token=$TOKEN -F Object-type=Crypt-Container -F CC-Size=10 -F object-Name=CC" $RETSTR
/AppId/Object [GET]
Access secure object.
IN: token#, object-name
OUT: json JSON response with object-file/content
run_curl "-X GET http://$IP:$PORT/SS/${APPID}/Object?ss-Token=${TOKEN}&object-name=${OBJNAME}" $RETSTR
/AppId/list [GET]
Get secure object list.
IN: token#
OUT: json JSON response with object-name-list
run_curl "-X GET http://$IP:$PORT/SS/${APPID}/list?ss-Token=${TOKEN}" $RETSTR
/AppId/Object [DELETE]
Delete secure object
IN: token#, object-name
OUT: 2xX ok | 4yY Failure
run_curl "-X DELETE http://$IP:$PORT/SS/${APPID}/Object?ssToken={TOKEN}&object-name=${OBJNAME}" $RETSTR
/AppId/CC/file [PUT]
Create files in encrypted container
IN: token#, file-body
OUT: 2xX ok | 4yY Failure
[1] Upload object from file to CC
run_curl "-X PUT http://$IP:9443/SS/${APPID}/CC/${OBJNAME}?ss-Token=$TOKEN --data-binary @${OBJNAME}" $RETCODE
[2] Upload Object content to CC
run_curl "-X PUT http://$IP:9443/SS/${APPID}/CC/${OBJNAME}?ss-Token=$TOKEN -d ${OBJCONTENT}" $RETCODE "
/AppId/CC/list [GET]
Get file list from encrypted container.
IN: token# OUT: json JSON response with file- list
run_curl "-X GET http://$IP:$PORT/SS/${APPID}/CC/list?ss-Token=${TOKEN}" $RETSTR
/AppId/CC/file [GET]
Access file from encrypted container.
IN: token#
OUT: 2xX ok | 4yY Failure
run_curl "-X GET http://$IP:$PORT/SS/${APPID}/CC/${OBJNAME}?ss-Token=${TOKEN}" $RETSTR
/AppId/CC/file [DELETE]
Delete file from encrypted container.
IN: token#
OUT: 2xX ok | 4yY Failure
run_curl "-X DELETE http://$IP:$PORT/SS/${APPID}/CC/${OBJNAME}?ss-Token=${TOKEN}" $RETCODE
/AppId/CC [DELETE]
Delete the encrypted container carved out.
IN: token#
OUT: 2xX ok | 4yY Failure
run_curl "-X DELETE http://$IP:$PORT/SS/${APPID}/CC?ss-Token=${TOKEN}" $RETCODE
Application Workflow To Make Use of Any SSS
GET SSS Token
run_curl "-X GET http://$IP:$PORT/SS/TOKEN/${APPID}/{APP-UUID}
$RETSTR
POST SSS Object
//from File
run_curl "-X POST http://$IP:$PORT/SS/${APPID}/Object -H 'content-type:/ multipart/form-data;' -F ss-Token=${TOKEN} -F Object-type=Object -F object-Name=${OBJNAME} -F ss-Content=@${OBJNAME}"
$RETSTR "Processing completed"
Or
//contents to file
run_curl "-X POST http://$IP:$PORT/SS/${APPID}/Object -H 'content-
type:/ multipart/form-data;' -F ss-Token=${TOKEN} -F Object-type=Object -F object-Name=${OBJNAME} -F ss-Content=${OBJCONTENT}"
$RETSTR "Processing completed"
GET SSS Object
run_curl "-X GET http://$IP:$PORT/SS/${APPID}/Object?ss-Token=${TOKEN}&object-name=${OBJNAME}" $RETSTR
GET CC Token
run_curl "-X GET http://$IP:$PORT/SS/TOKEN/${APPID}/{APP-UUID}” $RETSTR
Create CC Container
run_curl "-X POST http://$IP:9443/SS/${APPID}/Crypt-Container -H 'content-type: multipart/form-data' -F ss-Token=$TOKEN -F Object-type=Crypt-Container -F CC-Size=10 -F object-Name=CC" $RETSTR
"Processing completed"
PUT Container File
//from file
run_curl "-X PUT http://$IP:9443/SS/${APPID}/CC/${OBJNAME}?ss-Token=$TOKEN --data-binary @${OBJNAME}" $RETCODE "Processing
completed"
OR
//contents to file
run_curl "-X PUT http://$IP:9443/SS/${APPID}/CC/${OBJNAME}?ss-Token=$TOKEN -d ${OBJCONTENT}" $RETCODE "Processing completed"
GET Container File
run_curl "-X GET http://$IP:9443/SS/${APPID}/CC/${OBJNAME}?ss-Token=${TOKEN}" $RETSTR
DELETE Container File
run_curl "-X DELETE http://$IP:9443/SS/${APPID}/CC/${OBJNAME}?ss-Token=${TOKEN}" $RETCODE 204
Curl Usage Samples Show Case SSS and CC Usages From an Application
/ # curl --version
curl 7.37.1 (powerpc-poky-linux-gnu) libcurl/7.37.1 GnuTLS/3.3.5 zlib/1.2.
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp
smtp smtps telnet tftp
Features: IPv6 NTLM NTLM_WB SSL libz TLS-SRP
SSS Usage
/ # echo "hello world" > test.txt
/ # curl -X GET http://1.100.30.92:9443/SS/TOKEN/curl_app/0
x4G3rKJLQetKA8cqjO8WJiKnpb7chhwe0GrloazXyL0%3D/ #
/ #
/ # curl -X POST http://1.100.30.92:9443/SS/curl_app/Object -H 'content-type: multipart/form-data;' -F ss-Token=7YNUTG3b5dSlY5ZgwazES0oykNdBdVjxJciEGDo
Bad Token/ # 3FIA%3D -F Object-type=Object -F object-Name=test.txt -F ss-Content=@test.txt
/ # curl -X POST http://1.100.30.92:9443/SS/curl_app/Object -H 'content-type: multipart/form-data;' -F ss-Token=x4G3rKJLQetKA8cqjO8WJiKnpb7chhwe0GrloazXyL0%3D -F Object-type=Object -F object-Name=test.txt -F ss-Content=@test.txt
File Already Exists/ #
/ # echo "hello world" > test1.txt
/ # curl -X POST http://1.100.30.92:9443/SS/curl_app/Object -H 'content-type: multipart/form-data;' -F ss-Token=x4G3rKJLQetKA8cqjO8WJiKnpb7chhwe0GrloazXyL0%3D -F Object-type=Object -F object-Name=test1.txt -F ss-Content=@test1.txt
Processing Completed/ #
/ #
/ # curl --silent -X GET http://1.100.30.92:9443/SS/caf/list?ss-Token=x4G3rKJLQetKA8cqjO8WJiKnpb7chhwe0GrloazXyL0%3D
Unauthorized Connection/ #
/ #
/ # curl --silent -X GET http://1.100.30.92:9443/SS/curl_app/list?ss-Token=x4G3rKJLQetKA8cqjO8WJiKnpb7chhwe0GrloazXyL0%3D
test1.txt, test.txt, test_new.txt/ #
/ #
CC Usage
/ # curl -X GET http://1.100.30.92:9443/SS/TOKEN/curl_app/0
E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D/ #
/ #
/ # curl -X POST http://1.100.30.92:9443/SS/curl_app/Crypt-Container -H 'content-type: multipart/form-data' -F ss-Token=E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D -F Object-type=Crypt-Container -F CC-Size=3 -F object-Name=CC
Processing Completed/ #
/ #
/ # curl -X PUT http://1.100.30.92:9443/SS/curl_app/CC/test.txt?ss-Token=E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D --data-binary @test.txt
Processing Completed/ #
/ #
/ # curl -X GET http://1.100.30.92:9443/SS/curl_app/CC/test.txt?ss-Token=E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D
hello world
/ # curl -X DELETE http://1.100.30.92:9443/SS/curl_app/CC/test.txt?ss-Token=E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D
/ #
/ # curl -X GET http://1.100.30.92:9443/SS/curl_app/CC/test.txt?ss-Token=E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D
Resouce Not Found/ #
/ #
/ # curl -X GET http://1.100.30.92:9443/SS/curl_app/CC/unmap?ss-Token=E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D
Bad Appid/ #
/ #
/ # curl -X DELETE http://1.100.30.92:9443/SS/curl_app/CC?ss-Token=E0Sag%2F5cFS5hIY%2BcmQ0xTxPRhZ7Suqs4COmEY2DJM1k%3D
/ #