diff mbox series

[RFC,v2,03/12] diglim: Objects

Message ID 20210726163700.2092768-4-roberto.sassu@huawei.com
State New
Headers show
Series integrity: Introduce DIGLIM | expand

Commit Message

Roberto Sassu July 26, 2021, 4:36 p.m. UTC
Define the objects to manage digest lists:

- digest_list_item: a digest list loaded into the kernel;
- digest_list_item_ref: a reference to a digest list;
- digest_item: a digest of a digest list.

Also define some helpers for the objects. More information can be found in
Documentation/security/diglim/implementation.rst.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 .../security/diglim/implementation.rst        | 105 ++++++++++++++
 MAINTAINERS                                   |   1 +
 security/integrity/diglim/diglim.h            | 134 ++++++++++++++++++
 3 files changed, 240 insertions(+)
 create mode 100644 security/integrity/diglim/diglim.h

Comments

Mauro Carvalho Chehab July 28, 2021, 11:38 a.m. UTC | #1
Em Mon, 26 Jul 2021 18:36:51 +0200
Roberto Sassu <roberto.sassu@huawei.com> escreveu:

> Define the objects to manage digest lists:

> 

> - digest_list_item: a digest list loaded into the kernel;

> - digest_list_item_ref: a reference to a digest list;

> - digest_item: a digest of a digest list.

> 

> Also define some helpers for the objects. More information can be found in

> Documentation/security/diglim/implementation.rst.

> 

> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

> ---

>  .../security/diglim/implementation.rst        | 105 ++++++++++++++

>  MAINTAINERS                                   |   1 +

>  security/integrity/diglim/diglim.h            | 134 ++++++++++++++++++

>  3 files changed, 240 insertions(+)

>  create mode 100644 security/integrity/diglim/diglim.h

> 

> diff --git a/Documentation/security/diglim/implementation.rst b/Documentation/security/diglim/implementation.rst

> index 59a180b3bb3f..6002049612a1 100644

> --- a/Documentation/security/diglim/implementation.rst

> +++ b/Documentation/security/diglim/implementation.rst

> @@ -95,3 +95,108 @@ with digest lists:

>  

>  - ``DIGEST_LIST_ADD``: the digest list is being added;

>  - ``DIGEST_LIST_DEL``: the digest list is being deleted.

> +

> +

> +Objects

> +-------

> +

> +This section defines the objects to manage digest lists.

> +

> +.. kernel-doc:: security/integrity/diglim/diglim.h

> +

> +They are represented in the following class diagram:

> +

> +::

> +

> + digest_offset,

> + hdr_offset---------------+

> +                          |

> +                          |

> + +------------------+     |     +----------------------+

> + | digest_list_item |--- N:1 ---| digest_list_item_ref |

> + +------------------+           +----------------------+

> +                                           |

> +                                          1:N

> +                                           |

> +                                    +-------------+

> +                                    | digest_item |

> +                                    +-------------+

> +

> +A ``digest_list_item`` is associated to one or multiple

> +``digest_list_item_ref``, one for each digest it contains. However,

> +a ``digest_list_item_ref`` is associated to only one ``digest_list_item``,

> +as it represents a single location within a specific digest list.

> +

> +Given that a ``digest_list_item_ref`` represents a single location, it is

> +associated to only one ``digest_item``. However, a ``digest_item`` can have

> +multiple references (as it might appears multiple times within the same

> +digest list or in different digest lists, if it is duplicated).

> +

> +All digest list references are stored for a given digest, so that a query

> +result can include the OR of the modifiers and actions of each referenced

> +digest list.

> +

> +The relationship between the described objects can be graphically

> +represented as:

> +

> +::


Just merge "::" at the previous line (everywhere).

> +

> + Hash table            +-------------+         +-------------+

> + PARSER      +-----+   | digest_item |         | digest_item |

> + FILE        | key |-->|             |-->...-->|             |

> + METADATA    +-----+   |ref0|...|refN|         |ref0|...|refN|

> +                       +-------------+         +-------------+

> +            ref0:         |                               | refN:

> +            digest_offset | +-----------------------------+ digest_offset

