• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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