Update of libimaevm with new functions 47/28547/1
authorPawel Polawski <p.polawski@samsung.com>
Wed, 9 Apr 2014 15:15:02 +0000 (17:15 +0200)
committerJanusz Kozerski <j.kozerski@samsung.com>
Thu, 9 Oct 2014 14:29:43 +0000 (16:29 +0200)
New functions allows to easy get / set IMA and EVM state
on the device instead of using raw kernel interface.
Also it is posiible to modify extended xattributes assigned
to IMA and EVM.

Added functions:
- int ima_get_state(int *state);
- int ima_set_state(int state);
- int evm_get_state(int *state);
- int evm_set_state(int state);
- int ima_set_xattr(const char *path);
- int ima_get_xattr(const char *path, char **hash);
- int evm_set_xattr(const char *path, const char *evm);
- int evm_get_xattr(const char *path, char **hash);

Change-Id: Ic9354bad61e331305eb65c29dc90a94894763fe3
Signed-off-by: Pawel Polawski <p.polawski@samsung.com>
Signed-off-by: Janusz Kozerski <j.kozerski@samsung.com>
packaging/ima-evm-utils.spec
src/imaevm.h
src/libimaevm.c

index 9d19fb8..4c24178 100644 (file)
@@ -51,6 +51,7 @@ exit 0
 /usr/share/doc/ima-evm-utils/*
 
 %changelog
+* Wed Apr 09 2014 Pawel Polawski <p.polawski@samsung.com>
+- Update of libimaevm source and header
 * Thu Apr 05 2012 Dmitry Kasatkin <dmitry.kasatkin@intel.com>
 - Initial RPM spec file
-
index 72de47a..9e7a931 100644 (file)
@@ -9,6 +9,7 @@
  * Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
  *                 <dmitry.kasatkin@intel.com>
  *                 <d.kasatkin@samsung.com>
+ * Pawel Polawski  <p.polawski@samsung.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -35,7 +36,7 @@
  * then also delete it in the license file.
  *
  * File: imaevm.h
- *      IMA/EVM header file
+ * IMA/EVM header file
  */
 
 #ifndef _LIBIMAEVM_H
@@ -199,4 +200,35 @@ int sign_hash(const char *algo, const unsigned char *hash, int size, const char
 int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen);
 int ima_verify_signature(const char *file, unsigned char *sig, int siglen);
 
+//IMA EVM API
+enum lib_retval {
+       LIB_SUCCESS,
+       LIB_ERROR_UNKNOWN,
+       LIB_ERROR_INPUT_PARAM,
+       LIB_ERROR_MEMORY,
+       LIB_ERROR_SYSCALL,
+       LIB_ERROR_ATTRIBUTE
+};
+
+enum ima_state {
+       IMA_STATE_DISABLED,
+       IMA_STATE_ENABLED,
+       IMA_STATE_FIX
+};
+
+enum evm_state {
+       EVM_STATE_DISABLED,
+       EVM_STATE_ENABLED,
+       EVM_STATE_FIX
+};
+
+int ima_get_state(int *state);
+int ima_set_state(int state);
+int evm_get_state(int *state);
+int evm_set_state(int state);
+int ima_set_xattr(const char *path);
+int ima_get_xattr(const char *path, char **hash);
+int evm_set_xattr(const char *path, const char *evm);
+int evm_get_xattr(const char *path, char **hash);
+
 #endif
index 2ce819f..017d6a5 100644 (file)
@@ -9,6 +9,7 @@
  * Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
  *                 <dmitry.kasatkin@intel.com>
  *                 <d.kasatkin@samsung.com>
+ * Pawel Polawski  <p.polawski@samsung.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -35,7 +36,7 @@
  * then also delete it in the license file.
  *
  * File: libimaevm.c
- *      IMA/EVM library
+ * IMA/EVM library
  */
 
 /* should we use logger instead for library? */
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <asm/byteorder.h>
+#include <attr/xattr.h>
 #include <unistd.h>
 #include <dirent.h>
 #include <string.h>
 #include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
 
 #include <openssl/pem.h>
 #include <openssl/evp.h>