> +            hdr_offset    | |                               hdr_offset

> +                          | |

> +                          V V

> +                     +--------------------+

> +                     |  digest_list_item  |

> +                     |                    |

> +                     | size, buf, actions |

> +                     +--------------------+

> +                          ^

> +                          |

> + Hash table            +-------------+         +-------------+

> + DIGEST_LIST +-----+   |ref0         |         |ref0         |

> +             | key |-->|             |-->...-->|             |

> +             +-----+   | digest_item |         | digest_item |

> +                       +-------------+         +-------------+

> +

> +The reference for the digest of the digest list differs from the references

> +for the other digest types. ``digest_offset`` and ``hdr_offset`` are set to

> +zero, so that the digest of the digest list is retrieved from the

> +``digest_list_item`` structure directly (see ``get_digest()`` below).

> +

> +Finally, this section defines useful helpers to access a digest or the

> +header the digest belongs to. For example:

> +

> +::

> +

> + static inline struct compact_list_hdr *get_hdr(

> +                                      struct digest_list_item *digest_list,

> +                                      loff_t hdr_offset)


I would write this to avoid ending a line with an open parenthesis. You could,
for instance, write it as:

	static inline struct compact_list_hdr *
	get_hdr(struct digest_list_item *digest_list,
		off_t hdr_offset)

if you also want to avoid to have a line bigger than 80 columns.

> + {

> +         return (struct compact_list_hdr *)(digest_list->buf + hdr_offset);

> + }

> +

> +the header can be obtained by summing the address of the digest list buffer

> +in the ``digest_list_item`` structure with ``hdr_offset``.

> +

> +Similarly:

> +

> +::

> +

> + static inline u8 *get_digest(struct digest_list_item *digest_list,

> +                              loff_t digest_offset, loff_t hdr_offset)

> + {

> +         /* Digest list digest is stored in a different place. */

> +         if (!digest_offset)

> +                 return digest_list->digest;

> +         return digest_list->buf + digest_offset;

> + }

> +

> +the digest can be obtained by summing the address of the digest list buffer

> +with ``digest_offset`` (except for the digest lists, where the digest is

> +stored in the ``digest`` field of the ``digest_list_item`` structure).

> diff --git a/MAINTAINERS b/MAINTAINERS

> index f61f5239468a..f7592d41367d 100644

> --- a/MAINTAINERS

> +++ b/MAINTAINERS

> @@ -5462,6 +5462,7 @@ F:	Documentation/security/diglim/implementation.rst

>  F:	Documentation/security/diglim/index.rst

>  F:	Documentation/security/diglim/introduction.rst

>  F:	include/uapi/linux/diglim.h

> +F:	security/integrity/diglim/diglim.h

>  

>  DIOLAN U2C-12 I2C DRIVER

>  M:	Guenter Roeck <linux@roeck-us.net>

> diff --git a/security/integrity/diglim/diglim.h b/security/integrity/diglim/diglim.h

> new file mode 100644

> index 000000000000..578253d7e1d1

> --- /dev/null

> +++ b/security/integrity/diglim/diglim.h

> @@ -0,0 +1,134 @@

> +/* SPDX-License-Identifier: GPL-2.0 */

> +/*

> + * Copyright (C) 2005,2006,2007,2008 IBM Corporation

> + * Copyright (C) 2017-2021 Huawei Technologies Duesseldorf GmbH

> + *

> + * Author: Roberto Sassu <roberto.sassu@huawei.com>

> + *

> + * Definitions only used inside DIGLIM.

> + */

> +

> +#ifndef __DIGLIM_INTERNAL_H

> +#define __DIGLIM_INTERNAL_H

> +

> +#include <linux/types.h>

> +#include <linux/crypto.h>

> +#include <linux/fs.h>

> +#include <linux/security.h>

> +#include <linux/hash.h>

> +#include <linux/tpm.h>

> +#include <linux/audit.h>

> +#include <crypto/hash_info.h>

> +#include <linux/hash_info.h>

> +#include <uapi/linux/diglim.h>

> +

> +#define MAX_DIGEST_SIZE 64

> +#define HASH_BITS 10

