root/usr/src/uts/common/sys/tsol/label_macro.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _LABEL_MACRO_H
#define _LABEL_MACRO_H

#include <sys/types.h>

#ifdef  __cplusplus
extern "C" {
#endif

/* PRIVATE ONLY TO THE LABEL LIBRARY.  DO NOT USE ELSEWHERE */

/* Actual Binary Label Structure Definitions */

typedef int16_t _Classification;
typedef struct {
        union {
                uint8_t         class_ar[2];
                _Classification class_chunk;
        } class_u;
} Classification_t;

typedef struct {
        uint32_t c1;
        uint32_t c2;
        uint32_t c3;
        uint32_t c4;
        uint32_t c5;
        uint32_t c6;
        uint32_t c7;
        uint32_t c8;
} Compartments_t;

typedef struct {
        uint32_t m1;
        uint32_t m2;
        uint32_t m3;
        uint32_t m4;
        uint32_t m5;
        uint32_t m6;
        uint32_t m7;
        uint32_t m8;
} Markings_t;

typedef struct _mac_label_impl {
        uint8_t id;             /* Magic to say label type */
        uint8_t _c_len;         /* Number of Compartment words */
        Classification_t classification;
        Compartments_t compartments;
} _mac_label_impl_t;

typedef _mac_label_impl_t       _blevel_impl_t,         /* compatibility */
                                _bslabel_impl_t,        /* Sensitivity Label */
                                _bclear_impl_t;         /* Clearance */

typedef struct _binary_information_label_impl { /* Information Label */
        _mac_label_impl_t       binformation_level;
        Markings_t markings;
} _bilabel_impl_t;

typedef struct _binary_cmw_label_impl {         /* CMW Label */
        _bslabel_impl_t bcl_sensitivity_label;
        _bilabel_impl_t bcl_information_label;
} _bclabel_impl_t;

typedef struct _binary_level_range_impl {       /* Level Range */
        _mac_label_impl_t lower_bound;
        _mac_label_impl_t upper_bound;
} _brange_impl_t, brange_t;

#define NMLP_MAX        0x10
#define NSLS_MAX        0x4

typedef _mac_label_impl_t blset_t[NSLS_MAX];

/* Label Identifier Types */

#define SUN_MAC_ID      0x41    /* MAC label, legacy SUN_SL_ID */
#define SUN_UCLR_ID     0x49    /* User Clearance, legacy SUN_CLR_ID */

#define _C_LEN          8       /* number of compartments words */

/* m_label_t macros */
#define _MTYPE(l, t) \
        (((_mac_label_impl_t *)(l))->id == (t))

#define _MSETTYPE(l, t) \
        (((_mac_label_impl_t *)(l))->id = (t))

#define _MGETTYPE(l)    (((_mac_label_impl_t *)(l))->id)

#define _MEQUAL(l1, l2) \
        (LCLASS(l1) == LCLASS(l2) && \
        (l1)->_comps.c1 == (l2)->_comps.c1 && \
        (l1)->_comps.c2 == (l2)->_comps.c2 && \
        (l1)->_comps.c3 == (l2)->_comps.c3 && \
        (l1)->_comps.c4 == (l2)->_comps.c4 && \
        (l1)->_comps.c5 == (l2)->_comps.c5 && \
        (l1)->_comps.c6 == (l2)->_comps.c6 && \
        (l1)->_comps.c7 == (l2)->_comps.c7 && \
        (l1)->_comps.c8 == (l2)->_comps.c8)

#define SUN_INVALID_ID  0       /* uninitialized label */
#define SUN_CMW_ID      0x83    /* 104 - total bytes in CMW Label */
#define SUN_SL_ID       0x41    /* 36 - total bytes in Sensitivity Label */
#define SUN_SL_UN       0xF1    /* undefined Sensitivity Label */
#define SUN_IL_ID       0x42    /* 68 - total bytes in Information Label */
#define SUN_IL_UN       0x73    /* undefined Information Label */
#define SUN_CLR_ID      0x49    /* 36 - total bytes in Clearance */
#define SUN_CLR_UN      0xF9    /* undefined Clearance */

#define _bcl_sl         bcl_sensitivity_label
#define _bcl_il         bcl_information_label
#define _bslev_il       binformation_level

#define _lclass         classification
#ifdef  _BIG_ENDIAN
#define LCLASS(slp)     ((slp)->_lclass.class_u.class_chunk)
#define LCLASS_SET(slp, l)      ((slp)->_lclass.class_u.class_chunk = (l))
#else
#define LCLASS(slp)     \
        ((_Classification)(((slp)->_lclass.class_u.class_ar[0] << 8) | \
        (slp)->_lclass.class_u.class_ar[1]))
#define LCLASS_SET(slp, l)      \
        ((slp)->_lclass.class_u.class_ar[0] = (uint8_t)((l)>> 8), \
        (slp)->_lclass.class_u.class_ar[1] = (uint8_t)(l))
#endif  /* _BIG_ENDIAN */
#define _comps          compartments

#define _iid            _bslev_il.id
#define _i_c_len                _bslev_il._c_len
#define _iclass         _bslev_il._lclass
#ifdef  _BIG_ENDIAN
#define ICLASS(ilp)     ((ilp)->_iclass.class_u.class_chunk)
#define ICLASS_SET(ilp, l)      ((ilp)->_iclass.class_u.class_chunk = (l))
#else
#define ICLASS(ilp)     \
        ((_Classification)(((ilp)->_iclass.class_u.class_ar[0] << 8) | \
        (ilp)->_iclass.class_u.class_ar[1]))
#define ICLASS_SET(ilp, l)      \
        ((ilp)->_iclass.class_u.class_ar[0] = (uint8_t)((l)>> 8), \
        (ilp)->_iclass.class_u.class_ar[1] = (uint8_t)(l))
#endif  /* _BIG_ENDIAN */
#define _icomps         _bslev_il._comps
#define _imarks         markings

/* Manifest Constant Values */

#define LOW_CLASS       0       /* Admin_Low classification value */
#define HIGH_CLASS      0x7FFF  /* Admin_High classification value */
#define EMPTY_SET       0       /* Empty compartments and markings set */
#define UNIVERSAL_SET   0xFFFFFFFFU     /* Universal compartments and */
                                        /* markings set */

/* Construct initial labels */

#define _LOW_LABEL(l, t) \
        ((l)->id = t, (l)->_c_len = _C_LEN, LCLASS_SET(l, LOW_CLASS), \
        (l)->_comps.c1 = (l)->_comps.c2 = (l)->_comps.c3 = (l)->_comps.c4 = \
        (l)->_comps.c5 = (l)->_comps.c6 = (l)->_comps.c7 = (l)->_comps.c8 = \
        EMPTY_SET)

#define _HIGH_LABEL(l, t) \
        ((l)->id = t, (l)->_c_len = _C_LEN, LCLASS_SET(l, HIGH_CLASS), \
        (l)->_comps.c1 = (l)->_comps.c2 = (l)->_comps.c3 = (l)->_comps.c4 = \
        (l)->_comps.c5 = (l)->_comps.c6 = (l)->_comps.c7 = (l)->_comps.c8 = \
        UNIVERSAL_SET)

/* Macro equivalents */

/* Is this memory a properly formatted label of type t? */
#define BLTYPE(l, t) \
        ((t) == SUN_CMW_ID ? \
        (((_bclabel_impl_t *)(l))->_bcl_sl.id == SUN_SL_ID || \
        ((_bclabel_impl_t *)(l))->_bcl_sl.id == SUN_SL_UN) && \
        (((_bclabel_impl_t *)(l))->_bcl_il._iid == SUN_IL_ID || \
        ((_bclabel_impl_t *)(l))->_bcl_il._iid == SUN_IL_UN) : \
        ((_mac_label_impl_t *)(l))->id == (t))

/* Are the levels of these labels equal? */
#define BLEQUAL(l1, l2) \
        _BLEQUAL((_mac_label_impl_t *)(l1), (_mac_label_impl_t *)(l2))

#define _BLEQUAL(l1, l2) \
        (LCLASS(l1) == LCLASS(l2) && \
        (l1)->_comps.c1 == (l2)->_comps.c1 && \
        (l1)->_comps.c2 == (l2)->_comps.c2 && \
        (l1)->_comps.c3 == (l2)->_comps.c3 && \
        (l1)->_comps.c4 == (l2)->_comps.c4 && \
        (l1)->_comps.c5 == (l2)->_comps.c5 && \
        (l1)->_comps.c6 == (l2)->_comps.c6 && \
        (l1)->_comps.c7 == (l2)->_comps.c7 && \
        (l1)->_comps.c8 == (l2)->_comps.c8)

/* Does the level of l1 dominate that of l2? */
#define BLDOMINATES(l1, l2) \
        _BLDOMINATES((_mac_label_impl_t *)(l1), (_mac_label_impl_t *)(l2))

#define _BLDOMINATES(l1, l2) (LCLASS(l1) >= LCLASS(l2) && \
        (l2)->_comps.c1 == ((l1)->_comps.c1 & (l2)->_comps.c1) && \
        (l2)->_comps.c2 == ((l1)->_comps.c2 & (l2)->_comps.c2) && \
        (l2)->_comps.c3 == ((l1)->_comps.c3 & (l2)->_comps.c3) && \
        (l2)->_comps.c4 == ((l1)->_comps.c4 & (l2)->_comps.c4) && \
        (l2)->_comps.c5 == ((l1)->_comps.c5 & (l2)->_comps.c5) && \
        (l2)->_comps.c6 == ((l1)->_comps.c6 & (l2)->_comps.c6) && \
        (l2)->_comps.c7 == ((l1)->_comps.c7 & (l2)->_comps.c7) && \
        (l2)->_comps.c8 == ((l1)->_comps.c8 & (l2)->_comps.c8))

