File: evm-enable.sh

package info (click to toggle)
dracut 110-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,356 kB
  • sloc: sh: 24,895; ansic: 5,236; makefile: 346; perl: 186; python: 48; javascript: 19
file content (169 lines) | stat: -rwxr-xr-x 4,808 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/bin/sh

# Licensed under the GPLv2
#
# Copyright (C) 2011 Politecnico di Torino, Italy
#                    TORSEC group -- http://security.polito.it
# Roberto Sassu <roberto.sassu@polito.it>

EVMSECFILE="${SECURITYFSDIR}/evm"
EVMCONFIG="${NEWROOT}/etc/sysconfig/evm"
EVMKEYDESC="evm-key"
EVMKEYTYPE="encrypted"
EVMKEYID=""
EVM_ACTIVATION_BITS=0

# The following variables can be set in /etc/sysconfig/evm:
# EVMKEY: path to the symmetric key; defaults to /etc/keys/evm-trusted.blob
# EVMKEYDESC: Description of the symmetric key; default is 'evm-key'
# EVMKEYTYPE: Type of the symmetric key; default is 'encrypted'
# EVMX509: path to x509 cert; default is /etc/keys/x509_evm.der
# EVM_ACTIVATION_BITS: additional EVM activation bits, such as
#                      EVM_SETUP_COMPLETE; default is 0
# EVMKEYSDIR: Directory with more x509 certs; default is /etc/keys/evm/

load_evm_key() {
    # read the configuration from the config file
    # shellcheck disable=SC1090
    [ -f "${EVMCONFIG}" ] \
        && . "${EVMCONFIG}"

    # override the EVM key path name from the 'evmkey=' parameter in the kernel
    # command line
    if EVMKEYARG=$(getarg evmkey=); then
        EVMKEY=${EVMKEYARG}
    fi

    # set the default value
    [ -z "${EVMKEY}" ] \
        && EVMKEY="/etc/keys/evm-trusted.blob"

    # set the EVM key path name
    EVMKEYPATH="${NEWROOT}${EVMKEY}"

    # check for EVM encrypted key's existence
    if [ ! -f "${EVMKEYPATH}" ]; then
        if [ "${RD_DEBUG}" = "yes" ]; then
            info "integrity: EVM encrypted key file not found: ${EVMKEYPATH}"
        fi
        return 1
    fi

    # read the EVM encrypted key blob
    read -r KEYBLOB < "${EVMKEYPATH}"

    # load the EVM encrypted key
    if ! EVMKEYID=$(keyctl add ${EVMKEYTYPE} ${EVMKEYDESC} "load ${KEYBLOB}" @u); then
        info "integrity: failed to load the EVM encrypted key: ${EVMKEYDESC}"
        return 1
    fi
    return 0
}

load_evm_x509() {
    info "Load EVM IMA X509"

    # override the EVM key path name from the 'evmx509=' parameter in
    # the kernel command line
    if EVMX509ARG=$(getarg evmx509=); then
        EVMX509=${EVMX509ARG}
    fi

    # set the default value
    [ -z "${EVMX509}" ] \
        && EVMX509="/etc/keys/x509_evm.der"

    # set the EVM public key path name
    EVMX509PATH="${NEWROOT}${EVMX509}"

    # check for EVM public key's existence
    if [ ! -f "${EVMX509PATH}" ]; then
        EVMX509PATH=""
    fi

    local evm_pubid line
    if line=$(keyctl describe %keyring:.evm); then
        # the kernel already setup a trusted .evm keyring so use that one
        evm_pubid=${line%%:*}
    else
        # look for an existing regular keyring
        evm_pubid=$(keyctl search @u keyring _evm)
        if [ -z "${evm_pubid}" ]; then
            # create a new regular _evm keyring
            evm_pubid=$(keyctl newring _evm @u)
        fi
    fi

    if [ -z "${EVMKEYSDIR}" ]; then
        EVMKEYSDIR="/etc/keys/evm"
    fi
    # load the default EVM public key onto the EVM keyring along
    # with all the other ones in $EVMKEYSDIR
    local key_imported=1
    for PUBKEY in ${EVMX509PATH} "${NEWROOT}${EVMKEYSDIR}"/*; do
        if [ ! -f "${PUBKEY}" ]; then
            if [ "${RD_DEBUG}" = "yes" ]; then
                info "integrity: EVM x509 cert file not found: ${PUBKEY}"
            fi
            continue
        fi
        if ! evmctl import "${PUBKEY}" "${evm_pubid}"; then
            info "integrity: failed to load the EVM X509 cert ${PUBKEY}"
            return 1
        fi
        key_imported=0
    done

    if [ "${RD_DEBUG}" = "yes" ]; then
        keyctl show @u
    fi

    return ${key_imported}
}

unload_evm_key() {
    # unlink the EVM encrypted key
    keyctl unlink "${EVMKEYID}" @u || {
        info "integrity: failed to unlink the EVM encrypted key: ${EVMKEYDESC}"
        return 1
    }

    return 0
}

enable_evm() {
    # check kernel support for EVM
    if [ ! -e "${EVMSECFILE}" ]; then
        if [ "${RD_DEBUG}" = "yes" ]; then
            info "integrity: EVM kernel support is disabled"
        fi
        return 0
    fi

    local evm_configured=0
    local EVM_INIT_HMAC=1 EVM_INIT_X509=2

    # try to load the EVM encrypted key
    load_evm_key && evm_configured=${EVM_INIT_HMAC}

    # try to load the EVM public key
    load_evm_x509 && evm_configured=$((evm_configured | EVM_INIT_X509))

    # only enable EVM if a key or x509 certificate could be loaded
    if [ $evm_configured -eq 0 ]; then
        return 1
    fi

    # initialize EVM
    info "Enabling EVM"
    echo $((evm_configured | EVM_ACTIVATION_BITS)) > "${EVMSECFILE}"

    if [ "$((evm_configured & EVM_INIT_HMAC))" -ne 0 ]; then
        # unload the EVM encrypted key
        unload_evm_key || return 1
    fi

    return 0
}

enable_evm