diff --git a/verifier.cpp b/verifier.cpp
index 98c7337..c4cd612 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -14,27 +14,29 @@
  * limitations under the License.
  */
 
-#include "asn1_decoder.h"
-#include "common.h"
-#include "ui.h"
-#include "verifier.h"
-
-#include "mincrypt/dsa_sig.h"
-#include "mincrypt/p256.h"
-#include "mincrypt/p256_ecdsa.h"
-#include "mincrypt/rsa.h"
-#include "mincrypt/sha.h"
-#include "mincrypt/sha256.h"
-
 #include <errno.h>
 #include <malloc.h>
 #include <stdio.h>
 #include <string.h>
 
+#include <algorithm>
+#include <memory>
+
+#include <openssl/ecdsa.h>
+#include <openssl/obj_mac.h>
+
+#include "asn1_decoder.h"
+#include "common.h"
+#include "print_sha1.h"
+#include "ui.h"
+#include "verifier.h"
+
 //extern RecoveryUI* ui;
 
 #define PUBLIC_KEYS_FILE "/res/keys"
 
+static constexpr size_t MiB = 1024 * 1024;
+
 /*
  * Simple version of PKCS#7 SignedData extraction. This extracts the
  * signature OCTET STRING to be used for signature verification.
@@ -113,16 +115,16 @@
 //
 // Return VERIFY_SUCCESS, VERIFY_FAILURE (if any error is encountered
 // or no key matches the signature).
+
 int verify_file(unsigned char* addr, size_t length) {
     //ui->SetProgress(0.0);
 
-    int numKeys;
-    Certificate* pKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys);
-    if (pKeys == NULL) {
+    std::vector<Certificate> keys;
+    if (!load_keys(PUBLIC_KEYS_FILE, keys)) {
         LOGE("Failed to load keys\n");
         return INSTALL_CORRUPT;
     }
-    LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE);
+    LOGI("%d key(s) loaded from %s\n", keys.size(), PUBLIC_KEYS_FILE);
 
     // An archive with a whole-file signature will end in six bytes:
     //
@@ -184,8 +186,7 @@
         return VERIFY_FAILURE;
     }
 
-    size_t i;
-    for (i = 4; i < eocd_size-3; ++i) {
+    for (size_t i = 4; i < eocd_size-3; ++i) {
         if (eocd[i  ] == 0x50 && eocd[i+1] == 0x4b &&
             eocd[i+2] == 0x05 && eocd[i+3] == 0x06) {
             // if the sequence $50 $4b $05 $06 appears anywhere after
@@ -197,30 +198,30 @@
         }
     }
 
-#define BUFFER_SIZE 4096
-
     bool need_sha1 = false;
     bool need_sha256 = false;
-    for (i = 0; i < numKeys; ++i) {
-        switch (pKeys[i].hash_len) {
-            case SHA_DIGEST_SIZE: need_sha1 = true; break;
-            case SHA256_DIGEST_SIZE: need_sha256 = true; break;
+    for (const auto& key : keys) {
+        switch (key.hash_len) {
+            case SHA_DIGEST_LENGTH: need_sha1 = true; break;
+            case SHA256_DIGEST_LENGTH: need_sha256 = true; break;
         }
     }
 
     SHA_CTX sha1_ctx;
     SHA256_CTX sha256_ctx;
-    SHA_init(&sha1_ctx);
-    SHA256_init(&sha256_ctx);
+    SHA1_Init(&sha1_ctx);
+    SHA256_Init(&sha256_ctx);
 
     double frac = -1.0;
     size_t so_far = 0;
     while (so_far < signed_len) {
-        size_t size = signed_len - so_far;
-        if (size > BUFFER_SIZE) size = BUFFER_SIZE;
+        // On a Nexus 5X, experiment showed 16MiB beat 1MiB by 6% faster for a
+        // 1196MiB full OTA and 60% for an 89MiB incremental OTA.
+        // http://b/28135231.
+        size_t size = std::min(signed_len - so_far, 16 * MiB);
 
-        if (need_sha1) SHA_update(&sha1_ctx, addr + so_far, size);
-        if (need_sha256) SHA256_update(&sha256_ctx, addr + so_far, size);
+        if (need_sha1) SHA1_Update(&sha1_ctx, addr + so_far, size);
+        if (need_sha256) SHA256_Update(&sha256_ctx, addr + so_far, size);
         so_far += size;
 
         double f = so_far / (double)signed_len;
@@ -230,15 +231,22 @@
         }
     }
 
-    const uint8_t* sha1 = SHA_final(&sha1_ctx);
-    const uint8_t* sha256 = SHA256_final(&sha256_ctx);
+    uint8_t sha1[SHA_DIGEST_LENGTH];
+    SHA1_Final(sha1, &sha1_ctx);
+    uint8_t sha256[SHA256_DIGEST_LENGTH];
+    SHA256_Final(sha256, &sha256_ctx);
 
-    uint8_t* sig_der = NULL;
+    uint8_t* sig_der = nullptr;
     size_t sig_der_length = 0;
 
+    uint8_t* signature = eocd + eocd_size - signature_start;
     size_t signature_size = signature_start - FOOTER_SIZE;
-    if (!read_pkcs7(eocd + eocd_size - signature_start, signature_size, &sig_der,
-            &sig_der_length)) {
+
+    LOGI("signature (offset: 0x%zx, length: %zu): %s\n",
+            length - signature_start, signature_size,
+            print_hex(signature, signature_size).c_str());
+
+    if (!read_pkcs7(signature, signature_size, &sig_der, &sig_der_length)) {
         LOGE("Could not find signature DER block\n");
         return VERIFY_FAILURE;
     }
@@ -248,25 +256,28 @@
      * any key can match, we need to try each before determining a verification
      * failure has happened.
      */
