Key Manager

The Key Manager (KM) provides JavaScript applications with key management and cryptographic functionality. It makes this available on the device's public bus via a number of API calls. The Key Manager implements a key store , allowing apps a place to safely keep keys where they are readily available for cryptographic operations.

The Key Manager is designed to do the following:

Keys are stored encrypted in a database. They have both an app name (i.e., "com.someone.appname") and a key name. The latter is not necessarily unique—two different apps can both have a key with the same name. However, the Key Manager service obtains the app name from the protocol, making it almost impossible for apps to use the same keys.

An app can use the KM service to store or generate a key while specifying its encryption algorithm type, length, and an option to hide the key and never return it to the application, though it remains available for cryptographic operations.

In this section:


Supported Key Types

In cryptography, a key is a piece of information (a parameter) that determines the functional output of a cryptographic algorithm or cipher. Without a key, the algorithm would have no result. In encryption, a key specifies the particular transformation of plaintext (unencrypted text) into ciphertext (encrypted text), or vice-versa during decryption. Keys are also used in other cryptographic algorithms, such as digital signature schemes and message authentication codes.

Key Manager supports the following key encryption algorithm types:

  • AES—Advanced Encryption Standard. AES-128, AES-192, and AES-256 are supported.

  • 3DES (3 key outer CBC)—The size includes the padding.

  • HMAC — SHA1 —Hash-based Message Authentication Code - Secure Hash Algorithm-1 . Any size from 16 bytes up is supported.

  • BLOB—For storing any type of data, up to 4k bytes.

  • ASCIIBLOB—An ascii (non-base64 encoded) BLOB. The data must be in valid JSON format with no unescaped JSON formatting characters.


Supported Block Cipher Modes

A block cipher is a type of symmetric-key encryption algorithm that transforms a fixed-length block of plaintext data into a block of ciphertext data of the same length. This transformation takes place with the aid of a user-provided secret key. Decryption is performed by applying the reverse transformation to the ciphertext block using the same secret key. The fixed length is called the block size, and for many block ciphers, the block size is 64 bits or 128 bits.

AES and 3DES are the supported block ciphers.

Key Manager supports the following block cipher modes:

  • CBC—Cipher Block Chaining.
  • ECB—Electronic CodeBook.
  • CFB—Cipher FeedBack Mode.

Supported Block Cipher Padding Modes

Because a block cipher works on units of a fixed size, but messages come in a variety of lengths, some modes (mainly CBC) require that the final block be padded before encryption.

Key Manager supports the following block cipher padding modes:

  • None—Data must be a multiple of the block size.
  • PKCS1—Public Key Cryptography Standards #1.

Methods

You can asynchronously call Key Manager methods through the serviceRequest function which takes 2 parameters:

  • The Key Manager URI (Uniform Resource Identifier).
  • A JSON (JavaScript Object Notation) object containing parameters, callback functions, and other data.

Depending on outcome, the API returns a JSON result to either the success or failure callback function. These functions can then parse the result. Your app needs to take into account the call's asynchronous nature (results may be delayed) and not block user interaction while awaiting results.

About JSON

For more information on calling services such as Key Manager, see the Services Overview.

JSON is a lightweight data-interchange text format based on a subset of the JavaScript programming language that is easy for humans to read and write and for machines to parse and generate. Like XML, JSON contains name/value pair collections and ordered list of values (i.e., arrays).

For more information on JSON, see the following websites:

