diff options
-rw-r--r-- | dl3.c | 98 |
1 files changed, 75 insertions, 23 deletions
@@ -8,6 +8,7 @@ #include "libusb.h" #include "pkts.h" +#include "hdcp.h" #include <openssl/bn.h> #include <openssl/rsa.h> #include <openssl/evp.h> @@ -17,6 +18,9 @@ #include <gcrypt.h> +struct hdcp_session_info { + gcry_sexp_t pub_key; +}; static int VID = 0x17e9; static int PID = 0x4301; @@ -24,7 +28,7 @@ static int PID = 0x4301; static unsigned char mykm[16] = { 0xcd, 0xef, 0x65, 0x33, 0x69, 0x23, 0xfa, 0x3e, 0x60, 0xee, 0xdd, 0x5c, 0xce, 0xfb, 0x39, 0x19 }; -static int create_gcrypt_pubkey(gcry_sexp_t *pub_key, +static int create_gcrypt_pubkey(struct hdcp_session_info *info, const uint8_t *n, const uint8_t *e, int n_len, int e_len) @@ -55,7 +59,7 @@ static int create_gcrypt_pubkey(gcry_sexp_t *pub_key, printf("pub key %s\n", buf); - ret = gcry_sexp_sscan(pub_key, NULL, buf, strlen(buf)); + ret = gcry_sexp_sscan(&info->pub_key, NULL, buf, strlen(buf)); if (ret != 0) return -1; return 0; @@ -89,9 +93,9 @@ static int create_gcrypt_km(gcry_sexp_t *km, return 0; } -static void decode_cert(const unsigned char *buf, int len, gcry_sexp_t *pub_key) +static void decode_cert(struct hdcp_session_info *info, const uint8_t *buf, int len) { - const unsigned char *start = buf + (len - 522); + const uint8_t *start = buf + 2; BIGNUM *e, *m; int i, ret; EVP_PKEY *pRsaKey = EVP_PKEY_new(); @@ -131,12 +135,14 @@ static void decode_cert(const unsigned char *buf, int len, gcry_sexp_t *pub_key) } printf("\n"); - ret = create_gcrypt_pubkey(pub_key, - &start[5], - &start[133], - 128, 3); - if (ret != 0) { - fprintf(stderr, "failed to create pubkey %d\n", ret); + if (info) { + ret = create_gcrypt_pubkey(info, + &start[5], + &start[133], + 128, 3); + if (ret != 0) { + fprintf(stderr, "failed to create pubkey %d\n", ret); + } } ctx = EVP_PKEY_CTX_new(pRsaKey, NULL); @@ -166,6 +172,54 @@ static void decode_cert(const unsigned char *buf, int len, gcry_sexp_t *pub_key) printf("ret is %d\n", ret); } +static void decode_h_prime(struct hdcp_session_info *info, + const uint8_t *buf, int len) +{ + const uint8_t *start = buf + 1; + int i; + + printf("h_prime: "); + for (i = 0; i < 32; i++) { + printf("%02x", start[i]); + } + printf("\n"); + +} + +static void decode_rx(struct hdcp_session_info *info, + const uint8_t *buf, int len) +{ + /**/ + int msglen = buf[2] | (buf[3] << 8); + int midlen; + + if (buf[0] != 0 || buf[1] != 0) + return; + + if (buf[4] != 0x4 || buf[7] != 0x80) + return; + + /* hdcp packet */ + if (buf[18] != 0x84 && buf[20] != 0x30) + return; + + switch (buf[22]) { + case HDCP_AKE_SEND_CERT: + decode_cert(info, buf + 22, len - 22); + break; + case HDCP_AKE_SEND_RRX: + printf("send rrx\n"); + break; + case HDCP_AKE_SEND_H_PRIME: + decode_h_prime(info, buf + 22, len - 22); + break; + case HDCP_AKE_SEND_PAIRING_INFO: + printf("send pairing info\n"); + break; + } + +} + static int write_to_usb(libusb_device_handle *handle, int endpoint_out, const uint8_t *buf, int len, int *size) { @@ -209,6 +263,9 @@ static int send_buffer(libusb_device_handle *handle, int endpoint_out, int endpo int size; int len2, len; gcry_sexp_t pub_key, km, result; + struct hdcp_session_info info; + + memset(&info, 0, sizeof(info)); dl3_empty_packet(buf, &len); r = write_to_usb(handle, endpoint_out, buf, len, &size); @@ -234,26 +291,19 @@ static int send_buffer(libusb_device_handle *handle, int endpoint_out, int endpo if (r < 0) return r; + decode_rx(&info, buf, size); + r = block_read_usb(handle, endpoint_in, buf, &size); if (r < 0) return r; - /* special cert print */ - printf("{"); - for (i = 0; i < size; i++) { - printf("0x%02x, ", buf[i]); - if ((i % 8) == 7) - printf("\n"); - } - printf("}\n"); - - decode_cert(buf, size, &pub_key); + decode_rx(&info, buf, size); r = create_gcrypt_km(&km, mykm, 16); if (r != 0) fprintf(stderr, "failed to create km\n"); - r = gcry_pk_encrypt(&result, km, pub_key); + r = gcry_pk_encrypt(&result, km, info.pub_key); GCRY_SEXP list = gcry_sexp_find_token( result, "a", 0); @@ -278,6 +328,8 @@ static int send_buffer(libusb_device_handle *handle, int endpoint_out, int endpo r = block_read_usb(handle, endpoint_in, buf, &size); if (r < 0) return r; + decode_rx(&info, buf, size); + /* find H' */ } while (1); return 0; } @@ -336,8 +388,8 @@ int main(int argc, char** argv) { int r; - decode_cert(dplinkcert, 546); -#if 0 + // decode_cert(NULL, dplinkcert, 546); +#if 1 r = libusb_init(NULL); if (r < 0) return r; |