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