@@ -791,3 +795,277 @@ int sign_hash(const char *hashalgo, const unsigned char *hash, int size, const c
        return params.x509 ? sign_hash_v2(hashalgo, hash, size, keyfile, sig) :
                             sign_hash_v1(hashalgo, hash, size, keyfile, sig);
 }
+
+#define IMA_STATE_PATH  "/sys/kernel/security/ima/ima_state"
+#define IMA_XATTR   "security.ima"
+
+#define EVM_STATE_PATH  "/sys/kernel/security/evm/evm_state"
+#define EVM_XATTR   "security.evm"
+
+int ima_get_state(int *state)
+{
+       int fd;
+       char buff;
+
+       if (!state) {
+               log_err("Error input param\n");
+               return LIB_ERROR_INPUT_PARAM;
+       }
+
+       fd = open(IMA_STATE_PATH, O_RDONLY);
+       if (fd < 0) {
+               log_err("Unable to open file\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       if (read(fd, &buff, sizeof(buff)) < 0) {
+               log_err("Unable to read file\n");
+               close(fd);
+               return LIB_ERROR_SYSCALL;
+       }
+
+       close(fd);
+
+       switch (buff) {
+       case '0':
+               *state = IMA_STATE_DISABLED;
+               return LIB_SUCCESS;
+       case '1':
+               *state = IMA_STATE_ENABLED;
+               return LIB_SUCCESS;
+       case '2':
+               *state = IMA_STATE_FIX;
+               return LIB_SUCCESS;
+       default:
+               log_err("Unknown IMA state\n");
+               return LIB_ERROR_UNKNOWN;
+       }
+}
+
+int ima_set_state(int state)
+{
+       char buff;
+
+       int fd = open(IMA_STATE_PATH, O_RDWR);
+       if (fd < 0) {
+               log_err("Unable to open file\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       switch (state) {
+       case IMA_STATE_DISABLED:
+               buff = '0';
+               break;
+       case IMA_STATE_ENABLED:
+               buff = '1';
+               break;
+       case IMA_STATE_FIX:
+               buff = '2';
+               break;
+       default:
+               log_err("Wrong IMA state\n");
+               close(fd);
+               return LIB_ERROR_UNKNOWN;
+       }
+
+       if (write(fd, &buff, sizeof(buff)) < 0) {
+               log_err("Unable to write file\n");
+               close(fd);
+               return LIB_ERROR_SYSCALL;
+       }
+
+       close(fd);
+       return LIB_SUCCESS;
+}
+
+int evm_get_state(int *state)
+{
+       int fd;
+       char buff;
+
+       if (!state) {
+               log_err("Error input param\n");
+               return LIB_ERROR_INPUT_PARAM;
+       }
+
+       fd = open(EVM_STATE_PATH, O_RDONLY);
+       if (fd < 0) {
+               log_err("Unable to open file\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       if (read(fd, &buff, sizeof(buff)) < 0) {
+               log_err("Unable to read file\n");
+               close(fd);
+               return LIB_ERROR_SYSCALL;
+       }
+
+       close(fd);
+
+       switch (buff) {
+       case '0':
+               *state = EVM_STATE_DISABLED;
+               return LIB_SUCCESS;
+       case '1':
+               *state = EVM_STATE_ENABLED;
+               return LIB_SUCCESS;
+       case '2':
+               *state = EVM_STATE_FIX;
+               return LIB_SUCCESS;
+       default:
+               log_err("Unknown EVM state\n");
+               return LIB_ERROR_UNKNOWN;
+       }
+}
+
+int evm_set_state(int state)
+{
+       char buff;
+
+       int fd = open(EVM_STATE_PATH, O_RDWR);
+       if (fd < 0) {
+               log_err("Unable to open file\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       switch (state) {
+       case EVM_STATE_DISABLED:
+               buff = '0';
+               break;
+       case EVM_STATE_ENABLED:
+               buff = '1';
+               break;
+       case EVM_STATE_FIX:
+               buff = '2';
+               break;
+       default:
+               log_err("Wrong EVM state\n");
+               close(fd);
+               return LIB_ERROR_UNKNOWN;
+       }
+
+       if (write(fd, &buff, sizeof(buff)) < 0) {
+               log_err("Unable to write file\n");
+               close(fd);
+               return LIB_ERROR_SYSCALL;
+       }
+
+       close(fd);
+       return LIB_SUCCESS;
+}
+
+int ima_set_xattr(const char *path)
+{
+       int ret;
+
+       if (!path) {
+               log_err("Error input param\n");
+               return LIB_ERROR_INPUT_PARAM;
+       }
+
+       ret = setxattr(path, IMA_XATTR, hash, strlen(hash), 0);
+       if (ret < 0) {
+               log_err("Unable to set xattr\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       return LIB_SUCCESS;
+}
+
+int ima_get_xattr(const char *path, char **hash)
+{
+       int ret;
+
+       if (!path || !hash) {
+               log_err("Error input param\n");
+               return LIB_ERROR_INPUT_PARAM;
+       }
+
+       //read xattr size only
+       ret = getxattr(path, IMA_XATTR, NULL, 0);
+       if (ret < 0) {
+               if (errno == ENOATTR) {
+                       log_err("Missing attribute or no access\n");
+                       return LIB_ERROR_ATTRIBUTE;
+               }
+               log_err("Error in read xattr\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       *hash = calloc(ret + 1, sizeof(char));
+       if (!(*hash)) {
+               log_err("Allocation error\n");
+               return LIB_ERROR_MEMORY;
+       }
+
+       ret = getxattr(path, IMA_XATTR, *hash, ret);
+       if (ret < 0) {
+               if (errno == ENOATTR) {
+                       log_err("Missing attribute or no access\n");
+                       return LIB_ERROR_ATTRIBUTE;
+               }
+               log_err("Error in read xattr\n");
+               free(*hash);
+               return LIB_ERROR_SYSCALL;
+       }
+
+       return LIB_SUCCESS;
+}
+
+int evm_set_xattr(const char *path, const char *evm)
+{
+       int ret;
+
+       if (!path || !evm) {
+               log_err("Error input param\n");
+               return LIB_ERROR_INPUT_PARAM;
+       }
+
+       ret = setxattr(path, EVM_XATTR, evm, strlen(evm), 0);
+       if (ret < 0) {
+               log_err("Unable to set xattr\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       return LIB_SUCCESS;
+}
+
+int evm_get_xattr(const char *path, char **hash)
+{
+       int ret;
+
+       if (!path || !hash) {
+               log_err("Error input param\n");
+               return LIB_ERROR_INPUT_PARAM;
+       }
+
+       //read xattr size only
+       ret = getxattr(path, EVM_XATTR, NULL, 0);
+       if (ret < 0) {
+               if (errno == ENOATTR) {
+                       log_err("Missing attribute or no access\n");
+                       return LIB_ERROR_ATTRIBUTE;
+               }
+               log_err("Error in read xattr\n");
+               return LIB_ERROR_SYSCALL;
+       }
+
+       *hash = calloc(ret + 1, sizeof(char));
+       if (!(*hash)) {
+               log_err("Allocation error\n");
+               return LIB_ERROR_MEMORY;
+       }
+
+       ret = getxattr(path, EVM_XATTR, *hash, ret);
+       if (ret < 0) {
+               if (errno == ENOATTR) {
+                       log_err("Missing attribute or no access\n");
+                       return LIB_ERROR_ATTRIBUTE;
+               }
+               log_err("Error in read xattr\n");
+               free(*hash);
+               return LIB_ERROR_SYSCALL;
+       }
+
+       return LIB_SUCCESS;
+}