A primer on how JSON data objects are formatted is beyond the scope of this document—consult the two links above for more information. However, in brief:

  • Curly brackets ('{', '}') are used to enclose objects.
  • Angle brackets ('[', ']') are used to enclose arrays.
  • Colons (':') are used as delimiters in name/value pairs.
  • Quotes (") are used for string values. Numeric values are not quoted.

Data Formatting

Since JSON objects are composed and formatted with ascii (UTF-8) text, data to and from the Key Manager service needs to be base64 encoded to avoid having it interpreted as JSON formatting instructions. This includes key data, data to be encrypted or decrypted, and IVs (Initialization Vectors). The webOS JavaScript foundation libraries provide the following base64 encoding and decoding functions: TBD

Key Manager Public Methods

  • crypt—Encrypts or decrypts data.
  • export—Wraps a key using a specified wrapping key.
  • fetchKey—Returns key metadata and key data.
  • generate—Generates a key.
  • import—Takes a wrapped key and imports it.
  • keyInfo—Returns key metadata but not the key data.
  • remove—Deletes a key from the database.
  • store—Stores a key in the database.

 


crypt

You can use this API to encrypt or decrypt data. The key encryption algorithm specified (AES, 3DES, or HMACSHA1) must be the same as the one used to create the key.

Key data needs to be base64 encoded. Since JSON objects are composed and formatted with ascii (UTF-8) text, data needs to be base64 encoded to avoid having it interpreted as JSON formatting instructions. The webOS JavaScript foundation libraries provide the following base64 encoding/decoding functions: TBD

Schema

{
  "keyname"   : string,
  "algorithm" : string,
  "pad"       : string,
  "mode"      : string,
  "iv"        : string,
  "decrypt"   : boolean,
  "data"      : string
}

Parameters

Argument Required Type Description
keyname Yes string Key name.
algorithm Yes string Possible values: "AES", "3DES", or "HMACSHA1".
pad No string Possible values: "PKCS1", or "none". Required for block ciphers.
mode No string Possible values: "CBC", "CFB", "ECB", or "none". This is only appropriate for block ciphers. none is not valid for block ciphers.
iv No string Initialization Vector—a block of bits that is required to allow a stream cipher or a block cipher to to produce a unique stream independent from other streams produced by the same encryption key without having to go through a re-keying process. Only required for CBC and CFB modes. 16 bytes for AES, 8 bytes for 3DES.
decrypt Yes boolean false to encrypt, true to decrypt.
data Yes string Data to encrypt or decrypt.

Returns

{
  "returnValue" : boolean,
  "errorText"   : string, |
  "data"        : string
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure)
errorText No string Error message returned on failure.
data No string Encrypted data.

Example

this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "crypt",
  parameters: {
      "keyname"   : "myKey",
      "algorithm" : "AES",
      "decrypt"   : false,
      "data"      : "Here is my secret, secret credit card number: 3456-8720-8735=0678"
  },
  onSuccess: function(e){ Mojo.Log.info("Crypt success, data="+e.data); },
  onFailure: function(e){ Mojo.Log.info("Crypt failure, err="+e.errorText); }
});

 


export

Wraps a key using a specified wrapping key. Both keys must belong to the same owner. A key can not wrap itself.

Schema

{ 
  "keyname"        : string,
  "wrappingkeyname": string
}

Parameters

Argument Type Description
keyname string Key name.
wrappingkeyname string Wrapping key name.

Returns

{
  "returnValue" : boolean,
  "errorText"   : string, |
  "wrappedkey"  : string
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure)
errorText No string Error message returned on failure.
wrappedkey No string Wrapped key returned on success.

Example

this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "export",
  parameters: {
      "keyname": "MyKey",
      "wrappingkeyname": "MyWrappingKey"
  },
  onSuccess: function(e) {Mojo.Log.info("KeyManager: export success="+JSON.stringify(e));},
  onFailure: function(e) {Mojo.Log.info("KeyManager: export failure="+JSON.stringify(e));}
});

 


fetchKey

Returns key metadata and key data. Key data is returned if the key had been originally stored or generated with nohide = true. Otherwise, the call fails and a "key is not exportable" error message is returned.

Schema

{
  "keyname" : string
}

Parameters

Argument Required Type Description
keyname Yes string Key name.

Returns