> +#define DIGLIM_HTABLE_SIZE (1 << HASH_BITS)

> +

> +/**

> + * struct digest_list_item - a digest list loaded into the kernel

> + *

> + * @size: size of the digest list buffer

> + * @buf: digest list buffer

> + * @digest: digest of the digest list

> + * @label: label used to identify the digest list (e.g. file name)

> + * @actions: actions performed on the digest list

> + * @algo: digest algorithm

> + */

> +struct digest_list_item {

> +	loff_t size;

> +	u8 *buf;

> +	u8 digest[64];

> +	const char *label;

> +	u8 actions;

> +	enum hash_algo algo;

> +};

> +

> +/**

> + * struct digest_list_item_ref - a reference to a digest list

> + *

> + * @list: linked list pointers

> + * @digest_list: pointer to struct digest_list_item

> + * @digest_offset: offset of the digest in the referenced digest list

> + * @hdr_offset: offset of the header the digest refers to in the digest list

> + */

> +struct digest_list_item_ref {

> +	struct list_head list;

> +	struct digest_list_item *digest_list;

> +	u32 digest_offset;

> +	u32 hdr_offset;

> +};

> +

> +/**

> + * struct digest_item - a digest of a digest list

> + *

> + * @hnext: pointers of the hash table

> + * @refs: linked list of struct digest_list_item_ref

> + */

> +struct digest_item {

> +	struct hlist_node hnext;

> +	struct list_head refs;

> +};

> +



> +struct h_table {

> +	unsigned long len;

> +	struct hlist_head queue[DIGLIM_HTABLE_SIZE];

> +};

> +

> +static inline unsigned int hash_key(u8 *digest)

> +{

> +	return (digest[0] | digest[1] << 8) % DIGLIM_HTABLE_SIZE;

> +}

> +

> +static inline struct compact_list_hdr *get_hdr(

> +					struct digest_list_item *digest_list,

> +					loff_t hdr_offset)


Same here with regards to open parenthesis.

> +{

> +	return (struct compact_list_hdr *)(digest_list->buf + hdr_offset);

> +}

> +

> +static inline enum hash_algo get_algo(struct digest_list_item *digest_list,

> +				      loff_t digest_offset, loff_t hdr_offset)

> +{

> +	/* Digest list digest algorithm is stored in a different place. */

> +	if (!digest_offset)

> +		return digest_list->algo;

> +

> +	return get_hdr(digest_list, hdr_offset)->algo;

> +}

> +

> +static inline u8 *get_digest(struct digest_list_item *digest_list,

> +			     loff_t digest_offset, loff_t hdr_offset)

> +{

> +	/* Digest list digest is stored in a different place. */

> +	if (!digest_offset)

> +		return digest_list->digest;

> +

> +	return digest_list->buf + digest_offset;

> +}

> +

> +static inline struct compact_list_hdr *get_hdr_ref(

> +					struct digest_list_item_ref *ref)

> +{

> +	return get_hdr(ref->digest_list, ref->hdr_offset);

> +}

> +

> +static inline enum hash_algo get_algo_ref(struct digest_list_item_ref *ref)

> +{

> +	/* Digest list digest algorithm is stored in a different place. */

> +	if (!ref->digest_offset)

> +		return ref->digest_list->algo;

> +

> +	return get_hdr_ref(ref)->algo;

> +}

> +

> +static inline u8 *get_digest_ref(struct digest_list_item_ref *ref)

> +{

> +	/* Digest list digest is stored in a different place. */

> +	if (!ref->digest_offset)

> +		return ref->digest_list->digest;

> +

> +	return ref->digest_list->buf + ref->digest_offset;

> +}


I would also document the above static inline functions and 
struct h_table.

> +#endif /*__DIGLIM_INTERNAL_H*/




Thanks,
Mauro
Roberto Sassu July 28, 2021, 11:47 a.m. UTC | #2
> From: Mauro Carvalho Chehab [mailto:mchehab+huawei@kernel.org]

> Sent: Wednesday, July 28, 2021 1:39 PM

> Em Mon, 26 Jul 2021 18:36:51 +0200

> Roberto Sassu <roberto.sassu@huawei.com> escreveu:

