📄 bsg.c
字号:
psize, pdata, d); memcpy(d, pdata, psize); } } d += psize; } } else if (format == __FMT_PACKED) { // the source buffer is a pack_constbuf_t, which has a size and a // pointer. just copy the buffer value, the size is not included in the // output stream. pack_constbuf_t * buf = (pack_constbuf_t*) s; if (dst) { bsglog ("BSG: __FMT_PACKED, size=%d, src=%p, dst=%p\n", buf->size, buf->data, d); memcpy(d, buf->data, buf->size); } s += buf->size; d += buf->size; } else if (format == 0) {// No flags are set. This is a structure & it should // be looked up in the bsg_s_fmt[] const BSG_Format* x = find_format (type); if (x == NULL) { vtpmloginfo(VTPM_LOG_BSG, "BSG_Pack: cannot find type %d\n", type); return -1; } if (dst) bsglog ("BSG_Pack type %s\n", x->name); // iterate through the fields const BSG_UINT32* f = x->fields; for (; *f; f++) { int fsize; g_log_recursion_level++; fsize = BSG_Pack_private((BSG_Type) *f, &s, dst ? d : NULL); g_log_recursion_level--; if (fsize <= 0) return fsize; d += fsize; } } else { vtpmlogerror(VTPM_LOG_BSG, "BSG_Pack(): Unknown format %d\n", format); return -1; } *src = s; return (d - dst);}/** * Unflatten a TCPA structure from a buffer in big-endian format * @type: TCPA structure type * @src: flattened data * @dst: (IN) TCPA structure (OUT) end of TCPA structure * Returns: Flattened size * Note: Returns flattened size NOT the unpacked structure size */static int BSG_Unpack_private(BSG_Type type, const BSG_BYTE* src, BSG_BYTE** dst) { // check incoming parameters if (src == NULL) return 0; const BSG_BYTE* s = src; BSG_BYTE* d = dst ? *dst:NULL; if (dst && !d) dst = NULL; BSG_UINT32 size = __FMT_MASK_SIZE(type); BSG_UINT32 format = __FMT_MASK_FORMAT(type); if (format == __FMT_CONST) {// We are dealing with a fixed length value ie. UINT32 BSG_UINT32 val = BSG_UnpackConst(s, size); if (dst) { switch (size) { case 1: *(BYTE *) d = (BSG_BYTE) val; break; case 2: *(unsigned short*) d = (unsigned short) val; break; case 4: *(BSG_UINT32*) d = (BSG_UINT32) val; break; } } s += size; d += size; } else if (format == __FMT_DATA) {// We are dealing with raw data. Not sure when this is used. if (dst) memcpy(d, s, size); d += size; s += size; } else if (format == __FMT_SIZE || format == __FMT_HSIZE) {// It's a size, followed by that much data or handles BSG_UINT32 psize = BSG_UnpackConst(s, size); if (psize > BSG_MAX_BUF_SIZE) { vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack runs into var-sized data bigger than %u bytes!!\n", BSG_MAX_BUF_SIZE); return -1; } if (dst) { switch (size) { case 1: *(BYTE *) d = (BSG_BYTE) psize; break; case 2: *(unsigned short*) d = (unsigned short) psize; break; case 4: *(BSG_UINT32*) d = (BSG_UINT32) psize; break; } } s += size; d += size; BSG_BYTE* pdata = NULL; if (psize) { if (format == __FMT_HSIZE) { // This is a list of psize Handles if (dst) { BSG_HANDLE* s2 = (BSG_HANDLE*) s; pdata = (BSG_BYTE *)malloc(psize * sizeof(BSG_HANDLE)); if (!pdata) return -1; BSG_HANDLE* p2 = (BSG_HANDLE*) pdata; BSG_UINT32 i; for (i = 0; i < psize; i++) { BSG_PackConst(s2[i], 4, (BSG_BYTE*)(p2 + i)); } } s += psize * sizeof(BSG_HANDLE); } else { // If it's not psize handles, it's psize data. if (dst) { pdata = (BSG_BYTE *)malloc(sizeof(BSG_BYTE) * psize); if (!pdata) return -1; memcpy(pdata, s, psize); } s += psize; } } if (dst) *(void**) d = pdata; d += sizeof(void*); } else if (format == __FMT_PACKED) { // this doesn't make sense for unpacking! vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack() called with format __FMT_PACKED. " "This does not make sense\n"); return -1; } else if (format == 0) {// No flags are set. This is a structure & it should // be looked up in the bsg_s_fmt[] const BSG_Format* x = find_format (type); if (x == NULL) { vtpmlogerror(VTPM_LOG_BSG, "BSG_Unpack: cannot find type %d\n", type); return -1; } const BSG_UINT32* f = x->fields; for (; *f; f++) { int fsize = BSG_Unpack_private((BSG_Type) *f, s, dst ? &d:NULL); if (fsize <= 0) return fsize; s += fsize; } } if (dst) *dst = d; return (s - src);}/** * Free memory associated with unpacked TCPA structure * @type: TCPA structure type * @src: (IN) TCPA structure (OUT) end of TCPA structure * Note: Destroy should be called on all structures created with Unpack * to ensure that any allocated memory is freed */static void BSG_Destroy_private(BSG_Type type, BSG_BYTE** src) { BSG_BYTE* s = *src; BSG_UINT32 size = __FMT_MASK_SIZE(type); BSG_UINT32 format = __FMT_MASK_FORMAT(type); if ((src == NULL) || (*src == NULL)) { vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy() called with NULL src\n"); return; } if (format == __FMT_CONST || format == __FMT_DATA) s += size; else if (format == __FMT_SIZE || format == __FMT_HSIZE) { s += size; BSG_BYTE* ptr = *(BSG_BYTE**) s; free(ptr); s += sizeof(void*); } else if (format == __FMT_PACKED) { // this doesn't make sense for unpacking, hence also for Destroy() vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy() called with format __FMT_PACKED. " "This does not make sense\n"); return; } else if (format == 0) { const BSG_Format* x = find_format (type); if (x == NULL) { vtpmlogerror(VTPM_LOG_BSG, "BSG_Destroy: cannot find type %d\n", type); return; } const BSG_UINT32* f = x->fields; for (; *f; f++) BSG_Destroy_private((BSG_Type) *f, &s); } *src = s;}int BSG_Pack(BSG_Type type, const void* src, BSG_BYTE* dst){ const BSG_BYTE* src2 = (const BSG_BYTE*) src; return BSG_Pack_private(type, &src2, dst);}int BSG_Unpack(BSG_Type type, const BSG_BYTE* src, void* dst){ BSG_BYTE* dst2 = (BSG_BYTE*) dst; return BSG_Unpack_private(type, src, dst ? &dst2:NULL);}void BSG_Destroy(BSG_Type type, void* src){ BSG_BYTE* src2 = (BSG_BYTE*) src; BSG_Destroy_private(type, &src2);} /** * Pack a 8/16/32-bit constant into a buffer in big-endian format * @val: constant value * @size: constant size in bytes (1, 2, or 4) * @dst: (OUT) buffer */void BSG_PackConst(BSG_UINT32 val, int size, BSG_BYTE* dst) { bsglog ("BSG: PackConst on %d of size %i into address %p\n", val, size, dst); switch (size) { case 4: dst[0] = (BSG_BYTE)((val >> 24) & 0xff); dst[1] = (BSG_BYTE)((val >> 16) & 0xff); dst[2] = (BSG_BYTE)((val >> 8) & 0xff); dst[3] = (BSG_BYTE)(val & 0xff); break; case 2: dst[0] = (BSG_BYTE)((val >> 8) & 0xff); dst[1] = (BSG_BYTE)(val & 0xff); break; case 1: dst[0] = (BSG_BYTE)(val & 0xff); break; }}/** * Unpack a 8/16/32-bit constant from a buffer in big-endian format * @src: buffer * @size: constant size in bytes (1, 2, or 4) */BSG_UINT32 BSG_UnpackConst(const BSG_BYTE* src, int size) { BSG_UINT32 val = 0; if (src == NULL) return 0; switch (size) { case 4: val = (((BSG_UINT32) src[0]) << 24 | ((BSG_UINT32) src[1]) << 16 | ((BSG_UINT32) src[2]) << 8 | (BSG_UINT32) src[3]); break; case 2: val = (((BSG_UINT32) src[0]) << 8 | (BSG_UINT32) src[1]); break; case 1: val = (BSG_UINT32) src[0]; break; } return val;}// Pack a list of parameters. Beware not to send values, but rather you must// send a pointer to your values Instead. This includes UINT32's.int BSG_PackList( BSG_BYTE* dst, int ParamCount, ... ) { int ParamNumber; BSG_Type format; BSG_BYTE* val = NULL; int size=0; va_list paramList; va_start( paramList, ParamCount ); for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) { //Strangeness with int is because gcc wanted an int rather than a enum of ints. format = (BSG_Type) va_arg( paramList, int ); val = va_arg( paramList, BSG_BYTE* ); size += BSG_Pack(format, val, dst == NULL ? NULL : dst + size); } va_end (paramList); return size;}// Unpack a list of parameters. int BSG_UnpackList( const BSG_BYTE* src, int ParamCount, ... ) { int ParamNumber = 0; BSG_Type format; BSG_BYTE* val = NULL; int size = 0; va_list paramList; va_start( paramList, ParamCount ); for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) { format = (BSG_Type) va_arg( paramList, int ); val = va_arg( paramList, BSG_BYTE* ); size += BSG_Unpack(format, src + size, val); } va_end( paramList ); return size;}// Destroy any memory allocated by calls to unpack void BSG_DestroyList(int ParamCount, ... ) { int ParamNumber = 0; BSG_Type argType; BSG_BYTE* paramValue = NULL; va_list paramList; va_start( paramList, ParamCount ); for( ParamNumber = 1; ParamNumber <= ParamCount; ParamNumber++) { argType = (BSG_Type) va_arg( paramList, int ); paramValue = va_arg( paramList, BSG_BYTE* ); BSG_Destroy(argType, paramValue); } va_end( paramList ); return;}// and a tuple versionTPM_RESULT BSG_DestroyTuple (int numParams, pack_tuple_t params[]) { int i; for (i = 0; i < numParams; i++) BSG_Destroy (params[i].type, params[i].addr); return TPM_SUCCESS;}//// wrappers of Pack and PackList which malloc the ouput buffer. to be freed// by the caller later//int BSG_PackMalloc (BSG_Type type, const void* src, BSG_BYTE** o_dst) { int size = BSG_Pack (type, src, NULL); BSG_BYTE * dest = (BSG_BYTE*) malloc (size); if (dest == NULL) return -1; size = BSG_Pack(type, src, dest); *o_dst = dest; return size;}int BSG_PackListMalloc(BSG_BYTE** outBuffer, int ParamCount, ... ) { va_list args; int size; va_start (args, ParamCount); size = BSG_PackList (NULL, ParamCount, args); va_end (args); BSG_BYTE * dest = (BSG_BYTE*) malloc (size); if (dest == NULL) return -1; va_start (args, ParamCount); size = BSG_PackList (dest, ParamCount, args); va_end (args); *outBuffer = dest; return size;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -