added HMAC API error handling
[platform/upstream/ima-evm-utils.git] / src / evmctl.c
1 /*
2  * evm-utils - IMA/EVM support utilities
3  *
4  * Copyright (C) 2011 Nokia Corporation
5  * Copyright (C) 2011 Intel Corporation
6  *
7  * Authors:
8  * Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
9  *                 <dmitry.kasatkin@intel.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * version 2.1 as published by the Free Software Foundation.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  *
25  * File: evmctl.c
26  *       IMA/EVM control program
27  */
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/ioctl.h>
32 #include <sys/param.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <attr/xattr.h>
40 #include <getopt.h>
41 #include <signal.h>
42 #include <keyutils.h>
43 #include <asm/byteorder.h>
44 #include <syslog.h>
45 #include <attr/xattr.h>
46 #include <dirent.h>
47
48 #include <openssl/sha.h>
49 #include <openssl/rsa.h>
50 #include <openssl/pem.h>
51 #include <openssl/hmac.h>
52 #include <openssl/engine.h>
53 #include <openssl/evp.h>
54 #include <openssl/err.h>
55
56 #define USE_FPRINTF
57
58 #ifdef USE_FPRINTF
59 #define do_log(level, fmt, args...)     ({ if (level <= verbose) fprintf(stderr, fmt, ##args); })
60 #define do_log_dump(level, p, len)      ({ if (level <= verbose) do_dump(stderr, p, len); })
61 #else
62 #define do_log(level, fmt, args...)     syslog(level, fmt, ##args)
63 #define do_log_dump(p, len)
64 #endif
65
66 #ifdef DEBUG
67 #define log_debug(fmt, args...)         do_log(LOG_DEBUG, "%s:%d " fmt, __func__ , __LINE__ , ##args)
68 #define log_debug_dump(p, len)          do_log_dump(LOG_DEBUG, p, len)
69 #else
70 #define log_debug(fmt, args...)
71 #define log_debug_dump(p, len)
72 #endif
73
74 #define log_dump(p, len)                do_log_dump(LOG_INFO, p, len)
75 #define log_info(fmt, args...)          do_log(LOG_INFO, fmt, ##args)
76 #define log_err(fmt, args...)           do_log(LOG_ERR, fmt, ##args)
77 #define log_errno(fmt, args...)         do_log(LOG_ERR, fmt ": %s (%d)\n", ##args, strerror(errno), errno)
78
79 #define DATA_SIZE       4096
80 #define SHA1_HASH_LEN   20
81
82 #define EXT2_IOC_GETVERSION     _IOR('v', 1, long)
83 #define EXT34_IOC_GETVERSION    _IOR('f', 3, long)
84
85 #define FS_IOC_GETFLAGS         _IOR('f', 1, long)
86 #define FS_IOC_SETFLAGS         _IOW('f', 2, long)
87 #define FS_IOC32_GETFLAGS       _IOR('f', 1, int)
88 #define FS_IOC32_SETFLAGS       _IOW('f', 2, int)
89
90 struct h_misc {
91         unsigned long ino;
92         uint32_t generation;
93         uid_t uid;
94         gid_t gid;
95         unsigned short mode;
96 } hmac_misc;
97
98 enum pubkey_algo {
99         PUBKEY_ALGO_RSA,
100         PUBKEY_ALGO_MAX,
101 };
102
103 enum digest_algo {
104         DIGEST_ALGO_SHA1,
105         DIGEST_ALGO_SHA256,
106         DIGEST_ALGO_MAX
107 };
108
109 struct pubkey_hdr {
110         uint8_t version;        /* key format version */
111         uint32_t timestamp;     /* key made, always 0 for now */
112         uint8_t algo;
113         uint8_t nmpi;
114         char mpi[0];
115 } __attribute__ ((packed));
116
117 struct signature_hdr {
118         uint8_t version;        /* signature format version */
119         uint32_t timestamp;     /* signature made */
120         uint8_t algo;
121         uint8_t hash;
122         uint8_t keyid[8];
123         uint8_t nmpi;
124         char mpi[0];
125 } __attribute__ ((packed));
126
127 static char *evm_config_xattrnames[] = {
128         "security.selinux",
129         "security.SMACK64",
130         "security.ima",
131         "security.capability",
132         NULL
133 };
134
135 struct command {
136         char *name;
137         int (*func)(struct command *cmd);
138         int cmd;
139         char *arg;
140         char *msg;              /* extra info message */
141 };
142
143 static int verbose = LOG_INFO - 1;
144 static int g_argc;
145 static char **g_argv;
146 static int xattr = 1;
147 static int digest;
148 static int digsig;
149 static char *hash_algo = "sha1";
150 static int binkey;
151 static char *keypass;
152 static int sigfile;
153
154 struct command cmds[];
155 static void print_usage(struct command *cmd);
156
157 static void do_dump(FILE *fp, const void *ptr, int len)
158 {
159         int i;
160         uint8_t *data = (uint8_t *) ptr;
161
162         for (i = 0; i < len; i++)
163                 fprintf(fp, "%02x", data[i]);
164         fprintf(fp, "\n");
165 }
166
167 static void dump(const void *ptr, int len)
168 {
169         do_dump(stdout, ptr, len);
170 }
171
172 static inline int get_filesize(const char *filename)
173 {
174         struct stat stats;
175         /*  Need to know the file length */
176         stat(filename, &stats);
177         return (int)stats.st_size;
178 }
179
180 static inline int get_fdsize(int fd)
181 {
182         struct stat stats;
183         /*  Need to know the file length */
184         fstat(fd, &stats);
185         return (int)stats.st_size;
186 }
187
188 static int bin2file(const char *file, const char *ext, const unsigned char *data, int len)
189 {
190         FILE *fp;
191         char name[strlen(file) + (ext ? strlen(ext) : 0) + 2];
192         int err;
193
194         if (ext)
195                 sprintf(name, "%s.%s", file, ext);
196         else
197                 sprintf(name, "%s", file);
198
199         log_info("Writing to %s\n", name);
200
201         fp = fopen(name, "w");
202         if (!fp) {
203                 log_errno("Unable to open %s for writing", name);
204                 return -1;
205         }
206         err = fwrite(data, len, 1, fp);
207         fclose(fp);
208         return err;
209 }
210
211 static char *file2bin(const char *file, int *size)
212 {
213         FILE *fp;
214         int len;
215         char *data;
216
217         len = get_filesize(file);
218         fp = fopen(file, "r");
219         if (!fp) {
220                 log_errno("Unable to open %s", file);
221                 return NULL;
222         }
223         data = malloc(len);
224         if (!fread(data, len, 1, fp))
225                 len = 0;
226         fclose(fp);
227
228         *size = len;
229         return data;
230 }
231
232 /*
233  * Create binary key representation suitable for kernel
234  */
235 static int key2bin(RSA *key, unsigned char *pub)
236 {
237         int len, b, offset = 0;
238         struct pubkey_hdr *pkh = (struct pubkey_hdr *)pub;
239
240         /* add key header */
241         pkh->version = 1;
242         pkh->timestamp = 0;     /* PEM has no timestamp?? */
243         pkh->algo = PUBKEY_ALGO_RSA;
244         pkh->nmpi = 2;
245
246         offset += sizeof(*pkh);
247
248         len = BN_num_bytes(key->n);
249         b = BN_num_bits(key->n);
250         pub[offset++] = b >> 8;
251         pub[offset++] = b & 0xff;
252         BN_bn2bin(key->n, &pub[offset]);
253         offset += len;
254
255         len = BN_num_bytes(key->e);
256         b = BN_num_bits(key->e);
257         pub[offset++] = b >> 8;
258         pub[offset++] = b & 0xff;
259         BN_bn2bin(key->e, &pub[offset]);
260         offset += len;
261
262         return offset;
263 }
264
265 static int read_key(const char *inkey, unsigned char *pub)
266 {
267         FILE *fp;
268         RSA *key = NULL, *key1;
269         int len;
270
271         fp = fopen(inkey, "r");
272         if (!fp) {
273                 log_errno("read key failed from file %s", inkey);
274                 return -1;
275         }
276
277         key1 = PEM_read_RSA_PUBKEY(fp, &key, NULL, NULL);
278         fclose(fp);
279         if (!key1) {
280                 log_errno("PEM_read_RSA_PUBKEY() failed");
281                 return -1;
282         }
283
284         len = key2bin(key, pub);
285
286         RSA_free(key);
287
288         return len;
289 }
290
291 static void calc_keyid(uint8_t *keyid, char *str, const unsigned char *pkey, int len)
292 {
293         uint8_t sha1[SHA_DIGEST_LENGTH];
294         uint64_t id;
295
296         log_debug("pkey:\n");
297         log_debug_dump(pkey, len);
298         SHA1(pkey, len, sha1);
299
300         /* sha1[12 - 19] is exactly keyid from gpg file */
301         memcpy(keyid, sha1 + 12, 8);
302         log_debug("keyid:\n");
303         log_debug_dump(keyid, 8);
304
305         id = __be64_to_cpup((__be64 *) keyid);
306         sprintf(str, "%llX", (unsigned long long)id);
307         log_info("keyid: %s\n", str);
308 }
309
310 static int sign_hash(const unsigned char *hash, int size, const char *keyfile, unsigned char *sig)
311 {
312         int err, len;
313         SHA_CTX ctx;
314         unsigned char pub[1024];
315         RSA *key = NULL, *key1;
316         FILE *fp;
317         char name[20];
318         unsigned char sighash[20];
319         struct signature_hdr *hdr = (struct signature_hdr *)sig;
320         uint16_t *blen;
321
322         log_info("hash: ");
323         log_dump(hash, size);
324
325         fp = fopen(keyfile, "r");
326         if (!fp) {
327                 log_errno("Unable to open keyfile %s", keyfile);
328                 return -1;
329         }
330         key1 = PEM_read_RSAPrivateKey(fp, &key, NULL, keypass);
331         fclose(fp);
332         if (!key1) {
333                 log_errno("RSAPrivateKey() failed");
334                 return -1;
335         }
336
337         /* now create a new hash */
338         hdr->version = 1;
339         hdr->timestamp = time(NULL);
340         hdr->algo = PUBKEY_ALGO_RSA;
341         hdr->hash = DIGEST_ALGO_SHA1;
342
343         len = key2bin(key, pub);
344         calc_keyid(hdr->keyid, name, pub, len);
345
346         hdr->nmpi = 1;
347
348         SHA1_Init(&ctx);
349         SHA1_Update(&ctx, hash, size);
350         SHA1_Update(&ctx, hdr, sizeof(*hdr));
351         SHA1_Final(sighash, &ctx);
352         log_info("sighash: ");
353         log_dump(sighash, sizeof(sighash));
354
355         err = RSA_private_encrypt(sizeof(sighash), sighash, sig + sizeof(*hdr) + 2, key, RSA_PKCS1_PADDING);
356         RSA_free(key);
357         if (err < 0) {
358                 log_errno("RSA_private_encrypt() failed: %d", err);
359                 return -1;
360         }
361
362         len = err;
363
364         /* we add bit length of the signature to make it gnupg compatible */
365         blen = (uint16_t *) (sig + sizeof(*hdr));
366         *blen = __cpu_to_be16(len << 3);
367         len += sizeof(*hdr) + 2;
368         log_info("evm/ima signature: %d bytes\n", len);
369         if (!xattr || verbose >= LOG_INFO)
370                 dump(sig, len);
371
372         return len;
373 }
374
375 static int calc_evm_hash(const char *file, unsigned char *hash)
376 {
377         struct stat st;
378         int fd, err;
379         uint32_t generation;
380         EVP_MD_CTX ctx;
381         const EVP_MD *md;
382         unsigned int mdlen;
383         char **xattrname;
384         char xattr_value[1024];
385
386         fd = open(file, 0);
387         if (fd < 0) {
388                 log_errno("Unable to open %s", file);
389                 return -1;
390         }
391
392         if (fstat(fd, &st)) {
393                 log_errno("fstat() failed");
394                 return -1;
395         }
396
397         if (ioctl(fd, EXT34_IOC_GETVERSION, &generation)) {
398                 log_errno("ioctl() failed");
399                 return -1;
400         }
401
402         close(fd);
403
404         log_info("generation: %u\n", generation);
405
406         md = EVP_get_digestbyname("sha1");
407         if (!md) {
408                 log_errno("EVP_get_digestbyname() failed");
409                 return -1;
410         }
411
412         err = EVP_DigestInit(&ctx, md);
413         if (!err) {
414                 log_errno("EVP_DigestInit() failed");
415                 return -1;
416         }
417
418         for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
419                 err = getxattr(file, *xattrname, xattr_value, sizeof(xattr_value));
420                 if (err < 0) {
421                         log_info("no attr: %s\n", *xattrname);
422                         continue;
423                 }
424                 /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
425                 log_info("name: %s, size: %d\n", *xattrname, err);
426                 log_debug_dump(xattr_value, err);
427                 err = EVP_DigestUpdate(&ctx, xattr_value, err);
428                 if (!err) {
429                         log_errno("EVP_DigestUpdate() failed");
430                         return -1;
431                 }
432         }
433
434         memset(&hmac_misc, 0, sizeof(hmac_misc));
435         hmac_misc.ino = st.st_ino;
436         hmac_misc.generation = generation;
437         hmac_misc.uid = st.st_uid;
438         hmac_misc.gid = st.st_gid;
439         hmac_misc.mode = st.st_mode;
440
441         err = EVP_DigestUpdate(&ctx, (const unsigned char *)&hmac_misc, sizeof(hmac_misc));
442         if (!err) {
443                 log_errno("EVP_DigestUpdate() failed");
444                 return -1;
445         }
446         err = EVP_DigestFinal(&ctx, hash, &mdlen);
447         if (!err) {
448                 log_errno("EVP_DigestFinal() failed");
449                 return -1;
450         }
451
452         return 0;
453 }
454
455 static int sign_evm(const char *file, const char *key)
456 {
457         unsigned char hash[20];
458         unsigned char sig[1024] = "\x03";
459         int err;
460
461         calc_evm_hash(file, hash);
462
463         err = sign_hash(hash, sizeof(hash), key, sig + 1);
464         if (err < 0)
465                 return err;
466
467         if (xattr) {
468                 err = setxattr(file, "security.evm", sig, err + 1, 0);
469                 if (err < 0) {
470                         log_errno("setxattr failed: %s", file);
471                         return err;
472                 }
473         }
474
475         return 0;
476 }
477
478 static int calc_file_hash(const char *file, uint8_t *hash)
479 {
480         EVP_MD_CTX ctx;
481         const EVP_MD *md;
482         uint8_t *data;
483         int err, size, bs = DATA_SIZE;
484         size_t len;
485         unsigned int mdlen;
486         FILE *fp;
487
488         data = malloc(bs);
489         if (!data) {
490                 log_errno("malloc failed");
491                 return -1;
492         }
493
494         fp = fopen(file, "r");
495         if (!fp) {
496                 log_errno("Unable to open %s", file);
497                 return -1;
498         }
499
500         md = EVP_get_digestbyname(hash_algo);
501         if (!md) {
502                 log_errno("EVP_get_digestbyname() failed");
503                 return -1;
504         }
505
506         err = EVP_DigestInit(&ctx, md);
507         if (!err) {
508                 log_errno("EVP_DigestInit() failed");
509                 return -1;
510         }
511
512         for (size = get_fdsize(fileno(fp)); size; size -= len) {
513                 len = MIN(size, bs);
514                 err = fread(data, len, 1, fp);
515                 if (!err) {
516                         if (ferror(fp)) {
517                                 log_errno("fread() error\n");
518                                 return -1;
519                         }
520                         break;
521                 }
522                 err = EVP_DigestUpdate(&ctx, data, len);
523                 if (!err) {
524                         log_errno("EVP_DigestUpdate() failed");
525                         return -1;
526                 }
527         }
528
529         err = EVP_DigestFinal(&ctx, hash, &mdlen);
530         if (!err) {
531                 log_errno("EVP_DigestFinal() failed");
532                 return -1;
533         }
534
535         fclose(fp);
536
537         free(data);
538
539         return mdlen;
540 }
541
542 struct dirent_list {
543         struct dirent_list *next;
544         struct dirent de;
545 };
546
547 static int calc_dir_hash(const char *file, uint8_t *hash)
548 {
549         EVP_MD_CTX ctx;
550         const EVP_MD *md;
551         int err;
552         unsigned int mdlen;
553         struct dirent *de;
554         DIR *dir;
555         struct dirent_list *head = NULL, *pos, *prev, *cur;
556         uint64_t ino;
557
558         dir = opendir(file);
559         if (!dir) {
560                 log_errno("Unable to open %s", file);
561                 return -1;
562         }
563
564         md = EVP_get_digestbyname(hash_algo);
565         if (!md) {
566                 log_errno("EVP_get_digestbyname() failed");
567                 return -1;
568         }
569
570         err = EVP_DigestInit(&ctx, md);
571         if (!err) {
572                 log_errno("EVP_DigestInit() failed");
573                 return -1;
574         }
575
576         while ((de = readdir(dir))) {
577                 /*log_debug("entry: ino: %lu, %s\n", de->d_ino, de->d_name);*/
578                 for (prev = NULL, pos = head; pos; prev = pos, pos = pos->next) {
579                         if (de->d_ino < pos->de.d_ino)
580                                 break;
581                 }
582                 cur = malloc(sizeof(*cur));
583                 cur->de = *de;
584                 cur->next = pos;
585                 if (!head || !prev)
586                         head = cur;
587                 else
588                         prev->next = cur;
589         }
590
591         for (cur = head; cur; cur = pos) {
592                 pos = cur->next;
593                 ino = cur->de.d_ino;
594                 log_debug("entry: ino: %llu, %s\n", (unsigned long long)ino, cur->de.d_name);
595                 err = EVP_DigestUpdate(&ctx, cur->de.d_name, strlen(cur->de.d_name));
596                 if (!err) {
597                         log_errno("EVP_DigestUpdate() failed");
598                         return -1;
599                 }
600                 err = EVP_DigestUpdate(&ctx, &ino, sizeof(ino));
601                 if (!err) {
602                         log_errno("EVP_DigestUpdate() failed");
603                         return -1;
604                 }
605                 free(cur);
606         }
607
608         err = EVP_DigestFinal(&ctx, hash, &mdlen);
609         if (!err) {
610                 log_errno("EVP_DigestFinal() failed");
611                 return -1;
612         }
613
614         closedir(dir);
615
616         return mdlen;
617 }
618
619 static int hash_ima(const char *file)
620 {
621         unsigned char hash[65] = "\x01"; /* MAX hash size + 1 */
622         int err;
623         struct stat st;
624
625         /*  Need to know the file length */
626         err = stat(file, &st);
627         if (err < 0) {
628                 log_errno("stat() failed");
629                 return err;
630         }
631
632         if (S_ISDIR(st.st_mode))
633                 err = calc_dir_hash(file, hash + 1);
634         else
635                 err = calc_file_hash(file, hash + 1);
636         if (err < 0)
637                 return err;
638
639         if (verbose >= LOG_INFO)
640                 log_info("hash: ");
641
642         if (!xattr || verbose >= LOG_INFO)
643                 dump(hash, err + 1);
644
645         if (xattr) {
646                 err = setxattr(file, "security.ima", hash, err + 1, 0);
647                 if (err < 0) {
648                         log_errno("setxattr failed: %s", file);
649                         return err;
650                 }
651         }
652
653         return 0;
654 }
655
656 static int cmd_hash_ima(struct command *cmd)
657 {
658         char *file = g_argv[optind++];
659
660         if (!file) {
661                 log_err("Parameters missing\n");
662                 print_usage(cmd);
663                 return 1;
664         }
665
666         return hash_ima(file);
667 }
668
669 static int sign_ima(const char *file, const char *key)
670 {
671         unsigned char hash[64];
672         unsigned char sig[1024] = "\x03";
673         int err;
674
675         err = calc_file_hash(file, hash);
676         if (err < 0)
677                 return err;
678
679         err = sign_hash(hash, err, key, sig + 1);
680         if (err < 0)
681                 return err;
682
683         if (sigfile)
684                 bin2file(file, "sig", sig, err + 1);
685
686         if (xattr) {
687                 err = setxattr(file, "security.ima", sig, err + 1, 0);
688                 if (err < 0) {
689                         log_errno("setxattr failed: %s", file);
690                         return err;
691                 }
692         }
693
694         return 0;
695 }
696
697 static int cmd_sign_ima(struct command *cmd)
698 {
699         char *key, *file = g_argv[optind++];
700
701         if (!file) {
702                 log_err("Parameters missing\n");
703                 print_usage(cmd);
704                 return 1;
705         }
706
707         key = g_argv[optind++];
708         if (!key)
709                 key = "/etc/keys/privkey_evm.pem";
710
711         return sign_ima(file, key);
712
713 }
714
715 static int cmd_sign_evm(struct command *cmd)
716 {
717         char *key, *file = g_argv[optind++];
718         int err;
719
720         if (!file) {
721                 log_err("Parameters missing\n");
722                 print_usage(cmd);
723                 return 1;
724         }
725
726         key = g_argv[optind++];
727         if (!key)
728                 key = "/etc/keys/privkey_evm.pem";
729
730         if (digsig) {
731                 err = sign_ima(file, key);
732                 if (err)
733                         return err;
734         }
735
736         if (digest) {
737                 err = hash_ima(file);
738                 if (err)
739                         return err;
740         }
741
742         return sign_evm(file, key);
743 }
744
745 static int verify_hash(const unsigned char *hash, int size, unsigned char *sig, int siglen, const char *keyfile)
746 {
747         int err, len;
748         SHA_CTX ctx;
749         unsigned char out[1024];
750         RSA *key = NULL, *key1;
751         FILE *fp;
752         unsigned char sighash[20];
753         struct signature_hdr *hdr = (struct signature_hdr *)sig;
754
755         log_info("hash: ");
756         log_dump(hash, size);
757
758         fp = fopen(keyfile, "r");
759         if (!fp) {
760                 log_errno("Unable to open keyfile %s", keyfile);
761                 return -1;
762         }
763         key1 = PEM_read_RSA_PUBKEY(fp, &key, NULL, NULL);
764         fclose(fp);
765         if (!key1) {
766                 log_errno("PEM_read_RSA_PUBKEY() failed");
767                 return -1;
768         }
769
770         SHA1_Init(&ctx);
771         SHA1_Update(&ctx, hash, size);
772         SHA1_Update(&ctx, hdr, sizeof(*hdr));
773         SHA1_Final(sighash, &ctx);
774         log_info("sighash: ");
775         log_dump(sighash, sizeof(sighash));
776
777         err = RSA_public_decrypt(siglen - sizeof(*hdr) - 2, sig + sizeof(*hdr) + 2, out, key, RSA_PKCS1_PADDING);
778         RSA_free(key);
779         if (err < 0) {
780                 log_errno("RSA_public_decrypt() failed: %d", err);
781                 return -1;
782         }
783
784         len = err;
785
786         if (len != sizeof(sighash) || memcmp(out, sighash, len) != 0) {
787                 log_errno("Verification failed: %d", err);
788                 return -1;
789         } else {
790                 /*log_info("Verification is OK\n");*/
791                 printf("Verification is OK\n");
792         }
793
794         return 0;
795 }
796
797 static int verify_evm(const char *file, const char *key)
798 {
799         unsigned char hash[20];
800         unsigned char sig[1024];
801         int err;
802
803         calc_evm_hash(file, hash);
804
805         err = getxattr(file, "security.evm", sig, sizeof(sig));
806         if (err < 0) {
807                 log_errno("getxattr failed");
808                 return err;
809         }
810
811         if (sig[0] != 0x03) {
812                 log_errno("security.evm has not signature");
813                 return err;
814         }
815
816         return verify_hash(hash, sizeof(hash), sig + 1, err - 1, key);
817 }
818
819 static int cmd_verify_evm(struct command *cmd)
820 {
821         char *key, *file = g_argv[optind++];
822
823         if (!file) {
824                 log_err("Parameters missing\n");
825                 print_usage(cmd);
826                 return 1;
827         }
828
829         key = g_argv[optind++];
830         if (!key)
831                 key = "/etc/keys/pubkey_evm.pem";
832
833         return verify_evm(file, key);
834 }
835
836 static int cmd_convert(struct command *cmd)
837 {
838         char *inkey, *outkey = NULL;
839         unsigned char pub[1024];
840         char name[20];
841         int len;
842         uint8_t keyid[8];
843
844         inkey = g_argv[optind++];
845         if (!inkey)
846                 inkey = "/etc/keys/pubkey_evm.pem";
847         else
848                 outkey = g_argv[optind++];
849
850         if (!outkey)
851                 outkey = "pubkey_evm.bin";
852
853         log_info("Convert public key %s to %s\n", inkey, outkey);
854
855         len = read_key(inkey, pub);
856         if (len < 0)
857                 return -1;
858
859         calc_keyid(keyid, name, pub, len);
860
861         bin2file(outkey, name, pub, len);
862
863         return 0;
864 }
865
866 static int cmd_import_bin(struct command *cmd)
867 {
868         int len;
869         char *inkey, *ring = NULL;
870         char *key, name[20];
871         key_serial_t id;
872         uint8_t keyid[8];
873
874         inkey = g_argv[optind++];
875         if (!inkey)
876                 inkey = "/etc/keys/pubkey_evm.bin";
877         else
878                 ring = g_argv[optind++];
879
880         if (!ring)
881                 id = KEY_SPEC_USER_KEYRING;
882         else
883                 id = atoi(ring);
884
885         key = file2bin(inkey, &len);
886         if (!key)
887                 return -1;
888
889         calc_keyid(keyid, name, (unsigned char *)key, len);
890
891         log_info("Importing public key %s from file %s into keyring %d\n", name, inkey, id);
892
893         id = add_key("user", name, key, len, id);
894         if (id < 0) {
895                 log_errno("add_key failed");
896                 return -1;
897         }
898
899         log_info("keyid: %d\n", id);
900         printf("%d\n", id);
901
902         free(key);
903
904         return 0;
905 }
906
907 static int cmd_import(struct command *cmd)
908 {
909         char *inkey, *ring = NULL;
910         unsigned char key[1024];
911         int id, len;
912         char name[20];
913         uint8_t keyid[8];
914
915         if (binkey)
916                 return cmd_import_bin(cmd);
917
918         inkey = g_argv[optind++];
919         if (!inkey)
920                 inkey = "/etc/keys/pubkey_evm.pem";
921         else
922                 ring = g_argv[optind++];
923
924         if (!ring)
925                 id = KEY_SPEC_USER_KEYRING;
926         else
927                 id = atoi(ring);
928
929         len = read_key(inkey, key);
930         if (len < 0)
931                 return -1;
932
933         calc_keyid(keyid, name, key, len);
934
935         log_info("Importing public key %s from file %s into keyring %d\n", name, inkey, id);
936
937         id = add_key("user", name, key, len, id);
938         if (id < 0) {
939                 log_errno("add_key failed");
940                 return -1;
941         }
942
943         log_info("keyid: %d\n", id);
944         printf("%d\n", id);
945
946         return 0;
947 }
948
949 #define MAX_KEY_SIZE 128
950
951 static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *hash)
952 {
953         struct stat st;
954         int fd, err;
955         uint32_t generation;
956         HMAC_CTX ctx;
957         unsigned int mdlen;
958         char **xattrname;
959         unsigned char xattr_value[1024];
960         char *key;
961         int keylen;
962         unsigned char evmkey[MAX_KEY_SIZE];
963
964         key = file2bin(keyfile, &keylen);
965         if (!key) {
966                 log_errno("Unable to read a key: %s\n", keyfile);
967                 return -1;
968         }
969
970         if (keylen > sizeof(evmkey)) {
971                 log_errno("key is too long\n");
972                 return -1;
973         }
974
975         /* EVM key is 128 bytes */
976         memcpy(evmkey, key, keylen);
977         memset(evmkey + keylen, 0, sizeof(evmkey) - keylen);
978
979         fd = open(file, 0);
980         if (fd < 0) {
981                 log_errno("Unable to open %s", file);
982                 return -1;
983         }
984
985         if (fstat(fd, &st)) {
986                 log_errno("fstat() failed");
987                 return -1;
988         }
989
990         if (ioctl(fd, EXT34_IOC_GETVERSION, &generation)) {
991                 log_errno("ioctl() failed");
992                 return -1;
993         }
994
995         close(fd);
996
997         log_info("generation: %u\n", generation);
998
999         err = HMAC_Init(&ctx, evmkey, sizeof(evmkey), EVP_sha1());
1000         if (!err) {
1001                 log_errno("HMAC_Init() failed");
1002                 return -1;
1003         }
1004
1005         for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
1006                 err = getxattr(file, *xattrname, xattr_value, sizeof(xattr_value));
1007                 if (err < 0) {
1008                         log_info("no attr: %s\n", *xattrname);
1009                         continue;
1010                 }
1011                 /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
1012                 log_info("name: %s, size: %d\n", *xattrname, err);
1013                 log_debug_dump(xattr_value, err);
1014                 err = HMAC_Update(&ctx, xattr_value, err);
1015                 if (!err) {
1016                         log_errno("HMAC_Update() failed");
1017                         return -1;
1018                 }
1019         }
1020
1021         memset(&hmac_misc, 0, sizeof(hmac_misc));
1022         hmac_misc.ino = st.st_ino;
1023         hmac_misc.generation = generation;
1024         hmac_misc.uid = st.st_uid;
1025         hmac_misc.gid = st.st_gid;
1026         hmac_misc.mode = st.st_mode;
1027
1028         err = HMAC_Update(&ctx, (const unsigned char *)&hmac_misc, sizeof(hmac_misc));
1029         if (!err) {
1030                 log_errno("HMAC_Update() failed");
1031                 return -1;
1032         }
1033         err = HMAC_Final(&ctx, hash, &mdlen);
1034         if (!err) {
1035                 log_errno("HMAC_Final() failed");
1036                 return -1;
1037         }
1038         HMAC_CTX_cleanup(&ctx);
1039
1040         free(key);
1041
1042         return 0;
1043 }
1044
1045 static int hmac_evm(const char *file, const char *key)
1046 {
1047         unsigned char hash[20];
1048         unsigned char sig[1024] = "\x02";
1049         int err;
1050
1051         calc_evm_hmac(file, key, hash);
1052
1053         log_info("hmac: ");
1054         log_dump(hash, sizeof(hash));
1055         memcpy(sig + 1, hash, sizeof(hash));
1056         err = sizeof(hash);
1057
1058         if (xattr) {
1059                 err = setxattr(file, "security.evm", sig, err + 1, 0);
1060                 if (err < 0) {
1061                         log_errno("setxattr failed: %s", file);
1062                         return err;
1063                 }
1064         }
1065
1066         return 0;
1067 }
1068
1069 static int cmd_hmac_evm(struct command *cmd)
1070 {
1071         char *key, *file = g_argv[optind++];
1072         int err;
1073
1074         if (!file) {
1075                 log_err("Parameters missing\n");
1076                 print_usage(cmd);
1077                 return 1;
1078         }
1079
1080         key = g_argv[optind++];
1081         if (!key)
1082                 key = "/etc/keys/privkey_evm.pem";
1083
1084         if (digsig) {
1085                 err = sign_ima(file, key);
1086                 if (err)
1087                         return err;
1088         }
1089
1090         if (digest) {
1091                 err = hash_ima(file);
1092                 if (err)
1093                         return err;
1094         }
1095
1096         return hmac_evm(file, "/etc/keys/evm-key-plain");
1097 }
1098
1099 static void print_usage(struct command *cmd)
1100 {
1101         printf("usage: %s %s\n", cmd->name, cmd->arg ? cmd->arg : "");
1102 }
1103
1104 static void print_full_usage(struct command *cmd)
1105 {
1106         if (cmd->name)
1107                 printf("usage: %s %s\n", cmd->name, cmd->arg ? cmd->arg : "");
1108         if (cmd->msg)
1109                 printf("description:\n%s", cmd->msg);
1110
1111 }
1112
1113 static int print_command_usage(struct command *cmds, char *command)
1114 {
1115         struct command *cmd;
1116
1117         for (cmd = cmds; cmd->name; cmd++) {
1118                 if (strcmp(cmd->name, command) == 0) {
1119                         print_full_usage(cmd);
1120                         return 0;
1121                 }
1122         }
1123         printf("invalid command: %s\n", command);
1124         return 1;
1125 }
1126
1127 static void print_all_usage(struct command *cmds)
1128 {
1129         struct command *cmd;
1130
1131         for (cmd = cmds; cmd->name; cmd++) {
1132                 if (cmd->arg)
1133                         printf("%s %s\n", cmd->name, cmd->arg);
1134                 else if (cmd->msg)
1135                         printf("%s", cmd->msg);
1136         }
1137 }
1138
1139 static int call_command(struct command *cmds, char *command)
1140 {
1141         struct command *cmd;
1142
1143         for (cmd = cmds; cmd->name; cmd++) {
1144                 if (strcasecmp(cmd->name, command) == 0)
1145                         return cmd->func(cmd);
1146         }
1147         printf("Invalid command: %s\n", command);
1148         return -1;
1149 }
1150
1151 static int cmd_help(struct command *cmd)
1152 {
1153         if (!g_argv[optind]) {
1154                 print_usage(cmd);
1155                 return 0;
1156         } else
1157                 return print_command_usage(cmds, g_argv[optind]);
1158 }
1159
1160 static void usage(void)
1161 {
1162         printf("Usage: evmctl <command> [parameters..]\n");
1163
1164         print_all_usage(cmds);
1165 }
1166
1167 struct command cmds[] = {
1168         {"help", cmd_help, 0, "<command>"},
1169         {"import", cmd_import, 0, "[--bin] inkey keyring", "Import public key (PEM/bin) into the keyring.\n"},
1170         {"convert", cmd_convert, 0, "inkey outkey", "Convert PEM public key into IMA/EVM kernel friendly format.\n"},
1171         {"sign", cmd_sign_evm, 0, "[--imahash | --imasig ] file [key]", "Sign file metadata.\n"},
1172         {"verify", cmd_verify_evm, 0, "file", "Verify EVM signature (for debugging).\n"},
1173         {"ima_sign", cmd_sign_ima, 0, "[--sigfile] file [key]", "Sign file content.\n"},
1174         {"ima_hash", cmd_hash_ima, 0, "file", "Hash file content.\n"},
1175         {"hmac", cmd_hmac_evm, 0, "[--imahash | --imasig ] file [key]", "Sign file metadata with HMAC (for debugging).\n"},
1176         {0, 0, 0, NULL}
1177 };
1178
1179 static struct option opts[] = {
1180         {"help", 0, 0, 'h'},
1181         {"inkey", 1, 0, 'k'},
1182         {"imasig", 0, 0, 's'},
1183         {"imahash", 0, 0, 'd'},
1184         {"hashalgo", 1, 0, 'a'},
1185         {"bin", 0, 0, 'b'},
1186         {"pass", 1, 0, 'p'},
1187         {"sigfile", 0, 0, 'f'},
1188         {}
1189
1190 };
1191
1192 int main(int argc, char *argv[])
1193 {
1194         int err = 0, c, lind;
1195
1196         g_argv = argv;
1197         g_argc = argc;
1198
1199         while (1) {
1200                 c = getopt_long(argc, argv, "hk:vnsda:bp:f", opts, &lind);
1201                 if (c == -1)
1202                         break;
1203
1204                 switch (c) {
1205                 case 'h':
1206                         usage();
1207                         exit(0);
1208                         break;
1209                 case 'k':
1210                         printf("inkey: %s\n", optarg);
1211                         break;
1212                 case 'v':
1213                         verbose++;
1214                         break;
1215                 case 'd':
1216                         digest = 1;
1217                         break;
1218                 case 's':
1219                         digsig = 1;
1220                         break;
1221                 case 'n':
1222                         /* do not set Extended Attributes... just print signature */
1223                         xattr = 0;
1224                         break;
1225                 case 'a':
1226                         hash_algo = optarg;
1227                         break;
1228                 case 'b':
1229                         binkey = 1;
1230                         break;
1231                 case 'p':
1232                         keypass = optarg;
1233                         break;
1234                 case 'f':
1235                         sigfile = 1;
1236                         break;
1237                 case '?':
1238                         exit(1);
1239                         break;
1240                 default:
1241                         log_err("getopt() returned: %d (%c)\n", c, c);
1242                 }
1243         }
1244
1245         OpenSSL_add_all_algorithms();
1246         ERR_load_crypto_strings();
1247
1248         if (argv[optind] == NULL)
1249                 usage();
1250         else
1251                 err = call_command(cmds, argv[optind++]);
1252
1253         if (err)
1254                 log_err("error: %s\n", ERR_error_string(ERR_get_error(), NULL));
1255
1256         ERR_free_strings();
1257         EVP_cleanup();
1258
1259         return err;
1260 }