in bcm/spu.c [20:315]
void spum_dump_msg_hdr(u8 *buf, unsigned int buf_len)
{
u8 *ptr = buf;
struct SPUHEADER *spuh = (struct SPUHEADER *)buf;
unsigned int hash_key_len = 0;
unsigned int hash_state_len = 0;
unsigned int cipher_key_len = 0;
unsigned int iv_len;
u32 pflags;
u32 cflags;
u32 ecf;
u32 cipher_alg;
u32 cipher_mode;
u32 cipher_type;
u32 hash_alg;
u32 hash_mode;
u32 hash_type;
u32 sctx_size; /* SCTX length in words */
u32 sctx_pl_len; /* SCTX payload length in bytes */
packet_log("\n");
packet_log("SPU Message header %p len: %u\n", buf, buf_len);
/* ========== Decode MH ========== */
packet_log(" MH 0x%08x\n", be32_to_cpup((__be32 *)ptr));
if (spuh->mh.flags & MH_SCTX_PRES)
packet_log(" SCTX present\n");
if (spuh->mh.flags & MH_BDESC_PRES)
packet_log(" BDESC present\n");
if (spuh->mh.flags & MH_MFM_PRES)
packet_log(" MFM present\n");
if (spuh->mh.flags & MH_BD_PRES)
packet_log(" BD present\n");
if (spuh->mh.flags & MH_HASH_PRES)
packet_log(" HASH present\n");
if (spuh->mh.flags & MH_SUPDT_PRES)
packet_log(" SUPDT present\n");
packet_log(" Opcode 0x%02x\n", spuh->mh.op_code);
ptr += sizeof(spuh->mh) + sizeof(spuh->emh); /* skip emh. unused */
/* ========== Decode SCTX ========== */
if (spuh->mh.flags & MH_SCTX_PRES) {
pflags = be32_to_cpu(spuh->sa.proto_flags);
packet_log(" SCTX[0] 0x%08x\n", pflags);
sctx_size = pflags & SCTX_SIZE;
packet_log(" Size %u words\n", sctx_size);
cflags = be32_to_cpu(spuh->sa.cipher_flags);
packet_log(" SCTX[1] 0x%08x\n", cflags);
packet_log(" Inbound:%lu (1:decrypt/vrfy 0:encrypt/auth)\n",
(cflags & CIPHER_INBOUND) >> CIPHER_INBOUND_SHIFT);
packet_log(" Order:%lu (1:AuthFirst 0:EncFirst)\n",
(cflags & CIPHER_ORDER) >> CIPHER_ORDER_SHIFT);
packet_log(" ICV_IS_512:%lx\n",
(cflags & ICV_IS_512) >> ICV_IS_512_SHIFT);
cipher_alg = (cflags & CIPHER_ALG) >> CIPHER_ALG_SHIFT;
cipher_mode = (cflags & CIPHER_MODE) >> CIPHER_MODE_SHIFT;
cipher_type = (cflags & CIPHER_TYPE) >> CIPHER_TYPE_SHIFT;
packet_log(" Crypto Alg:%u Mode:%u Type:%u\n",
cipher_alg, cipher_mode, cipher_type);
hash_alg = (cflags & HASH_ALG) >> HASH_ALG_SHIFT;
hash_mode = (cflags & HASH_MODE) >> HASH_MODE_SHIFT;
hash_type = (cflags & HASH_TYPE) >> HASH_TYPE_SHIFT;
packet_log(" Hash Alg:%x Mode:%x Type:%x\n",
hash_alg, hash_mode, hash_type);
packet_log(" UPDT_Offset:%u\n", cflags & UPDT_OFST);
ecf = be32_to_cpu(spuh->sa.ecf);
packet_log(" SCTX[2] 0x%08x\n", ecf);
packet_log(" WriteICV:%lu CheckICV:%lu ICV_SIZE:%u ",
(ecf & INSERT_ICV) >> INSERT_ICV_SHIFT,
(ecf & CHECK_ICV) >> CHECK_ICV_SHIFT,
(ecf & ICV_SIZE) >> ICV_SIZE_SHIFT);
packet_log("BD_SUPPRESS:%lu\n",
(ecf & BD_SUPPRESS) >> BD_SUPPRESS_SHIFT);
packet_log(" SCTX_IV:%lu ExplicitIV:%lu GenIV:%lu ",
(ecf & SCTX_IV) >> SCTX_IV_SHIFT,
(ecf & EXPLICIT_IV) >> EXPLICIT_IV_SHIFT,
(ecf & GEN_IV) >> GEN_IV_SHIFT);
packet_log("IV_OV_OFST:%lu EXP_IV_SIZE:%u\n",
(ecf & IV_OFFSET) >> IV_OFFSET_SHIFT,
ecf & EXP_IV_SIZE);
ptr += sizeof(struct SCTX);
if (hash_alg && hash_mode) {
char *name = "NONE";
switch (hash_alg) {
case HASH_ALG_MD5:
hash_key_len = 16;
name = "MD5";
break;
case HASH_ALG_SHA1:
hash_key_len = 20;
name = "SHA1";
break;
case HASH_ALG_SHA224:
hash_key_len = 28;
name = "SHA224";
break;
case HASH_ALG_SHA256:
hash_key_len = 32;
name = "SHA256";
break;
case HASH_ALG_SHA384:
hash_key_len = 48;
name = "SHA384";
break;
case HASH_ALG_SHA512:
hash_key_len = 64;
name = "SHA512";
break;
case HASH_ALG_AES:
hash_key_len = 0;
name = "AES";
break;
case HASH_ALG_NONE:
break;
}
packet_log(" Auth Key Type:%s Length:%u Bytes\n",
name, hash_key_len);
packet_dump(" KEY: ", ptr, hash_key_len);
ptr += hash_key_len;
} else if ((hash_alg == HASH_ALG_AES) &&
(hash_mode == HASH_MODE_XCBC)) {
char *name = "NONE";
switch (cipher_type) {
case CIPHER_TYPE_AES128:
hash_key_len = 16;
name = "AES128-XCBC";
break;
case CIPHER_TYPE_AES192:
hash_key_len = 24;
name = "AES192-XCBC";
break;
case CIPHER_TYPE_AES256:
hash_key_len = 32;
name = "AES256-XCBC";
break;
}
packet_log(" Auth Key Type:%s Length:%u Bytes\n",
name, hash_key_len);
packet_dump(" KEY: ", ptr, hash_key_len);
ptr += hash_key_len;
}
if (hash_alg && (hash_mode == HASH_MODE_NONE) &&
(hash_type == HASH_TYPE_UPDT)) {
char *name = "NONE";
switch (hash_alg) {
case HASH_ALG_MD5:
hash_state_len = 16;
name = "MD5";
break;
case HASH_ALG_SHA1:
hash_state_len = 20;
name = "SHA1";
break;
case HASH_ALG_SHA224:
hash_state_len = 32;
name = "SHA224";
break;
case HASH_ALG_SHA256:
hash_state_len = 32;
name = "SHA256";
break;
case HASH_ALG_SHA384:
hash_state_len = 48;
name = "SHA384";
break;
case HASH_ALG_SHA512:
hash_state_len = 64;
name = "SHA512";
break;
case HASH_ALG_AES:
hash_state_len = 0;
name = "AES";
break;
case HASH_ALG_NONE:
break;
}
packet_log(" Auth State Type:%s Length:%u Bytes\n",
name, hash_state_len);
packet_dump(" State: ", ptr, hash_state_len);
ptr += hash_state_len;
}
if (cipher_alg) {
char *name = "NONE";
switch (cipher_alg) {
case CIPHER_ALG_DES:
cipher_key_len = 8;
name = "DES";
break;
case CIPHER_ALG_3DES:
cipher_key_len = 24;
name = "3DES";
break;
case CIPHER_ALG_AES:
switch (cipher_type) {
case CIPHER_TYPE_AES128:
cipher_key_len = 16;
name = "AES128";
break;
case CIPHER_TYPE_AES192:
cipher_key_len = 24;
name = "AES192";
break;
case CIPHER_TYPE_AES256:
cipher_key_len = 32;
name = "AES256";
break;
}
break;
case CIPHER_ALG_NONE:
break;
}
packet_log(" Cipher Key Type:%s Length:%u Bytes\n",
name, cipher_key_len);
/* XTS has two keys */
if (cipher_mode == CIPHER_MODE_XTS) {
packet_dump(" KEY2: ", ptr, cipher_key_len);
ptr += cipher_key_len;
packet_dump(" KEY1: ", ptr, cipher_key_len);
ptr += cipher_key_len;
cipher_key_len *= 2;
} else {
packet_dump(" KEY: ", ptr, cipher_key_len);
ptr += cipher_key_len;
}
if (ecf & SCTX_IV) {
sctx_pl_len = sctx_size * sizeof(u32) -
sizeof(struct SCTX);
iv_len = sctx_pl_len -
(hash_key_len + hash_state_len +
cipher_key_len);
packet_log(" IV Length:%u Bytes\n", iv_len);
packet_dump(" IV: ", ptr, iv_len);
ptr += iv_len;
}
}
}
/* ========== Decode BDESC ========== */
if (spuh->mh.flags & MH_BDESC_PRES) {
struct BDESC_HEADER *bdesc = (struct BDESC_HEADER *)ptr;
packet_log(" BDESC[0] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
packet_log(" OffsetMAC:%u LengthMAC:%u\n",
be16_to_cpu(bdesc->offset_mac),
be16_to_cpu(bdesc->length_mac));
ptr += sizeof(u32);
packet_log(" BDESC[1] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
packet_log(" OffsetCrypto:%u LengthCrypto:%u\n",
be16_to_cpu(bdesc->offset_crypto),
be16_to_cpu(bdesc->length_crypto));
ptr += sizeof(u32);
packet_log(" BDESC[2] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
packet_log(" OffsetICV:%u OffsetIV:%u\n",
be16_to_cpu(bdesc->offset_icv),
be16_to_cpu(bdesc->offset_iv));
ptr += sizeof(u32);
}
/* ========== Decode BD ========== */
if (spuh->mh.flags & MH_BD_PRES) {
struct BD_HEADER *bd = (struct BD_HEADER *)ptr;
packet_log(" BD[0] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
packet_log(" Size:%ubytes PrevLength:%u\n",
be16_to_cpu(bd->size), be16_to_cpu(bd->prev_length));
ptr += 4;
}
/* Double check sanity */
if (buf + buf_len != ptr) {
packet_log(" Packet parsed incorrectly. ");
packet_log("buf:%p buf_len:%u buf+buf_len:%p ptr:%p\n",
buf, buf_len, buf + buf_len, ptr);
}
packet_log("\n");
}