-    for (i = 0; i < numKeys; ++i) {
+    size_t i = 0;
+    for (const auto& key : keys) {
         const uint8_t* hash;
-        switch (pKeys[i].hash_len) {
-            case SHA_DIGEST_SIZE: hash = sha1; break;
-            case SHA256_DIGEST_SIZE: hash = sha256; break;
-            default: continue;
+        int hash_nid;
+        switch (key.hash_len) {
+            case SHA_DIGEST_LENGTH:
+                hash = sha1;
+                hash_nid = NID_sha1;
+                break;
+            case SHA256_DIGEST_LENGTH:
+                hash = sha256;
+                hash_nid = NID_sha256;
+                break;
+            default:
+                continue;
         }
 
         // The 6 bytes is the "(signature_start) $ff $ff (comment_size)" that
         // the signing tool appends after the signature itself.
-        if (pKeys[i].key_type == Certificate::RSA) {
-            if (sig_der_length < RSANUMBYTES) {
-                // "signature" block isn't big enough to contain an RSA block.
-                LOGI("signature is too short for RSA key %zu\n", i);
-                continue;
-            }
-
-            if (!RSA_verify(pKeys[i].rsa, sig_der, RSANUMBYTES,
-                            hash, pKeys[i].hash_len)) {
+        if (key.key_type == Certificate::KEY_TYPE_RSA) {
+            if (!RSA_verify(hash_nid, hash, key.hash_len, sig_der,
+                            sig_der_length, key.rsa.get())) {
                 LOGI("failed to verify against RSA key %zu\n", i);
                 continue;
             }
@@ -274,18 +285,10 @@
             LOGI("whole-file signature verified against RSA key %zu\n", i);
             free(sig_der);
             return VERIFY_SUCCESS;
-        } else if (pKeys[i].key_type == Certificate::EC
-                && pKeys[i].hash_len == SHA256_DIGEST_SIZE) {
-            p256_int r, s;
-            if (!dsa_sig_unpack(sig_der, sig_der_length, &r, &s)) {
-                LOGI("Not a DSA signature block for EC key %zu\n", i);
-                continue;
-            }
-
-            p256_int p256_hash;
-            p256_from_bin(hash, &p256_hash);
-            if (!p256_ecdsa_verify(&(pKeys[i].ec->x), &(pKeys[i].ec->y),
-                                   &p256_hash, &r, &s)) {
+        } else if (key.key_type == Certificate::KEY_TYPE_EC
+                && key.hash_len == SHA256_DIGEST_LENGTH) {
+            if (!ECDSA_verify(0, hash, key.hash_len, sig_der,
+                              sig_der_length, key.ec.get())) {
                 LOGI("failed to verify against EC key %zu\n", i);
                 continue;
             }
@@ -294,15 +297,160 @@
             free(sig_der);
             return VERIFY_SUCCESS;
         } else {
-            LOGI("Unknown key type %d\n", pKeys[i].key_type);
+            LOGI("Unknown key type %d\n", key.key_type);
         }
-		LOGI("i: %i, eocd_size: %i, RSANUMBYTES: %i\n", i, eocd_size, RSANUMBYTES);
+        i++;
+    }
+
+    if (need_sha1) {
+        LOGI("SHA-1 digest: %s\n", print_hex(sha1, SHA_DIGEST_LENGTH).c_str());
+    }
+    if (need_sha256) {
+        LOGI("SHA-256 digest: %s\n", print_hex(sha256, SHA256_DIGEST_LENGTH).c_str());
     }
     free(sig_der);
     LOGE("failed to verify whole-file signature\n");
     return VERIFY_FAILURE;
 }
 
+std::unique_ptr<RSA, RSADeleter> parse_rsa_key(FILE* file, uint32_t exponent) {
+    // Read key length in words and n0inv. n0inv is a precomputed montgomery
+    // parameter derived from the modulus and can be used to speed up
+    // verification. n0inv is 32 bits wide here, assuming the verification logic
+    // uses 32 bit arithmetic. However, BoringSSL may use a word size of 64 bits
+    // internally, in which case we don't have a valid n0inv. Thus, we just
+    // ignore the montgomery parameters and have BoringSSL recompute them
+    // internally. If/When the speedup from using the montgomery parameters
+    // becomes relevant, we can add more sophisticated code here to obtain a
+    // 64-bit n0inv and initialize the montgomery parameters in the key object.
+    uint32_t key_len_words = 0;
+    uint32_t n0inv = 0;
+    if (fscanf(file, " %i , 0x%x", &key_len_words, &n0inv) != 2) {
+        return nullptr;
+    }
+
+    if (key_len_words > 8192 / 32) {
+        LOGE("key length (%d) too large\n", key_len_words);
+        return nullptr;
+    }
+
+    // Read the modulus.
+    std::unique_ptr<uint32_t[]> modulus(new uint32_t[key_len_words]);
+    if (fscanf(file, " , { %u", &modulus[0]) != 1) {
+        return nullptr;
+    }
+    for (uint32_t i = 1; i < key_len_words; ++i) {
+        if (fscanf(file, " , %u", &modulus[i]) != 1) {
+            return nullptr;
+        }
+    }
+
+    // Cconvert from little-endian array of little-endian words to big-endian
+    // byte array suitable as input for BN_bin2bn.
+    std::reverse((uint8_t*)modulus.get(),
+                 (uint8_t*)(modulus.get() + key_len_words));
+
+    // The next sequence of values is the montgomery parameter R^2. Since we
+    // generally don't have a valid |n0inv|, we ignore this (see comment above).
+    uint32_t rr_value;
+    if (fscanf(file, " } , { %u", &rr_value) != 1) {
+        return nullptr;
+    }
+    for (uint32_t i = 1; i < key_len_words; ++i) {
+        if (fscanf(file, " , %u", &rr_value) != 1) {
+            return nullptr;
+        }
+    }
+    if (fscanf(file, " } } ") != 0) {
+        return nullptr;
+    }
+
+    // Initialize the key.
+    std::unique_ptr<RSA, RSADeleter> key(RSA_new());
+    if (!key) {
+      return nullptr;
+    }
+
+    key->n = BN_bin2bn((uint8_t*)modulus.get(),
+                       key_len_words * sizeof(uint32_t), NULL);
+    if (!key->n) {
+      return nullptr;
+    }
+
+    key->e = BN_new();
+    if (!key->e || !BN_set_word(key->e, exponent)) {
+      return nullptr;
+    }
+
+    return key;
+}
+
+struct BNDeleter {
+  void operator()(BIGNUM* bn) {
+    BN_free(bn);
+  }
+};
+
+std::unique_ptr<EC_KEY, ECKEYDeleter> parse_ec_key(FILE* file) {
+    uint32_t key_len_bytes = 0;
+    if (fscanf(file, " %i", &key_len_bytes) != 1) {
+        return nullptr;
+    }
+
+    std::unique_ptr<EC_GROUP, void (*)(EC_GROUP*)> group(
+        EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1), EC_GROUP_free);
+    if (!group) {
+        return nullptr;
+    }
+
+    // Verify that |key_len| matches the group order.
+    if (key_len_bytes != BN_num_bytes(EC_GROUP_get0_order(group.get()))) {
+        return nullptr;
+    }
+
+    // Read the public key coordinates. Note that the byte order in the file is
+    // little-endian, so we convert to big-endian here.
+    std::unique_ptr<uint8_t[]> bytes(new uint8_t[key_len_bytes]);
+    std::unique_ptr<BIGNUM, BNDeleter> point[2];
+    for (int i = 0; i < 2; ++i) {
+        unsigned int byte = 0;
+        if (fscanf(file, " , { %u", &byte) != 1) {
+            return nullptr;
+        }
+        bytes[key_len_bytes - 1] = byte;
+
+        for (size_t i = 1; i < key_len_bytes; ++i) {
+            if (fscanf(file, " , %u", &byte) != 1) {
+                return nullptr;
+            }
+            bytes[key_len_bytes - i - 1] = byte;
+        }
+
+        point[i].reset(BN_bin2bn(bytes.get(), key_len_bytes, nullptr));
+        if (!point[i]) {
+            return nullptr;
+        }
+
+        if (fscanf(file, " }") != 0) {
+            return nullptr;
+        }
+    }
+
+    if (fscanf(file, " } ") != 0) {
+        return nullptr;
+    }
+
+    // Create and initialize the key.
+    std::unique_ptr<EC_KEY, ECKEYDeleter> key(EC_KEY_new());
+    if (!key || !EC_KEY_set_group(key.get(), group.get()) ||
+        !EC_KEY_set_public_key_affine_coordinates(key.get(), point[0].get(),
+                                                  point[1].get())) {
+        return nullptr;
+    }
+
+    return key;
+}
+
 // Reads a file containing one or more public keys as produced by
 // DumpPublicKey:  this is an RSAPublicKey struct as it would appear
 // as a C source literal, eg:
@@ -332,140 +480,85 @@
 //       4: 2048-bit RSA key with e=65537 and SHA-256 hash
 //       5: 256-bit EC key using the NIST P-256 curve parameters and SHA-256 hash
 //
-// Returns NULL if the file failed to parse, or if it contain zero keys.
-Certificate*
-load_keys(const char* filename, int* numKeys) {
-    Certificate* out = NULL;
-    *numKeys = 0;
-
-    FILE* f = fopen(filename, "r");
-    if (f == NULL) {
+// Returns true on success, and appends the found keys (at least one) to certs.
+// Otherwise returns false if the file failed to parse, or if it contains zero
+// keys. The contents in certs would be unspecified on failure.
+bool load_keys(const char* filename, std::vector<Certificate>& certs) {
+    std::unique_ptr<FILE, decltype(&fclose)> f(fopen(filename, "r"), fclose);
+    if (!f) {
         LOGE("opening %s: %s\n", filename, strerror(errno));
-        goto exit;
+        return false;
     }
 
-    {
-        int i;
-        bool done = false;
-        while (!done) {
-            ++*numKeys;
-            out = (Certificate*)realloc(out, *numKeys * sizeof(Certificate));
-            Certificate* cert = out + (*numKeys - 1);
-            memset(cert, '\0', sizeof(Certificate));
+    while (true) {
+        certs.emplace_back(0, Certificate::KEY_TYPE_RSA, nullptr, nullptr);
+        Certificate& cert = certs.back();
+        uint32_t exponent = 0;
 
-            char start_char;
-            if (fscanf(f, " %c", &start_char) != 1) goto exit;
-            if (start_char == '{') {
-                // a version 1 key has no version specifier.
-                cert->key_type = Certificate::RSA;
-                cert->rsa = (RSAPublicKey*)malloc(sizeof(RSAPublicKey));
-                cert->rsa->exponent = 3;
-                cert->hash_len = SHA_DIGEST_SIZE;
-            } else if (start_char == 'v') {
-                int version;
-                if (fscanf(f, "%d {", &version) != 1) goto exit;
-                switch (version) {
-                    case 2:
-                        cert->key_type = Certificate::RSA;
-                        cert->rsa = (RSAPublicKey*)malloc(sizeof(RSAPublicKey));
-                        cert->rsa->exponent = 65537;
-                        cert->hash_len = SHA_DIGEST_SIZE;
-                        break;
-                    case 3:
-                        cert->key_type = Certificate::RSA;
-                        cert->rsa = (RSAPublicKey*)malloc(sizeof(RSAPublicKey));
-                        cert->rsa->exponent = 3;
-                        cert->hash_len = SHA256_DIGEST_SIZE;
-                        break;
-                    case 4:
-                        cert->key_type = Certificate::RSA;
-                        cert->rsa = (RSAPublicKey*)malloc(sizeof(RSAPublicKey));
-                        cert->rsa->exponent = 65537;
-                        cert->hash_len = SHA256_DIGEST_SIZE;
-                        break;
-                    case 5:
-                        cert->key_type = Certificate::EC;
-                        cert->ec = (ECPublicKey*)calloc(1, sizeof(ECPublicKey));
-                        cert->hash_len = SHA256_DIGEST_SIZE;
-                        break;
-                    default:
-                        goto exit;
-                }
+        char start_char;
+        if (fscanf(f.get(), " %c", &start_char) != 1) return false;
+        if (start_char == '{') {
+            // a version 1 key has no version specifier.
+            cert.key_type = Certificate::KEY_TYPE_RSA;
+            exponent = 3;
+            cert.hash_len = SHA_DIGEST_LENGTH;
+        } else if (start_char == 'v') {
+            int version;
+            if (fscanf(f.get(), "%d {", &version) != 1) return false;
+            switch (version) {
+                case 2:
+                    cert.key_type = Certificate::KEY_TYPE_RSA;
+                    exponent = 65537;
+                    cert.hash_len = SHA_DIGEST_LENGTH;
+                    break;
+                case 3:
+                    cert.key_type = Certificate::KEY_TYPE_RSA;
+                    exponent = 3;
+                    cert.hash_len = SHA256_DIGEST_LENGTH;
+                    break;
+                case 4:
+                    cert.key_type = Certificate::KEY_TYPE_RSA;
+                    exponent = 65537;
+                    cert.hash_len = SHA256_DIGEST_LENGTH;
+                    break;
+                case 5:
+                    cert.key_type = Certificate::KEY_TYPE_EC;
+                    cert.hash_len = SHA256_DIGEST_LENGTH;
+                    break;
+                default:
+                    return false;
+            }
+        }
+
+        if (cert.key_type == Certificate::KEY_TYPE_RSA) {
+            cert.rsa = parse_rsa_key(f.get(), exponent);
+            if (!cert.rsa) {
+              return false;
             }
 
-            if (cert->key_type == Certificate::RSA) {
-                RSAPublicKey* key = cert->rsa;
-                if (fscanf(f, " %i , 0x%x , { %u",
-                           &(key->len), &(key->n0inv), &(key->n[0])) != 3) {
-                    goto exit;
-                }
-                if (key->len != RSANUMWORDS) {
-                    LOGE("key length (%d) does not match expected size\n", key->len);
-                    goto exit;
-                }
-                for (i = 1; i < key->len; ++i) {
-                    if (fscanf(f, " , %u", &(key->n[i])) != 1) goto exit;
-                }
-                if (fscanf(f, " } , { %u", &(key->rr[0])) != 1) goto exit;
-                for (i = 1; i < key->len; ++i) {
-                    if (fscanf(f, " , %u", &(key->rr[i])) != 1) goto exit;
-                }
-                fscanf(f, " } } ");
-
-                LOGI("read key e=%d hash=%d\n", key->exponent, cert->hash_len);
-            } else if (cert->key_type == Certificate::EC) {
-                ECPublicKey* key = cert->ec;
-                int key_len;
-                unsigned int byte;
-                uint8_t x_bytes[P256_NBYTES];
-                uint8_t y_bytes[P256_NBYTES];
-                if (fscanf(f, " %i , { %u", &key_len, &byte) != 2) goto exit;
-                if (key_len != P256_NBYTES) {
-                    LOGE("Key length (%d) does not match expected size %d\n", key_len, P256_NBYTES);
-                    goto exit;
-                }
-                x_bytes[P256_NBYTES - 1] = byte;
-                for (i = P256_NBYTES - 2; i >= 0; --i) {
-                    if (fscanf(f, " , %u", &byte) != 1) goto exit;
-                    x_bytes[i] = byte;
-                }
-                if (fscanf(f, " } , { %u", &byte) != 1) goto exit;
-                y_bytes[P256_NBYTES - 1] = byte;
-                for (i = P256_NBYTES - 2; i >= 0; --i) {
-                    if (fscanf(f, " , %u", &byte) != 1) goto exit;
-                    y_bytes[i] = byte;
-                }
-                fscanf(f, " } } ");
-                p256_from_bin(x_bytes, &key->x);
-                p256_from_bin(y_bytes, &key->y);
-            } else {
-                LOGE("Unknown key type %d\n", cert->key_type);
-                goto exit;
+            LOGI("read key e=%d hash=%d\n", exponent, cert.hash_len);
+        } else if (cert.key_type == Certificate::KEY_TYPE_EC) {
+            cert.ec = parse_ec_key(f.get());
+            if (!cert.ec) {
+              return false;
             }
+        } else {
+            LOGE("Unknown key type %d\n", cert.key_type);
+            return false;
+        }
 
-            // if the line ends in a comma, this file has more keys.
-            switch (fgetc(f)) {
-            case ',':
-                // more keys to come.
-                break;
-
-            case EOF:
-                done = true;
-                break;
-
-            default:
-                LOGE("unexpected character between keys\n");
-                goto exit;
-            }
+        // if the line ends in a comma, this file has more keys.
+        int ch = fgetc(f.get());
+        if (ch == ',') {
+            // more keys to come.
+            continue;
+        } else if (ch == EOF) {
+            break;
+        } else {
+            LOGE("unexpected character between keys\n");
+            return false;
         }
     }
 
-    fclose(f);
-    return out;
-
-exit:
-    if (f) fclose(f);
-    free(out);
-    *numKeys = 0;
-    return NULL;
+    return true;
 }