{
  "returnValue" : boolean,
  "errorText"   : string, |
  "keyname"     : string,
  "type"        : string,
  "keydata"     : string
  "nohide"      : boolean
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure).
errorText No string Error message returned on failure.
keyname No string Key name. Returned on success.
type No string Key type. One of the following—"AES", "3DES", "HMACSHA1", "BLOB", or "ASCIIBLOB". Returned on success.
keydata No string Optional key data string. Returned if nohide is true. Returned on success.
nohide No boolean If true, it means key data can be returned with this call. Returned on success.

Example

this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "fetchKey",
  parameters: {
      "keyname" :"MyKey"
  },
  onSuccess: function(e){
      var MyKeyB64 = Base64.decode(e.keydata);
      Mojo.Log.info("KeyManager: fetchKey Success: keydata= "+MyKeyB64+ ", keyname="+e.keyname);
  },
  onFailure: function(e){ Mojo.Log.info("fetchKey Failure, err="+e.errorText); }
});

 


generate

Generates a key with the name specified. If nohide = true, the key data can be accessed with fetchKey.

Types and their size requirements:

  • AES—16 (default), 24 or 32 bytes. These sizes correspond to AES 128, 192 or 256 bit.
  • 3DES—24 bytes.
  • HMACSHA1—16 bytes or up.
  • BLOB—Up to 4096 bytes. The BLOB type is used for safely storing data of any kind.
  • ASCIIBLOB—Same as BLOB but for storing ascii, JSON formatted text that is not base64 encoded.

Schema

{
  "keyname": string,
  "size"   : integer,
  "type"   : string,
  "nohide" : boolean
}

Parameters

Argument Required Type Description
keyname Yes string Name of key to generate.
size Yes integer Key size in bytes.
type Yes string Key type. Must be one of the following—"AES", "3DES", "HMACSHA1", "BLOB", or "ASCIIBLOB".
nohide No boolean If false (default), the key data can not be exported with fetchKey.

Returns

{
  "returnValue" : boolean,
  "errorText"   : string
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure).
errorText No string Error message returned on failure.

Example

this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "generate",
  parameters: {
      "keyname" : "MyGenKey",
      "size"    : 16,
      "type"    : "HMACSHA1",
      "nohide"  : true
  },
  onSuccess: function(e){ Mojo.Log.info("KeyManager: Generate MyGenKey success, e="+JSON.stringify(e)); },
  onFailure: function(e){ Mojo.Log.info("KeyManager: Generate MyGenKey failure, e="+JSON.stringify(e)); }
});

 


import

Import takes a wrapped key and imports it. If the wrapping key is not present, the key is not installed and an error is returned. If successful, the unwrapped key's name is returned. A wrapped key can not replace an existing key with the same owner and name.

Schema

{
  "wrappedKey": string
}

Parameters

Argument Type Description
wrappedKey string Wrapped key.

Returns

{
  "returnValue" : boolean,
  "errorText"   : string, |
  "keyname"     : string
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure).
errorText No string Error message returned on failure. Returned on success.
keyname No string Key name.

Example

this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "import",
  parameters: {
      "wrappedKey": "MyWrappedKey"
  },
  onSuccess: function(e){ Mojo.Log.info("Import success, e="+JSON.stringify(e)); },
  onFailure: function(e){ Mojo.Log.info("Import failure, e="+JSON.stringify(e)); }
});

 


keyInfo

Returns the key's metadata but not the key data.

Schema

{
  "keyname" : string
}

Parameters

Argument Required Type Description
keyname Yes string Key name

Returns

{
  "returnValue" : boolean,
  "errorText"   : string, |
  "keyname"     : string,
  "type"        : string,
  "nohide"      : boolean,
  "backup"      : boolean,
  "noexport"    : boolean,
  "cloud"       : boolean,
  "unwrap_only" : boolean,
  "shared"      : boolean
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure).
errorText No string Error message returned on failure.
keyname No string Key name. Returned on success.
type No string One of the following—"AES", "3DES", "HMACSHA1", "BLOB", or "ASCIIBLOB". Returned on success.
nohide No boolean Indicates if key data is accessible via fetchKey (true), or can only be used for operations (false). Returned on success.
backup No boolean Is this key backed up in the cloud with the device backup? Returned on success.
noexport No boolean Key can be exported flag. Returned on success.
cloud No boolean Is this key stored in the cloud and used for backups? Returned on success.
unwrap_only No boolean If true, key can only be used to unwrap wrapped keys and no other operation. Returned on success.
shared No boolean Can other apps access the key flag. Returned on success.