> 

> > Define the objects to manage digest lists:

> >

> > - digest_list_item: a digest list loaded into the kernel;

> > - digest_list_item_ref: a reference to a digest list;

> > - digest_item: a digest of a digest list.

> >

> > Also define some helpers for the objects. More information can be found in

> > Documentation/security/diglim/implementation.rst.

> >

> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

> > ---

> >  .../security/diglim/implementation.rst        | 105 ++++++++++++++

> >  MAINTAINERS                                   |   1 +

> >  security/integrity/diglim/diglim.h            | 134 ++++++++++++++++++

> >  3 files changed, 240 insertions(+)

> >  create mode 100644 security/integrity/diglim/diglim.h

> >

> > diff --git a/Documentation/security/diglim/implementation.rst

> b/Documentation/security/diglim/implementation.rst

> > index 59a180b3bb3f..6002049612a1 100644

> > --- a/Documentation/security/diglim/implementation.rst

> > +++ b/Documentation/security/diglim/implementation.rst

> > @@ -95,3 +95,108 @@ with digest lists:

> >

> >  - ``DIGEST_LIST_ADD``: the digest list is being added;

> >  - ``DIGEST_LIST_DEL``: the digest list is being deleted.

> > +

> > +

> > +Objects

> > +-------

> > +

> > +This section defines the objects to manage digest lists.

> > +

> > +.. kernel-doc:: security/integrity/diglim/diglim.h

> > +

> > +They are represented in the following class diagram:

> > +

> > +::

> > +

> > + digest_offset,

> > + hdr_offset---------------+

> > +                          |

> > +                          |

> > + +------------------+     |     +----------------------+

> > + | digest_list_item |--- N:1 ---| digest_list_item_ref |

> > + +------------------+           +----------------------+

> > +                                           |

> > +                                          1:N

> > +                                           |

> > +                                    +-------------+

> > +                                    | digest_item |

> > +                                    +-------------+

> > +

> > +A ``digest_list_item`` is associated to one or multiple

> > +``digest_list_item_ref``, one for each digest it contains. However,

> > +a ``digest_list_item_ref`` is associated to only one ``digest_list_item``,

> > +as it represents a single location within a specific digest list.

> > +

> > +Given that a ``digest_list_item_ref`` represents a single location, it is

> > +associated to only one ``digest_item``. However, a ``digest_item`` can have

> > +multiple references (as it might appears multiple times within the same

> > +digest list or in different digest lists, if it is duplicated).

> > +

> > +All digest list references are stored for a given digest, so that a query

> > +result can include the OR of the modifiers and actions of each referenced

> > +digest list.

> > +

> > +The relationship between the described objects can be graphically

> > +represented as:

> > +

> > +::

> 

> Just merge "::" at the previous line (everywhere).


Ok.

> > +

> > + Hash table            +-------------+         +-------------+

> > + PARSER      +-----+   | digest_item |         | digest_item |

> > + FILE        | key |-->|             |-->...-->|             |

> > + METADATA    +-----+   |ref0|...|refN|         |ref0|...|refN|

> > +                       +-------------+         +-------------+

> > +            ref0:         |                               | refN:

> > +            digest_offset | +-----------------------------+ digest_offset

> > +            hdr_offset    | |                               hdr_offset

> > +                          | |

> > +                          V V

> > +                     +--------------------+

> > +                     |  digest_list_item  |

> > +                     |                    |

> > +                     | size, buf, actions |

> > +                     +--------------------+

> > +                          ^

> > +                          |

> > + Hash table            +-------------+         +-------------+

> > + DIGEST_LIST +-----+   |ref0         |         |ref0         |

> > +             | key |-->|             |-->...-->|             |

> > +             +-----+   | digest_item |         | digest_item |

> > +                       +-------------+         +-------------+

> > +

> > +The reference for the digest of the digest list differs from the references

> > +for the other digest types. ``digest_offset`` and ``hdr_offset`` are set to

> > +zero, so that the digest of the digest list is retrieved from the

> > +``digest_list_item`` structure directly (see ``get_digest()`` below).

> > +

> > +Finally, this section defines useful helpers to access a digest or the

