Integrity Measurement Architecture(IMA) & Linux Extended Verification Module (EVM) - security

I am trying to activate IMA appraisal & EVM modules.
After compiling linux kernel 3.10.2 on my bt5R3 and setting kernel boot option in a first time like this:
GRUB_CMDLINE_LINUX="rootflags=i_version ima_tcb ima_appraise=fix ima_appraise_tcb evm=fix"
and after running this command to generate xattr security.ima and security.evm
find / \( -fstype rootfs -o -fstype ext4 \) -type f -uid 0 -exec head -c 1 '{}' \;
like this:
GRUB_CMDLINE_LINUX="rootflags=i_version ima_tcb ima_appraise=enforce ima_appraise_tcb evm=enforce"
I try to create digital signature of xattr like it's recommended on this tutorial
Tutorial to IMA & EVM
Every steps have been followed, creating RSA keys, loading them early at boot in initramfs with keyctl.
Session Keyring
-3 --alswrv 0 65534 keyring: _uid_ses.0
977514165 --alswrv 0 65534 \_ keyring: _uid.0
572301790 --alswrv 0 0 \_ user: kmk-user
126316032 --alswrv 0 0 \_ encrypted: evm-key
570886575 --alswrv 0 0 \_ keyring: _ima
304346597 --alswrv 0 0 \_ keyring: _evm
However as soon as I reboot my OS when I try to read a signed and hashed file I get the error "Permission Denied"
Running dmesg tells me :
[ 5461.175996] type=1800 audit(1375262160.913:57): pid=1756 uid=0 auid=4294967295 ses=4294967295 op="appraise_data" cause="**invalid-HMAC**" comm="sh" name="/root/Desktop/new.sh" dev="sda1" ino=546526 res=0
Have you any idea why i get invalid HMAC ?
They keys are loaded like the tutorial says...
#!/bin/sh -e
PREREQ=""
# Output pre-requisites
prereqs()
{
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
grep -q "ima=off" /proc/cmdline && exit 1
mount -n -t securityfs securityfs /sys/kernel/security
IMA_POLICY=/sys/kernel/security/ima/policy
LSM_POLICY=/etc/ima_policy
grep -v "^#" $LSM_POLICY >$IMA_POLICY
# import EVM HMAC key
keyctl show |grep -q kmk || keyctl add user kmk "testing123" #u
keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" #u
#keyctl revoke kmk
# import Module public key
mod_id=`keyctl newring _module #u`
evmctl import /etc/keys/pubkey_evm.pem $mod_id
# import IMA public key
ima_id=`keyctl newring _ima #u`
evmctl import /etc/keys/pubkey_evm.pem $ima_id
# import EVM public key
evm_id=`keyctl newring _evm #u`
evmctl import /etc/keys/pubkey_evm.pem $evm_id
# enable EVM
echo "1" > /sys/kernel/security/evm
# enable module checking
#echo "1" > /sys/kernel/security/module_check
Thanks for your help

Solved, new kernel use HMAC v2 and you have to activate asymmetric key when you compile kernel.
cat .config should have this entries:
CONFIG_EVM_HMAC_VERSION=2
CONFIG_ASYMMETRIC_KEY_TYPE=y
Then when you hash or sign a file use
evmctl -u - -x --imasig/--imahash $file
As well you should have create the asymetric keys and load them in _evm and _ima keyring with keyctl with initramfs.

Related

Check duplicate disk LABEL before mounting it to the system in bash script

is there a way to check if there is duplicate disk LABEL before mounting it to the system?
i need to make sure that if the user have two external drives, if the two of them have the same label, prompt to the user a warning and asking it to remove the duplicated disk.
my code is in the early stages:
if mountpoint -q "${JOB_MOUNT_DIR}"; then
echo " ${JOB_MOUNT_HD_LABEL} já está montado e está pronto para uso"
else
echo "O dispositivo ""${JOB_MOUNT_HD_LABEL}"" não está montado no diretório ""${JOB_MOUNT_DIR}"""
echo "Deseja montar o diretório?"
echo -n "Qual sua opção? [s/n]: "
read -r "opcao"
if [ "$opcao" == "s" ]; then
mkdir -p "${JOB_MOUNT_DIR}/${JOB_MOUNT_HD_LABEL}"
mount -L "${JOB_MOUNT_HD_LABEL}" "${JOB_MOUNT_DIR}/${JOB_MOUNT_HD_LABEL}"
exit 0
else
echo "Disco não irá ser montado"
exit 0
fi
fi
exit 0
some parts are in pt-br i think that will not be a problem
first it checks if that the disk is already mounted, if not it asks to mount, then there is the problem to know which of the two disk with the same LABEL is to mount
You can use:
lsblk -o name,label
NAME LABEL
mmcblk0
└─mmcblk0p1 eMMC
Or you can use:
blkid
/dev/nvme0n1p1: UUID="36D7-B890" TYPE="vfat" PARTUUID="8614534f-01"
/dev/nvme0n1p5: UUID="65885781-bd9b-4c62-afb0-4a82a0e5759e" TYPE="ext4" PARTUUID="8614534f-05"
/dev/mmcblk0p1: LABEL="eMMC" UUID="79ff33b4-2add-4f2f-844e-d7d242c18578" TYPE="ext4" PARTUUID="d4b36674-ab5f-4f15-bb83-313cce242fe4"
You may need to prefix above commands with sudo
If the above commands get your labels correctly, you can pipe the output roughly as follows to list duplicates:
lsblk -o label | sort | uniq -d

Destroying luks header on dm-crypt linux

I am trying to destroy the luks header on one of my logical volume data1, I am still able to read the file inside data1 after I delete the luks header. I suppose it should not be the case right? Can someone help me in understanding this case?
lsblk output
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 894.2G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 893.8G 0 part
├─vg0-root 251:0 0 758.7G 0 lvm
│ └─luks-45f803e5-3c17-4aaf-a9ad-d66c8b5458de 251:2 0 758.7G 0 crypt /
├─vg0-swap 251:1 0 75G 0 lvm [SWAP]
├─vg0-data3 251:3 0 20G 0 lvm
│ └─luks-6e168d35-26dc-429c-a3d6-8cb4f1c1d39e 251:7 0 20G 0 crypt /data3
├─vg0-data2 251:4 0 20G 0 lvm
│ └─luks-75727dd1-a332-423d-8c37-4cedf9cbe83c 251:8 0 20G 0 crypt /data2
└─vg0-data1 251:5 0 20G 0 lvm
└─luks-cf2d9729-2d1b-48b8-8502-dea937ef602f 251:6 0 20G 0 crypt /data1
Luksdump output to check if the luks header is exists:
-130-sapam#test-host:~ $ sudo cryptsetup luksDump /dev/mapper/vg0-data1
LUKS header information for /dev/mapper/vg0-data1
Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha256
Payload offset: 4096
MK bits: 256
MK digest: 9f e7 1a b3 0e fb 4e bc 6d 1b 9e 46 f8 bd 15 22 ea 04 6e c3
MK salt: 83 5e 90 5b b3 a1 c5 a5 d4 22 a0 3e 23 25 51 50
fc cd a8 ac db 9f d0 a8 8b 81 6e 9a 92 1f d8 d3
MK iterations: 43750
UUID: cf2d9729-2d1b-48b8-8502-dea937ef602f
Key Slot 0: ENABLED
Iterations: 439102
Salt: f1 6d 23 b0 b7 ee fc 09 8c 6b 92 ef b2 17 ef d9
0c 83 64 29 bf bc 98 3f f6 93 4b 45 06 49 a9 21
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED
Destroying the luks header:
-130-sapam#test-host:~ $ sudo dd bs=512 count=4096 if=/dev/zero of=/dev/mapper/vg0-data1
4096+0 records in
4096+0 records out
2097152 bytes (2.1 MB) copied, 0.00444235 s, 472 MB/s
-0-sapam#test-host:~ $ sudo cryptsetup luksDump /dev/mapper/vg0-data1
-1-sapam#test-host:~ $
I still able to read the file inside /data1/
-1-sapam#test-host:~ $ cat /data1/foo
james
-0-sapam#test-host:~ $
From my understanding is once the header is destroyed, the /data1 should not be able to read right?
It seems you are destroying already mounted partition.
Encryption/decryption keys are hold in the memory while the partition is mounted. You should unmout your LUKS partition first:
# umount /data1
and then erase the LUKS header. You won't be able to mount it again.
Please note cryptsetup utility has a command to erase LUKS header:
# cryptsetup luksErase /dev/mapper/vg0-data1
The advantage of this operation is that you can restore LUKS header from the backup if you done it before.
from cryptsetup(8):
erase <device>
luksErase <device>
Erase all keyslots and make the LUKS container permanently inac‐
cessible. You do not need to provide any password for this op‐
eration.
WARNING: This operation is irreversible.
While luksErase is nice to wipe the keyslots area, note that it doesn't actually destroy the entire LUKS Header. It leaves the metadata intact.
I submitted a feature request asking for the luksErase command to have the ability to wipe the plaintext metadata in the header as well, but the developer rejected & closed it :(
LUKS Header Shredder
You can use the following BASH script to find every LUKS device on the system, wipe the headers, and shutdown the machine.
Disclaimer
The script below contains experimental software that may or may not lead to corruption or total permanent deletion of some or all of your data. I cannot be responsible for any data loss that has occurred as a result of following this guide.
The contents of this answer is provided openly and is licensed under the CC-BY-SA license. The software included in this guide is licensed under the GNU GPLv3 license. All content here is consistent with the limitations of liabilities outlined in its respective licenses.
I highly recommend that any experiments with the script included in this answer is used exclusively on a disposable machine containing no valuable data.
If data loss is a concern for you, then leave now and do not proceed. You have been warned.
#!/bin/bash
#set -x
################################################################################
# File: buskill-selfdestruct.sh
# Purpose: Self-destruct trigger script for BusKill Kill Cord
# For more info, see: https://buskill.in/
# WARNING: THIS IS EXPERIMENTAL SOFTWARE THAT IS DESIGNED TO CAUSE PERMANENT,
# COMPLETE AND IRREVERSIBLE DATA LOSS!
# Note : This script will *not* execute unless it's passed the '--yes'
# argument. Be sure to test this trigger before depending on it!
# Authors: Michael Altfield <michael#buskill.in>
# Created: 2020-03-11
# Updated: 2020-03-11
# Version: 0.1
################################################################################
############
# SETTINGS #
############
BUSKILL_LOCK='/usr/local/bin/buskill-lock.sh'
[ -f ${BUSKILL_LOCK} ] || echo "ERROR: Unable to find buskill-lock.sh"
CRYPTSETUP=`which cryptsetup` || echo "ERROR: Unable to find cryptsetup"
LS=`which ls` || echo "ERROR: Unable to find ls"
CAT=`which cat` || echo "ERROR: Unable to find cat"
GREP=`which grep` || echo "ERROR: Unable to find grep"
ECHO=`which echo` || echo "ERROR: Unable to find echo"
AWK=`which awk` || echo "ERROR: Unable to find awk"
HEAD=`which head` || echo "ERROR: Unable to find head"
LSBLK=`which lsblk` || echo "ERROR: Unable to find lsblk"
OD=`which od` || echo "ERROR: Unable to find od"
##############
# ROOT CHECK #
##############
# re-run as root
if [[ $EUID -ne 0 ]]; then
exec sudo /bin/bash "$0" "$#"
fi
###########
# CONFIRM #
###########
# for safety, exit if this script is executed without a '--yes' argument
${ECHO} "${#}" | ${GREP} '\--yes' &> /dev/null
if [ $? -ne 0 ]; then
${ECHO} "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
${ECHO} "================================================================================"
${ECHO} "WARNING: THIS IS EXPERIMENTAL SOFTWARE THAT IS DESIGNED TO CAUSE PERMANENT, COMPLETE AND IRREVERSIBLE DATA LOSS!"
${ECHO} "================================================================================"
${ECHO} "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
${ECHO}
${ECHO} "cowardly refusing to execute without the '--yes' argument for your protection. If really you want to proceed with damaging your system, retry with the '--yes' argument"
exit 1
fi
###########################
# (DELAYED) HARD SHUTDOWN #
###########################
# The most secure encrypted computer is an encrypted computer that is *off*
# This is our highest priority; initiate a hard-shutdown to occur in 5 minutes regardless
# of what happens later in this script
nohup sleep 60 && echo o > /proc/sysrq-trigger &
nohup sleep 61 && shutdown -h now &
nohup sleep 62 && poweroff --force --no-sync &
###############
# LOCK SCREEN #
###############
# first action: lock the screen!
${BUSKILL_LOCK} &
#####################
# WIPE LUKS VOLUMES #
#####################
# overwrite luks headers
${ECHO} "INFO: shredding LUKS header (plaintext metadata and keyslots with encrypted master decryption key)"
writes=''
IFS=$'\n'
for line in $( ${LSBLK} --list --output 'PATH,FSTYPE' | ${GREP} 'crypt' ); do
device="`${ECHO} \"${line}\" | ${AWK} '{print \$1}'`"
${ECHO} -e "\t${device}"
###########################
# OVERWRITE LUKS KEYSLOTS #
###########################
# erases all keyslots, making the LUKS container "permanently inaccessible"
${CRYPTSETUP} luksErase --batch-mode "${device}" || ${HEAD} --bytes 20M /dev/urandom > ${device} &
# store the pid of the above write tasks so we can try to wait for it to
# flush to disk later -- before triggering a brutal hard-shutdown
writes="${writes} $!"
#####################################
# OVERWRITE LUKS PLAINTEXT METADATA #
#####################################
luksVersion=`${OD} --skip-bytes 6 --read-bytes 2 --format d2 --endian=big --address-radix "n" "${device}"`
# get the end byte to overwrite. For more info, see:
# https://security.stackexchange.com/questions/227359/how-to-determine-start-and-end-bytes-of-luks-header
if [[ $luksVersion -eq 1 ]]; then
# LUKS1: https://gitlab.com/cryptsetup/cryptsetup/-/wikis/LUKS-standard/on-disk-format.pdf
# in LUKS1, the whole header ends at 512 * the `payload-offset`
# this is actually more than we need (includes keyslots), but
# it's the fastest/easiest to bound to fetch in LUKS1
payloadOffset=`${OD} --skip-bytes 104 --read-bytes 4 --format d4 --endian=big --address-radix "n" "${device}"`
luksEndByte=$(( 512 * ${payloadOffset} ))
elif [[ $luksVersion -eq 2 ]]; then
# LUKS2: https://gitlab.com/cryptsetup/LUKS2-docs/blob/master/luks2_doc_wip.pdf
# in LUKS2, the end of the plaintext metadata area is twice the
# size of the `hdr_size` field
hdr_size=`${OD} --skip-bytes 8 --read-bytes 8 --format d8 --endian=big --address-radix "n" "${device}"`
luksEndByte=$(( 2 * ${hdr_size} ))
else
# version unclear; just overwrite 20 MiB
luksEndByte=20971520
fi
# finally, shred that plaintext metadata; we do this in a new file descriptor
# to prevent bash from truncating if ${device} is a file
exec 5<> "${device}"
${HEAD} --bytes "${luksEndByte}" /dev/urandom >&5 &
writes="${writes} $!"
exec 5>&-
done
#######################
# WAIT ON DISK WRITES #
#######################
# wait until all the write tasks above have completed
# note: do *not* put quotes around this arg or the whitespace will break wait
wait ${writes}
# clear write buffer to ensure headers overwrites are actually synced to disks
sync; echo 3 > /proc/sys/vm/drop_caches
#################################
# WIPE DECRYPTION KEYS FROM RAM #
#################################
# suspend each currently-decrypted LUKS volume
${ECHO} "INFO: removing decryption keys from memory"
for device in $( ${LS} -1 "/dev/mapper" ); do
${ECHO} -e "\t${device}";
${CRYPTSETUP} luksSuspend "${device}" &
# clear page caches in memory (again)
sync; echo 3 > /proc/sys/vm/drop_caches
done
#############################
# (IMMEDIATE) HARD SHUTDOWN #
#############################
# do whatever works; this is important.
echo o > /proc/sysrq-trigger &
sleep 1
shutdown -h now &
sleep 1
poweroff --force --no-sync &
# exit cleanly (lol)
exit 0
Sources
LUKS Header Shredder (BusKill Self-Destruct Trigger)
https://github.com/BusKill/buskill-linux/blob/master/triggers/buskill-selfdestruct.sh

Podman (libpod) fails to run while mounting shm with SELinux context

I am currently trying out Podman on Gentoo Linux:
# grep -i selinux /usr/src/linux-4.19.82-gentoo/.config
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
CONFIG_DEFAULT_SECURITY_SELINUX=y
CONFIG_DEFAULT_SECURITY="selinux"
# getenforce
Permissive
Unfortunately, it fails while trying to mount shm with SELinux context. I tried it with VFS and fuse-overlayfs:
$ podman --log-level=debug run -it --rm localhost/ubuntu:latest /bin/bash
...
DEBU[0000] ExitCode msg: "failed to mount shm tmpfs \"/home/david/.local/share/containers/storage/overlay-containers/a05754757bafec92198c27b6ba954c40ac6a0ee99f29927f216bddb6c6ad4d07/userdata/shm\": invalid argument"
ERRO[0000] failed to mount shm tmpfs "/home/david/.local/share/containers/storage/overlay-containers/a05754757bafec92198c27b6ba954c40ac6a0ee99f29927f216bddb6c6ad4d07/userdata/shm": invalid argument
I patched my Podman for debugging:
gentoo ~/libpod-1.6.3 # git diff | tee /etc/portage/patches/app-emulation/libpod/00.patch
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 471648b..a2c001a 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
## -43,6 +43,11 ## import (
func (c *Container) mountSHM(shmOptions string) error {
if err := unix.Mount("shm", c.config.ShmDir, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV,
label.FormatMountLabel(shmOptions, c.config.MountLabel)); err != nil {
+ logrus.Debugf("AAAAA %s", c.config.ShmDir)
+ logrus.Debugf("BBBBB %s", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV)
+ logrus.Debugf("CCCCC %s", shmOptions)
+ logrus.Debugf("DDDDD %s", c.config.MountLabel)
+ logrus.Debugf("EEEEE %s", label.FormatMountLabel(shmOptions, c.config.MountLabel))
return errors.Wrapf(err, "failed to mount shm tmpfs %q", c.config.ShmDir)
}
return nil
And, got this output:
$ podman --log-level=debug run -it --rm localhost/ubuntu:latest /bin/bash
...
DEBU[0000] AAAAA /home/david/.local/share/containers/storage/overlay-containers/a05754757bafec92198c27b6ba954c40ac6a0ee99f29927f216bddb6c6ad4d07/userdata/shm
DEBU[0000] BBBBB %!s(int=14)
DEBU[0000] CCCCC mode=1777,size=65536000
DEBU[0000] DDDDD system_u:object_r:svirt_lxc_file_t
DEBU[0000] EEEEE mode=1777,size=65536000,context="system_u:object_r:svirt_lxc_file_t"
...
Mounting shm without the context option worked:
# mount -t tmpfs -o mode=1777,size=65536000 shm /mnt/
# mount | grep shm
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,seclabel)
shm on /mnt type tmpfs (rw,relatime,seclabel,size=64000k)
But, it fails with the context option:
# mount -t tmpfs -o mode=1777,size=65536000,context="system_u:object_r:svirt_lxc_file_t" shm /mnt/
mount: /mnt: wrong fs type, bad option, bad superblock on shm, missing codepage or helper program, or other error.
And, running Podman without SELinux works.
Some info on the machine:
vagrant#gentoo ~ $ eix -I libpod
[I] app-emulation/libpod
Available versions: (~)1.6.3^t {apparmor btrfs ostree +rootless selinux}
Installed versions: 1.6.3^t(07:51:44 AM 11/18/2019)(rootless selinux -apparmor -btrfs -ostree)
Homepage: https://github.com/containers/libpod/
Description: Library and podman tool for running OCI-based containers in Pods
vagrant#gentoo ~ $ eix -I install-xattr
[I] sys-apps/install-xattr
Available versions: 0.5 (~)0.7 (~)0.8 **9999*l
Installed versions: 0.8(06:07:20 PM 11/17/2019)
Homepage: https://dev.gentoo.org/~blueness/install-xattr/
Description: Wrapper to coreutil's install to preserve Filesystem Extended Attributes
vagrant#gentoo ~ $ emerge --info
Portage 2.3.76 (python 3.6.9-final-0, default/linux/amd64/17.1/no-multilib/hardened/selinux, gcc-9.2.0, glibc-2.29-r2, 4.19.82-gentoo x86_64)
=================================================================
System uname: Linux-4.19.82-gentoo-x86_64-Intel_Core_Processor_-Skylake,_IBRS-with-gentoo-2.6
KiB Mem: 2036312 total, 1846924 free
KiB Swap: 4000764 total, 4000764 free
Timestamp of repository gentoo: Sun, 17 Nov 2019 17:00:01 +0000
Head commit of repository gentoo: 6c3900366099220296f7765bd1f0668d980d0d29
sh bash 4.4_p23-r1
ld GNU ld (Gentoo 2.32 p2) 2.32.0
app-shells/bash: 4.4_p23-r1::gentoo
dev-lang/perl: 5.28.2-r1::gentoo
dev-lang/python: 2.7.16::gentoo, 3.6.9::gentoo
dev-util/cmake: 3.14.6::gentoo
sys-apps/baselayout: 2.6-r1::gentoo
sys-apps/openrc: 0.41.2::gentoo
sys-apps/sandbox: 2.13::gentoo
sys-devel/autoconf: 2.69-r4::gentoo
sys-devel/automake: 1.16.1-r1::gentoo
sys-devel/binutils: 2.32-r1::gentoo
sys-devel/gcc: 9.2.0-r2::gentoo
sys-devel/gcc-config: 2.1::gentoo
sys-devel/libtool: 2.4.6-r3::gentoo
sys-devel/make: 4.2.1-r4::gentoo
sys-kernel/linux-headers: 4.19::gentoo (virtual/os-headers)
sys-libs/glibc: 2.29-r2::gentoo
Repositories:
gentoo
location: /usr/portage
sync-type: rsync
sync-uri: rsync://rsync.gentoo.org/gentoo-portage
priority: -1000
sync-rsync-verify-jobs: 1
sync-rsync-verify-max-age: 24
sync-rsync-verify-metamanifest: yes
sync-rsync-extra-opts:
localrepo
location: /var/db/repos/localrepo
masters: gentoo
ACCEPT_KEYWORDS="amd64"
ACCEPT_LICENSE="#FREE"
CBUILD="x86_64-pc-linux-gnu"
CFLAGS="-mtune=generic -O2 -pipe"
CHOST="x86_64-pc-linux-gnu"
CONFIG_PROTECT="/etc /usr/share/gnupg/qualified.txt"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/gconf /etc/gentoo-release /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo"
CXXFLAGS="-mtune=generic -O2 -pipe"
DISTDIR="/distfiles"
ENV_UNSET="DBUS_SESSION_BUS_ADDRESS DISPLAY GOBIN PERL5LIB PERL5OPT PERLPREFIX PERL_CORE PERL_MB_OPT PERL_MM_OPT XAUTHORITY XDG_CACHE_HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_RUNTIME_DIR"
FCFLAGS="-O2 -pipe"
FEATURES="assume-digests binpkg-docompress binpkg-dostrip binpkg-logs config-protect-if-modified distlocks ebuild-locks fixlafiles ipc-sandbox merge-sync multilib-strict network-sandbox news parallel-fetch preserve-libs protect-owned sandbox selinux sesandbox sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync xattr"
FFLAGS="-O2 -pipe"
GENTOO_MIRRORS="http://distfiles.gentoo.org"
LANG="en_US.UTF-8"
LDFLAGS="-Wl,-O1 -Wl,--as-needed"
MAKEOPTS="-j3"
PKGDIR="/packages"
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --exclude=/.git"
PORTAGE_TMPDIR="/var/tmp"
USE="acl alsa amd64 bzip2 crypt cxx hardened iconv ipv6 libtirpc ncurses nls nptl open_perms openmp openssl pam pcre peer_perms pie readline seccomp selinux split-usr ssl ssp ubac unicode usb xattr xtpax zlib" ABI_X86="64" ADA_TARGET="gnat_2018" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m maestro3 trident usb-audio via82xx via82xx-modem ymfpci" APACHE2_MODULES="authn_core authz_core socache_shmcb unixd actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache cgi cgid dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" CALLIGRA_FEATURES="karbon sheets words" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" CPU_FLAGS_X86="mmx mmxext sse sse2" ELIBC="glibc" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock greis isync itrax mtk3301 nmea ntrip navcom oceanserver oldstyle oncore rtcm104v2 rtcm104v3 sirf skytraq superstar2 timing tsip tripmate tnt ublox ubx" GRUB_PLATFORMS="emu efi-32 efi-64 pc" INPUT_DEVICES="libinput keyboard mouse" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LIBREOFFICE_EXTENSIONS="presenter-console presenter-minimizer" NETBEANS_MODULES="apisupport cnd groovy gsf harness ide identity j2ee java mobility nb php profiler soa visualweb webcommon websvccommon xml" OFFICE_IMPLEMENTATION="libreoffice" PHP_TARGETS="php7-2" POSTGRES_TARGETS="postgres10 postgres11" PYTHON_SINGLE_TARGET="python3_6" PYTHON_TARGETS="python3_6 python2_7" RUBY_TARGETS="ruby24 ruby25" USERLAND="GNU" VIDEO_CARDS="amdgpu fbdev intel nouveau radeon radeonsi vesa dummy v4l" XTABLES_ADDONS="quota2 psd pknock lscan length2 ipv4options ipset ipp2p iface geoip fuzzy condition tee tarpit sysrq steal rawnat logmark ipmark dhcpmac delude chaos account"
Unset: CC, CPPFLAGS, CTARGET, CXX, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LC_ALL, LINGUAS, PORTAGE_BINHOST, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS
Late answer here, as noted by duexsco the svirt_lxc_file_t enforcement type is missing which can be installed by emerging sec-policy/selinux-virt on Gentoo.
Why an interface (/usr/share/selinux/strict/include/services/virt.if) from sec-policy/selinux-base uses an enforcement type from sec-policy/selinux-virt is also a rather interesting question.

openssl unknown option error

I ran this script below:
#!/bin/bash
keyFile=video.key
openssl rand 16 > $keyFile
encryptionKey=$(cat $keyFile | hexdump -e '16/1 "%02x"')
splitFilePrefix=stream
encryptedSplitFilePrefix=enc/${splitFilePrefix}
numberOfTsFiles=$(ls ${splitFilePrefix}*.ts | wc -l)
for (( i=1; i<$numberOfTsFiles; i++ ))
do
initializationVector=printf '%032x' $i
openssl aes-128-cbc -e -in ${splitFilePrefix}$i.ts -out ${encryptedSplitFilePrefix}$i.ts -nosalt -iv $initializationVector -K $encryptionKey
done
right after the execution, the bash gives me an error:
./script.sh: line 14: fg: no job control
unknown option '9d268d620c68938b4578c3f299c91a1a'
options are
-in <file> input file
-out <file> output file
-pass <arg> pass phrase source
-e encrypt
-d decrypt
-a/-base64 base64 encode/decode, depending on encryption flag
-k passphrase is the next argument
-kfile passphrase is the first line of the file argument
-md the next argument is the md to use to create a key
from a passphrase. One of md2, md5, sha or sha1
-S salt in hex is the next argument
-K/-iv key/iv in hex is the next argument
-[pP] print the iv/key (then exit if -P)
-bufsize <n> buffer size
-nopad disable standard block padding
-engine e use engine e, possibly a hardware device.
Cipher Types
-aes-128-cbc -aes-128-cbc-hmac-sha1 -aes-128-cfb
-aes-128-cfb1 -aes-128-cfb8 -aes-128-ctr
-aes-128-ecb -aes-128-gcm -aes-128-ofb
-aes-128-xts -aes-192-cbc -aes-192-cfb
-aes-192-cfb1 -aes-192-cfb8 -aes-192-ctr
-aes-192-ecb -aes-192-gcm -aes-192-ofb
-aes-256-cbc -aes-256-cbc-hmac-sha1 -aes-256-cfb
-aes-256-cfb1 -aes-256-cfb8 -aes-256-ctr
-aes-256-ecb -aes-256-gcm -aes-256-ofb
-aes-256-xts -aes128 -aes192
-aes256 -bf -bf-cbc
-bf-cfb -bf-ecb -bf-ofb
-blowfish -camellia-128-cbc -camellia-128-cfb
-camellia-128-cfb1 -camellia-128-cfb8 -camellia-128-ecb
-camellia-128-ofb -camellia-192-cbc -camellia-192-cfb
-camellia-192-cfb1 -camellia-192-cfb8 -camellia-192-ecb
-camellia-192-ofb -camellia-256-cbc -camellia-256-cfb
-camellia-256-cfb1 -camellia-256-cfb8 -camellia-256-ecb
-camellia-256-ofb -camellia128 -camellia192
-camellia256 -cast -cast-cbc
-cast5-cbc -cast5-cfb -cast5-ecb
-cast5-ofb -des -des-cbc
-des-cfb -des-cfb1 -des-cfb8
-des-ecb -des-ede -des-ede-cbc
-des-ede-cfb -des-ede-ofb -des-ede3
-des-ede3-cbc -des-ede3-cfb -des-ede3-cfb1
-des-ede3-cfb8 -des-ede3-ofb -des-ofb
-des3 -desx -desx-cbc
-id-aes128-GCM -id-aes192-GCM -id-aes256-GCM
-rc2 -rc2-40-cbc -rc2-64-cbc
-rc2-cbc -rc2-cfb -rc2-ecb
-rc2-ofb -rc4 -rc4-40
-rc4-hmac-md5 -seed -seed-cbc
-seed-cfb -seed-ecb -seed-ofb
I read openssl manual and thought either -K or -iv part is wrong, but couldn't figure out which option and why is it wrong
Your problem is that this line:
initializationVector=printf '%032x' $i
Should look like this:
initializationVector=$(printf '%032x' $i)
It made initializationVector empty.
You can find it out if you add set -x at the top, and then see exactly what is the command line you're attempting to run.
before fixing it looked like this:
openssl aes-128-cbc -e -in stream1.ts -out enc/stream1.ts -nosalt -iv -K 7aeb2faae0289b9828b2994f50a4cc3a
which made openssl command think that -K is the value for the -iv option, and the key itself is another command option.
Hence the error: unknown option '7aeb2faae0289b9828b2994f50a4cc3a' (in my case).
do
initializationVector=printf '%032x' $i
openssl aes-128-cbc -e -in ${splitFilePrefix}$i.ts -out ${encryptedSplitFilePrefix}$i.ts \
-nosalt -iv $initializationVector -K $encryptionKey
done
You are missing the leading dash on the cipher. Try -aes-128-cbc instead. From the enc(1) docs:
SYNOPSIS
openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64] [-A]
[-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md] [-p]
[-P] [-bufsize number] [-nopad] [-debug] [-none] [-engine id]

How do I uniquely identify an USB-device?

I was wondering how to get the unique id of a USB storage device.
I already know how to fetch the SCSI serial id from this post : USB-drive serial number under linux C++
The post mentions using the Device Descriptor to get the ID. Can someone post some code to determine the Device Descriptor information under Linux?
ls -l /dev/disk/by-id
I suggest to use libusb. You can find the documentation here.
With USB, the "device name" of a device can change, depending on the order of which, the device was connected.
Surprisingly few devices have a real serial number.
If you can't get a unique identification from the device itself, the only solution is to depend on the physical address of connection. The drawback on this, is that the address changes, if you plug the device into another USB connector.
Programmatically you can use sysfs to get the information the kernel has, about the device. Sysfs is a file-system-like representation of devices as the kernel sees them. (Its not real files on the disk)
With it, you can:
- identify the device type with product and vendor ID
- read the serial number of the device, if it has one.
- read the physical connection number on the USB hub
You could start by finding your type of devices in /sys/class. In this example I use an USB→LPT port. But the principle is the same.
$ ls -l /sys/class/usbmisc
lp1 -> ../../devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5:1.0/usbmisc/lp1
lp2 -> ../../devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.6/4-1.6:1.0/usbmisc/lp2
Grap the device name from the uevent file:
cat /sys/class/usbmisc/lp1/uevent
MAJOR=180
MINOR=1
DEVNAME=__usb/lp1__
add /dev so you get the device name to open: /dev/usb/lp1
Use the real path:
$ cd -P /sys/class/usbmisc/lp1
Step back 3 branches:
$ cd ../../../
/sys/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5
This directory contains a lot of the information on the device:
idProduct and idVendor can be used to uniquely identify the device type.
If there is a serial file and it contains a unique serial number, you are done.
Otherwise your option is to use the physical connection as identification, wich is this directory name “4-1.5” It is unique for the physical connection, and will as you already mentioned change if you plug the device to another port.
Generalizing Simon Rigét's answer, I came up with this bash function that, given optional vendor id and product id, returns a list of device node names, related to that vendor id and that product id if given.
getDevNodes() {
if [ -n "$1" ] && [ "$1" != "no_class" ]; then
2>/dev/null find -L /sys/class/$1 -maxdepth 2 -mindepth 2 -name uevent -exec realpath "{}" +
else
find /sys/devices -name uevent
fi | {
if [ -z "$1" ]; then
readarray -t lines < <(find /sys/class -maxdepth 2 -mindepth 2 -type l -print -exec realpath "{}" +)
local -i count=${#lines[#]} sys_dev=count/2 sys_class=0
local -A classes
while [ $sys_dev -lt $count ]; do
class="${lines[$sys_class]#/*/*/}"
class="${class%/*}"
classes["${lines[$sys_dev]}"]="$class"
sys_dev+=1
sys_class+=1
done
fi
readarray -t uevents
for u in "${uevents[#]}"; do
DEVNAME=; DEVTYPE=no_type; while IFS="=" read key value; do {
[ "$key" = "DEVNAME" ] && DEVNAME=/dev/"$value"
} || {
[ "$key" = "DEVTYPE" ] && DEVTYPE="$value"
}; done < "$u"
if [ -n "$DEVNAME" ]; then
path="${u%/uevent}"
while [ "$path" != "/sys/devices" ] && ! [ -f "$path"/idVendor ]; do
path="${path%/*}"
done
[ "$path" != "/sys/devices" ] && {
read readIdVendor < "$path"/idVendor
read readIdProduct < "$path"/idProduct
} || {
readIdVendor=----
readIdProduct=----
}
echo "${1:-${classes[${u%/uevent}]:-no_class}}" "$DEVTYPE" "$readIdVendor" "$readIdProduct" "$DEVNAME"
fi
done
} | grep "^${1:-[[:graph:]]\+} ${2:-[[:graph:]]\+} ${3:-....} ${4:-....}" | cat
}
For instance, this is what my lsusb tells me:
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 008: ID 0bda:b719 Realtek Semiconductor Corp.
Bus 001 Device 006: ID 0bda:57b5 Realtek Semiconductor Corp.
Bus 001 Device 004: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller
Bus 001 Device 097: ID 1004:6344 LG Electronics, Inc. G2 Android Phone [tethering mode]
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
So, if I wanted to see which device nodes are associated with the vendor id 0x1004 and the product id 0x6344 I'd do the following:
$ getDevNodes "" "" 1004 6344
no_class usb_device 1004 6344 /dev/bus/usb/001/097
tty no_type 1004 6344 /dev/ttyACM0
So we've got two device nodes, one of which is of class tty with no devtype and the other is of unknown class but with a devtype usb_device.
One can also only give the vendor id, like this:
$ getDevNodes "" "" 0bda
no_class usb_device 0bda 0129 /dev/bus/usb/001/004
no_class usb_device 0bda b719 /dev/bus/usb/001/008
no_class no_type 0bda 57b5 /dev/media0
video4linux no_type 0bda 57b5 /dev/video0
input no_type 0bda 57b5 /dev/input/event14
no_class usb_device 0bda 57b5 /dev/bus/usb/001/006
If I only wanted video4linux class devices whose vendor id is 0bda, then I'd do the following:
$ getDevNodes video4linux "" "" 0bda
video4linux no_type 0bda 57b5 /dev/video0
Arguments are basically filters over the complete list of device nodes and their associated info. Omitting one of those arguments, or using the empty string "" as an argument, disables the filter for that specific argument.
Arguments are given in this order: 1: the class, 2: the type, 3: the vendor id, 4: the product id.
Here follows a lite version of the above function that runs faster at the expense of some functionalities: the device nodes are printed without the additional info and there's no filter for the device type.
getDevNodesLite() {
if [ -n "$1" ]; then
2>/dev/null find -L /sys/class/$1 -maxdepth 2 -mindepth 2 -name uevent -exec realpath "{}" +
else
find /sys/devices -name uevent
fi | {
if [ -n "$2" ]; then
readarray -t uevents
for u in "${uevents[#]}"; do
path="${u%/uevent}"
while [ "$path" != "/sys/devices" ] && ! [ -f "$path"/idVendor ]; do
path="${path%/*}"
done
[ "$path" != "/sys/devices" ] && read readValue < "$path"/idVendor && [ "$readValue" = "$2" ] && {
if [ -n "$idProduct" ]; then
read readValue < "$path"/idProduct && [ "$readValue" = "$3" ]
fi
} && echo "$u"
done
else
cat
fi
} | {
readarray -t uevents
[ ${#uevents[#]} -gt 0 ] && sed -n 's,DEVNAME=\(.*\),/dev/\1,p' "${uevents[#]}"
}
}
To add to what everyone else has said:
USB devices do not always have a serial number; even when one is present, it is not guaranteed to be globally unique. (For instance, my Apple USB keyboard has no serial number, and GoPro cameras all have the same bogus serial number of 123456789ABC.) As such, it is not always possible to uniquely identify a device.
do sudo blkid and it will list the id of all mounted devices with a filesystem

Resources