summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dl3.c98
1 files changed, 75 insertions, 23 deletions
diff --git a/dl3.c b/dl3.c
index df09865..38b375d 100644
--- a/dl3.c
+++ b/dl3.c
@@ -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;