Add Cipher support to autodocs.
Ciphers are more complicated than other categories because providers can
declare that they provide a base algorithm but users request an
algorithm/mode/padding triple, so we need to investigate the possible
values of that triple and see which ones actually end up available.
We ignore all the PBE ciphers because they're a mess and we don't
want them to show up in the documentation.
The starting API level for AES/GCM/NOPADDING is actually an educated
guess, it's approximately correct but might be off by one or two.
I'll update it if I later get better information.
Bug: 35793879
Test: Ran run_update_crypto_support.sh
Change-Id: Ifb827818626690ff223f691c8297731790074283
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index d50eb2c..8e6cc4f 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -163,6 +163,411 @@
{
"algorithms": [
{
+ "name": "AES/CBC/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CBC/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CBC/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CFB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CFB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CFB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTR/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTR/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTR/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTS/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTS/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/CTS/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/ECB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/ECB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/ECB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/GCM/NOPADDING",
+ "supported_api_levels": "21+"
+ },
+ {
+ "name": "AES/OFB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/OFB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES/OFB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "AES_128/CBC/NOPADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/CBC/PKCS5PADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/ECB/NOPADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/ECB/PKCS5PADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_128/GCM/NOPADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/CBC/NOPADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/CBC/PKCS5PADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/ECB/NOPADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/ECB/PKCS5PADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "AES_256/GCM/NOPADDING",
+ "supported_api_levels": "26+"
+ },
+ {
+ "name": "ARC4/ECB/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CBC/ISO10126PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CBC/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CBC/PKCS5PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CFB/ISO10126PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CFB/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CFB/PKCS5PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTR/ISO10126PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTR/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTR/PKCS5PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTS/ISO10126PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTS/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/CTS/PKCS5PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/ECB/ISO10126PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/ECB/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/ECB/PKCS5PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/OFB/ISO10126PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/OFB/NOPADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "BLOWFISH/OFB/PKCS5PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "DES/CBC/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CBC/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CBC/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CFB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CFB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CFB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTR/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTR/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTR/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTS/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTS/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/CTS/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/ECB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/ECB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/ECB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/OFB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/OFB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DES/OFB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CBC/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CBC/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CBC/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CFB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CFB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CFB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CTR/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CTR/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CTR/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CTS/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CTS/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/CTS/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/ECB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/ECB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/ECB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/OFB/ISO10126PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/OFB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "DESEDE/OFB/PKCS5PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/ECB/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/ECB/OAEPPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/ECB/OAEPWITHSHA-224ANDMGF1PADDING",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/ECB/OAEPWITHSHA-384ANDMGF1PADDING",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/ECB/PKCS1PADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/NONE/NOPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/NONE/OAEPPADDING",
+ "supported_api_levels": "1+"
+ },
+ {
+ "name": "RSA/NONE/OAEPWITHSHA-1ANDMGF1PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/NONE/OAEPWITHSHA-224ANDMGF1PADDING",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/NONE/OAEPWITHSHA-256ANDMGF1PADDING",
+ "supported_api_levels": "10+"
+ },
+ {
+ "name": "RSA/NONE/OAEPWITHSHA-384ANDMGF1PADDING",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/NONE/OAEPWITHSHA-512ANDMGF1PADDING",
+ "supported_api_levels": "23+"
+ },
+ {
+ "name": "RSA/NONE/PKCS1PADDING",
+ "supported_api_levels": "1+"
+ }
+ ],
+ "name": "Cipher"
+ },
+ {
+ "algorithms": [
+ {
"name": "DH",
"supported_api_levels": "1+"
},
@@ -822,5 +1227,5 @@
"name": "TrustManagerFactory"
}
],
- "last_updated": "2017-03-14 15:13:50 UTC"
+ "last_updated": "2017-03-16 10:29:21 UTC"
}
\ No newline at end of file
diff --git a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
index 34aed4b..1cd8646 100644
--- a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
+++ b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
@@ -16,6 +16,7 @@
package libcore.java.security;
+import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
@@ -25,6 +26,8 @@
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
/**
* Prints a list of all algorithms provided by security providers. Intended to be run
@@ -34,15 +37,50 @@
*/
public class ListProviders {
+ private static final boolean SHOW_PROVIDER = false;
+
// These algorithms were previously provided, but now are aliases for a different
// algorithm. For documentation purposes, we want to continue having them show up
// as supported.
- private static final Set<String> KNOWN_ALIASES = new HashSet<>(Arrays.asList(new String[]{
+ private static final Set<String> KNOWN_ALIASES = new TreeSet<>(Arrays.asList(new String[]{
"Alg.Alias.Signature.DSA",
"Alg.Alias.Signature.DSAwithSHA1",
"Alg.Alias.Signature.ECDSA",
"Alg.Alias.Signature.ECDSAwithSHA1",
}));
+
+ // Ciphers come in algorithm/mode/padding combinations, and not all combinations are explicitly
+ // registered by the providers (sometimes only the base algorithm is registered). While there
+ // is a mechanism for providers to specify which modes and/or paddings are supported for a
+ // given algorithm, none of our providers use it. Thus, when a base algorithm is seen, all
+ // combinations of modes and paddings will be tried to see which ones are supported.
+ private static final Set<String> CIPHER_MODES = new TreeSet<>(Arrays.asList(new String[]{
+ "CBC",
+ "CFB",
+ "CTR",
+ "CTS",
+ "ECB",
+ "GCM",
+ "OFB",
+ "NONE",
+ }));
+ private static final Set<String> CIPHER_PADDINGS = new TreeSet<>(Arrays.asList(new String[]{
+ "NoPadding",
+ "OAEPPadding",
+ "OAEPwithSHA-1andMGF1Padding",
+ "OAEPwithSHA-224andMGF1Padding",
+ "OAEPwithSHA-256andMGF1Padding",
+ "OAEPwithSHA-384andMGF1Padding",
+ "OAEPwithSHA-512andMGF1Padding",
+ "PKCS1Padding",
+ "PKCS5Padding",
+ "ISO10126Padding",
+ }));
+
+ private static void print(Provider p, String type, String algorithm) {
+ System.out.println((SHOW_PROVIDER ? p.getName() + ": " : "") + type + " " + algorithm);
+ }
+
public static void main(String[] argv) {
System.out.println("BEGIN ALGORITHM LIST");
for (Provider p : Security.getProviders()) {
@@ -58,12 +96,33 @@
});
services.addAll(p.getServices());
for (Provider.Service s : services) {
- System.out.println(s.getType() + " " + s.getAlgorithm());
+ if (s.getType().equals("Cipher") && s.getAlgorithm().startsWith("PBE")) {
+ // PBE ciphers are a mess and generally don't do anything but delegate
+ // to the underlying cipher. We don't want to document them.
+ continue;
+ }
+ if (s.getType().equals("Cipher") && s.getAlgorithm().indexOf('/') == -1) {
+ for (String mode : CIPHER_MODES) {
+ for (String padding : CIPHER_PADDINGS) {
+ try {
+ String name = s.getAlgorithm() + "/" + mode + "/" + padding;
+ Cipher.getInstance(name, p);
+ print(p, s.getType(), name);
+ } catch (NoSuchAlgorithmException
+ |NoSuchPaddingException
+ |IllegalArgumentException e) {
+ // This combination doesn't work
+ }
+ }
+ }
+ } else {
+ print(p, s.getType(), s.getAlgorithm());
+ }
}
for (String alias : KNOWN_ALIASES) {
if (p.containsKey(alias)) {
String[] elements = alias.split("\\."); // Split takes a regex
- System.out.println(elements[2] + " " + elements[3]);
+ print(p, elements[2], elements[3]);
}
}
}
diff --git a/tools/docs/crypto/update_crypto_support.py b/tools/docs/crypto/update_crypto_support.py
index c8d19df..7d7861f 100755
--- a/tools/docs/crypto/update_crypto_support.py
+++ b/tools/docs/crypto/update_crypto_support.py
@@ -29,7 +29,6 @@
import json
import sys
-# TODO(b/35793879): Support more categories
SUPPORTED_CATEGORIES = [
'AlgorithmParameterGenerator',
'AlgorithmParameters',
@@ -37,6 +36,7 @@
'CertPathBuilder',
'CertPathValidator',
'CertStore',
+ 'Cipher',
'KeyAgreement',
'KeyFactory',
'KeyGenerator',
@@ -73,6 +73,12 @@
# reverse. X.509 is the official name of the standard, so use that.
if name == "X509":
name = "X.509"
+ # PKCS5PADDING and PKCS7PADDING are the same thing (more accurately, PKCS#5
+ # is a special case of PKCS#7), but providers are inconsistent in their
+ # naming. Use PKCS5PADDING because that's what our docs have used
+ # historically.
+ if name.endswith("/PKCS7PADDING"):
+ name = name[:-1 * len("/PKCS7PADDING")] + "/PKCS5PADDING"
return name
def get_current_data(f):