> > +header the digest belongs to. For example:

> > +

> > +::

> > +

> > + static inline struct compact_list_hdr *get_hdr(

> > +                                      struct digest_list_item *digest_list,

> > +                                      loff_t hdr_offset)

> 

> I would write this to avoid ending a line with an open parenthesis. You could,

> for instance, write it as:

> 

> 	static inline struct compact_list_hdr *

> 	get_hdr(struct digest_list_item *digest_list,

> 		off_t hdr_offset)

> 

> if you also want to avoid to have a line bigger than 80 columns.


Ok.

> > + {

> > +         return (struct compact_list_hdr *)(digest_list->buf + hdr_offset);

> > + }

> > +

> > +the header can be obtained by summing the address of the digest list buffer

> > +in the ``digest_list_item`` structure with ``hdr_offset``.

> > +

> > +Similarly:

> > +

> > +::

> > +

> > + static inline u8 *get_digest(struct digest_list_item *digest_list,

> > +                              loff_t digest_offset, loff_t hdr_offset)

> > + {

> > +         /* Digest list digest is stored in a different place. */

> > +         if (!digest_offset)

> > +                 return digest_list->digest;

> > +         return digest_list->buf + digest_offset;

> > + }

> > +

> > +the digest can be obtained by summing the address of the digest list buffer

> > +with ``digest_offset`` (except for the digest lists, where the digest is

> > +stored in the ``digest`` field of the ``digest_list_item`` structure).

> > diff --git a/MAINTAINERS b/MAINTAINERS

> > index f61f5239468a..f7592d41367d 100644

> > --- a/MAINTAINERS

> > +++ b/MAINTAINERS

> > @@ -5462,6 +5462,7 @@ F:

> 	Documentation/security/diglim/implementation.rst

> >  F:	Documentation/security/diglim/index.rst

> >  F:	Documentation/security/diglim/introduction.rst

> >  F:	include/uapi/linux/diglim.h

> > +F:	security/integrity/diglim/diglim.h

> >

> >  DIOLAN U2C-12 I2C DRIVER

> >  M:	Guenter Roeck <linux@roeck-us.net>

> > diff --git a/security/integrity/diglim/diglim.h

> b/security/integrity/diglim/diglim.h

> > new file mode 100644

> > index 000000000000..578253d7e1d1

> > --- /dev/null

> > +++ b/security/integrity/diglim/diglim.h

> > @@ -0,0 +1,134 @@

> > +/* SPDX-License-Identifier: GPL-2.0 */

> > +/*

> > + * Copyright (C) 2005,2006,2007,2008 IBM Corporation

> > + * Copyright (C) 2017-2021 Huawei Technologies Duesseldorf GmbH

> > + *

> > + * Author: Roberto Sassu <roberto.sassu@huawei.com>

> > + *

> > + * Definitions only used inside DIGLIM.

> > + */

> > +

> > +#ifndef __DIGLIM_INTERNAL_H

> > +#define __DIGLIM_INTERNAL_H

> > +

> > +#include <linux/types.h>

> > +#include <linux/crypto.h>

> > +#include <linux/fs.h>

> > +#include <linux/security.h>

> > +#include <linux/hash.h>

> > +#include <linux/tpm.h>

> > +#include <linux/audit.h>

> > +#include <crypto/hash_info.h>

> > +#include <linux/hash_info.h>

> > +#include <uapi/linux/diglim.h>

> > +

> > +#define MAX_DIGEST_SIZE 64

> > +#define HASH_BITS 10

> > +#define DIGLIM_HTABLE_SIZE (1 << HASH_BITS)

> > +

> > +/**

> > + * struct digest_list_item - a digest list loaded into the kernel

> > + *

> > + * @size: size of the digest list buffer

> > + * @buf: digest list buffer

> > + * @digest: digest of the digest list

> > + * @label: label used to identify the digest list (e.g. file name)

> > + * @actions: actions performed on the digest list

> > + * @algo: digest algorithm

> > + */

> > +struct digest_list_item {

> > +	loff_t size;

> > +	u8 *buf;

> > +	u8 digest[64];

> > +	const char *label;

> > +	u8 actions;

> > +	enum hash_algo algo;

> > +};

