├── src ├── r2secrets.arm │ ├── Module.symvers │ ├── r2secr.ko │ ├── include │ │ ├── otp_api.h │ │ ├── rip2_config.h │ │ ├── rip2_common.h │ │ ├── crypto_api.h │ │ ├── crypto_api_target.h │ │ ├── ripdrv.h │ │ ├── rip2_crypto.h │ │ ├── rip_ids.h │ │ └── rip2.h │ ├── Makefile │ └── r2secr.c └── r2secrets.mips │ ├── Makefile │ ├── include │ ├── rip2_config.h │ ├── rip2_crypto.h │ ├── rip_ids.h │ └── rip2.h │ └── r2secr.c ├── lime.arm.4.1.38.ko ├── lime.arm.4.1.52.ko ├── r2secr.mips.2.6.ko ├── r2secr.arm.4.1.38.ko ├── r2secr.arm64.4.1.45.ko ├── lime.arm.3.4.11-rt19.ko ├── lime.arm.4.1.52_p2v8.ko ├── r2secr.arm.3.4.11-rt19.ko ├── r2secr.mips.3.4.11-rt19.ko ├── ripdrv.arm.3.4.11-rt19.ko ├── cfg_dec.py ├── README.md ├── blidec_enhanced.py └── eripv2.py /src/r2secrets.arm/Module.symvers: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lime.arm.4.1.38.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/lime.arm.4.1.38.ko -------------------------------------------------------------------------------- /lime.arm.4.1.52.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/lime.arm.4.1.52.ko -------------------------------------------------------------------------------- /r2secr.mips.2.6.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/r2secr.mips.2.6.ko -------------------------------------------------------------------------------- /r2secr.arm.4.1.38.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/r2secr.arm.4.1.38.ko -------------------------------------------------------------------------------- /r2secr.arm64.4.1.45.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/r2secr.arm64.4.1.45.ko -------------------------------------------------------------------------------- /lime.arm.3.4.11-rt19.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/lime.arm.3.4.11-rt19.ko -------------------------------------------------------------------------------- /lime.arm.4.1.52_p2v8.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/lime.arm.4.1.52_p2v8.ko -------------------------------------------------------------------------------- /r2secr.arm.3.4.11-rt19.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/r2secr.arm.3.4.11-rt19.ko -------------------------------------------------------------------------------- /r2secr.mips.3.4.11-rt19.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/r2secr.mips.3.4.11-rt19.ko -------------------------------------------------------------------------------- /ripdrv.arm.3.4.11-rt19.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/ripdrv.arm.3.4.11-rt19.ko -------------------------------------------------------------------------------- /src/r2secrets.arm/r2secr.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedro-n-rocha/secr/HEAD/src/r2secrets.arm/r2secr.ko -------------------------------------------------------------------------------- /src/r2secrets.arm/include/otp_api.h: -------------------------------------------------------------------------------- 1 | #ifndef __OTP_API_H__ 2 | #define __OTP_API_H__ 3 | 4 | int otp_chipid_read(void); 5 | 6 | #endif /* __OTP_API_H__ */ 7 | 8 | -------------------------------------------------------------------------------- /src/r2secrets.mips/Makefile: -------------------------------------------------------------------------------- 1 | COMPILER=mips-openwrt-linux- 2 | ARCH=mips 3 | 4 | obj-m += r2secr.o 5 | 6 | export STAGING_DIR=/usr/local/src/openwrt_vant-6_gpl/staging_dir/ 7 | 8 | 9 | ccflags-y := -DCC_HAVE_ASM_GOTO -DUSE_IMMEDIATE 10 | 11 | KDIR := /usr/local/src/openwrt_vant-6_gpl/build_dir/target-mips_mips32_uClibc-0.9.33.2/linux-brcm63xx-tch_VANTF/linux-3.4.11/ 12 | 13 | all: 14 | make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) modules 15 | 16 | clean: 17 | make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) clean 18 | -------------------------------------------------------------------------------- /src/r2secrets.arm/Makefile: -------------------------------------------------------------------------------- 1 | #TOOLCHAIN LOCATION = /usr/local/src/openwrt_agtef_gpl/openwrt_agtef_gpl/staging_dir/toolchain-arm_cortex-a9+neon_gcc-4.8-linaro_uClibc-0.9.33.2_eabi/bin 2 | COMPILER=arm-openwrt-linux- 3 | ARCH=arm 4 | export STAGING_DIR=/usr/local/src/openwrt_agtef_gpl/newtry/openwrt_agtef_gpl/staging_dir 5 | 6 | EXTRA_CFLAGS+=-I/usr/local/src/openwrt_agtef_gpl/newtry/openwrt_agtef_gpl/staging_dir/target-arm_cortex-a9+neon_uClibc-0.9.33.2_eabi/usr/include/ 7 | 8 | obj-m += r2secr.o 9 | 10 | KDIR := /usr/local/src/openwrt_agtef_gpl/newtry/openwrt_agtef_gpl/build_dir/target-arm_cortex-a9+neon_uClibc-0.9.33.2_eabi/linux-brcm63xx-tch/linux-3.4.11 11 | 12 | all: 13 | make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) modules 14 | 15 | clean: 16 | make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) clean 17 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/rip2_config.h: -------------------------------------------------------------------------------- 1 | #ifndef RIP2_CONFIG_H 2 | #define RIP2_CONFIG_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern struct mutex rip2_biglock; 12 | 13 | #define ALLOC(size) kmalloc((size), GFP_KERNEL) 14 | #define FREE(ptr) kfree((ptr)) 15 | 16 | #define LOCK() mutex_lock(&rip2_biglock) 17 | #define UNLOCK() mutex_unlock(&rip2_biglock) 18 | 19 | #define ERR(fmt, ...) printk(fmt, ## __VA_ARGS__) 20 | #define INFO(fmt, ...) printk(fmt, ## __VA_ARGS__) 21 | #define DBG(fmt, ...) printk(fmt, ## __VA_ARGS__) 22 | 23 | #ifndef bswap_16 24 | #define bswap_16(x) __cpu_to_be16(x) 25 | #endif 26 | 27 | #ifndef bswap_32 28 | #define bswap_32(x) __cpu_to_be32(x) 29 | #endif 30 | 31 | #endif /* RIP2_CONFIG */ 32 | -------------------------------------------------------------------------------- /src/r2secrets.mips/include/rip2_config.h: -------------------------------------------------------------------------------- 1 | #ifndef RIP2_CONFIG_H 2 | #define RIP2_CONFIG_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern struct mutex rip2_biglock; 12 | 13 | #define ALLOC(size) kmalloc((size), GFP_KERNEL) 14 | #define FREE(ptr) kfree((ptr)) 15 | 16 | #define LOCK() mutex_lock(&rip2_biglock) 17 | #define UNLOCK() mutex_unlock(&rip2_biglock) 18 | 19 | #define ERR(fmt, ...) printk(fmt, ## __VA_ARGS__) 20 | #define INFO(fmt, ...) printk(fmt, ## __VA_ARGS__) 21 | #define DBG(fmt, ...) printk(fmt, ## __VA_ARGS__) 22 | 23 | #ifndef bswap_16 24 | #define bswap_16(x) __cpu_to_be16(x) 25 | #endif 26 | 27 | #ifndef bswap_32 28 | #define bswap_32(x) __cpu_to_be32(x) 29 | #endif 30 | 31 | #endif /* RIP2_CONFIG */ 32 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/rip2_common.h: -------------------------------------------------------------------------------- 1 | #include "rip2_config.h" 2 | 3 | #if defined(__BYTE_ORDER) 4 | #if __BYTE_ORDER == __BIG_ENDIAN 5 | #define HTOBE16(x) (x) 6 | #define HTOBE32(x) (x) 7 | #define BETOH16(x) (x) 8 | #define BETOH32(x) (x) 9 | #elif __BYTE_ORDER == __LITTLE_ENDIAN 10 | #define HTOBE16(x) ( bswap_16(x)) 11 | #define HTOBE32(x) ( bswap_32(x)) 12 | #define BETOH16(x) ( bswap_16(x)) 13 | #define BETOH32(x) ( bswap_32(x)) 14 | #else 15 | #error Please define the correct endianness (__BYTE_ORDER defined) 16 | #endif 17 | #else 18 | #if defined(__BIG_ENDIAN) 19 | #define HTOBE16(x) (x) 20 | #define HTOBE32(x) (x) 21 | #define BETOH16(x) (x) 22 | #define BETOH32(x) (x) 23 | #elif defined (__LITTLE_ENDIAN) 24 | #define HTOBE16(x) ( bswap_16(x)) 25 | #define HTOBE32(x) ( bswap_32(x)) 26 | #define BETOH16(x) ( bswap_16(x)) 27 | #define BETOH32(x) ( bswap_32(x)) 28 | #else 29 | #error Please define the correct endianness (__BYTE_ORDER not defined) 30 | #endif 31 | #endif 32 | 33 | 34 | int rip2_crypto_init(uint8_t *ripStart); 35 | 36 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/crypto_api.h: -------------------------------------------------------------------------------- 1 | #ifndef __CRYPTO_API_H__ 2 | #define __CRYPTO_API_H__ 3 | 4 | #define RSA_KEYFORMAT_2048_PUBLICMODULUSONLY 2 5 | #define RSA_KEYFORMAT_1024_PUBLICMODULUSONLY 3 6 | 7 | int aes_create_crypto(unsigned char *iv, unsigned char *key, int key_len_bits, void *crypto_ctx, int size_of_ctx); 8 | int aes_encrypt_blocks(void *crypto_ctx, unsigned char *idata, unsigned int numBytes, unsigned char *odata); 9 | int aes_decrypt_blocks(void *crypto_ctx, unsigned char *idata, unsigned int numBytes, unsigned char *odata); 10 | int aes_destroy_crypto(void *crypto_ctx, int size_of_ctx); 11 | 12 | int rsa_create_crypto(unsigned char *key, 13 | int keyformat, 14 | void *crypto_ctx, 15 | int size_of_ctx); 16 | int rsa_delete_crypto(void *crypto_ctx); 17 | 18 | int rsa_verifysig_pss_sha256(void *crypto_ctx, 19 | unsigned char *sig, 20 | int siglen, 21 | unsigned char *data, 22 | int datalen); 23 | 24 | void random_get_data(unsigned char *buf, int len); 25 | 26 | #include "crypto_api_target.h" 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/crypto_api_target.h: -------------------------------------------------------------------------------- 1 | 2 | #define CAPI_MAX_ENC_CTX_SIZE 632 /* AES (Rijndael keyInstance * 2) */ 3 | #define CAPI_MAX_AUTH_CTX_SIZE 256 4 | 5 | #define MIN_RSA_MODULUS_BITS 508 6 | #define MAX_RSA_MODULUS_BITS 2048 7 | #define MAX_RSA_MODULUS_LEN ((MAX_RSA_MODULUS_BITS + 7) / 8) 8 | 9 | #define RSA_MODULUS_LEN 256 10 | #define RSA_PRIME_LEN 128 11 | 12 | typedef struct { 13 | unsigned int bits; /* length in bits of modulus */ 14 | unsigned char modulus[RSA_MODULUS_LEN]; /* modulus */ 15 | unsigned char exponent[RSA_MODULUS_LEN]; /* public exponent */ 16 | } R_RSA_PUBLIC_KEY; 17 | 18 | typedef struct { 19 | unsigned int bits; /* length in bits of modulus */ 20 | unsigned char modulus[RSA_MODULUS_LEN]; /* modulus */ 21 | unsigned char publicExponent[RSA_MODULUS_LEN]; /* public exponent */ 22 | unsigned char exponent[RSA_MODULUS_LEN]; /* private exponent */ 23 | unsigned char prime[2][RSA_PRIME_LEN]; /* prime factors */ 24 | unsigned char primeExponent[2][RSA_PRIME_LEN]; /* exponents for CRT */ 25 | unsigned char coefficient[RSA_PRIME_LEN]; /* CRT coefficient */ 26 | } R_RSA_PRIVATE_KEY; 27 | 28 | #define RSA_CTX_SIZE (sizeof(R_RSA_PRIVATE_KEY) + 4) 29 | 30 | #define IV_LENGTH 16 31 | 32 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/ripdrv.h: -------------------------------------------------------------------------------- 1 | /************** COPYRIGHT AND CONFIDENTIALITY INFORMATION ********************* 2 | ** ** 3 | ** Copyright (c) 2012 Technicolor ** 4 | ** All Rights Reserved ** 5 | ** ** 6 | ** This program contains proprietary information which is a trade ** 7 | ** secret of TECHNICOLOR and/or its affiliates and also is protected as ** 8 | ** an unpublished work under applicable Copyright laws. Recipient is ** 9 | ** to retain this program in confidence and is not permitted to use or ** 10 | ** make copies thereof other than as permitted in a written agreement ** 11 | ** with TECHNICOLOR, UNLESS OTHERWISE EXPRESSLY ALLOWED BY APPLICABLE LAWS. ** 12 | ** ** 13 | ******************************************************************************/ 14 | 15 | 16 | /** @file 17 | * 18 | * File containing kernel API to access the Remote Inventory Parameters (RIP). 19 | */ 20 | 21 | #ifndef __RIPDRV_H__ 22 | #define __RIPDRV_H__ 23 | 24 | /* contains definitions for the linux ioctl routines for the rip 25 | * (Remote Inventory PROM) 26 | * 27 | */ 28 | #include 29 | 30 | #define RIP_DEVICE "/dev/rip" 31 | #define RIP_IOC_MAGIC 'D' /* same as asm-s390/dasd.h but unlikely to be conflicting */ 32 | 33 | /* ioctl definitions for rip access */ 34 | #define RIP_IOCTL_READ _IOWR(RIP_IOC_MAGIC, 1, int) 35 | #define RIP_IOCTL_WRITE _IOWR(RIP_IOC_MAGIC, 2, int) 36 | #define RIP_IOCTL_FLAGS _IOWR(RIP_IOC_MAGIC, 3, int) 37 | #define RIP_IOCTL_LOCK _IOWR(RIP_IOC_MAGIC, 4, int) 38 | 39 | typedef struct rip_ioctl_data 40 | { 41 | unsigned long len; 42 | unsigned short id; 43 | unsigned char *data; 44 | unsigned long attrHi; 45 | unsigned long attrLo; 46 | } rip_ioctl_data_t; 47 | 48 | #endif //__RIPDRV_H__ 49 | -------------------------------------------------------------------------------- /cfg_dec.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | ################################################################ 3 | # surrealiz3 4 | ################################################################ 5 | # 6 | # grab you encrypted config file 7 | # grab RIP_ID_RANDOM_KEY_B_0x0108-... from eripv2 parser 8 | # python ../cfg_dec.py --randb RIP_ID_RANDOM_KEY_B_0x0108-... --cfg config.bin 9 | # find config.bin.plain decrypted 10 | # 11 | # 12 | 13 | 14 | from hexdump import hexdump 15 | from Crypto.Cipher import AES 16 | from hashlib import sha1 17 | import hmac 18 | import argparse 19 | 20 | parser = argparse.ArgumentParser() 21 | 22 | parser.add_argument('--randb' , help='',required=True) 23 | parser.add_argument('--cfg' , help='',required=True) 24 | args = parser.parse_args() 25 | tmp = vars(args) 26 | 27 | fnrandb = tmp['randb'] 28 | fncfg = tmp['cfg'] 29 | 30 | fcfg = open(fncfg,'rb') 31 | 32 | 33 | print("-------------------------------- HDR ---------------------") 34 | l = fcfg.readline() 35 | hexdump(l) 36 | while l: 37 | l = fcfg.readline() 38 | hexdump(l) 39 | if l == b"\n": 40 | stcry = fcfg.tell() 41 | break 42 | print("") 43 | 44 | fcfg.seek(0) 45 | 46 | cfg = fcfg.read() 47 | fcfg.close() 48 | 49 | frandb = open(fnrandb, 'rb') 50 | randb = frandb.read() 51 | frandb.close() 52 | 53 | randb_key = randb[0:32] 54 | print("-------------------------------- AESk --------------------") 55 | hexdump(randb_key) 56 | print("") 57 | 58 | randb_sigk = randb[0:64] 59 | 60 | print("-------------------------------- SIGk --------------------") 61 | hexdump(randb_sigk) 62 | print("") 63 | 64 | cfg_crypt_blk = cfg[stcry:-20] 65 | IV = cfg_crypt_blk[0:16] 66 | 67 | cfg_digest_blk = cfg[-20:] 68 | print("-------------------------------- DIGST -------------------") 69 | hexdump(cfg_digest_blk) 70 | print("") 71 | 72 | aes = AES.new(randb_key, AES.MODE_CBC, IV) 73 | dec = aes.decrypt(cfg_crypt_blk[16:]) 74 | 75 | hash = hmac.new(randb_sigk,cfg[:-20],sha1) 76 | digst = hash.digest() 77 | 78 | print("-------------------------------- CDIGST ------------------") 79 | hexdump(digst) 80 | print("") 81 | 82 | if cfg_digest_blk != digst: 83 | print(" [*] !!! HMAC-SHA1 failed ,something is wrong or no sig check is required !!! check plain contents") 84 | 85 | print("\n [*] dumping to file: %s" % fncfg + ".plain\n") 86 | f = open(fncfg+'.plain','wb') 87 | f.write(cfg[:stcry]) 88 | f.write(dec) 89 | f.close 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/r2secrets.arm/r2secr.c: -------------------------------------------------------------------------------- 1 | #include /* Needed by all modules */ 2 | #include /* Needed for KERN_INFO */ 3 | #include 4 | 5 | #include "include/rip_ids.h" 6 | #include "include/rip2_crypto.h" 7 | 8 | 9 | #define __ASM_ARCH_MEMORY_H 10 | #define PHYS_OFFSET UL(0x00000000) 11 | static inline void * rip2_crypto_phys_to_virt (void *p) 12 | { 13 | return (void*)(phys_to_virt((unsigned long)p)); 14 | } 15 | 16 | 17 | void DumpHex(const void* data, size_t size) { 18 | char ascii[17]; 19 | size_t i, j; 20 | ascii[16] = '\0'; 21 | for (i = 0; i < size; ++i) { 22 | printk("%02X ", ((unsigned char*)data)[i]); 23 | if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { 24 | ascii[i % 16] = ((unsigned char*)data)[i]; 25 | } else { 26 | ascii[i % 16] = '.'; 27 | } 28 | if ((i+1) % 8 == 0 || i+1 == size) { 29 | printk(" "); 30 | if ((i+1) % 16 == 0) { 31 | printk("| %s \n", ascii); 32 | } else if (i+1 == size) { 33 | ascii[(i+1) % 16] = '\0'; 34 | if ((i+1) % 16 <= 8) { 35 | printk(" "); 36 | } 37 | for (j = (i+1) % 16; j < 16; ++j) { 38 | printk(" "); 39 | } 40 | printk("| %s \n", ascii); 41 | } 42 | } 43 | } 44 | } 45 | 46 | 47 | static int __init k_module_init(void) 48 | { 49 | extern unsigned char *r2secr; 50 | unsigned char * data_ptr; 51 | Rip2Secrets *r2secr_struct = (Rip2Secrets *)(rip2_crypto_phys_to_virt(r2secr)); 52 | 53 | printk("r2secr : %lx \n" , (unsigned long ) r2secr ) ; 54 | printk("r2secr_struct : %lx \n" , (unsigned long ) r2secr_struct ) ; 55 | printk("r2secr_struct->magic : %lx \n" , (unsigned long ) r2secr_struct->magic ) ; 56 | printk("r2secr_struct->items : %lx \n" , (unsigned long ) r2secr_struct->items ) ; 57 | 58 | Rip2SecretsItem *nextFreeItem = r2secr_struct->items; 59 | 60 | while(nextFreeItem->id != 0 ){ 61 | 62 | printk("nextFreeItem->id : %x \n" , nextFreeItem->id ) ; 63 | printk("nextFreeItem->length : %d \n" , nextFreeItem->length ) ; 64 | printk("nextFreeItem->data : %lx \n" ,(unsigned long) nextFreeItem->data ) ; 65 | data_ptr = rip2_crypto_phys_to_virt(nextFreeItem->data); 66 | 67 | printk("data_ptr : %lx \n" ,(unsigned long) data_ptr ) ; 68 | DumpHex(data_ptr,nextFreeItem->length); 69 | 70 | //for( i = 0 ; i < nextFreeItem->length ; i++ ) 71 | // printk("%x",nextFreeItem->data[i]); 72 | 73 | ++nextFreeItem; 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | static void __exit k_module_cleanup(void) 80 | { 81 | printk(KERN_INFO "module cleanup \n"); 82 | } 83 | 84 | module_init(k_module_init); 85 | module_exit(k_module_cleanup); 86 | MODULE_LICENSE("GPL"); 87 | -------------------------------------------------------------------------------- /src/r2secrets.mips/r2secr.c: -------------------------------------------------------------------------------- 1 | #include /* Needed by all modules */ 2 | #include /* Needed for KERN_INFO */ 3 | #include 4 | 5 | #include "include/rip_ids.h" 6 | #include "include/rip2_crypto.h" 7 | 8 | 9 | #define rip2_crypto_phys_to_virt 10 | 11 | 12 | 13 | void DumpHex(const void* data, size_t size) { 14 | char ascii[17]; 15 | size_t i, j; 16 | ascii[16] = '\0'; 17 | for (i = 0; i < size; ++i) { 18 | printk("%02X ", ((unsigned char*)data)[i]); 19 | if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { 20 | ascii[i % 16] = ((unsigned char*)data)[i]; 21 | } else { 22 | ascii[i % 16] = '.'; 23 | } 24 | if ((i+1) % 8 == 0 || i+1 == size) { 25 | printk(" "); 26 | if ((i+1) % 16 == 0) { 27 | printk("| %s \n", ascii); 28 | } else if (i+1 == size) { 29 | ascii[(i+1) % 16] = '\0'; 30 | if ((i+1) % 16 <= 8) { 31 | printk(" "); 32 | } 33 | for (j = (i+1) % 16; j < 16; ++j) { 34 | printk(" "); 35 | } 36 | printk("| %s \n", ascii); 37 | } 38 | } 39 | } 40 | } 41 | 42 | 43 | 44 | static int __init k_module_init(void) 45 | { 46 | extern unsigned char *r2secr; 47 | 48 | unsigned char * data_ptr; 49 | 50 | Rip2Secrets *r2secr_struct = (Rip2Secrets *)(rip2_crypto_phys_to_virt(r2secr)); 51 | //int i = 0 ; 52 | //uint32_t length; 53 | //char tmp[256 + 256 + 16]; /* Allocate for data + cryptopadding + signature */ 54 | 55 | printk("r2secr : %lx \n" , (unsigned long ) r2secr ) ; 56 | printk("r2secr_struct : %lx \n" , (unsigned long ) r2secr_struct ) ; 57 | printk("r2secr_struct->magic : %lx \n" , (unsigned long ) r2secr_struct->magic ) ; 58 | printk("r2secr_struct->items : %lx \n" , (unsigned long ) r2secr_struct->items ) ; 59 | 60 | 61 | Rip2SecretsItem *nextFreeItem = r2secr_struct->items; 62 | 63 | while(nextFreeItem->id != 0 ){ 64 | 65 | printk("nextFreeItem->id : %x \n" , nextFreeItem->id ) ; 66 | printk("nextFreeItem->length : %d \n" , nextFreeItem->length ) ; 67 | printk("nextFreeItem->data : %lx \n" ,(unsigned long) nextFreeItem->data ) ; 68 | data_ptr = rip2_crypto_phys_to_virt(nextFreeItem->data); 69 | 70 | printk("data_ptr : %lx \n" ,(unsigned long) data_ptr ) ; 71 | DumpHex(data_ptr,nextFreeItem->length); 72 | 73 | //for( i = 0 ; i < nextFreeItem->length ; i++ ) 74 | // printk("%x",nextFreeItem->data[i]); 75 | 76 | ++nextFreeItem; 77 | } 78 | 79 | 80 | 81 | return 0; 82 | } 83 | 84 | static void __exit k_module_cleanup(void) 85 | { 86 | printk(KERN_INFO "module cleanup \n"); 87 | } 88 | 89 | module_init(k_module_init); 90 | module_exit(k_module_cleanup); 91 | MODULE_LICENSE("GPL"); 92 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/rip2_crypto.h: -------------------------------------------------------------------------------- 1 | /************** COPYRIGHT AND CONFIDENTIALITY INFORMATION ********************* 2 | ** ** 3 | ** Copyright (c) 2012 Technicolor ** 4 | ** All Rights Reserved ** 5 | ** ** 6 | ** This program contains proprietary information which is a trade ** 7 | ** secret of TECHNICOLOR and/or its affiliates and also is protected as ** 8 | ** an unpublished work under applicable Copyright laws. Recipient is ** 9 | ** to retain this program in confidence and is not permitted to use or ** 10 | ** make copies thereof other than as permitted in a written agreement ** 11 | ** with TECHNICOLOR, UNLESS OTHERWISE EXPRESSLY ALLOWED BY APPLICABLE LAWS. ** 12 | ** ** 13 | ** Programmer(s) : Gino Peeters (email : gino.peeters@technicolor.com) ** 14 | ** ** 15 | ******************************************************************************/ 16 | 17 | #include "rip2.h" 18 | 19 | #define INTEGRKEYSIZE 256 20 | #define CONFIDKEYSIZE 16 21 | 22 | typedef struct crypt_key_t { 23 | int length; /* in bytes */ 24 | unsigned char *key; /* Only pointers; we don't to copy the BEK */ 25 | unsigned char *iv; 26 | } crypt_key; 27 | 28 | #define SKIP_SIGNATURE_CHECK ((unsigned char *) 0xFFFFFFFE) 29 | 30 | typedef struct sign_key_t { 31 | int length; /* in bytes*/ 32 | unsigned char *key; 33 | } sign_key; 34 | 35 | extern crypt_key bek; 36 | extern crypt_key eck; 37 | extern sign_key eik; 38 | extern sign_key mcv; 39 | 40 | #define RIP2SECRETSMAGIC 0xD104EA5B 41 | 42 | typedef struct { 43 | T_RIP2_ID id; 44 | uint32_t length; 45 | unsigned char *data; 46 | } Rip2SecretsItem; 47 | 48 | typedef struct { 49 | unsigned int magic; 50 | unsigned int version; 51 | Rip2SecretsItem items[]; 52 | } Rip2Secrets; 53 | 54 | /* 55 | * Initializes the rip2 crypto module 56 | * IN: ripStart: reference address for all RIPv2 actions (usually beginning of the flash) 57 | * 58 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_BADCRYPTO upon error. 59 | */ 60 | int rip2_crypto_init(uint8_t *ripStart); 61 | 62 | /* 63 | * Verifies whether all cryptographic requirements of the eRIPv2 are met 64 | * IN: ripStart: reference address for all RIPv2 actions (usually beginning of the flash) 65 | * 66 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_BADCRYPTO upon error. 67 | */ 68 | int rip2_crypto_check(uint8_t *ripStart); 69 | 70 | /* 71 | * Stores the keys to be passed to the OS in ram, and returns a pointer to this data 72 | * 73 | * RETURNS: pointer when successful, 0 upon error 74 | */ 75 | unsigned char *rip2_crypto_pass_linux(void); 76 | 77 | int rip2_crypto_import_eik(unsigned char *data, int length); 78 | int rip2_crypto_import_eck(unsigned char *data, int length); 79 | 80 | /* 81 | * Process an item with a crypto attribute set; processing means checking the signature and/or 82 | * decrypting the item. 83 | * IN: data: the raw data (signed/crypted) as found in the eRIPv2 sector 84 | * length: total length of the raw data; on successful return this becomes the real length 85 | * crypto_attr: the cryptographic attributes 86 | * 87 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_BADCRYPTO upon error. 88 | */ 89 | int rip2_crypto_process(uint8_t *data, 90 | uint32_t *length, 91 | uint32_t crypto_attr, 92 | T_RIP2_ID id); 93 | 94 | int rip2_crypto_encrypt_with_ECK (uint8_t *data, uint32_t *length); 95 | 96 | -------------------------------------------------------------------------------- /src/r2secrets.mips/include/rip2_crypto.h: -------------------------------------------------------------------------------- 1 | /************** COPYRIGHT AND CONFIDENTIALITY INFORMATION ********************* 2 | ** ** 3 | ** Copyright (c) 2012 Technicolor ** 4 | ** All Rights Reserved ** 5 | ** ** 6 | ** This program contains proprietary information which is a trade ** 7 | ** secret of TECHNICOLOR and/or its affiliates and also is protected as ** 8 | ** an unpublished work under applicable Copyright laws. Recipient is ** 9 | ** to retain this program in confidence and is not permitted to use or ** 10 | ** make copies thereof other than as permitted in a written agreement ** 11 | ** with TECHNICOLOR, UNLESS OTHERWISE EXPRESSLY ALLOWED BY APPLICABLE LAWS. ** 12 | ** ** 13 | ** Programmer(s) : Gino Peeters (email : gino.peeters@technicolor.com) ** 14 | ** ** 15 | ******************************************************************************/ 16 | 17 | #include "rip2.h" 18 | 19 | #define INTEGRKEYSIZE 256 20 | #define CONFIDKEYSIZE 16 21 | 22 | typedef struct crypt_key_t { 23 | int length; /* in bytes */ 24 | unsigned char *key; /* Only pointers; we don't to copy the BEK */ 25 | unsigned char *iv; 26 | } crypt_key; 27 | 28 | #define SKIP_SIGNATURE_CHECK ((unsigned char *) 0xFFFFFFFE) 29 | 30 | typedef struct sign_key_t { 31 | int length; /* in bytes*/ 32 | unsigned char *key; 33 | } sign_key; 34 | 35 | extern crypt_key bek; 36 | extern crypt_key eck; 37 | extern sign_key eik; 38 | extern sign_key mcv; 39 | 40 | #define RIP2SECRETSMAGIC 0xD104EA5B 41 | 42 | typedef struct { 43 | T_RIP2_ID id; 44 | uint32_t length; 45 | unsigned char *data; 46 | } Rip2SecretsItem; 47 | 48 | typedef struct { 49 | unsigned int magic; 50 | unsigned int version; 51 | Rip2SecretsItem items[]; 52 | } Rip2Secrets; 53 | 54 | /* 55 | * Initializes the rip2 crypto module 56 | * IN: ripStart: reference address for all RIPv2 actions (usually beginning of the flash) 57 | * 58 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_BADCRYPTO upon error. 59 | */ 60 | int rip2_crypto_init(uint8_t *ripStart); 61 | 62 | /* 63 | * Verifies whether all cryptographic requirements of the eRIPv2 are met 64 | * IN: ripStart: reference address for all RIPv2 actions (usually beginning of the flash) 65 | * 66 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_BADCRYPTO upon error. 67 | */ 68 | int rip2_crypto_check(uint8_t *ripStart); 69 | 70 | /* 71 | * Stores the keys to be passed to the OS in ram, and returns a pointer to this data 72 | * 73 | * RETURNS: pointer when successful, 0 upon error 74 | */ 75 | unsigned char *rip2_crypto_pass_linux(void); 76 | 77 | int rip2_crypto_import_eik(unsigned char *data, int length); 78 | int rip2_crypto_import_eck(unsigned char *data, int length); 79 | 80 | /* 81 | * Process an item with a crypto attribute set; processing means checking the signature and/or 82 | * decrypting the item. 83 | * IN: data: the raw data (signed/crypted) as found in the eRIPv2 sector 84 | * length: total length of the raw data; on successful return this becomes the real length 85 | * crypto_attr: the cryptographic attributes 86 | * 87 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_BADCRYPTO upon error. 88 | */ 89 | int rip2_crypto_process(uint8_t *data, 90 | uint32_t *length, 91 | uint32_t crypto_attr, 92 | T_RIP2_ID id); 93 | 94 | int rip2_crypto_encrypt_with_ECK (uint8_t *data, uint32_t *length); 95 | 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | secr 3 | 4 | ################################################################ 5 | 6 | disclaimer : use at your own risk 7 | 8 | ** How to dump device keys and secrets 9 | 10 | 1. Get a USB stick and copy all the .ko files to it 11 | 12 | 2. Connect a USB drive to the router and config that it is mounted correctly i.e. 13 | ``` 14 | root@mygateway:~# ls -la /mnt/usb/USB-*/*.ko 15 | -rwxrwxrwx 1 root root ?0638 Dec 23 2018 /mnt/usb/USB-A1/lime.???.ko 16 | -rwxrwxrwx 1 root root ?531 Dec 23 2018 /mnt/usb/USB-A1/r2secr.???.ko 17 | -rwxrwxrwx 1 root root ?7183 Dec 23 2018 /mnt/usb/USB-A1/ripdrv.???.ko 18 | root@mygateway:~# 19 | ``` 20 | 21 | 3. Change current directory to USB mountpoint: 22 | ``` 23 | cd /mnt/usb/USB-A1/ 24 | ``` 25 | 26 | 4. Check your kernel version: 27 | ``` 28 | uname -a 29 | ``` 30 | 31 | 5. Try grabbing your ECKey using r2secr: 32 | 33 | On ARM (e.g. linux 4.1.38): 34 | ``` 35 | insmod r2secr.arm.4.1.38.ko && dmesg | tail -n 20 && rmmod r2secr 36 | ``` 37 | 38 | On ARM (if linux 3.4.11-rt19): 39 | ``` 40 | insmod r2secr.arm.3.4.11-rt19.ko && dmesg | tail -n 20 && rmmod r2secr 41 | ``` 42 | 43 | On MIPS (if linux 3.4.11-rt19): 44 | ``` 45 | insmod r2secr.mips.3.4-rt19.ko && dmesg | tail -n 20 && rmmod r2secr 46 | ``` 47 | 48 | On MIPS (if linux 2.6): 49 | ``` 50 | insmod r2secr.mips.2.6.ko && dmesg | tail -n 20 && rmmod r2secr 51 | ``` 52 | 53 | Same for other versions available in this repo. If you can't find a valid module for your platform, please, compile it and share it here ;-) 54 | 55 | If it worked you will get output like: 56 | ``` 57 | root@mygateway:/tmp/run/mountd/sda1# insmod r2secr.mips.3.4.ko && dmesg | tail -n 10 && rmmod r2secr 58 | [ 2554.482000] module cleanup 59 | [ 2574.716000] r2secr : affdf800 60 | [ 2574.719000] r2secr_struct : affdf800 61 | [ 2574.726000] r2secr_struct->magic : d104ea5b 62 | [ 2574.731000] r2secr_struct->items : affdf808 63 | [ 2574.735000] nextFreeItem->id : 11f 64 | [ 2574.738000] nextFreeItem->length : 16 65 | [ 2574.742000] nextFreeItem->data : affdf820 66 | [ 2574.747000] data_ptr : affdf820 67 | [ 2574.750000] XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ 68 | root@mygateway:/tmp/run/mountd/sda1# 69 | ``` 70 | 71 | If it didn't you need to grab a full RAM dump with LiME and take the ECKey from it. 72 | Read further in this page about how to to it. 73 | 74 | 6. Grab your eripv2 partition (mtd5 normally, confirm with 'cat /proc/mtd') for offline processing (should go to USB stick if steps have been followed) 75 | ``` 76 | cd /mnt/usb/USB-A1/ 77 | dd if=/dev/mtd5 of=mtd5.dump 78 | ``` 79 | 80 | 7. Copy it to a computer where you are able to run this python script with the key from above (with quotes if you keep spaces) 81 | ``` 82 | python3 eripv2.py --eripv2 mtd5.dump --eckey "XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX" 83 | ``` 84 | 85 | The secrets will be displayed on screen and dumped unencrypted contents to files ( messy :P ) 86 | OSCK key file is of relevance to decrypt encrypted rbi files with another script 87 | Relevant : 88 | OSCK 89 | OSIK 90 | EIK 91 | 92 | ** How to decrypt RBI firmwares 93 | 94 | 1. Copy RIP_ID_OSCK_0x0121-... to BOARD_NAME.osck 95 | 96 | 2. Use blidec_enhanced.py with .osck file from last step and .rbi firmware to decrypt to .bin 97 | ``` 98 | python3 blidec_enhanced.py --osck BOARD_NAME.osck --rbi my_firmware.rbi 99 | ``` 100 | 101 | 3. Inspect .bin root file system using 7-Zip or binwalk 102 | 103 | ** How to dump memory on newer platforms with LiME 104 | On some newer firmwares /dev/mem is not exposed or r2secr kernel symbol is not exported. You need to search for your ECKey into the full RAM dump made with LiME 105 | 106 | On ARM (if Linux 3.4.11-rt19): 107 | ``` 108 | # Double check the "path=..." exists before running this command 109 | insmod lime.arm.3.4.11-rt19.ko "path="/tmp/run/mountd/sda1/ram.dump" format=raw" 110 | ``` 111 | 112 | [Read more about LiME usage on 504ensicsLabs/LiME.](https://github.com/504ensicsLabs/LiME) 113 | 114 | 115 | ** How to expose all rip values in /proc 116 | ``` 117 | rmmod keymanager 118 | rmmod ripdrv 119 | insmod ripdrv.arm.3.4.ko 120 | ``` 121 | 122 | All private cryptos exposed now at /proc/rip 123 | EFU stuff at /proc/efu 124 | -------------------------------------------------------------------------------- /blidec_enhanced.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | #Decrypt script by Kbios 4 | #Modified by Ansuel 5 | 6 | print("DecryptScript creato da Ansuel && Kbios and enhanced by some random strangers :)") 7 | 8 | import sys, struct, zlib, binascii, hexdump, argparse 9 | 10 | try: 11 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 12 | from cryptography.hazmat.backends import default_backend 13 | 14 | except ImportError or ModuleNotFoundError: 15 | print("The Cryptography module is missing") 16 | install=input("Install? (Y/n): ") 17 | if install == "" or install == "Y" or install == "y": 18 | import pip 19 | 20 | pip.main(["install", "cryptography" ]) 21 | 22 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 23 | from cryptography.hazmat.backends import default_backend 24 | else: 25 | print("This script can't run without the modules installed.") 26 | input() 27 | sys.exit(1) 28 | 29 | def dumptofile( file , newext, data ): 30 | output_name = file[:(file.find(".rbi"))]+newext 31 | output_file = open(output_name,"w+b") 32 | output_file.write(data) 33 | output_file.close() 34 | 35 | def decrypt( file , key, debug=False ): 36 | datafile = open( file, "rb") 37 | globalheader = datafile.read(0x134) 38 | if debug: 39 | print('globalheader: ') 40 | hexdump.hexdump(globalheader) 41 | payloadstart = struct.unpack_from(">H", globalheader, 0x2A)[0] 42 | datafile.seek(payloadstart) 43 | data = datafile.read() 44 | 45 | while True: 46 | payloadtype = data[0] 47 | print("Layer type %X being handled" % payloadtype) 48 | if payloadtype == 0xB0: # cleartext 49 | if debug: 50 | dumptofile(file, "_B0cleartext.bin", data) 51 | data = data[1+4+1:] 52 | break 53 | elif payloadtype == 0xB8: # sha256 54 | if debug: 55 | dumptofile(file, "_B8sha265.bin", data) 56 | data = data[1+4+1+4+32:] 57 | elif payloadtype == 0xB4: # zip 58 | if debug: 59 | dumptofile(file, "_B4zip.bin", data) 60 | data = zlib.decompress(data[1+4+1+4:]) 61 | elif payloadtype == 0xB7: # aes256 62 | if debug: 63 | dumptofile(file, "_B7aes256.bin", data) 64 | if key is None: 65 | print("osck not provided - fail", file=sys.stderr) 66 | sys.exit(1) 67 | data = data[1+4+1+4:] # "\xB7" % "MUTE" % "\n" % payloadSize 68 | iv = data[:16] 69 | if debug: 70 | print('iv1: ') 71 | hexdump.hexdump(iv) 72 | keydata = data[16:64] 73 | if debug: 74 | print('keydata1: ') 75 | hexdump.hexdump(keydata) 76 | backend = default_backend() 77 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 78 | decryptor = cipher.decryptor() 79 | keydata = decryptor.update(keydata) + decryptor.finalize() 80 | if debug: 81 | print('keydata2: ') 82 | hexdump.hexdump(keydata) 83 | key = keydata[:-keydata[-1]] 84 | if debug: 85 | print('key2: ') 86 | hexdump.hexdump(key) 87 | iv = data[64:80] 88 | if debug: 89 | print('iv2: ') 90 | hexdump.hexdump(iv) 91 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) 92 | decryptor = cipher.decryptor() 93 | data = decryptor.update(data[80:]) + decryptor.finalize() 94 | data = data[:-data[-1]] 95 | else: 96 | raise Exception("There is no handler for this payload type. Is the decyption key correct?") 97 | 98 | dumptofile(file, ".bin", data) 99 | 100 | print("Decrypted file saved as .bin") 101 | print("Use binwalk on this file to extract") 102 | 103 | 104 | def _main(): 105 | try: 106 | parser = argparse.ArgumentParser() 107 | parser.add_argument('--rbi', help='.rbi firmware file name') 108 | parser.add_argument('--osckey', help='key file for your board') 109 | parser.add_argument('--debug', help='dump every BLI layer into separate file') 110 | args = parser.parse_args() 111 | file=vars(args)['rbi'].replace('"', '').strip() 112 | debug=False if vars(args)['debug'] == None else True 113 | 114 | if file != "" and file.endswith("rbi"): 115 | keyfile=vars(args)['osckey'].replace('"', '').strip() 116 | if keyfile != "" and ( keyfile.endswith(".osck") or keyfile.endswith(".osckhex") ): 117 | if keyfile.endswith(".osck"): 118 | f = open(keyfile, 'r+b') 119 | keydata = f.read() 120 | f.close() 121 | elif keyfile.endswith(".osckhex"): 122 | f = open(keyfile, 'r+b') 123 | keydata = binascii.unhexlify(f.read()) 124 | f.close() 125 | else: 126 | raise Exception("Sorry but '" + keyfile + "' is an invalid filename") 127 | 128 | return decrypt(file , keydata, debug) 129 | else: 130 | print("Invalid file name") 131 | except KeyboardInterrupt: 132 | print("Program Terminated") 133 | 134 | _main() 135 | 136 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/rip_ids.h: -------------------------------------------------------------------------------- 1 | /************** COPYRIGHT AND CONFIDENTIALITY INFORMATION ********************* 2 | ** ** 3 | ** Copyright (c) 2012 Technicolor ** 4 | ** All Rights Reserved ** 5 | ** ** 6 | ** This program contains proprietary information which is a trade ** 7 | ** secret of TECHNICOLOR and/or its affiliates and also is protected as ** 8 | ** an unpublished work under applicable Copyright laws. Recipient is ** 9 | ** to retain this program in confidence and is not permitted to use or ** 10 | ** make copies thereof other than as permitted in a written agreement ** 11 | ** with TECHNICOLOR, UNLESS OTHERWISE EXPRESSLY ALLOWED BY APPLICABLE LAWS. ** 12 | ** ** 13 | ******************************************************************************/ 14 | 15 | /** @file 16 | * 17 | * File containing identifiers for items in the Remote Inventory Parameters (RIP). 18 | */ 19 | 20 | #ifndef __RIP_IDS_H__ 21 | #define __RIP_IDS_H__ 22 | 23 | #define RIP_ID_LOWER_CHECKSUM 0x0000 /**< RIP CheckSum */ 24 | #define RIP_ID_UNPROT_FREE1 0x0002 /**< Customization Pattern */ 25 | #define RIP_ID_PART_NBR_VARIANT 0x0004 /**< PBA Code */ 26 | #define RIP_ID_ICS 0x0010 /**< PBA ICS */ 27 | #define RIP_ID_BOARD_SERIAL_NBR 0x0012 /**< PBA Serial nr */ 28 | #define RIP_ID_FACTORY_RELEASE_DATE 0x0022 /**< Product Date */ 29 | #define RIP_ID_FIA 0x0028 /**< FIA code */ 30 | #define RIP_ID_HANDOVER_DATE 0x002C /**< Repair Date */ 31 | #define RIP_ID_LAN_ADDR 0x0032 /**< Ethernet MAC */ 32 | #define RIP_ID_COMPANY_ID 0x0038 /**< Company ID */ 33 | #define RIP_ID_FACTORY_ID 0x003C /**< Factory ID */ 34 | #define RIP_ID_BOARD_NAME 0x0040 /**< Board Name */ 35 | #define RIP_ID_MEMORY_CONFIG 0x0048 /**< Memory Configuration */ 36 | #define RIP_ID_USB_LAN_ADDR 0x004C /**< USB MAC address */ 37 | #define RIP_ID_MODEM_ACCESS_CODE 0x0083 /**< Access Code */ 38 | #define RIP_ID_SECURE_REMOTE_MANG_PASWD 0x0088 /**< Remote Mgr Pwd */ 39 | #define RIP_ID_WLAN_LAN_ADDR 0x008D /**< WiFi MAC */ 40 | 41 | #define RIP_ID_PUBLIC_DSA_SYST 0x0100 /**< DSA Public Key, for Regular Firmware Signature */ 42 | #define RIP_ID_PUBLIC_DSA_RESC 0x0101 /**< DSA Public Key, for Rescue Firmware Signature */ 43 | #define RIP_ID_MODELNAME 0x0102 /**< String, Represents the board (ex: Livebox Mini...) */ 44 | #define RIP_ID_PRODUCT_CLASS 0x0103 /**< String, Represents the product type (ex: Livebox, Livebox2...) */ 45 | #define RIP_ID_LB_CLIENT_CERTIFICATE 0x0104 /**< PEM (x509v3), Unique Device Certificate */ 46 | #define RIP_ID_PRIVATE_KEY 0x0105 /**< PEM (PKCS#1), RSA Private Key (unique per device) */ 47 | #define RIP_ID_H235_KEY 0x0106 /**< String, Secret Key (unique per device) for voice activation */ 48 | #define RIP_ID_RANDOM_KEY_A 0x0107 /**< Random number 1 (256 bit) */ 49 | #define RIP_ID_RANDOM_KEY_B 0x0108 /**< Random number 2 (512 bit) */ 50 | #define RIP_ID_KEY_PWD 0x0109 /**< Key password, will return if possible RANDOM_KEY_A or a RIP calculated key */ 51 | #define RIP_ID_RALINK_CALIBRATION_DATA 0x0112 /**< Ralink wlan calibration data (256 bytes) */ 52 | #define RIP_ID_CHIPID 0x0115 /**< The unique ID of the CPU where the erip is coupled to */ 53 | #define RIP_ID_PUBLIC_RSA_KEY 0x0116 /**< Used for BLI RSA public key in eRIPv2 board. Called in /vobs/fsn/lib/ipkg/bli2_verify.c */ 54 | #define RIP_ID_SERIAL_NBR_BYTES 0x0118 /**< Unique Serial Number bytes ( to construct GPON ONT-Serial Number) (32 bit) */ 55 | #define RIP_ID_CLIENT_CERTIFICATE 0x011A /**< PEM (x509v3), Unique Device Certificate for recent boards */ 56 | #define RIP_ID_OPTICAL_FRONT_END 0x011B /**< Optical Front End type (1 Triplexer, 2 Diplexer, 3 Active Ethernet) (8 bit) */ 57 | #define RIP_ID_DUID_LLT 0x011C /**< DHCP Unique Identifier Link Local Timestamp */ 58 | #define RIP_ID_EIK 0x011E /**< Public RSA key for signature verification of encrypted eRIPv2 items */ 59 | #define RIP_ID_ECK 0x011F /**< AES key for decryption encrypted eRIPv2 items*/ 60 | #define RIP_ID_OSIK 0x0120 /**< OS integrity key; used to verify signatures in RSA signed BLIs and flash contents */ 61 | #define RIP_ID_OSCK 0x0121 /**< OS confidentiality key; used to decrypt AES-CBC encrypted BLIs */ 62 | #define RIP_ID_RESTRICTED_DOWNGR_TS 0x0122 /**< Restricted downgrade timestamp (unsigned int) */ 63 | #define RIP_ID_RESTRICTED_DOWNGR_OPT 0x0123 /**< Restricted downgrade options (8 bit) */ 64 | #define RIP_ID_GENERIC_ACCESS_KEY_LIST 0x0124 /**< Contains 10 access keys of 8 alphanumeric characters */ 65 | #define RIP_ID_UNLOCK_TAG 0x0125 /* Bootloader unlock tag, to convert production gateway into an unlocked gateway (to run unsigned builds) */ 66 | #define RIP_ID_OLYMPUS_IK 0x0127 /* Olympus integrity key; used to verify signatures in RSA LER signed BLIs */ 67 | #define RIP_ID_OLYMPUS_CK 0x0128 /* Olympus confidentiality key; used to decrypt AES-CBC encrypted LER BLIs */ 68 | 69 | #define RIP_ID_ID_DECT_CFG (0x4001) /**< DECT calibration data */ 70 | 71 | #define SS_RIP_ID_PREFIX (0x8000) /**< Values from the old Secure Storage start at 0x8000 */ 72 | #define RIP_ID_PRODID (SS_RIP_ID_PREFIX + 1) /**< Product ID */ 73 | #define RIP_ID_PRODNAME (SS_RIP_ID_PREFIX + 2) /**< Product friendly name */ 74 | #define RIP_ID_VARID (SS_RIP_ID_PREFIX + 3) /**< Variant ID */ 75 | #define RIP_ID_VARNAME (SS_RIP_ID_PREFIX + 4) /**< Variant friendly name */ 76 | 77 | #define RIP_CP_DSL_POTS 0x0 // Annex A HW 78 | #define RIP_CP_DSL_ISDN 0x4 // Annex B HW 79 | #define RIP_CP_DSL_M 0x0200 // Annex M HW 80 | #define RIP_CP_DSL_BJ 0x1004 // Annex B / J HW 81 | #define RIP_CP_DSL_MASK 0x1204 82 | 83 | 84 | #endif //__RIP_IDS_H__ 85 | -------------------------------------------------------------------------------- /src/r2secrets.mips/include/rip_ids.h: -------------------------------------------------------------------------------- 1 | /************** COPYRIGHT AND CONFIDENTIALITY INFORMATION ********************* 2 | ** ** 3 | ** Copyright (c) 2012 Technicolor ** 4 | ** All Rights Reserved ** 5 | ** ** 6 | ** This program contains proprietary information which is a trade ** 7 | ** secret of TECHNICOLOR and/or its affiliates and also is protected as ** 8 | ** an unpublished work under applicable Copyright laws. Recipient is ** 9 | ** to retain this program in confidence and is not permitted to use or ** 10 | ** make copies thereof other than as permitted in a written agreement ** 11 | ** with TECHNICOLOR, UNLESS OTHERWISE EXPRESSLY ALLOWED BY APPLICABLE LAWS. ** 12 | ** ** 13 | ******************************************************************************/ 14 | 15 | /** @file 16 | * 17 | * File containing identifiers for items in the Remote Inventory Parameters (RIP). 18 | */ 19 | 20 | #ifndef __RIP_IDS_H__ 21 | #define __RIP_IDS_H__ 22 | 23 | #define RIP_ID_LOWER_CHECKSUM 0x0000 /**< RIP CheckSum */ 24 | #define RIP_ID_UNPROT_FREE1 0x0002 /**< Customization Pattern */ 25 | #define RIP_ID_PART_NBR_VARIANT 0x0004 /**< PBA Code */ 26 | #define RIP_ID_ICS 0x0010 /**< PBA ICS */ 27 | #define RIP_ID_BOARD_SERIAL_NBR 0x0012 /**< PBA Serial nr */ 28 | #define RIP_ID_FACTORY_RELEASE_DATE 0x0022 /**< Product Date */ 29 | #define RIP_ID_FIA 0x0028 /**< FIA code */ 30 | #define RIP_ID_HANDOVER_DATE 0x002C /**< Repair Date */ 31 | #define RIP_ID_LAN_ADDR 0x0032 /**< Ethernet MAC */ 32 | #define RIP_ID_COMPANY_ID 0x0038 /**< Company ID */ 33 | #define RIP_ID_FACTORY_ID 0x003C /**< Factory ID */ 34 | #define RIP_ID_BOARD_NAME 0x0040 /**< Board Name */ 35 | #define RIP_ID_MEMORY_CONFIG 0x0048 /**< Memory Configuration */ 36 | #define RIP_ID_USB_LAN_ADDR 0x004C /**< USB MAC address */ 37 | #define RIP_ID_MODEM_ACCESS_CODE 0x0083 /**< Access Code */ 38 | #define RIP_ID_SECURE_REMOTE_MANG_PASWD 0x0088 /**< Remote Mgr Pwd */ 39 | #define RIP_ID_WLAN_LAN_ADDR 0x008D /**< WiFi MAC */ 40 | 41 | #define RIP_ID_PUBLIC_DSA_SYST 0x0100 /**< DSA Public Key, for Regular Firmware Signature */ 42 | #define RIP_ID_PUBLIC_DSA_RESC 0x0101 /**< DSA Public Key, for Rescue Firmware Signature */ 43 | #define RIP_ID_MODELNAME 0x0102 /**< String, Represents the board (ex: Livebox Mini...) */ 44 | #define RIP_ID_PRODUCT_CLASS 0x0103 /**< String, Represents the product type (ex: Livebox, Livebox2...) */ 45 | #define RIP_ID_LB_CLIENT_CERTIFICATE 0x0104 /**< PEM (x509v3), Unique Device Certificate */ 46 | #define RIP_ID_PRIVATE_KEY 0x0105 /**< PEM (PKCS#1), RSA Private Key (unique per device) */ 47 | #define RIP_ID_H235_KEY 0x0106 /**< String, Secret Key (unique per device) for voice activation */ 48 | #define RIP_ID_RANDOM_KEY_A 0x0107 /**< Random number 1 (256 bit) */ 49 | #define RIP_ID_RANDOM_KEY_B 0x0108 /**< Random number 2 (512 bit) */ 50 | #define RIP_ID_KEY_PWD 0x0109 /**< Key password, will return if possible RANDOM_KEY_A or a RIP calculated key */ 51 | #define RIP_ID_RALINK_CALIBRATION_DATA 0x0112 /**< Ralink wlan calibration data (256 bytes) */ 52 | #define RIP_ID_CHIPID 0x0115 /**< The unique ID of the CPU where the erip is coupled to */ 53 | #define RIP_ID_PUBLIC_RSA_KEY 0x0116 /**< Used for BLI RSA public key in eRIPv2 board. Called in /vobs/fsn/lib/ipkg/bli2_verify.c */ 54 | #define RIP_ID_SERIAL_NBR_BYTES 0x0118 /**< Unique Serial Number bytes ( to construct GPON ONT-Serial Number) (32 bit) */ 55 | #define RIP_ID_CLIENT_CERTIFICATE 0x011A /**< PEM (x509v3), Unique Device Certificate for recent boards */ 56 | #define RIP_ID_OPTICAL_FRONT_END 0x011B /**< Optical Front End type (1 Triplexer, 2 Diplexer, 3 Active Ethernet) (8 bit) */ 57 | #define RIP_ID_DUID_LLT 0x011C /**< DHCP Unique Identifier Link Local Timestamp */ 58 | #define RIP_ID_EIK 0x011E /**< Public RSA key for signature verification of encrypted eRIPv2 items */ 59 | #define RIP_ID_ECK 0x011F /**< AES key for decryption encrypted eRIPv2 items*/ 60 | #define RIP_ID_OSIK 0x0120 /**< OS integrity key; used to verify signatures in RSA signed BLIs and flash contents */ 61 | #define RIP_ID_OSCK 0x0121 /**< OS confidentiality key; used to decrypt AES-CBC encrypted BLIs */ 62 | #define RIP_ID_RESTRICTED_DOWNGR_TS 0x0122 /**< Restricted downgrade timestamp (unsigned int) */ 63 | #define RIP_ID_RESTRICTED_DOWNGR_OPT 0x0123 /**< Restricted downgrade options (8 bit) */ 64 | #define RIP_ID_GENERIC_ACCESS_KEY_LIST 0x0124 /**< Contains 10 access keys of 8 alphanumeric characters */ 65 | #define RIP_ID_UNLOCK_TAG 0x0125 /* Bootloader unlock tag, to convert production gateway into an unlocked gateway (to run unsigned builds) */ 66 | #define RIP_ID_OLYMPUS_IK 0x0127 /* Olympus integrity key; used to verify signatures in RSA LER signed BLIs */ 67 | #define RIP_ID_OLYMPUS_CK 0x0128 /* Olympus confidentiality key; used to decrypt AES-CBC encrypted LER BLIs */ 68 | 69 | #define RIP_ID_ID_DECT_CFG (0x4001) /**< DECT calibration data */ 70 | 71 | #define SS_RIP_ID_PREFIX (0x8000) /**< Values from the old Secure Storage start at 0x8000 */ 72 | #define RIP_ID_PRODID (SS_RIP_ID_PREFIX + 1) /**< Product ID */ 73 | #define RIP_ID_PRODNAME (SS_RIP_ID_PREFIX + 2) /**< Product friendly name */ 74 | #define RIP_ID_VARID (SS_RIP_ID_PREFIX + 3) /**< Variant ID */ 75 | #define RIP_ID_VARNAME (SS_RIP_ID_PREFIX + 4) /**< Variant friendly name */ 76 | 77 | #define RIP_CP_DSL_POTS 0x0 // Annex A HW 78 | #define RIP_CP_DSL_ISDN 0x4 // Annex B HW 79 | #define RIP_CP_DSL_M 0x0200 // Annex M HW 80 | #define RIP_CP_DSL_BJ 0x1004 // Annex B / J HW 81 | #define RIP_CP_DSL_MASK 0x1204 82 | 83 | 84 | #endif //__RIP_IDS_H__ 85 | -------------------------------------------------------------------------------- /src/r2secrets.arm/include/rip2.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************* 2 | 3 | *************************************************************************************/ 4 | 5 | #ifndef __T_RIP2_H__ 6 | #define __T_RIP2_H__ 7 | 8 | #include "rip2_config.h" 9 | 10 | #define RIP2_SZ (0x20000) /* 128kB */ 11 | #define CRC_SZ (4) 12 | 13 | #define RIP2_START (0) /* base address for the relative T_RIP2_HDR.addr */ 14 | 15 | #ifndef RIP2_OFFSET /* GPON LILAC board has 256KB bootloader, the RIP2_OFFSET will be 0x40000 */ 16 | #define RIP2_OFFSET (0x20000) /* start of the RIP2 sector */ 17 | #endif 18 | 19 | #define RIP2_SUCCESS (1) 20 | #define RIP2_ERR_INV_RIP (-1) 21 | #define RIP2_ERR_NOMEM (-2) 22 | #define RIP2_ERR_NOELEM (-3) 23 | #define RIP2_ERR_BADCRC (-4) 24 | #define RIP2_ERR_PERM (-5) 25 | #define RIP2_ERR_BADCRYPTO (-6) 26 | 27 | /* implement in target dependant platform.c file */ 28 | extern int rip2_flash_init(void *base, size_t size); 29 | extern int rip2_flash_read(loff_t from, size_t len, size_t *retlen, unsigned char *buf); 30 | extern int rip2_flash_write(loff_t to, size_t len, size_t *retlen, unsigned char *buf); 31 | extern int rip2_flash_clear(loff_t to, size_t len, size_t *retlen); 32 | extern void rip2_flash_release(void); 33 | extern unsigned long rip2_crc32(unsigned char *data, unsigned count); 34 | 35 | 36 | typedef union { 37 | struct { 38 | uint8_t version; 39 | uint8_t reserved[3]; 40 | } str; 41 | uint32_t val; 42 | } __attribute__((__packed__)) T_RIP2_HDR; 43 | #define RIP_VERSION_2 (0x02) 44 | 45 | typedef uint16_t T_RIP2_ID; 46 | 47 | typedef struct { 48 | T_RIP2_ID ID; 49 | uint32_t addr; 50 | uint32_t attr[2]; 51 | uint32_t length; 52 | } __attribute__((__packed__)) T_RIP2_ITEM; 53 | 54 | 55 | #define RIP2_ATTR_ANY 0xFFFFFFFF 56 | /* Inverted definition of CRC check bit, this way it's harder to bypass a CRC 57 | * check, since it now means setting this bit from 0 -> 1, whereas in the past 58 | * it was from 1 -> 0 (easy to do in flash) */ 59 | #define RIP2_ATTR_CRC_MSK 0x80000000 60 | #define RIP2_ATTR_CHK_CRC (~RIP2_ATTR_CRC_MSK) 61 | #define RIP2_ATTR_DONT_CHK_CRC (RIP2_ATTR_CRC_MSK) 62 | #define RIP2_ATTR_WRITABLE 0x40000000 63 | #define RIP2_ATTR_VALID 0x20000000 64 | /* Crypto flags interpretation is reversed ! */ 65 | #define RIP2_ATTR_N_EIK_SIGN 0x10000000 /* 60 */ 66 | #define RIP2_ATTR_N_ECK_ENCR 0x08000000 /* 59 */ 67 | #define RIP2_ATTR_N_MCV_SIGN 0x04000000 /* 58 */ 68 | #define RIP2_ATTR_N_BEK_ENCR 0x02000000 /* 57 */ 69 | #define ATTR_HI 1 70 | #define ATTR_LO 0 71 | 72 | #define RIP2_ATTR_HI_MASK 0xE0000000 73 | /* default value is: check crc|!writable|valid */ 74 | #define RIP2_ATTR_DEFAULT ((RIP2_ATTR_ANY & ~RIP2_ATTR_HI_MASK) | RIP2_ATTR_VALID) 75 | 76 | #define RIP2_ATTR_CRYPTO (RIP2_ATTR_N_EIK_SIGN | RIP2_ATTR_N_ECK_ENCR | RIP2_ATTR_N_MCV_SIGN | RIP2_ATTR_N_BEK_ENCR) 77 | 78 | typedef struct { 79 | T_RIP2_HDR hdr; 80 | T_RIP2_ITEM index[]; 81 | } __attribute__((__packed__)) T_RIP2_IDX; 82 | 83 | /* 84 | * Create an empty rip2 with just a header field 85 | * IN: ripPtr: a pointer to a memory buffer that will be used to store the 86 | * rip2. 87 | * verify: determines whether we are in verification of generation mode 88 | * size: the size of the RIP2 sector 89 | * 90 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_INV_RIP or RIP2_ERR_NOMEM 91 | * upon error. 92 | */ 93 | int rip2_init(uint8_t *ripPtr, 94 | int verify, 95 | unsigned int size); 96 | 97 | 98 | /* 99 | * Finds the first index item with the given RIP2 ID and the valid flag set 100 | * item is filled with the exact contents of the flash, untranslated. 101 | * 102 | * RETURNS: RIP2_ERR_NOELEM if no matching index found, 103 | * RIP2_SUCCESS otherwise 104 | */ 105 | int rip2_get_idx(T_RIP2_ID id, 106 | T_RIP2_ITEM *item); 107 | 108 | /* 109 | * find the first index item with the given RIP2 ID and the valid flag set. 110 | * fields of item are translated and ready for use 111 | */ 112 | int rip2_get_item(T_RIP2_ID id, 113 | T_RIP2_ITEM *item); 114 | 115 | /* 116 | * Returns the data pointer for the first index item with the given RIP2 ID 117 | * and the valid flag set. Returns length if length!=NULL. 118 | * If raw != 0 then data is returned as they are present in rip2. 119 | * 120 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 121 | * RIP2_ERR_BADCRC if a CRC error was detected 122 | * RIP2_SUCCESS otherwise 123 | */ 124 | int rip2_get_data_ex(uint8_t *ripStart, 125 | T_RIP2_ID id, 126 | uint8_t *data, 127 | uint32_t *length, 128 | int raw); 129 | 130 | /* 131 | * Returns the data pointer for the first index item with the given RIP2 ID 132 | * and the valid flag set 133 | * 134 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 135 | * RIP2_ERR_BADCRC if a CRC error was detected 136 | * RIP2_SUCCESS otherwise 137 | */ 138 | int rip2_get_data(uint8_t *ripStart, 139 | T_RIP2_ID id, 140 | uint8_t *data); 141 | 142 | /* 143 | * Copies the data for the first index item with the given RIP2 ID 144 | * and the valid flag set and updates length accordingly. 145 | * 146 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 147 | * RIP2_ERR_BADCRC if a CRC error was detected 148 | * RIP2_SUCCESS otherwise 149 | */ 150 | 151 | int rip2_drv_read (unsigned long *length, T_RIP2_ID id, void *data); 152 | 153 | /* 154 | * Returns the length for the first index item with the given RIP2 ID 155 | * and the valid flag set. 156 | * 157 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 158 | * RIP2_ERR_BADCRC if a CRC error was detected 159 | * RIP2_SUCCESS otherwise 160 | */ 161 | 162 | static inline int rip2_drv_read_length(unsigned long *length, T_RIP2_ID id) 163 | { 164 | return rip2_drv_read(length, id, NULL); 165 | } 166 | 167 | /* 168 | * Updates a rip2 field; if it does not yet exist, this performs rip2_add_item 169 | * 170 | * RETURNS: RIP2_SUCCESS if the item was successfully written 171 | * RIP2_ERR_PERM if the flags don't match or there are no write 172 | * permissions 173 | * RIP2_ERR_NOELEM if no matching element was found (should not 174 | * happen). 175 | */ 176 | 177 | int rip2_drv_write (uint8_t *data, 178 | size_t len, 179 | T_RIP2_ID id, 180 | uint32_t attrHi, 181 | uint32_t attrLo); 182 | 183 | /* 184 | * Locks the data corresponding to RIP2 ID id by disabling the 185 | * writable flag (if set). 186 | * 187 | * RETURNS: 0 if no matching id found 188 | * 1 otherwise 189 | */ 190 | int rip2_lock(T_RIP2_ID id); 191 | 192 | /* 193 | * Checks if data contains valid signature using EIK and sets flag. 194 | * 195 | * RETURNS: RIP2_ERR_NOELEM if no matching id found 196 | * RIP2_ERR_PERM if the flags don't match or there are no write 197 | * permissions 198 | * RIP2_SUCCESS otherwise 199 | */ 200 | int rip2_set_signed(T_RIP2_ID id); 201 | 202 | /* 203 | * Encrypts the data corresponding to RIP2 ID id using ECK. 204 | * First checks if item has RIP2_ATTR_N_EIK_SIGN flag set. 205 | * 206 | * RETURNS: RIP2_ERR_NOELEM if no matching id found 207 | * RIP2_ERR_PERM if the flags don't match or there are no write 208 | * permissions 209 | * RIP2_SUCCESS otherwise 210 | */ 211 | int rip2_encrypt(T_RIP2_ID id); 212 | 213 | /* 214 | * Performs some checks to determine whether the RIP2 content is ok: 215 | * - A CRC check on all elements 216 | * - Verify required crypto settings 217 | * 218 | * RETURNS: RIP2_SUCCESS if all ok 219 | * RIP2_ERR_BADCRC if CRC is invalid 220 | * RIP2_ERR_BADCRYPTO if some crypto requirement is not met 221 | */ 222 | int rip2_is_valid(uint8_t *ripStart); 223 | 224 | 225 | /* 226 | * Iterates over all index items which match the flags passed as an argument. 227 | * In case a NULL iterator was passed, the iterator will be restarted from 228 | * the RIP start address. 229 | * In case a non-NULL iterator was passed, the iterator continues from the last 230 | * entry it returned. 231 | * 232 | * RETURNS: RIP2_ERR_INV_RIP if an invalid start address was passed, 233 | * RIP2_ERR_NOELEM if no matching index found 234 | * RIP2_SUCCESS otherwise 235 | */ 236 | int rip2_get_next(T_RIP2_ITEM **from, 237 | const uint32_t flags, 238 | T_RIP2_ITEM *item); 239 | 240 | 241 | int rip2_verify_crc(uint8_t *ripStart); 242 | 243 | 244 | #endif /* __T_RIP2_H__ */ 245 | -------------------------------------------------------------------------------- /src/r2secrets.mips/include/rip2.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************* 2 | 3 | *************************************************************************************/ 4 | 5 | #ifndef __T_RIP2_H__ 6 | #define __T_RIP2_H__ 7 | 8 | #include "rip2_config.h" 9 | 10 | #define RIP2_SZ (0x20000) /* 128kB */ 11 | #define CRC_SZ (4) 12 | 13 | #define RIP2_START (0) /* base address for the relative T_RIP2_HDR.addr */ 14 | 15 | #ifndef RIP2_OFFSET /* GPON LILAC board has 256KB bootloader, the RIP2_OFFSET will be 0x40000 */ 16 | #define RIP2_OFFSET (0x20000) /* start of the RIP2 sector */ 17 | #endif 18 | 19 | #define RIP2_SUCCESS (1) 20 | #define RIP2_ERR_INV_RIP (-1) 21 | #define RIP2_ERR_NOMEM (-2) 22 | #define RIP2_ERR_NOELEM (-3) 23 | #define RIP2_ERR_BADCRC (-4) 24 | #define RIP2_ERR_PERM (-5) 25 | #define RIP2_ERR_BADCRYPTO (-6) 26 | 27 | /* implement in target dependant platform.c file */ 28 | extern int rip2_flash_init(void *base, size_t size); 29 | extern int rip2_flash_read(loff_t from, size_t len, size_t *retlen, unsigned char *buf); 30 | extern int rip2_flash_write(loff_t to, size_t len, size_t *retlen, unsigned char *buf); 31 | extern int rip2_flash_clear(loff_t to, size_t len, size_t *retlen); 32 | extern void rip2_flash_release(void); 33 | extern unsigned long rip2_crc32(unsigned char *data, unsigned count); 34 | 35 | 36 | typedef union { 37 | struct { 38 | uint8_t version; 39 | uint8_t reserved[3]; 40 | } str; 41 | uint32_t val; 42 | } __attribute__((__packed__)) T_RIP2_HDR; 43 | #define RIP_VERSION_2 (0x02) 44 | 45 | typedef uint16_t T_RIP2_ID; 46 | 47 | typedef struct { 48 | T_RIP2_ID ID; 49 | uint32_t addr; 50 | uint32_t attr[2]; 51 | uint32_t length; 52 | } __attribute__((__packed__)) T_RIP2_ITEM; 53 | 54 | 55 | #define RIP2_ATTR_ANY 0xFFFFFFFF 56 | /* Inverted definition of CRC check bit, this way it's harder to bypass a CRC 57 | * check, since it now means setting this bit from 0 -> 1, whereas in the past 58 | * it was from 1 -> 0 (easy to do in flash) */ 59 | #define RIP2_ATTR_CRC_MSK 0x80000000 60 | #define RIP2_ATTR_CHK_CRC (~RIP2_ATTR_CRC_MSK) 61 | #define RIP2_ATTR_DONT_CHK_CRC (RIP2_ATTR_CRC_MSK) 62 | #define RIP2_ATTR_WRITABLE 0x40000000 63 | #define RIP2_ATTR_VALID 0x20000000 64 | /* Crypto flags interpretation is reversed ! */ 65 | #define RIP2_ATTR_N_EIK_SIGN 0x10000000 /* 60 */ 66 | #define RIP2_ATTR_N_ECK_ENCR 0x08000000 /* 59 */ 67 | #define RIP2_ATTR_N_MCV_SIGN 0x04000000 /* 58 */ 68 | #define RIP2_ATTR_N_BEK_ENCR 0x02000000 /* 57 */ 69 | #define ATTR_HI 1 70 | #define ATTR_LO 0 71 | 72 | #define RIP2_ATTR_HI_MASK 0xE0000000 73 | /* default value is: check crc|!writable|valid */ 74 | #define RIP2_ATTR_DEFAULT ((RIP2_ATTR_ANY & ~RIP2_ATTR_HI_MASK) | RIP2_ATTR_VALID) 75 | 76 | #define RIP2_ATTR_CRYPTO (RIP2_ATTR_N_EIK_SIGN | RIP2_ATTR_N_ECK_ENCR | RIP2_ATTR_N_MCV_SIGN | RIP2_ATTR_N_BEK_ENCR) 77 | 78 | typedef struct { 79 | T_RIP2_HDR hdr; 80 | T_RIP2_ITEM index[]; 81 | } __attribute__((__packed__)) T_RIP2_IDX; 82 | 83 | /* 84 | * Create an empty rip2 with just a header field 85 | * IN: ripPtr: a pointer to a memory buffer that will be used to store the 86 | * rip2. 87 | * verify: determines whether we are in verification of generation mode 88 | * size: the size of the RIP2 sector 89 | * 90 | * RETURNS: RIP2_SUCCESS when successful, RIP2_ERR_INV_RIP or RIP2_ERR_NOMEM 91 | * upon error. 92 | */ 93 | int rip2_init(uint8_t *ripPtr, 94 | int verify, 95 | unsigned int size); 96 | 97 | 98 | /* 99 | * Finds the first index item with the given RIP2 ID and the valid flag set 100 | * item is filled with the exact contents of the flash, untranslated. 101 | * 102 | * RETURNS: RIP2_ERR_NOELEM if no matching index found, 103 | * RIP2_SUCCESS otherwise 104 | */ 105 | int rip2_get_idx(T_RIP2_ID id, 106 | T_RIP2_ITEM *item); 107 | 108 | /* 109 | * find the first index item with the given RIP2 ID and the valid flag set. 110 | * fields of item are translated and ready for use 111 | */ 112 | int rip2_get_item(T_RIP2_ID id, 113 | T_RIP2_ITEM *item); 114 | 115 | /* 116 | * Returns the data pointer for the first index item with the given RIP2 ID 117 | * and the valid flag set. Returns length if length!=NULL. 118 | * If raw != 0 then data is returned as they are present in rip2. 119 | * 120 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 121 | * RIP2_ERR_BADCRC if a CRC error was detected 122 | * RIP2_SUCCESS otherwise 123 | */ 124 | int rip2_get_data_ex(uint8_t *ripStart, 125 | T_RIP2_ID id, 126 | uint8_t *data, 127 | uint32_t *length, 128 | int raw); 129 | 130 | /* 131 | * Returns the data pointer for the first index item with the given RIP2 ID 132 | * and the valid flag set 133 | * 134 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 135 | * RIP2_ERR_BADCRC if a CRC error was detected 136 | * RIP2_SUCCESS otherwise 137 | */ 138 | int rip2_get_data(uint8_t *ripStart, 139 | T_RIP2_ID id, 140 | uint8_t *data); 141 | 142 | /* 143 | * Copies the data for the first index item with the given RIP2 ID 144 | * and the valid flag set and updates length accordingly. 145 | * 146 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 147 | * RIP2_ERR_BADCRC if a CRC error was detected 148 | * RIP2_SUCCESS otherwise 149 | */ 150 | 151 | int rip2_drv_read (unsigned long *length, T_RIP2_ID id, void *data); 152 | 153 | /* 154 | * Returns the length for the first index item with the given RIP2 ID 155 | * and the valid flag set. 156 | * 157 | * RETURNS: RIP2_ERR_NOELEM if no matching index found 158 | * RIP2_ERR_BADCRC if a CRC error was detected 159 | * RIP2_SUCCESS otherwise 160 | */ 161 | 162 | static inline int rip2_drv_read_length(unsigned long *length, T_RIP2_ID id) 163 | { 164 | return rip2_drv_read(length, id, NULL); 165 | } 166 | 167 | /* 168 | * Updates a rip2 field; if it does not yet exist, this performs rip2_add_item 169 | * 170 | * RETURNS: RIP2_SUCCESS if the item was successfully written 171 | * RIP2_ERR_PERM if the flags don't match or there are no write 172 | * permissions 173 | * RIP2_ERR_NOELEM if no matching element was found (should not 174 | * happen). 175 | */ 176 | 177 | int rip2_drv_write (uint8_t *data, 178 | size_t len, 179 | T_RIP2_ID id, 180 | uint32_t attrHi, 181 | uint32_t attrLo); 182 | 183 | /* 184 | * Locks the data corresponding to RIP2 ID id by disabling the 185 | * writable flag (if set). 186 | * 187 | * RETURNS: 0 if no matching id found 188 | * 1 otherwise 189 | */ 190 | int rip2_lock(T_RIP2_ID id); 191 | 192 | /* 193 | * Checks if data contains valid signature using EIK and sets flag. 194 | * 195 | * RETURNS: RIP2_ERR_NOELEM if no matching id found 196 | * RIP2_ERR_PERM if the flags don't match or there are no write 197 | * permissions 198 | * RIP2_SUCCESS otherwise 199 | */ 200 | int rip2_set_signed(T_RIP2_ID id); 201 | 202 | /* 203 | * Encrypts the data corresponding to RIP2 ID id using ECK. 204 | * First checks if item has RIP2_ATTR_N_EIK_SIGN flag set. 205 | * 206 | * RETURNS: RIP2_ERR_NOELEM if no matching id found 207 | * RIP2_ERR_PERM if the flags don't match or there are no write 208 | * permissions 209 | * RIP2_SUCCESS otherwise 210 | */ 211 | int rip2_encrypt(T_RIP2_ID id); 212 | 213 | /* 214 | * Performs some checks to determine whether the RIP2 content is ok: 215 | * - A CRC check on all elements 216 | * - Verify required crypto settings 217 | * 218 | * RETURNS: RIP2_SUCCESS if all ok 219 | * RIP2_ERR_BADCRC if CRC is invalid 220 | * RIP2_ERR_BADCRYPTO if some crypto requirement is not met 221 | */ 222 | int rip2_is_valid(uint8_t *ripStart); 223 | 224 | 225 | /* 226 | * Iterates over all index items which match the flags passed as an argument. 227 | * In case a NULL iterator was passed, the iterator will be restarted from 228 | * the RIP start address. 229 | * In case a non-NULL iterator was passed, the iterator continues from the last 230 | * entry it returned. 231 | * 232 | * RETURNS: RIP2_ERR_INV_RIP if an invalid start address was passed, 233 | * RIP2_ERR_NOELEM if no matching index found 234 | * RIP2_SUCCESS otherwise 235 | */ 236 | int rip2_get_next(T_RIP2_ITEM **from, 237 | const uint32_t flags, 238 | T_RIP2_ITEM *item); 239 | 240 | 241 | int rip2_verify_crc(uint8_t *ripStart); 242 | 243 | 244 | #endif /* __T_RIP2_H__ */ 245 | -------------------------------------------------------------------------------- /eripv2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | ################################################################ 3 | # surrealiz3 4 | ################################################################ 5 | ## 6 | ## grab your ECK key with r2secr.arm.ko ( insmod r2secr.arm.ko && dmesg ) 7 | ## or with r2secr.mips.ko ( insmod r2secr.arm.ko && dmesg ) 8 | ## 9 | ## output 10 | ## 11 | ## 34399.350000] r2secr : 1ffdf000 12 | ## [34399.352000] r2secr_struct : dffdf000 13 | ## [34399.356000] r2secr_struct->magic : d104ea5b 14 | ## [34399.361000] r2secr_struct->items : dffdf008 15 | ## [34399.365000] nextFreeItem->id : 11f 16 | ## [34399.369000] nextFreeItem->length : 16 17 | ## [34399.372000] nextFreeItem->data : 1ffdf020 18 | ## [34399.377000] data_ptr : dffdf020 19 | ## [34399.380000] XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX | ................ 20 | ## 21 | ## grab you eripv2 partition ,mtd5 for offline processing dd if=/dev/mtd5 of=/tmp/mtd5.dd 22 | ## copy it to where you are able to run this python script 23 | ## 24 | ## run: python eripv2.py --eripv2 mtd5.dd --eckey XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 25 | ## 26 | ## find the secrets on screen and dumped unencrypted contents to files 27 | ## OCK key file is of relevance to decrypt encrypted rbi files with another script 28 | ## disclaimer : use at your own risk 29 | 30 | 31 | import struct 32 | from hexdump import hexdump 33 | from Crypto.Cipher import AES 34 | from Crypto.PublicKey.RSA import construct 35 | from Crypto.Signature import PKCS1_v1_5, PKCS1_PSS 36 | from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5 37 | from binascii import hexlify,unhexlify 38 | import binascii 39 | import argparse 40 | import hashlib 41 | 42 | parser = argparse.ArgumentParser() 43 | parser.add_argument('--eripv2', help='eripv2 dump file name ( grab with dd if=/dev/mtd5 of=/tmp/mtd5.bin)') 44 | parser.add_argument('--eckey' , help='key file grab with kernel module for your arch (insmod r2secrets.arm && dmesg') 45 | parser.add_argument('--debug' , help='enable debugging') 46 | 47 | args = parser.parse_args() 48 | tmp = vars(args) 49 | DEBUG=False if tmp['debug'] == None else True 50 | fname = tmp['eripv2'] 51 | f = open(fname , 'rb') 52 | data = f.read() 53 | f.close() 54 | 55 | dlen=len(data) 56 | buff=data[0:dlen-4] 57 | 58 | ATTR_EIK_SIGN = 0x10000000 59 | ATTR_ECK_ENCR = 0x08000000 60 | ATTR_MCV_SIGN = 0x04000000 61 | ATTR_BEK_ENCR = 0x02000000 62 | ATTR_CRYPTO = (ATTR_EIK_SIGN | ATTR_ECK_ENCR | ATTR_MCV_SIGN | ATTR_BEK_ENCR) 63 | 64 | eck = unhexlify(tmp['eckey'].replace(' ', '').replace('"', '').strip()) 65 | eik = None 66 | fsh = '' 67 | 68 | # o.O # 69 | RIPS = { 70 | 0x0000: 'RIP_ID_LOWER_CHECKSUM', 71 | 0x0002: 'RIP_ID_UNPROT_FREE1', 72 | 0x0004: 'RIP_ID_PART_NBR_VARIANT', 73 | 0x0010: 'RIP_ID_ICS', 74 | 0x0012: 'RIP_ID_BOARD_SERIAL_NBR', 75 | 0x0022: 'RIP_ID_FACTORY_RELEASE_DATE', 76 | 0x0028: 'RIP_ID_FIA', 77 | 0x002C: 'RIP_ID_HANDOVER_DATE', 78 | 0x0032: 'RIP_ID_LAN_ADDR', 79 | 0x0038: 'RIP_ID_COMPANY_ID', 80 | 0x003C: 'RIP_ID_FACTORY_ID', 81 | 0x0040: 'RIP_ID_BOARD_NAME', 82 | 0x0048: 'RIP_ID_MEMORY_CONFIG', 83 | 0x004C: 'RIP_ID_USB_LAN_ADDR', 84 | 0x0083: 'RIP_ID_MODEM_ACCESS_CODE', 85 | 0x0088: 'RIP_ID_SECURE_REMOTE_MANG_PASWD', 86 | 0x008D: 'RIP_ID_WLAN_LAN_ADDR', 87 | 0x0100: 'RIP_ID_PUBLIC_DSA_SYST', 88 | 0x0101: 'RIP_ID_PUBLIC_DSA_RESC', 89 | 0x0102: 'RIP_ID_MODELNAME', 90 | 0x0103: 'RIP_ID_PRODUCT_CLASS', 91 | 0x0104: 'RIP_ID_LB_CLIENT_CERTIFICATE', 92 | 0x0105: 'RIP_ID_PRIVATE_KEY', 93 | 0x0106: 'RIP_ID_H235_KEY', 94 | 0x0107: 'RIP_ID_RANDOM_KEY_A', 95 | 0x0108: 'RIP_ID_RANDOM_KEY_B', 96 | 0x0109: 'RIP_ID_KEY_PWD', 97 | 0x0112: 'RIP_ID_RALINK_CALIBRATION_DATA', 98 | 0x0115: 'RIP_ID_CHIPID', 99 | 0x0116: 'RIP_ID_PUBLIC_RSA_KEY', 100 | 0x0118: 'RIP_ID_SERIAL_NBR_BYTES', 101 | 0x011A: 'RIP_ID_CLIENT_CERTIFICATE', 102 | 0x011B: 'RIP_ID_OPTICAL_FRONT_END', 103 | 0x011C: 'RIP_ID_DUID_LLT', 104 | 0x011E: 'RIP_ID_EIK', 105 | 0x011F: 'RIP_ID_ECK', 106 | 0x0120: 'RIP_ID_OSIK', 107 | 0x0121: 'RIP_ID_OSCK', 108 | 0x0122: 'RIP_ID_RESTRICTED_DOWNGR_TS', 109 | 0x0123: 'RIP_ID_RESTRICTED_DOWNGR_OPT', 110 | 0x0124: 'RIP_ID_GENERIC_ACCESS_KEY_LIST', 111 | 0x0125: 'RIP_ID_UNLOCK_TAG', 112 | 0x0127: 'RIP_ID_OLYMPUS_IK', 113 | 0x0128: 'RIP_ID_OLYMPUS_CK', 114 | 0x4001: 'RIP_ID_ID_DECT_CFG', 115 | 0x8001: 'RIP_ID_PRODUCT_ID', 116 | 0x8003: 'RIP_ID_VARIANT_ID' 117 | 118 | } 119 | xRIPS=dict(list(zip(list(RIPS.values()),list(RIPS.keys())))) 120 | 121 | class Map(dict): 122 | def __init__(self, **kwargs): 123 | super(Map, self).__init__(**kwargs) 124 | self.__dict__ = self 125 | 126 | 127 | def sha256_checksum(filename, block_size=65536): 128 | sha256 = hashlib.sha256() 129 | with open(filename, 'rb') as f: 130 | for block in iter(lambda: f.read(block_size), b''): 131 | sha256.update(block) 132 | return sha256.hexdigest() 133 | 134 | 135 | def decrypt_aes_sigret(data,key): 136 | IV = data[0:16] 137 | encdata = data[16:] 138 | aes = AES.new(key, AES.MODE_CBC, IV) 139 | dec = aes.decrypt(encdata) 140 | pad = struct.unpack('>B',bytes([dec[len(dec)-1]]))[0] 141 | sz = (len(dec) - pad ) -256 142 | return Map( data = dec[0:sz] , signature = dec[sz:sz+256]) 143 | 144 | def sigret(_data): 145 | #thin ice 4 256 keys only !! beware.. 146 | sz = (len(_data)) -256 147 | return Map( data = _data[0:sz] , signature = _data[sz:sz+256]) 148 | 149 | def parse_rip(key): 150 | if key in RIPS : 151 | return RIPS[key] 152 | return "RIP_ID_UNKN: 0x%04x" % key 153 | 154 | def get_idx(IDx,x): 155 | ID=0x0000 156 | while (ID != 0xffff): 157 | item = buff[len(buff)-(18*x):(len(buff)-(18*x)+18)] 158 | x=x+1 159 | ID = struct.unpack('>H',item[0:2])[0] 160 | if(ID == 0xffff): 161 | break 162 | if(ID == IDx): 163 | rip_item = Map( 164 | id=IDx, 165 | addr = struct.unpack('>L',item[2:6])[0]^0x20000 , 166 | attr_lo = (struct.unpack('>L',item[6:10])[0]) , 167 | attr_hi = (struct.unpack('>L',item[10:14])[0]) , 168 | length= struct.unpack('>L',item[14:18])[0], 169 | ) 170 | rip_item['data'] = buff[rip_item.addr:rip_item.addr + rip_item.length] 171 | return rip_item 172 | return None 173 | 174 | def load_eik(pub_mod): 175 | global eik 176 | e = int('10001', 16) 177 | n = int(hexlify(pub_mod),16) 178 | eik = construct((n, e)) 179 | 180 | def dump(id,data,pos=None): 181 | fn = "%s_0x%.4x-%s" %(RIPS[id],id,fsh[0:8]) if id in RIPS else "RIP_UNK_0x%.4x-%s" %(id,fsh[0:8]) # .. :P 182 | if DEBUG & pos != None: 183 | fn = "%.2x_" % pos + fn 184 | print("dumping to file %s ...." % fn.strip()) 185 | f = open(fn.strip(),'wb') 186 | f.write(data) 187 | f.close() 188 | hexdump(data) 189 | return 190 | 191 | def eripv2_walk(): 192 | x=1 193 | ID=0x0000 194 | while (ID != 0xffff): 195 | item = buff[len(buff)-(18*x):(len(buff)-(18*x)+18)] 196 | x=x+1 197 | ID = struct.unpack('>H',item[0:2])[0] 198 | if(ID == 0xffff): 199 | break 200 | item = get_idx(ID,x-1) # walk ahead from found tag 201 | print("%.4x" % item.addr) 202 | if(~item.attr_hi & ATTR_CRYPTO): 203 | if(~item.attr_hi & ATTR_ECK_ENCR): 204 | dec = decrypt_aes_sigret(item.data,eck) 205 | if(~item.attr_hi & ATTR_EIK_SIGN): 206 | print("%s EIK_SIGNED and ECK_ENCR" % parse_rip(ID)) 207 | if signverify(item.id,dec.data,dec.signature): 208 | print('SIG: OK (proves provided ECK is correct)') 209 | dump(item.id,dec.data,x-1) 210 | else: 211 | print('SIG: NOK (ECK wrong ???!! not dumping contents!!)') 212 | if DEBUG: 213 | dump(item.id,dec.data,x-1) 214 | else: 215 | print("%s ECK_ENCR only" % parse_rip(ID)) 216 | dump(item.id,dec.data,x-1) 217 | else: 218 | if(~item.attr_hi & ATTR_EIK_SIGN): 219 | print("%s EIK_SIGNED only" % parse_rip(ID)) 220 | dec = sigret(item.data); 221 | if signverify(item.id,dec.data,dec.signature): 222 | print('SIG: OK (proves parsed EIK is correct)') 223 | dump(item.id,dec.data,x-1) 224 | else: 225 | print('SIG: NOK (EIK wrong ???!! not dumping contents!!)') 226 | if DEBUG: 227 | dump(item.id,dec.data,x-1) 228 | 229 | if(~item.attr_hi & ATTR_BEK_ENCR): 230 | if(item.attr_hi & ATTR_MCV_SIGN): 231 | print("%s MCV_SIGNED and BEK_ENCR !UNSUPPORTED!!" % parse_rip(ID)) 232 | item.data = data[0:len(data)-256] # remove sig rsa 256 233 | else: 234 | print("%s BEK_ENCR only !!UNSUPPORTED!!" % parse_rip(ID)) #no bek yet :/ 235 | else: 236 | if(~item.attr_hi & ATTR_MCV_SIGN): 237 | print("%s MCV_SIGNED only" % parse_rip(ID)) 238 | dec = sigret(item.data) 239 | dump(item.id,dec.data,x-1) # no integrity check ... 240 | else: 241 | print("%s no_crypt" % parse_rip(ID)) 242 | dump(item.id,item.data,x-1) 243 | print("") 244 | 245 | def init(): 246 | global fsh 247 | fsh = sha256_checksum(fname) 248 | item = get_idx(xRIPS['RIP_ID_EIK'],1) 249 | if(item != None): 250 | load_eik(item.data[:256]) 251 | return 252 | 253 | def signverify(id , data , signature): 254 | signeddata = struct.pack('>H',id) 255 | signeddata += data 256 | signer = PKCS1_PSS.new(eik) 257 | digest = SHA256.new() 258 | digest.update(signeddata) 259 | try: 260 | return signer.verify(digest, signature) 261 | except: 262 | return False 263 | 264 | init() 265 | eripv2_walk() 266 | --------------------------------------------------------------------------------