/* Does the level of l1 strictly dominate that of l2? */
#define BLSTRICTDOM(l1, l2) (!BLEQUAL(l1, l2) && BLDOMINATES(l1, l2))

/* Is the level of l within the range r? */
#define BLINRANGE(l, r)\
        (BLDOMINATES((l), &((r)->lower_bound)) && \
        BLDOMINATES(&((r)->upper_bound), (l)))

/* Least Upper Bound level l1 and l2 replacing l1 with the result. */
#define BLMAXIMUM(l1, l2) \
        _BLMAXIMUM((_mac_label_impl_t *)(l1), (_mac_label_impl_t *)(l2))

#define _BLMAXIMUM(l1, l2)\
        (((l1)->_lclass = (LCLASS(l1) < LCLASS(l2)) ? \
        (l2)->_lclass : (l1)->_lclass), \
        (l1)->_comps.c1 |= (l2)->_comps.c1, \
        (l1)->_comps.c2 |= (l2)->_comps.c2, \
        (l1)->_comps.c3 |= (l2)->_comps.c3, \
        (l1)->_comps.c4 |= (l2)->_comps.c4, \
        (l1)->_comps.c5 |= (l2)->_comps.c5, \
        (l1)->_comps.c6 |= (l2)->_comps.c6, \
        (l1)->_comps.c7 |= (l2)->_comps.c7, \
        (l1)->_comps.c8 |= (l2)->_comps.c8)