> > +

> > +/**

> > + * struct digest_list_item_ref - a reference to a digest list

> > + *

> > + * @list: linked list pointers

> > + * @digest_list: pointer to struct digest_list_item

> > + * @digest_offset: offset of the digest in the referenced digest list

> > + * @hdr_offset: offset of the header the digest refers to in the digest list

> > + */

> > +struct digest_list_item_ref {

> > +	struct list_head list;

> > +	struct digest_list_item *digest_list;

> > +	u32 digest_offset;

> > +	u32 hdr_offset;

> > +};

> > +

> > +/**

> > + * struct digest_item - a digest of a digest list

> > + *

> > + * @hnext: pointers of the hash table

> > + * @refs: linked list of struct digest_list_item_ref

> > + */

> > +struct digest_item {

> > +	struct hlist_node hnext;

> > +	struct list_head refs;

> > +};

> > +

> 

> 

> > +struct h_table {

> > +	unsigned long len;

> > +	struct hlist_head queue[DIGLIM_HTABLE_SIZE];

> > +};

> > +

> > +static inline unsigned int hash_key(u8 *digest)

> > +{

> > +	return (digest[0] | digest[1] << 8) % DIGLIM_HTABLE_SIZE;

> > +}

> > +

> > +static inline struct compact_list_hdr *get_hdr(

> > +					struct digest_list_item *digest_list,

> > +					loff_t hdr_offset)

> 

> Same here with regards to open parenthesis.

> 

> > +{

> > +	return (struct compact_list_hdr *)(digest_list->buf + hdr_offset);

> > +}

> > +

> > +static inline enum hash_algo get_algo(struct digest_list_item *digest_list,

> > +				      loff_t digest_offset, loff_t hdr_offset)

> > +{

> > +	/* Digest list digest algorithm is stored in a different place. */

> > +	if (!digest_offset)

> > +		return digest_list->algo;

> > +

> > +	return get_hdr(digest_list, hdr_offset)->algo;

> > +}

> > +

> > +static inline u8 *get_digest(struct digest_list_item *digest_list,

> > +			     loff_t digest_offset, loff_t hdr_offset)

> > +{

> > +	/* Digest list digest is stored in a different place. */

> > +	if (!digest_offset)

> > +		return digest_list->digest;

> > +

> > +	return digest_list->buf + digest_offset;

> > +}

> > +

> > +static inline struct compact_list_hdr *get_hdr_ref(

> > +					struct digest_list_item_ref *ref)

> > +{

> > +	return get_hdr(ref->digest_list, ref->hdr_offset);

> > +}

> > +

> > +static inline enum hash_algo get_algo_ref(struct digest_list_item_ref *ref)

> > +{

> > +	/* Digest list digest algorithm is stored in a different place. */

> > +	if (!ref->digest_offset)

> > +		return ref->digest_list->algo;

> > +

> > +	return get_hdr_ref(ref)->algo;

> > +}

> > +

> > +static inline u8 *get_digest_ref(struct digest_list_item_ref *ref)

> > +{

> > +	/* Digest list digest is stored in a different place. */

> > +	if (!ref->digest_offset)

> > +		return ref->digest_list->digest;

> > +

> > +	return ref->digest_list->buf + ref->digest_offset;

> > +}

> 

> I would also document the above static inline functions and

> struct h_table.


Ok.

Thanks

Roberto

HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Li Peng, Li Jian, Shi Yanli

> > +#endif /*__DIGLIM_INTERNAL_H*/

> 

> 

> 

> Thanks,

> Mauro
diff mbox series

Patch

diff --git a/Documentation/security/diglim/implementation.rst b/Documentation/security/diglim/implementation.rst
index 59a180b3bb3f..6002049612a1 100644
--- a/Documentation/security/diglim/implementation.rst
+++ b/Documentation/security/diglim/implementation.rst
@@ -95,3 +95,108 @@  with digest lists:
 
 - ``DIGEST_LIST_ADD``: the digest list is being added;
 - ``DIGEST_LIST_DEL``: the digest list is being deleted.