Example

this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "keyInfo",
  parameters: {
      "keyname" :"MyKey"
  },
  onSuccess: function(e){ Mojo.Log.info("keyInfo Success: type= "+e.type); },
  onFailure: function(e){ Mojo.Log.info("keyInfo Failure err="+JSON.stringify(e)); }
});

 


remove

Given a key name, removes a key from the key store.

Schema

{
  "keyname" : string
}

Parameters

Argument Required Type Description
keyname Yes string Key name.

Returns

{
  "returnValue" : boolean,
  "errorText"   : string
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure).
errorText No string Error message on failure.

Example

this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "remove",
  parameters: {
      "keyname" : "MyKey4"
  },
  onSuccess: function(e){ Mojo.Log.info("Remove key success"); },
  onFailure: function(e){ Mojo.Log.info("Remove key failure, err="+JSON.stringify(e)); }
});

 


store

Stores a key in the database given a key name, data, key encryption algorithm type, and other optional parameters.

Key data needs to be base64 encoded unless its type is ASCIIBLOB. Since JSON objects are composed and formatted with ascii (UTF-8) text, data needs to be base64 encoded to avoid having it interpreted as JSON formatting instructions. The webOS JavaScript foundation libraries provide the following base64 encoding/decoding functions: TBD

Type must be one of the supported key types—AES, 3DES, HMACSHA1, BLOB, or ASCIIBLOB. BLOB is not actually a key type, but can be used to safely store data (up to 4096 bytes) of any kind. ASCIIBLOB is the same as BLOB, but for storing ascii, JSON formatted text.

If nohide is set to false (default), the key data can not be exported with fetchKey. BLOB types should not have nohide set, as that makes them useless.

The backup flag (keys backed up in the cloud with the device backup) is false by default.

The cloud flag indicates a key which is stored in the cloud and is a special key for backups. If true, The type should be ASCIIBLOB and the keydata contains the backup-specific part of the URL for fetching the key.

Schema

{
  "keyname" : string,
  "keydata" : string,
  "type"    : string,
  "nohide"  : boolean,
  "backup"  : boolean,
  "cloud"   : boolean
}

Parameters

Argument Required Type Description
keyname Yes string Key name.
keydata Yes string Key data.
type Yes string Key algroithm encryption type. Must be one of the following—AES, 3DES, HMACSHA1, BLOB, or ASCIIBLOB. 3DES keys must be properly formed with DES parity bits and weak key checking already done.
nohide No boolean If false (default), the key data can not be exported with fetchKey.
backup No boolean If true, this key is backed up in the cloud with the device backup. This field is false by default.
cloud No boolean Indicates a key which is stored in the cloud and is a special key for backups. The type should be ASCIIBLOB and the keydata contains the backup-specific part of the URL for fetching the key.

Returns

{ 
  "returnValue" : boolean,
  "errorText"   : string
}

Argument Required Type Description
returnValue Yes boolean true (success) or false (failure).
errorText No string Error message returned on failure.

Example

// The following base64 encoding functionality is something YOU need to provide
var KeyDataB64 = Base64.encode("123456");
this.controller.serviceRequest("palm://com.palm.keymanager/", {
  method: "store",
  parameters: {
      "keyname" : "MyKey",
      "keydata" : KeyDataB64,
      "type"    : "AES",
      "nohide"  : true
  },
  onSuccess: function(e){ Mojo.Log.info("Store key success"); },
  onFailure: function(e){ Mojo.Log.info("Store key failure, err="+JSON.stringify(e)); }
});