/* Greatest Lower Bound level l1 and l2 replacing l1 with the result. */
#define BLMINIMUM(l1, l2) \
        _BLMINIMUM((_mac_label_impl_t *)(l1), (_mac_label_impl_t *)(l2))

#define _BLMINIMUM(l1, l2)\
        (((l1)->_lclass = (LCLASS(l1) > LCLASS(l2)) ? \
        (l2)->_lclass : (l1)->_lclass), \
        (l1)->_comps.c1 &= (l2)->_comps.c1, \
        (l1)->_comps.c2 &= (l2)->_comps.c2, \
        (l1)->_comps.c3 &= (l2)->_comps.c3, \
        (l1)->_comps.c4 &= (l2)->_comps.c4, \
        (l1)->_comps.c5 &= (l2)->_comps.c5, \
        (l1)->_comps.c6 &= (l2)->_comps.c6, \
        (l1)->_comps.c7 &= (l2)->_comps.c7, \
        (l1)->_comps.c8 &= (l2)->_comps.c8)

/* Create Manifest Labels */

/* Write a System_Low CMW Label into this memory. */
#define BCLLOW(l) (BSLLOW(BCLTOSL(l)), BILLOW(BCLTOIL(l)))

/* Write a System_Low Sensitivity Label into this memory. */
#define BSLLOW(l) _BSLLOW((_bslabel_impl_t *)(l))

#define _BSLLOW(l) \
        ((l)->id = SUN_SL_ID, (l)->_c_len = _C_LEN, LCLASS_SET(l, LOW_CLASS), \
        (l)->_comps.c1 = (l)->_comps.c2 = (l)->_comps.c3 = (l)->_comps.c4 = \
        (l)->_comps.c5 = (l)->_comps.c6 = (l)->_comps.c7 = (l)->_comps.c8 = \
        EMPTY_SET)