+
+
+Objects
+-------
+
+This section defines the objects to manage digest lists.
+
+.. kernel-doc:: security/integrity/diglim/diglim.h
+
+They are represented in the following class diagram:
+
+::
+
+ digest_offset,
+ hdr_offset---------------+
+                          |
+                          |
+ +------------------+     |     +----------------------+
+ | digest_list_item |--- N:1 ---| digest_list_item_ref |
+ +------------------+           +----------------------+
+                                           |
+                                          1:N
+                                           |
+                                    +-------------+
+                                    | digest_item |
+                                    +-------------+
+
+A ``digest_list_item`` is associated to one or multiple
+``digest_list_item_ref``, one for each digest it contains. However,
+a ``digest_list_item_ref`` is associated to only one ``digest_list_item``,
+as it represents a single location within a specific digest list.
+
+Given that a ``digest_list_item_ref`` represents a single location, it is
+associated to only one ``digest_item``. However, a ``digest_item`` can have
+multiple references (as it might appears multiple times within the same
+digest list or in different digest lists, if it is duplicated).
+
+All digest list references are stored for a given digest, so that a query
+result can include the OR of the modifiers and actions of each referenced
+digest list.
+
+The relationship between the described objects can be graphically
+represented as:
+
+::
+
+ Hash table            +-------------+         +-------------+
+ PARSER      +-----+   | digest_item |         | digest_item |
+ FILE        | key |-->|             |-->...-->|             |
+ METADATA    +-----+   |ref0|...|refN|         |ref0|...|refN|
+                       +-------------+         +-------------+
+            ref0:         |                               | refN:
+            digest_offset | +-----------------------------+ digest_offset
+            hdr_offset    | |                               hdr_offset
+                          | |
+                          V V
+                     +--------------------+
+                     |  digest_list_item  |
+                     |                    |
+                     | size, buf, actions |
+                     +--------------------+
+                          ^
+                          |
+ Hash table            +-------------+         +-------------+
+ DIGEST_LIST +-----+   |ref0         |         |ref0         |
+             | key |-->|             |-->...-->|             |
+             +-----+   | digest_item |         | digest_item |
+                       +-------------+         +-------------+
+
+The reference for the digest of the digest list differs from the references
+for the other digest types. ``digest_offset`` and ``hdr_offset`` are set to
+zero, so that the digest of the digest list is retrieved from the
+``digest_list_item`` structure directly (see ``get_digest()`` below).
+
+Finally, this section defines useful helpers to access a digest or the
+header the digest belongs to. For example:
+
+::
+
+ static inline struct compact_list_hdr *get_hdr(
+                                      struct digest_list_item *digest_list,
+                                      loff_t hdr_offset)
+ {
+         return (struct compact_list_hdr *)(digest_list->buf + hdr_offset);
+ }
+
+the header can be obtained by summing the address of the digest list buffer
+in the ``digest_list_item`` structure with ``hdr_offset``.
+
+Similarly:
+
+::
+
+ static inline u8 *get_digest(struct digest_list_item *digest_list,
+                              loff_t digest_offset, loff_t hdr_offset)
+ {
+         /* Digest list digest is stored in a different place. */
+         if (!digest_offset)
+                 return digest_list->digest;
+         return digest_list->buf + digest_offset;
+ }
+
+the digest can be obtained by summing the address of the digest list buffer
+with ``digest_offset`` (except for the digest lists, where the digest is
+stored in the ``digest`` field of the ``digest_list_item`` structure).
diff --git a/MAINTAINERS b/MAINTAINERS
index f61f5239468a..f7592d41367d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5462,6 +5462,7 @@  F:	Documentation/security/diglim/implementation.rst
 F:	Documentation/security/diglim/index.rst
 F:	Documentation/security/diglim/introduction.rst
 F:	include/uapi/linux/diglim.h
+F:	security/integrity/diglim/diglim.h
 
 DIOLAN U2C-12 I2C DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
