14ae71c1dSDavid Howells /* Signature verification with an asymmetric key
24ae71c1dSDavid Howells  *
34ae71c1dSDavid Howells  * See Documentation/security/asymmetric-keys.txt
44ae71c1dSDavid Howells  *
54ae71c1dSDavid Howells  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
64ae71c1dSDavid Howells  * Written by David Howells (dhowells@redhat.com)
74ae71c1dSDavid Howells  *
84ae71c1dSDavid Howells  * This program is free software; you can redistribute it and/or
94ae71c1dSDavid Howells  * modify it under the terms of the GNU General Public Licence
104ae71c1dSDavid Howells  * as published by the Free Software Foundation; either version
114ae71c1dSDavid Howells  * 2 of the Licence, or (at your option) any later version.
124ae71c1dSDavid Howells  */
134ae71c1dSDavid Howells 
14c3ce6dfaSDavid Howells #define pr_fmt(fmt) "SIG: "fmt
154ae71c1dSDavid Howells #include <keys/asymmetric-subtype.h>
161f6a9ab0SPaul Gortmaker #include <linux/export.h>
174ae71c1dSDavid Howells #include <linux/err.h>
183b764563SDavid Howells #include <linux/slab.h>
194ae71c1dSDavid Howells #include <crypto/public_key.h>
204ae71c1dSDavid Howells #include "asymmetric_keys.h"
214ae71c1dSDavid Howells 
223b764563SDavid Howells /*
233b764563SDavid Howells  * Destroy a public key signature.
243b764563SDavid Howells  */
253b764563SDavid Howells void public_key_signature_free(struct public_key_signature *sig)
263b764563SDavid Howells {
273b764563SDavid Howells 	if (sig) {
283b764563SDavid Howells 		kfree(sig->s);
293b764563SDavid Howells 		kfree(sig->digest);
303b764563SDavid Howells 		kfree(sig);
313b764563SDavid Howells 	}
323b764563SDavid Howells }
333b764563SDavid Howells EXPORT_SYMBOL_GPL(public_key_signature_free);
343b764563SDavid Howells 
354ae71c1dSDavid Howells /**
364ae71c1dSDavid Howells  * verify_signature - Initiate the use of an asymmetric key to verify a signature
374ae71c1dSDavid Howells  * @key: The asymmetric key to verify against
384ae71c1dSDavid Howells  * @sig: The signature to check
394ae71c1dSDavid Howells  *
404ae71c1dSDavid Howells  * Returns 0 if successful or else an error.
414ae71c1dSDavid Howells  */
424ae71c1dSDavid Howells int verify_signature(const struct key *key,
434ae71c1dSDavid Howells 		     const struct public_key_signature *sig)
444ae71c1dSDavid Howells {
454ae71c1dSDavid Howells 	const struct asymmetric_key_subtype *subtype;
464ae71c1dSDavid Howells 	int ret;
474ae71c1dSDavid Howells 
484ae71c1dSDavid Howells 	pr_devel("==>%s()\n", __func__);
494ae71c1dSDavid Howells 
504ae71c1dSDavid Howells 	if (key->type != &key_type_asymmetric)
514ae71c1dSDavid Howells 		return -EINVAL;
524ae71c1dSDavid Howells 	subtype = asymmetric_key_subtype(key);
534ae71c1dSDavid Howells 	if (!subtype ||
54146aa8b1SDavid Howells 	    !key->payload.data[0])
554ae71c1dSDavid Howells 		return -EINVAL;
564ae71c1dSDavid Howells 	if (!subtype->verify_signature)
574ae71c1dSDavid Howells 		return -ENOTSUPP;
584ae71c1dSDavid Howells 
594ae71c1dSDavid Howells 	ret = subtype->verify_signature(key, sig);
604ae71c1dSDavid Howells 
614ae71c1dSDavid Howells 	pr_devel("<==%s() = %d\n", __func__, ret);
624ae71c1dSDavid Howells 	return ret;
634ae71c1dSDavid Howells }
644ae71c1dSDavid Howells EXPORT_SYMBOL_GPL(verify_signature);
65