192973c7820129b724e589268cfcba4600ffb168cWill Drewry// 292973c7820129b724e589268cfcba4600ffb168cWill Drewry// Copyright (C) 2017 The Android Open Source Project 392973c7820129b724e589268cfcba4600ffb168cWill Drewry// 492973c7820129b724e589268cfcba4600ffb168cWill Drewry// Licensed under the Apache License, Version 2.0 (the "License"); 592973c7820129b724e589268cfcba4600ffb168cWill Drewry// you may not use this file except in compliance with the License. 692973c7820129b724e589268cfcba4600ffb168cWill Drewry// You may obtain a copy of the License at 792973c7820129b724e589268cfcba4600ffb168cWill Drewry// 892973c7820129b724e589268cfcba4600ffb168cWill Drewry// http://www.apache.org/licenses/LICENSE-2.0 992973c7820129b724e589268cfcba4600ffb168cWill Drewry// 1092973c7820129b724e589268cfcba4600ffb168cWill Drewry// Unless required by applicable law or agreed to in writing, software 1192973c7820129b724e589268cfcba4600ffb168cWill Drewry// distributed under the License is distributed on an "AS IS" BASIS, 1292973c7820129b724e589268cfcba4600ffb168cWill Drewry// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1392973c7820129b724e589268cfcba4600ffb168cWill Drewry// See the License for the specific language governing permissions and 1492973c7820129b724e589268cfcba4600ffb168cWill Drewry// limitations under the License. 1592973c7820129b724e589268cfcba4600ffb168cWill Drewry// 1692973c7820129b724e589268cfcba4600ffb168cWill Drewry 1792973c7820129b724e589268cfcba4600ffb168cWill Drewrypackage com.android.verifiedboot.storage; 1892973c7820129b724e589268cfcba4600ffb168cWill Drewry 1992973c7820129b724e589268cfcba4600ffb168cWill Drewryimport javacard.framework.CardRuntimeException; 2092973c7820129b724e589268cfcba4600ffb168cWill Drewryimport javacard.framework.JCSystem; 2192973c7820129b724e589268cfcba4600ffb168cWill Drewryimport javacard.framework.Util; 2292973c7820129b724e589268cfcba4600ffb168cWill Drewry 2392973c7820129b724e589268cfcba4600ffb168cWill Drewryimport javacard.security.KeyBuilder; 2492973c7820129b724e589268cfcba4600ffb168cWill Drewryimport javacard.security.MessageDigest; 2592973c7820129b724e589268cfcba4600ffb168cWill Drewryimport javacard.security.RSAPublicKey; 2692973c7820129b724e589268cfcba4600ffb168cWill Drewryimport javacard.security.Signature; 2792973c7820129b724e589268cfcba4600ffb168cWill Drewry 2892973c7820129b724e589268cfcba4600ffb168cWill Drewryimport com.android.verifiedboot.storage.LockInterface; 2992973c7820129b724e589268cfcba4600ffb168cWill Drewryimport com.android.verifiedboot.globalstate.owner.OwnerInterface; 3092973c7820129b724e589268cfcba4600ffb168cWill Drewry 3192973c7820129b724e589268cfcba4600ffb168cWill Drewryclass CarrierLock implements LockInterface, BackupInterface { 3292973c7820129b724e589268cfcba4600ffb168cWill Drewry private final static byte VERSION = (byte) 1; 3392973c7820129b724e589268cfcba4600ffb168cWill Drewry private final static byte VERSION_SIZE = (byte) 8; 3492973c7820129b724e589268cfcba4600ffb168cWill Drewry private final static byte NONCE_SIZE = (byte) 8; 3592973c7820129b724e589268cfcba4600ffb168cWill Drewry private final static byte DEVICE_DATA_SIZE = (byte) (256 / 8); 3692973c7820129b724e589268cfcba4600ffb168cWill Drewry 3792973c7820129b724e589268cfcba4600ffb168cWill Drewry private final static byte[] PK_EXP = { (byte) 0x01, (byte) 0x00, (byte) 0x01 }; /* 65537 */ 38d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry // Production key. 39d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry private final static byte[] PK_MOD = { 40d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xA3, (byte) 0x19, (byte) 0x27, (byte) 0x0B, (byte) 0xC6, 41d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x3C, (byte) 0xC0, (byte) 0x92, (byte) 0x38, (byte) 0x7D, 42d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xE3, (byte) 0xC1, (byte) 0xAE, (byte) 0xDD, (byte) 0x2C, 43d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xAA, (byte) 0x1C, (byte) 0x93, (byte) 0x23, (byte) 0xAA, 44d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x13, (byte) 0xF2, (byte) 0x0D, (byte) 0x03, (byte) 0x5F, 45d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xB8, (byte) 0x98, (byte) 0xA8, (byte) 0xFA, (byte) 0x57, 46d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xE9, (byte) 0xBF, (byte) 0x15, (byte) 0xE3, (byte) 0xAC, 47d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xB5, (byte) 0x64, (byte) 0xE7, (byte) 0x18, (byte) 0x85, 48d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xE1, (byte) 0xE4, (byte) 0xF0, (byte) 0x36, (byte) 0x81, 49d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x57, (byte) 0xA8, (byte) 0x78, (byte) 0x70, (byte) 0xDF, 50d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x92, (byte) 0x06, (byte) 0xCF, (byte) 0xEE, (byte) 0x1A, 51d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x6B, (byte) 0xE8, (byte) 0x50, (byte) 0x28, (byte) 0xD9, 52d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x54, (byte) 0x03, (byte) 0x6E, (byte) 0xF2, (byte) 0x6C, 53d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x06, (byte) 0xCE, (byte) 0x02, (byte) 0x8A, (byte) 0xF4, 54d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x86, (byte) 0x07, (byte) 0xA8, (byte) 0xE6, (byte) 0x6C, 55d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x1F, (byte) 0xFE, (byte) 0xB4, (byte) 0x83, (byte) 0x79, 56d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x40, (byte) 0x02, (byte) 0x25, (byte) 0xBD, (byte) 0x6B, 57d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x67, (byte) 0x03, (byte) 0xEB, (byte) 0xF2, (byte) 0xC7, 58d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x74, (byte) 0xB9, (byte) 0xE8, (byte) 0x35, (byte) 0x76, 59d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x4C, (byte) 0x1D, (byte) 0xE7, (byte) 0x34, (byte) 0x72, 60d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x6C, (byte) 0x0E, (byte) 0xCE, (byte) 0xD6, (byte) 0x2C, 61d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x86, (byte) 0x59, (byte) 0x58, (byte) 0x10, (byte) 0x00, 62d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x7F, (byte) 0x70, (byte) 0xF7, (byte) 0x4A, (byte) 0x2F, 63d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xED, (byte) 0x39, (byte) 0x46, (byte) 0xAC, (byte) 0x3A, 64d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x32, (byte) 0x32, (byte) 0x0F, (byte) 0x7A, (byte) 0x5C, 65d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x8A, (byte) 0x07, (byte) 0xDE, (byte) 0xA1, (byte) 0x8F, 66d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x74, (byte) 0xD8, (byte) 0x99, (byte) 0x3A, (byte) 0xE0, 67d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x9A, (byte) 0x40, (byte) 0x80, (byte) 0x51, (byte) 0x1F, 68d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xAD, (byte) 0x4D, (byte) 0x2A, (byte) 0x1D, (byte) 0x53, 69d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xC3, (byte) 0x66, (byte) 0x65, (byte) 0x59, (byte) 0x6D, 70d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x40, (byte) 0xB8, (byte) 0x71, (byte) 0xB5, (byte) 0xD4, 71d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x50, (byte) 0x3E, (byte) 0x41, (byte) 0xE0, (byte) 0x14, 72d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x25, (byte) 0x80, (byte) 0xA9, (byte) 0x0C, (byte) 0x76, 73d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xD4, (byte) 0x6C, (byte) 0x48, (byte) 0x0F, (byte) 0x08, 74d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x5A, (byte) 0xCD, (byte) 0xE5, (byte) 0x28, (byte) 0x58, 75d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xA5, (byte) 0x35, (byte) 0x10, (byte) 0x5D, (byte) 0x05, 76d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xB0, (byte) 0xE1, (byte) 0x26, (byte) 0xD3, (byte) 0x08, 77d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xE9, (byte) 0x5D, (byte) 0xB3, (byte) 0x77, (byte) 0x19, 78d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xD7, (byte) 0xC3, (byte) 0xA7, (byte) 0x3E, (byte) 0x09, 79d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x01, (byte) 0x75, (byte) 0x14, (byte) 0x49, (byte) 0x5D, 80d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x21, (byte) 0xBA, (byte) 0x8D, (byte) 0x74, (byte) 0x0A, 81d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x45, (byte) 0xCA, (byte) 0x39, (byte) 0x24, (byte) 0x94, 82d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x33, (byte) 0x0F, (byte) 0x35, (byte) 0x40, (byte) 0x70, 83d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x0B, (byte) 0x6C, (byte) 0xF7, (byte) 0x93, (byte) 0x35, 84d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x9A, (byte) 0x40, (byte) 0x72, (byte) 0xD7, (byte) 0xDD, 85d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xA5, (byte) 0xAA, (byte) 0x2A, (byte) 0x7B, (byte) 0x32, 86d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xF6, (byte) 0x56, (byte) 0x71, (byte) 0xC6, (byte) 0xAB, 87d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xEB, (byte) 0xFB, (byte) 0xCD, (byte) 0x27, (byte) 0xA1, 88d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x4C, (byte) 0xDA, (byte) 0xA4, (byte) 0xB1, (byte) 0x66, 89d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0x2D, (byte) 0x57, (byte) 0x4B, (byte) 0x0D, (byte) 0x86, 90d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xD0, (byte) 0x98, (byte) 0x4B, (byte) 0x71, (byte) 0x8D, 91d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry (byte) 0xF5, 92d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry }; 93d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry 94d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry 95d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry /* Development key 9692973c7820129b724e589268cfcba4600ffb168cWill Drewry private final static byte[] PK_MOD = { 9792973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xAE, (byte) 0x14, (byte) 0xA4, (byte) 0x91, (byte) 0xA6, 9892973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xC8, (byte) 0x2E, (byte) 0x4D, (byte) 0x6B, (byte) 0xB3, 9992973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x4E, (byte) 0x23, (byte) 0x96, (byte) 0x57, (byte) 0x7C, 10092973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x2C, (byte) 0x7E, (byte) 0x69, (byte) 0xE6, (byte) 0xBF, 10192973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x5A, (byte) 0x9C, (byte) 0xD7, (byte) 0xA8, (byte) 0x38, 10292973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x0C, (byte) 0x9A, (byte) 0x54, (byte) 0x43, (byte) 0x4C, 10392973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x3C, (byte) 0xDA, (byte) 0xC5, (byte) 0xB1, (byte) 0x58, 10492973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x56, (byte) 0x9B, (byte) 0x5A, (byte) 0x05, (byte) 0xBA, 10592973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x2C, (byte) 0xAB, (byte) 0xC6, (byte) 0x50, (byte) 0x34, 10692973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x3C, (byte) 0x3B, (byte) 0x8E, (byte) 0xD8, (byte) 0x55, 10792973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xEB, (byte) 0xFA, (byte) 0x4F, (byte) 0x72, (byte) 0x81, 10892973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xA3, (byte) 0x8F, (byte) 0xDD, (byte) 0x8E, (byte) 0x0E, 10992973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xF2, (byte) 0xF6, (byte) 0xEF, (byte) 0x18, (byte) 0x95, 11092973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xCF, (byte) 0x71, (byte) 0x7D, (byte) 0x33, (byte) 0xA1, 11192973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xAE, (byte) 0xBE, (byte) 0x8C, (byte) 0xA5, (byte) 0x50, 11292973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x4C, (byte) 0xF2, (byte) 0xDC, (byte) 0x7B, (byte) 0x6C, 11392973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xAE, (byte) 0x14, (byte) 0x95, (byte) 0xB7, (byte) 0xE7, 11492973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xCA, (byte) 0xEB, (byte) 0xB0, (byte) 0x24, (byte) 0x5B, 11592973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xC9, (byte) 0x24, (byte) 0x2B, (byte) 0xC6, (byte) 0x96, 11692973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x99, (byte) 0xE9, (byte) 0x8B, (byte) 0x10, (byte) 0xCA, 11792973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x34, (byte) 0x2D, (byte) 0x84, (byte) 0x57, (byte) 0x09, 11892973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x4C, (byte) 0x32, (byte) 0x35, (byte) 0x68, (byte) 0x37, 11992973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x53, (byte) 0x0E, (byte) 0xF6, (byte) 0x93, (byte) 0x6C, 12092973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x86, (byte) 0x84, (byte) 0xC1, (byte) 0x44, (byte) 0x70, 12192973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x4A, (byte) 0x12, (byte) 0xAA, (byte) 0xC2, (byte) 0x9F, 12292973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x68, (byte) 0x5C, (byte) 0x42, (byte) 0xC8, (byte) 0xEB, 12392973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xD3, (byte) 0xAF, (byte) 0xD6, (byte) 0x34, (byte) 0x7F, 12492973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x9D, (byte) 0xC9, (byte) 0xE8, (byte) 0x81, (byte) 0x4A, 12592973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x5C, (byte) 0xDA, (byte) 0x36, (byte) 0x33, (byte) 0xFD, 12692973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x5C, (byte) 0x67, (byte) 0xBB, (byte) 0x91, (byte) 0x1C, 12792973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xF5, (byte) 0x21, (byte) 0xC0, (byte) 0x4E, (byte) 0x64, 12892973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x87, (byte) 0x89, (byte) 0xB6, (byte) 0x8B, (byte) 0xFD, 12992973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xDA, (byte) 0x30, (byte) 0x74, (byte) 0x1E, (byte) 0x00, 13092973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x57, (byte) 0xE1, (byte) 0x5C, (byte) 0xC4, (byte) 0xF2, 13192973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xEE, (byte) 0xF7, (byte) 0x05, (byte) 0x1C, (byte) 0xCE, 13292973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xF1, (byte) 0xCA, (byte) 0x88, (byte) 0xA0, (byte) 0x28, 13392973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x53, (byte) 0x2C, (byte) 0x84, (byte) 0xCD, (byte) 0xA3, 13492973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x6C, (byte) 0x1D, (byte) 0x15, (byte) 0x00, (byte) 0x5A, 13592973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x5D, (byte) 0x80, (byte) 0x40, (byte) 0x59, (byte) 0xE5, 13692973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xEA, (byte) 0xD1, (byte) 0x2A, (byte) 0xD6, (byte) 0x5A, 13792973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xE0, (byte) 0xE6, (byte) 0x9C, (byte) 0xEB, (byte) 0x23, 13892973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x4D, (byte) 0xD0, (byte) 0xB1, (byte) 0x27, (byte) 0xEE, 13992973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x41, (byte) 0x0D, (byte) 0xAA, (byte) 0x25, (byte) 0xBD, 14092973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xA0, (byte) 0xD0, (byte) 0x20, (byte) 0x00, (byte) 0x16, 14192973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x1F, (byte) 0x54, (byte) 0xC6, (byte) 0x4A, (byte) 0xDD, 14292973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x2A, (byte) 0x7E, (byte) 0x32, (byte) 0x43, (byte) 0x7F, 14392973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0xD8, (byte) 0x74, (byte) 0x0F, (byte) 0x94, (byte) 0x88, 14492973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x3F, (byte) 0x26, (byte) 0x27, (byte) 0x54, (byte) 0x5D, 14592973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x01, (byte) 0x83, (byte) 0xAE, (byte) 0x47, (byte) 0x37, 14692973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x03, (byte) 0x6C, (byte) 0x80, (byte) 0xFD, (byte) 0x6E, 14792973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x08, (byte) 0xEB, (byte) 0xB4, (byte) 0x55, (byte) 0x81, 14892973c7820129b724e589268cfcba4600ffb168cWill Drewry (byte) 0x13, 14992973c7820129b724e589268cfcba4600ffb168cWill Drewry }; 150d209f7146073eac530d0f46026a57839b10c8cf1Will Drewry */ 15192973c7820129b724e589268cfcba4600ffb168cWill Drewry 15292973c7820129b724e589268cfcba4600ffb168cWill Drewry // Layout: 15392973c7820129b724e589268cfcba4600ffb168cWill Drewry // LockValue (byte) || lastNonce (byte[8]) || deviceDataHash (byte[32]) 15492973c7820129b724e589268cfcba4600ffb168cWill Drewry private byte[] storage; 15592973c7820129b724e589268cfcba4600ffb168cWill Drewry private short storageOffset; 15692973c7820129b724e589268cfcba4600ffb168cWill Drewry RSAPublicKey verifyingKey; 15792973c7820129b724e589268cfcba4600ffb168cWill Drewry Signature verifier; 15892973c7820129b724e589268cfcba4600ffb168cWill Drewry MessageDigest md_sha256; /* For creating the lock data hash from the input. */ 15992973c7820129b724e589268cfcba4600ffb168cWill Drewry OwnerInterface globalState; 16092973c7820129b724e589268cfcba4600ffb168cWill Drewry 16192973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 16292973c7820129b724e589268cfcba4600ffb168cWill Drewry * Initializes the instance objects. 16392973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 16492973c7820129b724e589268cfcba4600ffb168cWill Drewry public CarrierLock() { 16592973c7820129b724e589268cfcba4600ffb168cWill Drewry try { 16692973c7820129b724e589268cfcba4600ffb168cWill Drewry verifyingKey = (RSAPublicKey)KeyBuilder.buildKey( 16792973c7820129b724e589268cfcba4600ffb168cWill Drewry KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_2048, false); 16892973c7820129b724e589268cfcba4600ffb168cWill Drewry verifyingKey.setExponent(PK_EXP, (short)0, (short)PK_EXP.length); 16992973c7820129b724e589268cfcba4600ffb168cWill Drewry verifyingKey.setModulus(PK_MOD, (short)0, (short)PK_MOD.length); 17092973c7820129b724e589268cfcba4600ffb168cWill Drewry } catch (CardRuntimeException e) { 17192973c7820129b724e589268cfcba4600ffb168cWill Drewry verifyingKey = null; 17292973c7820129b724e589268cfcba4600ffb168cWill Drewry } 17392973c7820129b724e589268cfcba4600ffb168cWill Drewry 17492973c7820129b724e589268cfcba4600ffb168cWill Drewry try { 17592973c7820129b724e589268cfcba4600ffb168cWill Drewry verifier = Signature.getInstance(Signature.ALG_RSA_SHA_256_PKCS1, false); 17692973c7820129b724e589268cfcba4600ffb168cWill Drewry verifier.init(verifyingKey, Signature.MODE_VERIFY); 17792973c7820129b724e589268cfcba4600ffb168cWill Drewry } catch (CardRuntimeException e) { 17892973c7820129b724e589268cfcba4600ffb168cWill Drewry verifier = null; 17992973c7820129b724e589268cfcba4600ffb168cWill Drewry } 18092973c7820129b724e589268cfcba4600ffb168cWill Drewry md_sha256 = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false); 18192973c7820129b724e589268cfcba4600ffb168cWill Drewry } 18292973c7820129b724e589268cfcba4600ffb168cWill Drewry 18392973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 18492973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 18592973c7820129b724e589268cfcba4600ffb168cWill Drewry * 18692973c7820129b724e589268cfcba4600ffb168cWill Drewry * Return the error states useful for diagnostics. 18792973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 18892973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 18992973c7820129b724e589268cfcba4600ffb168cWill Drewry public short initialized() { 19092973c7820129b724e589268cfcba4600ffb168cWill Drewry if (storage == null) { 19192973c7820129b724e589268cfcba4600ffb168cWill Drewry return 1; 19292973c7820129b724e589268cfcba4600ffb168cWill Drewry } 19392973c7820129b724e589268cfcba4600ffb168cWill Drewry if (verifyingKey == null) { 19492973c7820129b724e589268cfcba4600ffb168cWill Drewry return 2; 19592973c7820129b724e589268cfcba4600ffb168cWill Drewry } 19692973c7820129b724e589268cfcba4600ffb168cWill Drewry if (verifier == null) { 19792973c7820129b724e589268cfcba4600ffb168cWill Drewry return 3; 19892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 19992973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0; 20092973c7820129b724e589268cfcba4600ffb168cWill Drewry } 20192973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 20292973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 20392973c7820129b724e589268cfcba4600ffb168cWill Drewry * 20492973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 20592973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 20692973c7820129b724e589268cfcba4600ffb168cWill Drewry public short getStorageNeeded() { 20792973c7820129b724e589268cfcba4600ffb168cWill Drewry return NONCE_SIZE + DEVICE_DATA_SIZE + 1; 20892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 20992973c7820129b724e589268cfcba4600ffb168cWill Drewry 21092973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 21192973c7820129b724e589268cfcba4600ffb168cWill Drewry * Sets the backing store to use for state. 21292973c7820129b724e589268cfcba4600ffb168cWill Drewry * 21392973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param globalStateOwner interface for querying global state 21492973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param extStorage external array to use for storage 21592973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param extStorageOffset where to begin storing data 21692973c7820129b724e589268cfcba4600ffb168cWill Drewry * 21792973c7820129b724e589268cfcba4600ffb168cWill Drewry * This should be called before use. 21892973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 21992973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 22092973c7820129b724e589268cfcba4600ffb168cWill Drewry public void initialize(OwnerInterface globalStateOwner, byte[] extStorage, 22192973c7820129b724e589268cfcba4600ffb168cWill Drewry short extStorageOffset) { 22292973c7820129b724e589268cfcba4600ffb168cWill Drewry globalState = globalStateOwner; 22392973c7820129b724e589268cfcba4600ffb168cWill Drewry // Zero it first (in case we are interrupted). 22492973c7820129b724e589268cfcba4600ffb168cWill Drewry Util.arrayFillNonAtomic(extStorage, extStorageOffset, 22592973c7820129b724e589268cfcba4600ffb168cWill Drewry getStorageNeeded(), (byte) 0x00); 22692973c7820129b724e589268cfcba4600ffb168cWill Drewry storage = extStorage; 22792973c7820129b724e589268cfcba4600ffb168cWill Drewry storageOffset = extStorageOffset; 22892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 22992973c7820129b724e589268cfcba4600ffb168cWill Drewry 23092973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 23192973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 23292973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 23392973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 23492973c7820129b724e589268cfcba4600ffb168cWill Drewry public short get(byte[] lockOut, short outOffset) { 23592973c7820129b724e589268cfcba4600ffb168cWill Drewry if (storage == null) { 23692973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0001; 23792973c7820129b724e589268cfcba4600ffb168cWill Drewry } 23892973c7820129b724e589268cfcba4600ffb168cWill Drewry try { 23992973c7820129b724e589268cfcba4600ffb168cWill Drewry Util.arrayCopy(storage, lockOffset(), 24092973c7820129b724e589268cfcba4600ffb168cWill Drewry lockOut, outOffset, (short) 1); 24192973c7820129b724e589268cfcba4600ffb168cWill Drewry } catch (CardRuntimeException e) { 24292973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0002; 24392973c7820129b724e589268cfcba4600ffb168cWill Drewry } 24492973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0; 24592973c7820129b724e589268cfcba4600ffb168cWill Drewry } 24692973c7820129b724e589268cfcba4600ffb168cWill Drewry 24792973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 24892973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 24992973c7820129b724e589268cfcba4600ffb168cWill Drewry * 25092973c7820129b724e589268cfcba4600ffb168cWill Drewry * Returns 0xffff if {@link #initialize()} has not yet been called. 25192973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 25292973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 25392973c7820129b724e589268cfcba4600ffb168cWill Drewry public short lockOffset() { 25492973c7820129b724e589268cfcba4600ffb168cWill Drewry if (storage == null) { 25592973c7820129b724e589268cfcba4600ffb168cWill Drewry return (short) 0xffff; 25692973c7820129b724e589268cfcba4600ffb168cWill Drewry } 25792973c7820129b724e589268cfcba4600ffb168cWill Drewry return storageOffset; 25892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 25992973c7820129b724e589268cfcba4600ffb168cWill Drewry 26092973c7820129b724e589268cfcba4600ffb168cWill Drewry 26192973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 26292973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 26392973c7820129b724e589268cfcba4600ffb168cWill Drewry * 26492973c7820129b724e589268cfcba4600ffb168cWill Drewry * Returns 0xffff if {@link #initialize()} has not yet been called. 26592973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 26692973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 26792973c7820129b724e589268cfcba4600ffb168cWill Drewry public short metadataOffset() { 26892973c7820129b724e589268cfcba4600ffb168cWill Drewry if (storage == null) { 26992973c7820129b724e589268cfcba4600ffb168cWill Drewry return (short) 0xffff; 27092973c7820129b724e589268cfcba4600ffb168cWill Drewry } 27192973c7820129b724e589268cfcba4600ffb168cWill Drewry return (short)(storageOffset + NONCE_SIZE + 1); 27292973c7820129b724e589268cfcba4600ffb168cWill Drewry } 27392973c7820129b724e589268cfcba4600ffb168cWill Drewry 27492973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 27592973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 27692973c7820129b724e589268cfcba4600ffb168cWill Drewry * 27792973c7820129b724e589268cfcba4600ffb168cWill Drewry * Returns length of metadata. 27892973c7820129b724e589268cfcba4600ffb168cWill Drewry * 27992973c7820129b724e589268cfcba4600ffb168cWill Drewry * @return length of metadata. 28092973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 28192973c7820129b724e589268cfcba4600ffb168cWill Drewry public short metadataLength() { 28292973c7820129b724e589268cfcba4600ffb168cWill Drewry return (short) DEVICE_DATA_SIZE; 28392973c7820129b724e589268cfcba4600ffb168cWill Drewry } 28492973c7820129b724e589268cfcba4600ffb168cWill Drewry 28592973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 28692973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 28792973c7820129b724e589268cfcba4600ffb168cWill Drewry * 28892973c7820129b724e589268cfcba4600ffb168cWill Drewry * Always returns false. Locking CarrierLock requires 28992973c7820129b724e589268cfcba4600ffb168cWill Drewry * device data and unlocking (val=0x0) requires a signed 29092973c7820129b724e589268cfcba4600ffb168cWill Drewry * assertion. 29192973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 29292973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 29392973c7820129b724e589268cfcba4600ffb168cWill Drewry public short set(byte val) { 29492973c7820129b724e589268cfcba4600ffb168cWill Drewry return (short)0xffff; // Not implemented. 29592973c7820129b724e589268cfcba4600ffb168cWill Drewry } 29692973c7820129b724e589268cfcba4600ffb168cWill Drewry 29792973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 29892973c7820129b724e589268cfcba4600ffb168cWill Drewry * Performs the verification of the incoming unlock token. 29992973c7820129b724e589268cfcba4600ffb168cWill Drewry * 30092973c7820129b724e589268cfcba4600ffb168cWill Drewry * This will check the version code, the nonce value, and the signature. 30192973c7820129b724e589268cfcba4600ffb168cWill Drewry * 30292973c7820129b724e589268cfcba4600ffb168cWill Drewry * 30392973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param deviceData 30492973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param deviceDataOffset 30592973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param lastNonce 30692973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param lastNonceOffset 30792973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param unlockToken 30892973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param unlockTokenOffset 30992973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param unlockTokenLength 31092973c7820129b724e589268cfcba4600ffb168cWill Drewry * @return 0x0 on verified and an error code if not. 31192973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 31292973c7820129b724e589268cfcba4600ffb168cWill Drewry private short verifyUnlock(byte[] deviceData, short deviceDataOffset, 31392973c7820129b724e589268cfcba4600ffb168cWill Drewry byte[] lastNonce, short lastNonceOffset, 31492973c7820129b724e589268cfcba4600ffb168cWill Drewry byte[] unlockToken, short unlockTokenOffset, 31592973c7820129b724e589268cfcba4600ffb168cWill Drewry short unlockTokenLength) { 31692973c7820129b724e589268cfcba4600ffb168cWill Drewry if (unlockTokenLength < (short)(VERSION_SIZE + NONCE_SIZE + PK_MOD.length)) { 31792973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0002; 31892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 31992973c7820129b724e589268cfcba4600ffb168cWill Drewry // Only supported version is the uint64le_t 1 32092973c7820129b724e589268cfcba4600ffb168cWill Drewry if (unlockToken[unlockTokenOffset] != VERSION) { 32192973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0003; 32292973c7820129b724e589268cfcba4600ffb168cWill Drewry } 32392973c7820129b724e589268cfcba4600ffb168cWill Drewry 32492973c7820129b724e589268cfcba4600ffb168cWill Drewry byte[] message = JCSystem.makeTransientByteArray( 32592973c7820129b724e589268cfcba4600ffb168cWill Drewry (short)(NONCE_SIZE + DEVICE_DATA_SIZE), JCSystem.CLEAR_ON_DESELECT); 32692973c7820129b724e589268cfcba4600ffb168cWill Drewry // Collect the incoming nonce. 32792973c7820129b724e589268cfcba4600ffb168cWill Drewry Util.arrayCopy(unlockToken, (short)(unlockTokenOffset + VERSION_SIZE), 32892973c7820129b724e589268cfcba4600ffb168cWill Drewry message, (short) 0x0, (short) NONCE_SIZE); 32992973c7820129b724e589268cfcba4600ffb168cWill Drewry // Append the internallty stored device data. 33092973c7820129b724e589268cfcba4600ffb168cWill Drewry Util.arrayCopy(deviceData, deviceDataOffset, 33192973c7820129b724e589268cfcba4600ffb168cWill Drewry message, (short)NONCE_SIZE, (short) DEVICE_DATA_SIZE); 33292973c7820129b724e589268cfcba4600ffb168cWill Drewry 33392973c7820129b724e589268cfcba4600ffb168cWill Drewry // Verify it against the incoming signature. 33492973c7820129b724e589268cfcba4600ffb168cWill Drewry if (verifier.verify( 33592973c7820129b724e589268cfcba4600ffb168cWill Drewry message, (short) 0, (short) message.length, unlockToken, 33692973c7820129b724e589268cfcba4600ffb168cWill Drewry (short)(unlockTokenOffset + VERSION_SIZE + NONCE_SIZE), 33792973c7820129b724e589268cfcba4600ffb168cWill Drewry (short)(unlockTokenLength - (VERSION_SIZE + NONCE_SIZE))) == 33892973c7820129b724e589268cfcba4600ffb168cWill Drewry false) { 33992973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0004; 34092973c7820129b724e589268cfcba4600ffb168cWill Drewry } 34192973c7820129b724e589268cfcba4600ffb168cWill Drewry if (littleEndianUnsignedGreaterThan(NONCE_SIZE, 34292973c7820129b724e589268cfcba4600ffb168cWill Drewry unlockToken, (short)(unlockTokenOffset + VERSION_SIZE), 34392973c7820129b724e589268cfcba4600ffb168cWill Drewry lastNonce, lastNonceOffset) == true) { 34492973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0; 34592973c7820129b724e589268cfcba4600ffb168cWill Drewry } 34692973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0005; 34792973c7820129b724e589268cfcba4600ffb168cWill Drewry } 34892973c7820129b724e589268cfcba4600ffb168cWill Drewry 34992973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 35092973c7820129b724e589268cfcba4600ffb168cWill Drewry * Compares two little endian byte streams and returns 35192973c7820129b724e589268cfcba4600ffb168cWill Drewry * true if lhs is greater than rhs. 35292973c7820129b724e589268cfcba4600ffb168cWill Drewry * 35392973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param len number of bytes to compare 35492973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param lhs left hand size buffer 35592973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param lhsBase starting offset 35692973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param rhs right hand size buffer 35792973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param rhsBase starting offset 35892973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 35992973c7820129b724e589268cfcba4600ffb168cWill Drewry private boolean littleEndianUnsignedGreaterThan( 36092973c7820129b724e589268cfcba4600ffb168cWill Drewry byte len, 36192973c7820129b724e589268cfcba4600ffb168cWill Drewry byte[] lhs, short lhsBase, 36292973c7820129b724e589268cfcba4600ffb168cWill Drewry byte[] rhs, short rhsBase) { 36392973c7820129b724e589268cfcba4600ffb168cWill Drewry // Start with the most significant byte. 36492973c7820129b724e589268cfcba4600ffb168cWill Drewry short i = len; 36592973c7820129b724e589268cfcba4600ffb168cWill Drewry do { 36692973c7820129b724e589268cfcba4600ffb168cWill Drewry i -= 1; 36792973c7820129b724e589268cfcba4600ffb168cWill Drewry if (lhs[(short)(lhsBase +i)] > rhs[(short)(rhsBase + i)]) { 36892973c7820129b724e589268cfcba4600ffb168cWill Drewry return true; 36992973c7820129b724e589268cfcba4600ffb168cWill Drewry } 37092973c7820129b724e589268cfcba4600ffb168cWill Drewry if (lhs[(short)(lhsBase +i)] < rhs[(short)(rhsBase + i)]) { 37192973c7820129b724e589268cfcba4600ffb168cWill Drewry return false; 37292973c7820129b724e589268cfcba4600ffb168cWill Drewry } 37392973c7820129b724e589268cfcba4600ffb168cWill Drewry // Only proceed if the current bytes are equal. 37492973c7820129b724e589268cfcba4600ffb168cWill Drewry } while (i > 0); 37592973c7820129b724e589268cfcba4600ffb168cWill Drewry return false; 37692973c7820129b724e589268cfcba4600ffb168cWill Drewry } 37792973c7820129b724e589268cfcba4600ffb168cWill Drewry 37892973c7820129b724e589268cfcba4600ffb168cWill Drewry 37992973c7820129b724e589268cfcba4600ffb168cWill Drewry 38092973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 38192973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 38292973c7820129b724e589268cfcba4600ffb168cWill Drewry * Returns true if the lock is changed with associated metadata. 38392973c7820129b724e589268cfcba4600ffb168cWill Drewry * 38492973c7820129b724e589268cfcba4600ffb168cWill Drewry * If |lockValue| is non-zero, then |lockMeta| should contain a series of 38592973c7820129b724e589268cfcba4600ffb168cWill Drewry * ASCII (or hex) values separated by short lengths. These will be SHA256 38692973c7820129b724e589268cfcba4600ffb168cWill Drewry * hashed together to create a "device data hash". Its use is covered next. 38792973c7820129b724e589268cfcba4600ffb168cWill Drewry * 38892973c7820129b724e589268cfcba4600ffb168cWill Drewry * If |lockValue| is zero, then |lockMeta| should contain the following 38992973c7820129b724e589268cfcba4600ffb168cWill Drewry * (all little endian): 8-bit version tag (0x01) || byte[8] "64-bit nonce" 39092973c7820129b724e589268cfcba4600ffb168cWill Drewry * || byte[] Signature(nonce||deviceDataHash) The signature is using the 39192973c7820129b724e589268cfcba4600ffb168cWill Drewry * embedded key {@link #pkModulus} and the format is ALG_RSA_SHA_256_PKCS1. 39292973c7820129b724e589268cfcba4600ffb168cWill Drewry * If the signature verifies using the internally stored deviceDataHash and 39392973c7820129b724e589268cfcba4600ffb168cWill Drewry * the provided nonce, then one last check is applied. If the nonce, 39492973c7820129b724e589268cfcba4600ffb168cWill Drewry * treated as a little endian uint64_t, is greater than the stored nonce then 39592973c7820129b724e589268cfcba4600ffb168cWill Drewry * it will be rejected. Note, once unlocked, the device data hash is deleted 39692973c7820129b724e589268cfcba4600ffb168cWill Drewry * and the CarrierLock cannot be reapplied unless the device is taken out 39792973c7820129b724e589268cfcba4600ffb168cWill Drewry * of production mode (bootloader RMA path). 39892973c7820129b724e589268cfcba4600ffb168cWill Drewry * 39992973c7820129b724e589268cfcba4600ffb168cWill Drewry * If {@link #globalState} indicates that the device is not yet in production 40092973c7820129b724e589268cfcba4600ffb168cWill Drewry * mode, then the lock values can be toggled arbitrarily. 40192973c7820129b724e589268cfcba4600ffb168cWill Drewry * The lock values may also be changed in the bootloader or in the HLOS as 40292973c7820129b724e589268cfcba4600ffb168cWill Drewry * the transitions are either one-way (lock) or authenticated. It is required 40392973c7820129b724e589268cfcba4600ffb168cWill Drewry * that the lock state is assigned prior to transitioning to production as that 40492973c7820129b724e589268cfcba4600ffb168cWill Drewry * ensures that an unlocked device cannot be re-locked maliciously from the HLOS. 40592973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 40692973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 40792973c7820129b724e589268cfcba4600ffb168cWill Drewry public short setWithMetadata(byte lockValue, byte[] lockMeta, 40892973c7820129b724e589268cfcba4600ffb168cWill Drewry short lockMetaOffset, short lockMetaLength) { 40992973c7820129b724e589268cfcba4600ffb168cWill Drewry if (storage == null) { 41092973c7820129b724e589268cfcba4600ffb168cWill Drewry // TODO: move to constants. 41192973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0001; 41292973c7820129b724e589268cfcba4600ffb168cWill Drewry } 41392973c7820129b724e589268cfcba4600ffb168cWill Drewry // Ensure we don't update the nonce if we didn't go through verify. 41492973c7820129b724e589268cfcba4600ffb168cWill Drewry short resp = (short) 0xffff; 41592973c7820129b724e589268cfcba4600ffb168cWill Drewry if (lockValue == LOCK_UNLOCKED) { // SHUT IT DOWN. 41692973c7820129b724e589268cfcba4600ffb168cWill Drewry // If we're already unlocked, allow another call to make sure all the 41792973c7820129b724e589268cfcba4600ffb168cWill Drewry // data is cleared. 41892973c7820129b724e589268cfcba4600ffb168cWill Drewry if (storage[storageOffset] != LOCK_UNLOCKED && 41992973c7820129b724e589268cfcba4600ffb168cWill Drewry globalState.production() == true) { 42092973c7820129b724e589268cfcba4600ffb168cWill Drewry // RSA PKCS#1 signature should be the same length as the modulus but we'll allow it to 42192973c7820129b724e589268cfcba4600ffb168cWill Drewry // be larger because ???. XXX TODO 42292973c7820129b724e589268cfcba4600ffb168cWill Drewry resp = verifyUnlock(storage, (short)(storageOffset + 1 + NONCE_SIZE), 42392973c7820129b724e589268cfcba4600ffb168cWill Drewry storage, (short)(storageOffset + 1), 42492973c7820129b724e589268cfcba4600ffb168cWill Drewry lockMeta, lockMetaOffset, lockMetaLength); 42592973c7820129b724e589268cfcba4600ffb168cWill Drewry if (resp != (short) 0) { 42692973c7820129b724e589268cfcba4600ffb168cWill Drewry return resp; 42792973c7820129b724e589268cfcba4600ffb168cWill Drewry } 42892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 42992973c7820129b724e589268cfcba4600ffb168cWill Drewry JCSystem.beginTransaction(); 43092973c7820129b724e589268cfcba4600ffb168cWill Drewry storage[storageOffset] = lockValue; 43192973c7820129b724e589268cfcba4600ffb168cWill Drewry // Update the monotonically increasing "nonce" value. 43292973c7820129b724e589268cfcba4600ffb168cWill Drewry // Note that the nonce is only ever updated if a signed value 43392973c7820129b724e589268cfcba4600ffb168cWill Drewry // was seen or if we're not production() to assure it doesn't get 43492973c7820129b724e589268cfcba4600ffb168cWill Drewry // rolled forward. 43592973c7820129b724e589268cfcba4600ffb168cWill Drewry if (resp == 0) { 4368055858133dca4e507f7d17b9c931f2547a988afWill Drewry Util.arrayCopy(lockMeta, (short)(VERSION_SIZE + lockMetaOffset), 43792973c7820129b724e589268cfcba4600ffb168cWill Drewry storage, (short)(1 + storageOffset), 43892973c7820129b724e589268cfcba4600ffb168cWill Drewry (short)NONCE_SIZE); 43992973c7820129b724e589268cfcba4600ffb168cWill Drewry } 44092973c7820129b724e589268cfcba4600ffb168cWill Drewry // Delete the device-unique data. 44192973c7820129b724e589268cfcba4600ffb168cWill Drewry Util.arrayFillNonAtomic(storage, (short)(NONCE_SIZE + 1 + storageOffset), 44292973c7820129b724e589268cfcba4600ffb168cWill Drewry (short)DEVICE_DATA_SIZE, (byte)0x00); 44392973c7820129b724e589268cfcba4600ffb168cWill Drewry JCSystem.commitTransaction(); 44492973c7820129b724e589268cfcba4600ffb168cWill Drewry } else { // Locking. Expect a lockMeta of the device data. 44592973c7820129b724e589268cfcba4600ffb168cWill Drewry if (globalState.production() == true) { 44692973c7820129b724e589268cfcba4600ffb168cWill Drewry // Locking can only be done prior to production. 44792973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0006; 44892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 44992973c7820129b724e589268cfcba4600ffb168cWill Drewry md_sha256.reset(); 45092973c7820129b724e589268cfcba4600ffb168cWill Drewry JCSystem.beginTransaction(); 45192973c7820129b724e589268cfcba4600ffb168cWill Drewry // Hash all the input data and store the result as the device data 45292973c7820129b724e589268cfcba4600ffb168cWill Drewry // digest. 45392973c7820129b724e589268cfcba4600ffb168cWill Drewry md_sha256.doFinal(lockMeta, lockMetaOffset, lockMetaLength, 45492973c7820129b724e589268cfcba4600ffb168cWill Drewry storage, metadataOffset()); 45592973c7820129b724e589268cfcba4600ffb168cWill Drewry // Note that we never clear or overwrite the nonce. 45692973c7820129b724e589268cfcba4600ffb168cWill Drewry storage[storageOffset] = lockValue; 45792973c7820129b724e589268cfcba4600ffb168cWill Drewry JCSystem.commitTransaction(); 45892973c7820129b724e589268cfcba4600ffb168cWill Drewry } 45992973c7820129b724e589268cfcba4600ffb168cWill Drewry return 0x0000; 46092973c7820129b724e589268cfcba4600ffb168cWill Drewry } 46192973c7820129b724e589268cfcba4600ffb168cWill Drewry 46292973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 46392973c7820129b724e589268cfcba4600ffb168cWill Drewry * Given all the data, tests if the key actually works. 46492973c7820129b724e589268cfcba4600ffb168cWill Drewry * 46592973c7820129b724e589268cfcba4600ffb168cWill Drewry * buffer should contain: 46692973c7820129b724e589268cfcba4600ffb168cWill Drewry * fakeLastNonce | fakeDeviceData | version (8) | testNonce | signature 46792973c7820129b724e589268cfcba4600ffb168cWill Drewry * 46892973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param buffer Array with the test data. 46992973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param offset offset into the buffer. 47092973c7820129b724e589268cfcba4600ffb168cWill Drewry * @param length total length from offset. 47192973c7820129b724e589268cfcba4600ffb168cWill Drewry * @return 0x0 on verify and an error code otherwise. 47292973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 47392973c7820129b724e589268cfcba4600ffb168cWill Drewry public short testVector(byte[] buffer, short offset, short length) { 47492973c7820129b724e589268cfcba4600ffb168cWill Drewry return verifyUnlock(buffer, (short)(offset + NONCE_SIZE), // device data 47592973c7820129b724e589268cfcba4600ffb168cWill Drewry buffer, offset, // fake last nonce. 47692973c7820129b724e589268cfcba4600ffb168cWill Drewry // unlock data 47792973c7820129b724e589268cfcba4600ffb168cWill Drewry buffer, (short)(offset + NONCE_SIZE + DEVICE_DATA_SIZE), 47892973c7820129b724e589268cfcba4600ffb168cWill Drewry (short)(length - (NONCE_SIZE + DEVICE_DATA_SIZE))); 47992973c7820129b724e589268cfcba4600ffb168cWill Drewry } 48092973c7820129b724e589268cfcba4600ffb168cWill Drewry 48192973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 48292973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 48392973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 48492973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 48592973c7820129b724e589268cfcba4600ffb168cWill Drewry public short backupSize() { 48692973c7820129b724e589268cfcba4600ffb168cWill Drewry return getStorageNeeded(); 48792973c7820129b724e589268cfcba4600ffb168cWill Drewry } 48892973c7820129b724e589268cfcba4600ffb168cWill Drewry 48992973c7820129b724e589268cfcba4600ffb168cWill Drewry 49092973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 49192973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 49292973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 49392973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 49492973c7820129b724e589268cfcba4600ffb168cWill Drewry public short backup(byte[] outBytes, short outBytesOffset) { 49592973c7820129b724e589268cfcba4600ffb168cWill Drewry Util.arrayCopy(storage, storageOffset, 49692973c7820129b724e589268cfcba4600ffb168cWill Drewry outBytes, outBytesOffset, 49792973c7820129b724e589268cfcba4600ffb168cWill Drewry backupSize()); 49892973c7820129b724e589268cfcba4600ffb168cWill Drewry return backupSize(); 49992973c7820129b724e589268cfcba4600ffb168cWill Drewry } 50092973c7820129b724e589268cfcba4600ffb168cWill Drewry 50192973c7820129b724e589268cfcba4600ffb168cWill Drewry /** 50292973c7820129b724e589268cfcba4600ffb168cWill Drewry * {@inheritDoc} 50392973c7820129b724e589268cfcba4600ffb168cWill Drewry */ 50492973c7820129b724e589268cfcba4600ffb168cWill Drewry @Override 50592973c7820129b724e589268cfcba4600ffb168cWill Drewry public boolean restore(byte[] inBytes, short inBytesOffset, 50692973c7820129b724e589268cfcba4600ffb168cWill Drewry short inBytesLength) { 50792973c7820129b724e589268cfcba4600ffb168cWill Drewry if (inBytesLength > backupSize() || inBytesLength == (short)0) { 50892973c7820129b724e589268cfcba4600ffb168cWill Drewry return false; 50992973c7820129b724e589268cfcba4600ffb168cWill Drewry } 51092973c7820129b724e589268cfcba4600ffb168cWill Drewry Util.arrayCopy(inBytes, inBytesOffset, 51192973c7820129b724e589268cfcba4600ffb168cWill Drewry storage, storageOffset, 51292973c7820129b724e589268cfcba4600ffb168cWill Drewry inBytesLength); 51392973c7820129b724e589268cfcba4600ffb168cWill Drewry return true; 51492973c7820129b724e589268cfcba4600ffb168cWill Drewry } 51592973c7820129b724e589268cfcba4600ffb168cWill Drewry 51692973c7820129b724e589268cfcba4600ffb168cWill Drewry 51792973c7820129b724e589268cfcba4600ffb168cWill Drewry} 518