Back to top

Tutorial — Knox Attestation (v3)

Last updated April 25th, 2024

Knox 3.4 introduced the latest version of Attestation (v3) running on flagship devices from the Note 10 onwards. Enhanced Attestation uses the EnhancedAttestationPolicy class and v3 REST API. For information about the previous version of Attestation, see Attestation (v2).

Get a Vendor-Unique Attestation Key

In the header of every REST API call to the Attestation server, identify yourself by encoding your own unique Vendor-Unique Attestation Key.

If you don’t have access to License keys in the Knox Developer Portal, please contact your Samsung sales partner to request access.

To get this key:

  1. Sign in to the Knox Developer portal.
  2. Go to License keys > My license keys.
  3. Click ACTIONS > Get a license key.
  4. Go to VENDOR-UNIQUE ATTESTATION KEY.
  5. Enter a unique alias to describe this Vendor-Unique Attestation Key. This step is required.
  6. Click Get License Key.
  7. Under License Number, copy the key to use in your REST API calls.

Set up a server

In the following examples, we use an Apache server on a Linux operating system with PHP as the scripting language. You can set up such a web server from scratch quite simply. If you don’t have a web server, you can enroll in a free or trial cloud service to get quick access to one.

If you are new to web server setup, here are some basic Linux commands to set up the server:

install Ubuntu 14.0
sudo apt-get update
sudo apt-get install apache2
sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt php5-curl
sudo /etc/init.d/apache2 restart

Alternatively, you can use a pre-built environment, such as that provided by Apache Friends.

Once you have a web server with PHP support, copy your scripts into the folder /var/www/html. In the sample Attestation app, there are two PHP scripts, called nonces.php and measurements.php, which you can copy into this folder.

Get a nonce

A nonce is a random value that uniquely identifies each attestation request. To protect from replay attacks, each nonce is valid only for a short period of time. This ensures that the Attestation server can fail requests made using an invalid nonce once it expires, which prevents malicious attackers from accessing a past attestation result. A nonce also serves as a unique identifier for each attestation request.

For details about the syntax of the REST API calls to the Attestation Server, see the Attestation REST API reference.

Start attestation

Start attestation using EnhancedAttestationPolicy.

// import EnterpriseKnoxManager
// import EnhancedAttestationPolicy
// import EnhancedAttestationPolicyCallback

import com.samsung.android.knox.EnterpriseKnoxManager;
import com.samsung.android.knox.integrity.EnhancedAttestationPolicy;
import com.samsung.android.knox.integrity.EnhancedAttestationPolicyCallback;

// declare EnhancedAttestationPolicy to call api
private EnhancedAttestationPolicy mPolicy;
EnterpriseKnoxManager ekm = EnterpriseKnoxManager.getInstance(context);
mPolicy = ekm.getEnhancedAttestationPolicy();

//make callback to receive attestation result
EnhancedAttestationPolicyCallback cb = new EnhancedAttestationPolicyCallback() {
 @Override
 public void onAttestationFinished(final EnhancedAttestationResult result) {}
};

// call startAttestation (AUK is vendor Unique Key)
mPolicy.startAttestation(AUK, nonce, cb);

Handle attestation result

Your app handles the attestation result by passing it to the Callback method. This method handles the result sent by the EnhancedAttestationPolicy.

/// import package that defines constants for values returned by EnhancedAttestationResult
import com.samsung.android.knox.integrity.EnhancedAttestationResult

EnhancedAttestationPolicyCallback cb = new EnhancedAttestationPolicyCallback() {
 @Override
 public void onAttestationFinished(final EnhancedAttestationResult result) {
  if (result.getError() == EnhancedAttestationResult.ERROR_NONE) {
   Log.i(TAG, "attest: onSuccess");
   //should compare nonce to unique Id.
   if (nonce.equals(result.getUniqueId())) {
    //nonce verification success
   }
  ...
  } else {
   Log.i(TAG, "attest: onFailure");
   if (nonce.equals(result.getUniqueId())) {
    //nonce verification success
   }
  ...
  }
 }
};

Get verdict

Display the verdict

You can process the verdict in either the web script or Android app.

Here, we use the Android app to convert the attestation response into a JSONObject to extract the results of the attestation, including the attestation verdict:

//Parsing result of attestation
JsonObject = new JSONObject(mAttestationStatus);
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
EAResultInfo eAResultInfo = gson.fromJson(mAttestationStatus.responseData, EAResultInfo.class);
eAResultInfo.toString();

public static class EAResultInfo {
    int version;
    String nonce;
    String verdict;
    int warrantyFuseState;
    int trustBootState;
    int deviceIdState;

    App app;
    long timestamp;

    public String toString() {
        return "Version: " + version +
        "\nNonce: " + nonce +
        "\n\nVerdict: " + verdict +
        "\nWarranty bit: " + warrantyFuseState +
        "\nTrust boot: " + trustBootState +
        "\nDevice id Attestation: " + deviceIdState +
        "\n\nTimeStamp: " + timestamp +
        "\n\nApp package: " + app.pkg +
        "\n\nApp signature: " + app.signature;
        }
        
    static class App {
        String pkg;
        String signature;
        }
    }

For details about the fields returned in the result, see the Attestation REST API reference.

A verdict of:

  • Yes — indicates that the device passed the integrity checks
  • No — indicates that the device might have failed the integrity checks

The Warranty Bit indicates device has been rooted.

  • 0 — never rooted.
  • 1 — rooted.

The Trust boot indicates cross binary (or OEM unlock).

  • 0 — official binary.
  • 1 — Cross binary or OEM unlock.

Device ID Attestation

  • 0 — device ID passed integrity checks.
  • 1 — IMEI and S/N has been modified.
  • -1 — not supported

Is this page helpful?