/* Write a System_High Sensitivity Label into this memory. */
#define BSLHIGH(l) _BSLHIGH((_bslabel_impl_t *)(l))

#define _BSLHIGH(l) \
        ((l)->id = SUN_SL_ID, (l)->_c_len = _C_LEN, LCLASS_SET(l, HIGH_CLASS), \
        (l)->_comps.c1 = (l)->_comps.c2 = (l)->_comps.c3 = (l)->_comps.c4 = \
        (l)->_comps.c5 = (l)->_comps.c6 = (l)->_comps.c7 = (l)->_comps.c8 = \
        UNIVERSAL_SET)

/* Write a System_Low Information Label into this memory. */
#define BILLOW(l) _BILLOW((_bilabel_impl_t *)(l))

#define _BILLOW(l) \
        ((l)->_iid = SUN_IL_ID, (l)->_i_c_len = _C_LEN, \
        ICLASS_SET(l, LOW_CLASS), \
        (l)->_icomps.c1 = (l)->_icomps.c2 = (l)->_icomps.c3 = \
        (l)->_icomps.c4 = (l)->_icomps.c5 = (l)->_icomps.c6 = \
        (l)->_icomps.c7 = (l)->_icomps.c8 = EMPTY_SET, \
        (l)->_imarks.m1 = (l)->_imarks.m2 = (l)->_imarks.m3 = \
        (l)->_imarks.m4 = (l)->_imarks.m5 = (l)->_imarks.m6 = \
        (l)->_imarks.m7 = (l)->_imarks.m8 = EMPTY_SET)


/* Write a System_Low Sensitivity Label into this memory. */
#define BCLEARLOW(l) _BCLEARLOW((_bclear_impl_t *)(l))

#define _BCLEARLOW(c) \
        ((c)->id = SUN_CLR_ID, (c)->_c_len = _C_LEN, \
        LCLASS_SET(c, LOW_CLASS), \
        (c)->_comps.c1 = (c)->_comps.c2 = (c)->_comps.c3 = (c)->_comps.c4 = \
        (c)->_comps.c5 = (c)->_comps.c6 = (c)->_comps.c7 = (c)->_comps.c8 = \
        EMPTY_SET)

/* Write a System_High Sensitivity Label into this memory. */
#define BCLEARHIGH(l) _BCLEARHIGH((_bclear_impl_t *)(l))

#define _BCLEARHIGH(c) \
        ((c)->id = SUN_CLR_ID, (c)->_c_len = _C_LEN, \
        LCLASS_SET(c, HIGH_CLASS), \
        (c)->_comps.c1 = (c)->_comps.c2 = (c)->_comps.c3 = (c)->_comps.c4 = \
        (c)->_comps.c5 = (c)->_comps.c6 = (c)->_comps.c7 = (c)->_comps.c8 = \
        UNIVERSAL_SET)

/* Write an undefined Sensitivity Label into this memory. */
#define BSLUNDEF(l) (((_bslabel_impl_t *)(l))->id = SUN_SL_UN)

/* Write an undefined Clearance into this memory. */
#define BCLEARUNDEF(c) (((_bclear_impl_t *)(c))->id = SUN_CLR_UN)

/* Retrieve the Sensitivity Label portion of a CMW Label */
#define BCLTOSL(l) ((bslabel_t *)&((_bclabel_impl_t *)(l))->_bcl_sl)

/* Retrieve the Information Label portion of a CMW Label */
#define BCLTOIL(l) ((_bilabel_impl_t *)&((_bclabel_impl_t *)(l))->_bcl_il)

/* Copy the Sensitivity Label portion from a CMW Label */
#define GETCSL(l1, l2) \
        (*((_bslabel_impl_t *)(l1)) = ((_bclabel_impl_t *)(l2))->_bcl_sl)

/* Replace the Sensitivity Label portion of a CMW Label */
#define SETCSL(l1, l2) \
        (((_bclabel_impl_t *)(l1))->_bcl_sl = *((_bslabel_impl_t *)(l2)))

/* Set type of this memory to the label type 't' */
#define SETBLTYPE(l, t) (((_bclabel_impl_t *)(l))->_bcl_sl.id = (t))

#define GETBLTYPE(l)    (((const _bclabel_impl_t *)(l))->_bcl_sl.id)

#ifdef  __cplusplus
}
#endif

#endif  /* !_LABEL_MACRO_H */