p≡p Trust Rating Engine

Front matter

Title: Trust Rating Specification
Author: Volker Birk
Team: Engine Team
Reviewer(s): TBD
Created: 2021-02-11
Last updated: 2021-02-11
Ticket reference: ENGINE-847


p≡p is securing electronic communication. It is starting with Zero Trust, then building Trust following the Trust On First Use pattern, eventually completed by manual Trust Checks or integration in external Identity Management solutions. Trust Rating is based on this status information. Additionally, it considers the quality of the used cryptography.


This document describes the p≡p Trust Rating Engine, which is part of the p≡p engine, as well as the API for application programmers, which is part of the p≡p API.

Ratings are calculated for Outgoing Messages and Communication Channels on the one hand, and for Incoming Messages on the other.

The delivered rating is the base for the UI concept of p≡p.


  • User: a human being using a p≡p installation in Person to Person Communication

  • System: an IT system being secured by a p≡p installation in Machine to Machine Communication.

  • Identity: maps a Network Address to a User or System (“the Network Address, under which a User or a System appears in the network”)


The Trust Rating Engine is a core part of the p≡p engine. It is an innovation of p≡p.


The p≡p Trust Rating Engine delivers two types of Ratings:

  1. Ratings for “What would be the dependability of Privacy and Security when we send out a message now?”

  2. Ratings for “A message reached us, were Privacy and Security guaranteed for all what we know?”

It bases on the rating of

  • Cryptographic properties
  • Keys
  • Trust information and
  • Attack detection

by combining these information for each rating.

A p≡p Trust Rating is calulated in a three/four step process:

  1. Determine communication type (comm_type), a status sequence of cryptographic properties and key information

  2. Caluclate the rating values of different sources

  3. Add the rating values together

  4. Optional: calculate a color value as brief summary of the Rating

Use cases

This specification defines the design of the Managed Group Encryption Protocol. The following use cases illustrate the reasons why this design was chosen.

Use case:


Use case:


Technical Requirements

Key Rating

Default Key and Sender Key

Trust managment in management.db

Trust on First Use

Trustwords check

Attack detection


Status quo



The comm_type is an 8 bit integer for the rating base defined as sequence of possible states of keys and cryptography for an encrypted communication in the lower 7 bits. When all bits are 0 then the comm_type is unknown (no value). Bit 7 adds trust status information; if it is set then a reliable trust check (i.e. manually executed) was successful.

The following comm_type values are used:

PEP_ct_unknown = 0,

// range 0x01 to 0x09: no encryption, 0x0a to 0x0e: nothing reasonable

PEP_ct_no_encryption = 0x01,                // generic
PEP_ct_no_encrypted_channel = 0x02,
PEP_ct_key_not_found = 0x03,
PEP_ct_key_expired = 0x04,
PEP_ct_key_revoked = 0x05,
PEP_ct_key_b0rken = 0x06,
PEP_ct_key_expired_but_confirmed = 0x07, // NOT with confirmed bit. Just retaining info here in case of renewal.
PEP_ct_my_key_not_included = 0x09,

PEP_ct_security_by_obscurity = 0x0a,
PEP_ct_b0rken_crypto = 0x0b,
PEP_ct_key_too_short = 0x0c,

PEP_ct_compromised = 0x0e,                  // known compromised connection
PEP_ct_compromized = 0x0e,                  // deprecated misspelling
PEP_ct_mistrusted = 0x0f,                   // known mistrusted key

// range 0x10 to 0x3f: unconfirmed encryption

PEP_ct_unconfirmed_encryption = 0x10,       // generic
PEP_ct_OpenPGP_weak_unconfirmed = 0x11,     // RSA 1024 is weak

PEP_ct_to_be_checked = 0x20,                // generic
PEP_ct_SMIME_unconfirmed = 0x21,
PEP_ct_CMS_unconfirmed = 0x22,

PEP_ct_strong_but_unconfirmed = 0x30,       // generic
PEP_ct_OpenPGP_unconfirmed = 0x38,          // key at least 2048 bit RSA or EC
PEP_ct_OTR_unconfirmed = 0x3a,

// range 0x40 to 0x7f: unconfirmed encryption and anonymization