diff --git a/security/integrity/diglim/diglim.h b/security/integrity/diglim/diglim.h
new file mode 100644
index 000000000000..578253d7e1d1
--- /dev/null
+++ b/security/integrity/diglim/diglim.h
@@ -0,0 +1,134 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2005,2006,2007,2008 IBM Corporation
+ * Copyright (C) 2017-2021 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ *
+ * Definitions only used inside DIGLIM.
+ */
+
+#ifndef __DIGLIM_INTERNAL_H
+#define __DIGLIM_INTERNAL_H
+
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/fs.h>
+#include <linux/security.h>
+#include <linux/hash.h>
+#include <linux/tpm.h>
+#include <linux/audit.h>
+#include <crypto/hash_info.h>
+#include <linux/hash_info.h>
+#include <uapi/linux/diglim.h>
+
+#define MAX_DIGEST_SIZE 64
+#define HASH_BITS 10
+#define DIGLIM_HTABLE_SIZE (1 << HASH_BITS)
+
+/**
+ * struct digest_list_item - a digest list loaded into the kernel
+ *
+ * @size: size of the digest list buffer
+ * @buf: digest list buffer
+ * @digest: digest of the digest list
+ * @label: label used to identify the digest list (e.g. file name)
+ * @actions: actions performed on the digest list
+ * @algo: digest algorithm
+ */
+struct digest_list_item {
+	loff_t size;
+	u8 *buf;
+	u8 digest[64];
+	const char *label;
+	u8 actions;
+	enum hash_algo algo;
+};
+
+/**
+ * struct digest_list_item_ref - a reference to a digest list
+ *
+ * @list: linked list pointers
+ * @digest_list: pointer to struct digest_list_item
+ * @digest_offset: offset of the digest in the referenced digest list
+ * @hdr_offset: offset of the header the digest refers to in the digest list
+ */
+struct digest_list_item_ref {
+	struct list_head list;
+	struct digest_list_item *digest_list;
+	u32 digest_offset;
+	u32 hdr_offset;
+};
+
+/**
+ * struct digest_item - a digest of a digest list
+ *
+ * @hnext: pointers of the hash table
+ * @refs: linked list of struct digest_list_item_ref
+ */
+struct digest_item {
+	struct hlist_node hnext;
+	struct list_head refs;
+};
+
+struct h_table {
+	unsigned long len;
+	struct hlist_head queue[DIGLIM_HTABLE_SIZE];
+};
+
+static inline unsigned int hash_key(u8 *digest)
+{
+	return (digest[0] | digest[1] << 8) % DIGLIM_HTABLE_SIZE;
+}
+
+static inline struct compact_list_hdr *get_hdr(
+					struct digest_list_item *digest_list,
+					loff_t hdr_offset)
+{
+	return (struct compact_list_hdr *)(digest_list->buf + hdr_offset);
+}
+
+static inline enum hash_algo get_algo(struct digest_list_item *digest_list,
+				      loff_t digest_offset, loff_t hdr_offset)
+{
+	/* Digest list digest algorithm is stored in a different place. */
+	if (!digest_offset)
+		return digest_list->algo;
+
+	return get_hdr(digest_list, hdr_offset)->algo;
+}
+
+static inline u8 *get_digest(struct digest_list_item *digest_list,
+			     loff_t digest_offset, loff_t hdr_offset)
+{
+	/* Digest list digest is stored in a different place. */
+	if (!digest_offset)
+		return digest_list->digest;
+
+	return digest_list->buf + digest_offset;
+}
+
+static inline struct compact_list_hdr *get_hdr_ref(
+					struct digest_list_item_ref *ref)
+{
+	return get_hdr(ref->digest_list, ref->hdr_offset);
+}
+
+static inline enum hash_algo get_algo_ref(struct digest_list_item_ref *ref)
+{
+	/* Digest list digest algorithm is stored in a different place. */
+	if (!ref->digest_offset)
+		return ref->digest_list->algo;
+
+	return get_hdr_ref(ref)->algo;
+}
+
+static inline u8 *get_digest_ref(struct digest_list_item_ref *ref)
+{
+	/* Digest list digest is stored in a different place. */
+	if (!ref->digest_offset)
+		return ref->digest_list->digest;
+
+	return ref->digest_list->buf + ref->digest_offset;
+}
+#endif /*__DIGLIM_INTERNAL_H*/