Merge "Certificate not before time should be considered valid from 1970" am: 37d479fb3b am: ba761193ea
Original change: https://android-review.googlesource.com/c/platform/external/libese/+/2583686
Change-Id: Ia63d34c4e4da22387b14e71880b2c767150b23cf
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
index e7d8252..bb85b59 100644
--- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
+++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
@@ -245,8 +245,8 @@
@Override
public KMAttestationCert notBefore(short obj, boolean derEncoded, byte[] scratchpad) {
if (!derEncoded) {
- // convert milliseconds to UTC date
- indexes[NOT_BEFORE] = KMUtils.convertToDate(obj, scratchpad, true);
+ // convert milliseconds to UTC / Generalized time format
+ indexes[NOT_BEFORE] = KMUtils.convertToDate(obj, scratchpad);
} else {
indexes[NOT_BEFORE] =
KMByteBlob.instance(
@@ -262,17 +262,8 @@
short usageExpiryTimeObj, boolean derEncoded, byte[] scratchPad) {
if (!derEncoded) {
if (usageExpiryTimeObj != KMType.INVALID_VALUE) {
- // compare if the expiry time is greater then 2050 then use generalized
- // time format else use utc time format.
- short tmpVar = KMInteger.uint_64(KMUtils.firstJan2050, (short) 0);
- if (KMInteger.compare(usageExpiryTimeObj, tmpVar) >= 0) {
- usageExpiryTimeObj = KMUtils.convertToDate(usageExpiryTimeObj, scratchPad, false);
- } else {
- usageExpiryTimeObj = KMUtils.convertToDate(usageExpiryTimeObj, scratchPad, true);
- }
- indexes[NOT_AFTER] = usageExpiryTimeObj;
- } else {
- // notAfter = certExpirtyTimeObj;
+ // convert milliseconds to UTC / Generalized time format
+ indexes[NOT_AFTER] = KMUtils.convertToDate(usageExpiryTimeObj, scratchPad);
}
} else {
indexes[NOT_AFTER] = usageExpiryTimeObj;
diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java
index 95ee67f..425e1c8 100644
--- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java
+++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMUtils.java
@@ -44,12 +44,6 @@
public static final byte[] fourYrsMsec = {
0, 0, 0, 0x1D, 0x63, (byte) 0xEB, 0x0C, 0x00
}; // 126230400000
- public static final byte[] firstJan2020 = {
- 0, 0, 0x01, 0x6F, 0x5E, 0x66, (byte) 0xE8, 0x00
- }; // 1577836800000 msec
- public static final byte[] firstJan2050 = {
- 0, 0, 0x02, 0x4b, (byte) 0xCE, 0x5C, (byte) 0xF0, 0x00
- }; // 2524608000000
// msec
public static final byte[] febMonthLeapMSec = {
0, 0, 0, 0, (byte) 0x95, 0x58, 0x6C, 0x00
@@ -63,13 +57,31 @@
public static final byte[] ThirtDaysMonthMsec = {
0, 0, 0, 0, (byte) 0x9A, 0x7E, (byte) 0xC8, 0x00
}; // 2592000000
- public static final short year2051 = 2051;
- public static final short year2020 = 2020;
+ public static final byte[] firstJan2000 = {
+ 0, 0, 0, (byte) 0xDC, 0x6A, (byte) 0xCF, (byte) 0xAC, 0x00
+ }; // 946684800000
+ private static final byte[] dec319999Ms = {
+ (byte) 0, (byte) 0, (byte) 0xE6, 0x77, (byte) 0xD2, 0x1F, (byte) 0xD8, 0x18
+ }; // 253402300799000
+ public static final byte[] fourHundredYrsMSec = {
+ 0x00, 0x00, 0x0B, 0x7A, (byte) 0xF8, 0x5D, (byte) 0x9C, 0x00
+ }; // 12622780800000 ((365×400 + 100 - 3) * 24 * 60 * 60 * 1000)
+ public static final byte[] centuryWithLeapMSec = {
+ 0x00, 0x00, 0x02, (byte) 0xDE, (byte) 0xC1, (byte) 0xF4, (byte) 0x2C, 0x00
+ }; // 3155760000000 ((100×365 + 25) * 24 * 60 * 60 * 1000)
+ public static final byte[] centuryMSec = {
+ 0x00, 0x00, 0x02, (byte) 0xDE, (byte) 0xBC, (byte) 0xCD, (byte) 0xD0, 0x00
+ }; // 3155673600000 ((100×365 + 24) * 24 * 60 * 60 * 1000)
+ public static final short year1970 = 1970;
+ public static final short year2000 = 2000;
+ public static final short year2050 = 2050;
// Convert to milliseconds constants
public static final byte[] SEC_TO_MILLIS_SHIFT_POS = {9, 8, 7, 6, 5, 3};
+ // Represents long integer size
+ public static final byte UINT8 = 8;
// --------------------------------------
- public static short convertToDate(short time, byte[] scratchPad, boolean utcFlag) {
+ public static short convertToDate(short time, byte[] scratchPad) {
short yrsCount = 0;
short monthCount = 1;
@@ -77,8 +89,8 @@
short hhCount = 0;
short mmCount = 0;
short ssCount = 0;
+ short inputOffset = 0;
byte Z = 0x5A;
- boolean from2020 = true;
Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0);
Util.arrayCopyNonAtomic(
KMInteger.cast(time).getBuffer(),
@@ -86,157 +98,75 @@
scratchPad,
(short) (8 - KMInteger.cast(time).length()),
KMInteger.cast(time).length());
- // If the time is less then 1 Jan 2020 then it is an error
- if (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, firstJan2020, (short) 0, (short) 8)
- < 0) {
+ if (KMInteger.unsignedByteArrayCompare(scratchPad, inputOffset, dec319999Ms, (short) 0, UINT8)
+ > 0) {
KMException.throwIt(KMError.INVALID_ARGUMENT);
}
- if (utcFlag
- && KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, firstJan2050, (short) 0, (short) 8)
- >= 0) {
- KMException.throwIt(KMError.INVALID_ARGUMENT);
- }
-
- if (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, firstJan2050, (short) 0, (short) 8)
- < 0) {
- Util.arrayCopyNonAtomic(firstJan2020, (short) 0, scratchPad, (short) 8, (short) 8);
- subtract(scratchPad, (short) 0, (short) 8, (short) 16, (byte) 8);
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- } else {
- from2020 = false;
- Util.arrayCopyNonAtomic(firstJan2050, (short) 0, scratchPad, (short) 8, (short) 8);
- subtract(scratchPad, (short) 0, (short) 8, (short) 16, (byte) 8);
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- }
- // divide the given time with four yrs msec count
- if (KMInteger.unsignedByteArrayCompare(scratchPad, (short) 0, fourYrsMsec, (short) 0, (short) 8)
+ short quotient = 0;
+ short endYear = 0;
+ short baseYear = year1970;
+ if (KMInteger.unsignedByteArrayCompare(scratchPad, inputOffset, firstJan2000, (short) 0, UINT8)
>= 0) {
- Util.arrayCopyNonAtomic(fourYrsMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- // quotient is multiple of 4
- yrsCount = divide(scratchPad, (short) 0, (short) 8, (short) 16);
- yrsCount = (short) (yrsCount * 4); // number of yrs.
- // copy reminder as new dividend
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- }
-
- // Get the leap year index starting from the (base Year + yrsCount) Year.
- short leapYrIdx = getLeapYrIndex(from2020, yrsCount);
-
- // if leap year index is 0, then the number of days for the 1st year will be 366 days.
- // if leap year index is not 0, then the number of days for the 1st year will be 365 days.
- if (((leapYrIdx == 0)
- && (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, leapYearMsec, (short) 0, (short) 8)
- >= 0))
- || ((leapYrIdx != 0)
- && (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, yearMsec, (short) 0, (short) 8)
- >= 0))) {
- for (short i = 0; i < 4; i++) {
- yrsCount++;
- if (i == leapYrIdx) {
- Util.arrayCopyNonAtomic(leapYearMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- } else {
- Util.arrayCopyNonAtomic(yearMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- }
- subtract(scratchPad, (short) 0, (short) 8, (short) 16, (byte) 8);
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- if (((short) (i + 1) == leapYrIdx)) {
- if (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, leapYearMsec, (short) 0, (short) 8)
- < 0) {
- break;
- }
- } else {
- if (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, yearMsec, (short) 0, (short) 8)
- < 0) {
- break;
- }
- }
- }
- }
-
- // total yrs from 1970
- if (from2020) {
- yrsCount = (short) (year2020 + yrsCount);
- } else {
- yrsCount = (short) (year2051 + yrsCount);
- }
-
- // divide the given time with one month msec count
- if (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, oneMonthMsec, (short) 0, (short) 8)
- >= 0) {
- for (short i = 0; i < 12; i++) {
- if (i == 1) {
- // Feb month
- if (isLeapYear(yrsCount)) {
- // Leap year 29 days
- Util.arrayCopyNonAtomic(febMonthLeapMSec, (short) 0, scratchPad, (short) 8, (short) 8);
- } else {
- // 28 days
- Util.arrayCopyNonAtomic(febMonthMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- }
- } else if (((i <= 6) && ((i % 2 == 0))) || ((i > 6) && ((i % 2 == 1)))) {
- Util.arrayCopyNonAtomic(
- ThirtyOneDaysMonthMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- } else {
- // 30 Days
- Util.arrayCopyNonAtomic(ThirtDaysMonthMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- }
-
- if (KMInteger.unsignedByteArrayCompare(
- scratchPad, (short) 0, scratchPad, (short) 8, (short) 8)
- >= 0) {
- subtract(scratchPad, (short) 0, (short) 8, (short) 16, (byte) 8);
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- } else {
+ baseYear = year2000;
+ // difference in millis from year 2000
+ subtractAndCopy(scratchPad, inputOffset, firstJan2000, (short) 0);
+ // divide the time with 400 year milliseconds
+ quotient = divideAndCopy(scratchPad, inputOffset, fourHundredYrsMSec, (short) 0);
+ yrsCount = (short) (400 * quotient);
+ // divide the remaining time with 100 year milliseconds
+ endYear = (short) (yrsCount + 400);
+ for (; yrsCount <= endYear; yrsCount += 100) {
+ byte[] centuryMillis = centuryToMillis((short) (baseYear + yrsCount));
+ if ((KMInteger.unsignedByteArrayCompare(
+ scratchPad, inputOffset, centuryMillis, (short) 0, UINT8)
+ < 0)) {
break;
}
- monthCount++;
+ subtractAndCopy(scratchPad, inputOffset, centuryMillis, (short) 0);
}
}
+ yrsCount += baseYear;
+ yrsCount = adjustBaseYearToLeapYearsRange(yrsCount, scratchPad, inputOffset);
+ // divide the given time with four years msec count
+ quotient = divideAndCopy(scratchPad, inputOffset, fourYrsMsec, (short) 0);
+ yrsCount += (short) (quotient * 4); // number of yrs.
+ // divide the given time with one year msec
+ endYear = (short) (yrsCount + 4);
+ for (; yrsCount <= endYear; yrsCount++) {
+ byte[] yearMillis = yearToMillis(yrsCount);
+ if ((KMInteger.unsignedByteArrayCompare(scratchPad, inputOffset, yearMillis, (short) 0, UINT8)
+ < 0)) {
+ break;
+ }
+ subtractAndCopy(scratchPad, inputOffset, yearMillis, (short) 0);
+ }
+ // divide the given time with one month msec count
+ for (; monthCount <= 12; monthCount++) {
+ byte[] monthMillis = monthToMillis(yrsCount, monthCount);
+ if ((KMInteger.unsignedByteArrayCompare(
+ scratchPad, inputOffset, monthMillis, (short) 0, UINT8)
+ < 0)) {
+ break;
+ }
+ subtractAndCopy(scratchPad, inputOffset, monthMillis, (short) 0);
+ }
// divide the given time with one day msec count
- if (KMInteger.unsignedByteArrayCompare(scratchPad, (short) 0, oneDayMsec, (short) 0, (short) 8)
- >= 0) {
- Util.arrayCopyNonAtomic(oneDayMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- dayCount = divide(scratchPad, (short) 0, (short) 8, (short) 16);
- dayCount++;
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- }
+ dayCount = divideAndCopy(scratchPad, inputOffset, oneDayMsec, (short) 0);
+ dayCount++;
// divide the given time with one hour msec count
- if (KMInteger.unsignedByteArrayCompare(scratchPad, (short) 0, oneHourMsec, (short) 0, (short) 8)
- >= 0) {
- Util.arrayCopyNonAtomic(oneHourMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- hhCount = divide(scratchPad, (short) 0, (short) 8, (short) 16);
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- }
+ hhCount = divideAndCopy(scratchPad, inputOffset, oneHourMsec, (short) 0);
// divide the given time with one minute msec count
- if (KMInteger.unsignedByteArrayCompare(scratchPad, (short) 0, oneMinMsec, (short) 0, (short) 8)
- >= 0) {
- Util.arrayCopyNonAtomic(oneMinMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- mmCount = divide(scratchPad, (short) 0, (short) 8, (short) 16);
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- }
+ mmCount = divideAndCopy(scratchPad, inputOffset, oneMinMsec, (short) 0);
// divide the given time with one second msec count
- if (KMInteger.unsignedByteArrayCompare(scratchPad, (short) 0, oneSecMsec, (short) 0, (short) 8)
- >= 0) {
- Util.arrayCopyNonAtomic(oneSecMsec, (short) 0, scratchPad, (short) 8, (short) 8);
- ssCount = divide(scratchPad, (short) 0, (short) 8, (short) 16);
- Util.arrayCopyNonAtomic(scratchPad, (short) 16, scratchPad, (short) 0, (short) 8);
- }
+ ssCount = divideAndCopy(scratchPad, inputOffset, oneSecMsec, (short) 0);
// Now convert to ascii string YYMMDDhhmmssZ or YYYYMMDDhhmmssZ
- Util.arrayFillNonAtomic(scratchPad, (short) 0, (short) 256, (byte) 0);
- short len = numberToString(yrsCount, scratchPad, (short) 0); // returns YYYY
+ Util.arrayFillNonAtomic(scratchPad, inputOffset, (short) 256, (byte) 0);
+ short len = numberToString(yrsCount, scratchPad, inputOffset); // returns YYYY
len += numberToString(monthCount, scratchPad, len);
len += numberToString(dayCount, scratchPad, len);
len += numberToString(hhCount, scratchPad, len);
@@ -244,7 +174,7 @@
len += numberToString(ssCount, scratchPad, len);
scratchPad[len] = Z;
len++;
- if (utcFlag) {
+ if (yrsCount < year2050) {
return KMByteBlob.instance(scratchPad, (short) 2, (short) (len - 2)); // YY
} else {
return KMByteBlob.instance(scratchPad, (short) 0, len); // YYYY
@@ -268,6 +198,19 @@
return len;
}
+ // Divide the given input with the divisor and copy the remainder back to the
+ // input buffer from inputOff
+ private static short divideAndCopy(
+ byte[] scratchPad, short inputOff, byte[] divisor, short offset) {
+ short scratchPadOff = (short) (inputOff + 8);
+ Util.arrayCopyNonAtomic(divisor, offset, scratchPad, scratchPadOff, UINT8);
+ short q = divide(scratchPad, inputOff, scratchPadOff, (short) (scratchPadOff + 8));
+ if (q != 0) {
+ Util.arrayCopyNonAtomic(scratchPad, (short) (scratchPadOff + 8), scratchPad, inputOff, UINT8);
+ }
+ return q;
+ }
+
// Use Euclid's formula: dividend = quotient*divisor + remainder
// i.e. dividend - quotient*divisor = remainder where remainder < divisor.
// so this is division by subtraction until remainder remains.
@@ -363,6 +306,14 @@
}
}
+ // Subtract the two operands and copy the difference back to the input buffer from inputOff
+ private static void subtractAndCopy(byte[] scratchPad, short inputOff, byte[] buf, short bufOff) {
+ short scratchpadOff = (short) (inputOff + 8);
+ Util.arrayCopyNonAtomic(buf, bufOff, scratchPad, scratchpadOff, UINT8);
+ subtract(scratchPad, inputOff, scratchpadOff, (short) (scratchpadOff + 8), UINT8);
+ Util.arrayCopyNonAtomic(scratchPad, (short) (scratchpadOff + 8), scratchPad, inputOff, UINT8);
+ }
+
// subtraction by borrowing.
public static void subtract(byte[] buf, short op1, short op2, short result, byte sizeBytes) {
byte borrow = 0;
@@ -403,14 +354,51 @@
return false;
}
- public static short getLeapYrIndex(boolean from2020, short yrsCount) {
- short newBaseYr = (short) (from2020 ? (year2020 + yrsCount) : (year2051 + yrsCount));
- for (short i = 0; i < 4; i++) {
- if (isLeapYear((short) (newBaseYr + i))) {
- return i;
+ private static byte[] yearToMillis(short year) {
+ if (isLeapYear(year)) {
+ return leapYearMsec;
+ } else {
+ return yearMsec;
+ }
+ }
+
+ private static byte[] centuryToMillis(short year) {
+ if (isLeapYear(year)) {
+ return centuryWithLeapMSec;
+ } else {
+ return centuryMSec;
+ }
+ }
+
+ private static byte[] monthToMillis(short year, short month) {
+ if (month == 2) {
+ if (isLeapYear(year)) {
+ return febMonthLeapMSec;
+ } else {
+ return febMonthMsec;
+ }
+ } else if (((month <= 7) && ((month % 2 == 1))) || ((month > 7) && ((month % 2 == 0)))) {
+ return ThirtyOneDaysMonthMsec;
+ } else {
+ return ThirtDaysMonthMsec;
+ }
+ }
+
+ private static short adjustBaseYearToLeapYearsRange(
+ short year, byte[] scratchPad, short inputOffset) {
+ if (!isLeapYear(year)) {
+ // The rounded base year must fall within the range of leap years, which occur every
+ // four years. If the rounded base year is not a leap year then add one year to it
+ // so that it comes in the range of leap years. This is necessary when we divide the
+ // difference of the given time and rounded base year with four year milliseconds
+ // value.
+ if (KMInteger.unsignedByteArrayCompare(scratchPad, inputOffset, yearMsec, (short) 0, UINT8)
+ >= 0) {
+ subtractAndCopy(scratchPad, inputOffset, yearMsec, (short) 0);
+ year += 1;
}
}
- return -1;
+ return year;
}
public static void computeOnesCompliment(byte[] buf, short offset, short len) {