PEP_ct_unconfirmed_enc_anon = 0x40,         // generic
PEP_ct_pEp_unconfirmed = 0x7f,

PEP_ct_confirmed = 0x80,                    // this bit decides if trust is confirmed

// range 0x81 to 0x8f: reserved
// range 0x90 to 0xbf: confirmed encryption

PEP_ct_confirmed_encryption = 0x90,         // generic
PEP_ct_OpenPGP_weak = 0x91,                 // RSA 1024 is weak (unused)

PEP_ct_to_be_checked_confirmed = 0xa0,      // generic
PEP_ct_SMIME = 0xa1,
PEP_ct_CMS = 0xa2,

PEP_ct_strong_encryption = 0xb0,            // generic
PEP_ct_OpenPGP = 0xb8,                      // key at least 2048 bit RSA or EC
PEP_ct_OTR = 0xba,

// range 0xc0 to 0xff: confirmed encryption and anonymization

PEP_ct_confirmed_enc_anon = 0xc0,           // generic
PEP_ct_pEp = 0xff

Rating values

The Rating values are the result of a Rating calculation. The following Rating values are defined:

PEP_rating_undefined = 0,

// no color

PEP_rating_cannot_decrypt = 1,
PEP_rating_have_no_key = 2,
PEP_rating_unencrypted = 3,
PEP_rating_unreliable = 5,

PEP_rating_b0rken = -2,

// yellow

PEP_rating_reliable = 6,

// green

PEP_rating_trusted = 7,
PEP_rating_trusted_and_anonymized = 8,
PEP_rating_fully_anonymous = 9, 

// red

PEP_rating_mistrust = -1,
PEP_rating_under_attack = -3

Base Rating

The Base Rating Rʙ is a Rating value calculated by mapping a comm_type c with the Rating map function:

Rʙ := rating_from_comm_type( c )

DYNAMIC_API PEP_rating rating_from_comm_type(PEP_comm_type ct)
    if (ct == PEP_ct_unknown)
        return PEP_rating_undefined;

    else if (ct == PEP_ct_key_not_found)
        return PEP_rating_have_no_key;

    else if (ct == PEP_ct_compromised)
        return PEP_rating_under_attack;

    else if (ct == PEP_ct_mistrusted)
        return PEP_rating_mistrust;

    if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel ||
            ct == PEP_ct_my_key_not_included)
            return PEP_rating_unencrypted;

    if (ct >= PEP_ct_confirmed_enc_anon)
        return PEP_rating_trusted_and_anonymized;

    else if (ct >= PEP_ct_strong_encryption)
        return PEP_rating_trusted;

    else if (ct >= PEP_ct_strong_but_unconfirmed && ct < PEP_ct_confirmed)
        return PEP_rating_reliable;

        return PEP_rating_unreliable;

Addition of Rating values

Two Rating values can be added together. The result is a Rating value.

R = R₁ ⊕ R₂

The sum of two Rating values is undefined if at least one of the summands is undefined. Otherwise the sum is the minimum of the two summands.

DYNAMIC_API PEP_rating add_rating(PEP_rating rating1, PEP_rating rating2)
    if (rating1 == PEP_rating_undefined || rating2 == PEP_rating_undefined)
        return PEP_rating_undefined;

    return rating1 > rating2 ? rating2 : rating1;

This addition is commutative and associative:

  1. Commutative: R₁ ⊕ R₂ = R₂ ⊕ R₁
  2. Associative: (R₁ ⊕ R₂) ⊕ R₃ = R₁ ⊕ (R₂ ⊕ R₃)

Hence multiple Rating additions can be executed without caring about sequence.




Security considerations

Pros and Cons


For the API see in branch ENGINE-847 pEpEngine/src/rating_api.h


Rating a newly created message


Storage in management DB

The following information must be stored:


Security considerations

Service requirements

Service tooling


Enterprise Toolkit

Affected Teams

  • Implementation: Engine team


  • All p≡p for E-Mail Application teams for implementing UI
  • All p≡p Adapter developers for implementing the extension to the p≡p API
  • The p≡p Enterprise Toolkit developers
  • The p≡p Service & QA team

See also