libaacs | branch: master | npzacs <[email protected]> | Thu Dec 30 16:31:21 2010 
+0200| [e7aa4fd42c0d4df771db41881bf3aaee956758c2] | committer: npzacs 

Added functions to verify signatures:
crypto_aacs_verify():
  verify signature using public key from certificate
crypto_aacs_verify_aacsla():
  verify AACS LA signature
crypto_aacs_verify_cert():
  verify certificate signature

> http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=e7aa4fd42c0d4df771db41881bf3aaee956758c2
---

 src/libaacs/crypto.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libaacs/crypto.h |    4 ++
 2 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/src/libaacs/crypto.c b/src/libaacs/crypto.c
index 178bfaf..6dcadf8 100644
--- a/src/libaacs/crypto.c
+++ b/src/libaacs/crypto.c
@@ -302,6 +302,45 @@ static gcry_error_t _aacs_sexp_sha1(gcry_sexp_t 
*p_sexp_data,
     return err;
 }
 
+static gcry_error_t _aacs_sexp_signature(gcry_sexp_t *p_sexp_sign,
+                                         const uint8_t *signature)
+{
+    gcry_mpi_t   mpi_r = NULL;
+    gcry_mpi_t   mpi_s = NULL;
+    gcry_error_t err;
+
+    gcry_mpi_scan(&mpi_r, GCRYMPI_FMT_USG, signature,      20, NULL);
+    gcry_mpi_scan(&mpi_s, GCRYMPI_FMT_USG, signature + 20, 20, NULL);
+
+    /* Dump information about the md MPI when debugging */
+    if (GCRYPT_DEBUG) {
+        fprintf(stderr, "signature: ");
+        gcry_mpi_dump(mpi_r);
+        gcry_mpi_dump(mpi_s);
+        fprintf(stderr, "\n");
+    }
+
+    /* Build an s-expression for the signature */
+    GCRY_VERIFY("gcry_sexp_build",
+                gcry_sexp_build(p_sexp_sign, NULL,
+                               "(sig-val"
+                               "  (ecdsa"
+                               "    (r %m) (s %m)))",
+                               mpi_r, mpi_s));
+
+    /* Dump information about the data s-expression when debugging */
+    if (GCRYPT_DEBUG) {
+        gcry_sexp_dump(*p_sexp_sign);
+    }
+
+error:
+
+    gcry_mpi_release(mpi_r);
+    gcry_mpi_release(mpi_s);
+
+    return err;
+}
+
 /*
  *
  */
@@ -370,6 +409,55 @@ void crypto_aacs_sign(const uint8_t *cert, const uint8_t 
*priv_key, uint8_t *sig
     gcry_free(s);
 }
 
+static int _aacs_verify(const uint8_t *signature,
+                        const uint8_t *q_x, const uint8_t *q_y,
+                        const uint8_t *data, uint32_t len)
+{
+    gcry_sexp_t  sexp_key  = NULL;
+    gcry_sexp_t  sexp_sig  = NULL;
+    gcry_sexp_t  sexp_data = NULL;
+    gcry_error_t err;
+
+    GCRY_VERIFY("_aacs_sexp_key",
+                _aacs_sexp_key(&sexp_key, q_x, q_y, NULL));
+
+    GCRY_VERIFY("_aacs_sexp_sha1",
+                _aacs_sexp_sha1(&sexp_data, data, len));
+
+    GCRY_VERIFY("_aacs_sexp_signature",
+                _aacs_sexp_signature(&sexp_sig, signature));
+
+    GCRY_VERIFY("gcry_pk_verify",
+                gcry_pk_verify(sexp_sig, sexp_data, sexp_key));
+
+ error:
+    gcry_sexp_release(sexp_sig);
+    gcry_sexp_release(sexp_data);
+    gcry_sexp_release(sexp_key);
+
+    return err;
+}
+
+int crypto_aacs_verify(const uint8_t *cert, const uint8_t *signature, const 
uint8_t *data, uint32_t len)
+{
+    return !_aacs_verify(signature, cert + 12, cert + 32, data, len);
+}
+
+int  crypto_aacs_verify_aacsla(const uint8_t *signature, const uint8_t *data, 
uint32_t len)
+{
+    static const uint8_t aacs_la_pubkey_x[] = {0x63, 0xC2, 0x1D, 0xFF, 0xB2, 
0xB2, 0x79, 0x8A, 0x13, 0xB5,
+                                               0x8D, 0x61, 0x16, 0x6C, 0x4E, 
0x4A, 0xAC, 0x8A, 0x07, 0x72 };
+    static const uint8_t aacs_la_pubkey_y[] = {0x13, 0x7E, 0xC6, 0x38, 0x81, 
0x8F, 0xD9, 0x8F, 0xA4, 0xC3,
+                                               0x0B, 0x99, 0x67, 0x28, 0xBF, 
0x4B, 0x91, 0x7F, 0x6A, 0x27 };
+
+    return !_aacs_verify(signature, aacs_la_pubkey_x, aacs_la_pubkey_y, data, 
len);
+}
+
+int crypto_aacs_verify_cert(const uint8_t *cert)
+{
+    return crypto_aacs_verify_aacsla(cert + 52, cert, 52);
+}
+
 void crypto_aacs_title_hash(const uint8_t *ukf, uint64_t len, uint8_t *hash)
 {
     gcry_md_hash_buffer(GCRY_MD_SHA1, hash, ukf, len);
diff --git a/src/libaacs/crypto.h b/src/libaacs/crypto.h
index c352e54..1de79c4 100644
--- a/src/libaacs/crypto.h
+++ b/src/libaacs/crypto.h
@@ -33,6 +33,10 @@ AACS_PRIVATE void crypto_aacs_sign(const uint8_t *cert, 
const uint8_t *priv_key,
                                    const uint8_t *nonce, const uint8_t *point);
 AACS_PRIVATE void crypto_aacs_title_hash(const uint8_t *ukf, uint64_t len, 
uint8_t *hash);
 
+AACS_PRIVATE int  crypto_aacs_verify(const uint8_t *cert, const uint8_t 
*signature, const uint8_t *data, uint32_t len);
+AACS_PRIVATE int  crypto_aacs_verify_aacsla(const uint8_t *signature, const 
uint8_t *data, uint32_t len);
+AACS_PRIVATE int  crypto_aacs_verify_cert(const uint8_t *cert);
+
 AACS_PRIVATE void crypto_create_host_key_pair(uint8_t *key, uint8_t 
*key_point);
 AACS_PRIVATE void crypto_create_nonce(uint8_t *buf, size_t len);
 

_______________________________________________
libaacs-devel mailing list
[email protected]
http://mailman.videolan.org/listinfo/libaacs-devel

Reply via email to