1 /* Copyright 2019, The Android Open Source Project, Inc. 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package com.google.android.attestation; 17 18 import static com.google.android.attestation.Constants.KM_VERIFIED_BOOT_STATE_FAILED; 19 import static com.google.android.attestation.Constants.KM_VERIFIED_BOOT_STATE_SELF_SIGNED; 20 import static com.google.android.attestation.Constants.KM_VERIFIED_BOOT_STATE_UNVERIFIED; 21 import static com.google.android.attestation.Constants.KM_VERIFIED_BOOT_STATE_VERIFIED; 22 import static com.google.android.attestation.Constants.ROOT_OF_TRUST_DEVICE_LOCKED_INDEX; 23 import static com.google.android.attestation.Constants.ROOT_OF_TRUST_VERIFIED_BOOT_HASH_INDEX; 24 import static com.google.android.attestation.Constants.ROOT_OF_TRUST_VERIFIED_BOOT_KEY_INDEX; 25 import static com.google.android.attestation.Constants.ROOT_OF_TRUST_VERIFIED_BOOT_STATE_INDEX; 26 27 import org.bouncycastle.asn1.ASN1Boolean; 28 import org.bouncycastle.asn1.ASN1Encodable; 29 import org.bouncycastle.asn1.ASN1Enumerated; 30 import org.bouncycastle.asn1.ASN1OctetString; 31 import org.bouncycastle.asn1.ASN1Sequence; 32 import org.bouncycastle.asn1.DEROctetString; 33 import org.bouncycastle.asn1.DERSequence; 34 35 /** This collection of values defines key information about the device's status. */ 36 public class RootOfTrust { 37 38 public final byte[] verifiedBootKey; 39 public final boolean deviceLocked; 40 public final VerifiedBootState verifiedBootState; 41 public final byte[] verifiedBootHash; 42 RootOfTrust(ASN1Sequence rootOfTrust, int attestationVersion)43 private RootOfTrust(ASN1Sequence rootOfTrust, int attestationVersion) { 44 this.verifiedBootKey = 45 ((ASN1OctetString) rootOfTrust.getObjectAt(ROOT_OF_TRUST_VERIFIED_BOOT_KEY_INDEX)) 46 .getOctets(); 47 this.deviceLocked = 48 ASN1Parsing.getBooleanFromAsn1(rootOfTrust.getObjectAt(ROOT_OF_TRUST_DEVICE_LOCKED_INDEX)); 49 this.verifiedBootState = 50 verifiedBootStateToEnum( 51 ASN1Parsing.getIntegerFromAsn1( 52 rootOfTrust.getObjectAt(ROOT_OF_TRUST_VERIFIED_BOOT_STATE_INDEX))); 53 if (attestationVersion >= 3) { 54 this.verifiedBootHash = 55 ((ASN1OctetString) rootOfTrust.getObjectAt(ROOT_OF_TRUST_VERIFIED_BOOT_HASH_INDEX)) 56 .getOctets(); 57 } else { 58 this.verifiedBootHash = null; 59 } 60 } 61 createRootOfTrust(ASN1Sequence rootOfTrust, int attestationVersion)62 static RootOfTrust createRootOfTrust(ASN1Sequence rootOfTrust, int attestationVersion) { 63 if (rootOfTrust == null) { 64 return null; 65 } 66 return new RootOfTrust(rootOfTrust, attestationVersion); 67 } 68 verifiedBootStateToEnum(int securityLevel)69 private static VerifiedBootState verifiedBootStateToEnum(int securityLevel) { 70 switch (securityLevel) { 71 case KM_VERIFIED_BOOT_STATE_VERIFIED: 72 return VerifiedBootState.VERIFIED; 73 case KM_VERIFIED_BOOT_STATE_SELF_SIGNED: 74 return VerifiedBootState.SELF_SIGNED; 75 case KM_VERIFIED_BOOT_STATE_UNVERIFIED: 76 return VerifiedBootState.UNVERIFIED; 77 case KM_VERIFIED_BOOT_STATE_FAILED: 78 return VerifiedBootState.FAILED; 79 default: 80 throw new IllegalArgumentException("Invalid verified boot state."); 81 } 82 } 83 verifiedBootStateToInt(VerifiedBootState verifiedBootState)84 private static int verifiedBootStateToInt(VerifiedBootState verifiedBootState) { 85 switch (verifiedBootState) { 86 case VERIFIED: 87 return KM_VERIFIED_BOOT_STATE_VERIFIED; 88 case SELF_SIGNED: 89 return KM_VERIFIED_BOOT_STATE_SELF_SIGNED; 90 case UNVERIFIED: 91 return KM_VERIFIED_BOOT_STATE_UNVERIFIED; 92 case FAILED: 93 return KM_VERIFIED_BOOT_STATE_FAILED; 94 } 95 throw new IllegalArgumentException("Invalid verified boot state."); 96 } 97 98 /** 99 * This provides the device's current boot state, which represents the level of protection 100 * provided to the user and to apps after the device finishes booting. 101 */ 102 public enum VerifiedBootState { 103 VERIFIED, 104 SELF_SIGNED, 105 UNVERIFIED, 106 FAILED 107 } 108 toAsn1Sequence()109 public ASN1Sequence toAsn1Sequence() { 110 ASN1Encodable[] rootOfTrustElements; 111 if (this.verifiedBootHash != null) { 112 rootOfTrustElements = new ASN1Encodable[4]; 113 rootOfTrustElements[ROOT_OF_TRUST_VERIFIED_BOOT_HASH_INDEX] = 114 new DEROctetString(this.verifiedBootHash); 115 } else { 116 rootOfTrustElements = new ASN1Encodable[3]; 117 } 118 rootOfTrustElements[ROOT_OF_TRUST_VERIFIED_BOOT_KEY_INDEX] = 119 new DEROctetString(this.verifiedBootKey); 120 rootOfTrustElements[ROOT_OF_TRUST_DEVICE_LOCKED_INDEX] = 121 ASN1Boolean.getInstance(this.deviceLocked); 122 rootOfTrustElements[ROOT_OF_TRUST_VERIFIED_BOOT_STATE_INDEX] = 123 new ASN1Enumerated(verifiedBootStateToInt(this.verifiedBootState)); 124 return new DERSequence(rootOfTrustElements); 125 } 126 } 127