mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl1BJxsACgkQONu9yGCS aT4wBxAAymuWVXtmeWFQSFNji/RAJcHBAOvydIRMr7vwCXpojuRerNolo7WibM/B Mgx2OISn0d8rg98Cc3wiM6WUN9AeHr3lSWXORg3iBr0zP+ZO5Vs0Y2w9gueEJS+i egMvi2KZyS3Esrfmxv62pJ9DIVqyPVlvzN/Y79BARcwIeZOt+puycR5XV3WROzX9 Wy2JBz5f56m9qzPGKXGRLlvq7LghZ5EbyFoIb/fj9K6pFdVBrpSEOeocCQos9IEz 0+1TiWAkqOGLGZWJ3CFW/6Nbn1JO3hZpIgqxVczZXR+4UVhR+yniHUzZ20g89DzE mmprjKGv/8/7pXyXtGhjXuaZN5r1ldUje5SZf1X7SzxLuABSKIHykYJjKUQY2O3b 8tpPULGA77V7Ww4TtyRLeOVPqaVslWFgLP6snyileSdoxfISebo2KptQn0pmuFX2 Y0ePPot/aHHXmhrn5mAY9UZO9etqko8LjvVHDOsQQ99GJJ1BAz73w+wkKDtHXGuo iqUlSSW2YpThnAkufUlyhk10y6itGmy0P7GSrw8PCd9As2/LAz6c9+8+NPp/2P2Z Ffl2q7eUCqb0HixAnq5KqcPDSVdyqVtQ7XeN3lAEWVGmwpiu2xyuZgpQyT5FRqOZ mLYHZJF7FEZOZo+hkbH4O6j3umJ0QFJakVwrEiQ/ha0yLZpS3OM= =u0hP -----END PGP SIGNATURE----- Merge 4.14.135 into android-4.14 Changes in 4.14.135 MIPS: ath79: fix ar933x uart parity mode MIPS: fix build on non-linux hosts arm64/efi: Mark __efistub_stext_offset as an absolute symbol explicitly scsi: iscsi: set auth_protocol back to NULL if CHAP_A value is not supported dmaengine: imx-sdma: fix use-after-free on probe error path wil6210: fix potential out-of-bounds read ath10k: Do not send probe response template for mesh ath9k: Check for errors when reading SREV register ath6kl: add some bounds checking ath: DFS JP domain W56 fixed pulse type 3 RADAR detection batman-adv: fix for leaked TVLV handler. media: dvb: usb: fix use after free in dvb_usb_device_exit media: spi: IR LED: add missing of table registration crypto: talitos - fix skcipher failure due to wrong output IV media: marvell-ccic: fix DMA s/g desc number calculation media: vpss: fix a potential NULL pointer dereference media: media_device_enum_links32: clean a reserved field net: stmmac: dwmac1000: Clear unused address entries net: stmmac: dwmac4/5: Clear unused address entries qed: Set the doorbell address correctly signal/pid_namespace: Fix reboot_pid_ns to use send_sig not force_sig af_key: fix leaks in key_pol_get_resp and dump_sp. xfrm: Fix xfrm sel prefix length validation fscrypt: clean up some BUG_ON()s in block encryption/decryption media: mc-device.c: don't memset __user pointer contents media: staging: media: davinci_vpfe: - Fix for memory leak if decoder initialization fails. net: phy: Check against net_device being NULL crypto: talitos - properly handle split ICV. crypto: talitos - Align SEC1 accesses to 32 bits boundaries. tua6100: Avoid build warnings. locking/lockdep: Fix merging of hlocks with non-zero references media: wl128x: Fix some error handling in fm_v4l2_init_video_device() cpupower : frequency-set -r option misses the last cpu in related cpu list net: stmmac: dwmac4: fix flow control issue net: fec: Do not use netdev messages too early net: axienet: Fix race condition causing TX hang s390/qdio: handle PENDING state for QEBSM devices RAS/CEC: Fix pfn insertion net: sfp: add mutex to prevent concurrent state checks ipset: Fix memory accounting for hash types on resize perf cs-etm: Properly set the value of 'old' and 'head' in snapshot mode perf test 6: Fix missing kvm module load for s390 media: fdp1: Support M3N and E3 platforms iommu: Fix a leak in iommu_insert_resv_region gpio: omap: fix lack of irqstatus_raw0 for OMAP4 gpio: omap: ensure irq is enabled before wakeup regmap: fix bulk writes on paged registers bpf: silence warning messages in core rcu: Force inlining of rcu_read_lock() x86/cpufeatures: Add FDP_EXCPTN_ONLY and ZERO_FCS_FDS blkcg, writeback: dead memcgs shouldn't contribute to writeback ownership arbitration xfrm: fix sa selector validation sched/core: Add __sched tag for io_schedule() x86/atomic: Fix smp_mb__{before,after}_atomic() perf evsel: Make perf_evsel__name() accept a NULL argument vhost_net: disable zerocopy by default ipoib: correcly show a VF hardware address EDAC/sysfs: Fix memory leak when creating a csrow object ipsec: select crypto ciphers for xfrm_algo ipvs: defer hook registration to avoid leaks media: s5p-mfc: Make additional clocks optional media: i2c: fix warning same module names ntp: Limit TAI-UTC offset timer_list: Guard procfs specific code acpi/arm64: ignore 5.1 FADTs that are reported as 5.0 media: coda: fix mpeg2 sequence number handling media: coda: fix last buffer handling in V4L2_ENC_CMD_STOP media: coda: increment sequence offset for the last returned frame media: vimc: cap: check v4l2_fill_pixfmt return value media: hdpvr: fix locking and a missing msleep rtlwifi: rtl8192cu: fix error handle when usb probe failed mt7601u: do not schedule rx_tasklet when the device has been disconnected x86/build: Add 'set -e' to mkcapflags.sh to delete broken capflags.c mt7601u: fix possible memory leak when the device is disconnected ipvs: fix tinfo memory leak in start_sync_thread ath10k: add missing error handling ath10k: fix PCIE device wake up failed perf tools: Increase MAX_NR_CPUS and MAX_CACHES libata: don't request sense data on !ZAC ATA devices clocksource/drivers/exynos_mct: Increase priority over ARM arch timer rslib: Fix decoding of shortened codes rslib: Fix handling of of caller provided syndrome ixgbe: Check DDM existence in transceiver before access crypto: serpent - mark __serpent_setkey_sbox noinline crypto: asymmetric_keys - select CRYPTO_HASH where needed EDAC: Fix global-out-of-bounds write when setting edac_mc_poll_msec bcache: check c->gc_thread by IS_ERR_OR_NULL in cache_set_flush() net: hns3: fix a -Wformat-nonliteral compile warning net: hns3: add some error checking in hclge_tm module ath10k: destroy sdio workqueue while remove sdio module iwlwifi: mvm: Drop large non sta frames perf stat: Make metric event lookup more robust net: usb: asix: init MAC address buffers gpiolib: Fix references to gpiod_[gs]et_*value_cansleep() variants Bluetooth: hci_bcsp: Fix memory leak in rx_skb Bluetooth: 6lowpan: search for destination address in all peers Bluetooth: Check state in l2cap_disconnect_rsp gtp: add missing gtp_encap_disable_sock() in gtp_encap_enable() Bluetooth: validate BLE connection interval updates gtp: fix suspicious RCU usage gtp: fix Illegal context switch in RCU read-side critical section. gtp: fix use-after-free in gtp_encap_destroy() gtp: fix use-after-free in gtp_newlink() net: mvmdio: defer probe of orion-mdio if a clock is not ready iavf: fix dereference of null rx_buffer pointer floppy: fix div-by-zero in setup_format_params floppy: fix out-of-bounds read in next_valid_format floppy: fix invalid pointer dereference in drive_name floppy: fix out-of-bounds read in copy_buffer xen: let alloc_xenballooned_pages() fail if not enough memory free scsi: NCR5380: Reduce goto statements in NCR5380_select() scsi: NCR5380: Always re-enable reselection interrupt Revert "scsi: ncr5380: Increase register polling limit" scsi: core: Fix race on creating sense cache scsi: megaraid_sas: Fix calculation of target ID scsi: mac_scsi: Increase PIO/PDMA transfer length threshold scsi: mac_scsi: Fix pseudo DMA implementation, take 2 crypto: ghash - fix unaligned memory access in ghash_setkey() crypto: ccp - Validate the the error value used to index error messages crypto: arm64/sha1-ce - correct digest for empty data in finup crypto: arm64/sha2-ce - correct digest for empty data in finup crypto: chacha20poly1305 - fix atomic sleep when using async algorithm crypto: ccp - memset structure fields to zero before reuse crypto: ccp/gcm - use const time tag comparison. crypto: crypto4xx - fix a potential double free in ppc4xx_trng_probe Input: gtco - bounds check collection indent level Input: alps - don't handle ALPS cs19 trackpoint-only device Input: synaptics - whitelist Lenovo T580 SMBus intertouch Input: alps - fix a mismatch between a condition check and its comment regulator: s2mps11: Fix buck7 and buck8 wrong voltages arm64: tegra: Update Jetson TX1 GPU regulator timings iwlwifi: pcie: don't service an interrupt that was masked iwlwifi: pcie: fix ALIVE interrupt handling for gen2 devices w/o MSI-X NFSv4: Handle the special Linux file open access mode pnfs/flexfiles: Fix PTR_ERR() dereferences in ff_layout_track_ds_error lib/scatterlist: Fix mapping iterator when sg->offset is greater than PAGE_SIZE ASoC: dapm: Adapt for debugfs API change ALSA: seq: Break too long mutex context in the write loop ALSA: hda/realtek: apply ALC891 headset fixup to one Dell machine media: v4l2: Test type instead of cfg->type in v4l2_ctrl_new_custom() media: coda: Remove unbalanced and unneeded mutex unlock KVM: x86/vPMU: refine kvm_pmu err msg when event creation failed arm64: tegra: Fix AGIC register range fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys inodes. drm/nouveau/i2c: Enable i2c pads & busses during preinit padata: use smp_mb in padata_reorder to avoid orphaned padata jobs dm zoned: fix zone state management race xen/events: fix binding user event channels to cpus 9p/xen: Add cleanup path in p9_trans_xen_init 9p/virtio: Add cleanup path in p9_virtio_init x86/boot: Fix memory leak in default_get_smp_config() perf/x86/amd/uncore: Do not set 'ThreadMask' and 'SliceMask' for non-L3 PMCs perf/x86/amd/uncore: Set the thread mask for F17h L3 PMCs intel_th: pci: Add Ice Lake NNPI support PCI: Do not poll for PME if the device is in D3cold Btrfs: fix data loss after inode eviction, renaming it, and fsync it Btrfs: fix fsync not persisting dentry deletions due to inode evictions Btrfs: add missing inode version, ctime and mtime updates when punching hole HID: wacom: generic: only switch the mode on devices with LEDs HID: wacom: correct touch resolution x/y typo libnvdimm/pfn: fix fsdax-mode namespace info-block zero-fields coda: pass the host file in vma->vm_file on mmap gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM PCI: hv: Fix a use-after-free bug in hv_eject_device_work() crypto: caam - limit output IV to CBC to work around CTR mode DMA issue parisc: Ensure userspace privilege for ptraced processes in regset functions parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1 powerpc/32s: fix suspend/resume when IBATs 4-7 are used powerpc/watchpoint: Restore NV GPRs while returning from exception eCryptfs: fix a couple type promotion bugs intel_th: msu: Fix single mode with disabled IOMMU Bluetooth: Add SMP workaround Microsoft Surface Precision Mouse bug usb: Handle USB3 remote wakeup for LPM enabled devices correctly net: mvmdio: allow up to four clocks to be specified for orion-mdio dt-bindings: allow up to four clocks for orion-mdio dm bufio: fix deadlock with loop device compiler.h, kasan: Avoid duplicating __read_once_size_nocheck() compiler.h: Add read_word_at_a_time() function. lib/strscpy: Shut up KASAN false-positives in strscpy() bnx2x: Prevent load reordering in tx completion processing bnx2x: Prevent ptp_task to be rescheduled indefinitely caif-hsi: fix possible deadlock in cfhsi_exit_module() igmp: fix memory leak in igmpv3_del_delrec() ipv4: don't set IPv6 only flags to IPv4 addresses net: bcmgenet: use promisc for unsupported filters net: dsa: mv88e6xxx: wait after reset deactivation net: neigh: fix multiple neigh timer scheduling net: openvswitch: fix csum updates for MPLS actions nfc: fix potential illegal memory access rxrpc: Fix send on a connected, but unbound socket sky2: Disable MSI on ASUS P6T vrf: make sure skb->data contains ip header to make routing macsec: fix use-after-free of skb during RX macsec: fix checksumming after decryption netrom: fix a memory leak in nr_rx_frame() netrom: hold sock when setting skb->destructor bonding: validate ip header before check IPPROTO_IGMP net: make skb_dst_force return true when dst is refcounted tcp: fix tcp_set_congestion_control() use from bpf hook tcp: Reset bytes_acked and bytes_received when disconnecting net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query net: bridge: stp: don't cache eth dest pointer before skb pull dma-buf: balance refcount inbalance dma-buf: Discard old fence_excl on retrying get_fences_rcu for realloc MIPS: lb60: Fix pin mappings ext4: don't allow any modifications to an immutable file ext4: enforce the immutable flag on open files mm: add filemap_fdatawait_range_keep_errors() jbd2: introduce jbd2_inode dirty range scoping ext4: use jbd2_inode dirty range scoping ext4: allow directory holes mm: vmscan: scan anonymous pages on file refaults perf/events/amd/uncore: Fix amd_uncore_llc ID to use pre-defined cpu_llc_id NFSv4: Fix open create exclusive when the server reboots nfsd: increase DRC cache limit nfsd: give out fewer session slots as limit approaches nfsd: fix performance-limiting session calculation nfsd: Fix overflow causing non-working mounts on 1 TB machines hvsock: fix epollout hang from race condition drm/panel: simple: Fix panel_simple_dsi_probe usb: core: hub: Disable hub-initiated U1/U2 tty: max310x: Fix invalid baudrate divisors calculator pinctrl: rockchip: fix leaked of_node references tty: serial: cpm_uart - fix init when SMC is relocated drm/edid: Fix a missing-check bug in drm_load_edid_firmware() PCI: Return error if cannot probe VF drm/bridge: tc358767: read display_props in get_modes() drm/bridge: sii902x: pixel clock unit is 10kHz instead of 1kHz drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry memstick: Fix error cleanup path of memstick_init tty/serial: digicolor: Fix digicolor-usart already registered warning tty: serial: msm_serial: avoid system lockup condition serial: 8250: Fix TX interrupt handling condition drm/virtio: Add memory barriers for capset cache. phy: renesas: rcar-gen2: Fix memory leak at error paths powerpc/pseries/mobility: prevent cpu hotplug during DT update drm/rockchip: Properly adjust to a true clock in adjusted_mode tty: serial_core: Set port active bit in uart_port_activate usb: gadget: Zero ffs_io_data powerpc/pci/of: Fix OF flags parsing for 64bit BARs drm/msm: Depopulate platform on probe failure serial: mctrl_gpio: Check if GPIO property exisits before requesting it PCI: sysfs: Ignore lockdep for remove attribute kbuild: Add -Werror=unknown-warning-option to CLANG_FLAGS PCI: xilinx-nwl: Fix Multi MSI data programming iio: iio-utils: Fix possible incorrect mask calculation powerpc/xmon: Fix disabling tracing while in xmon recordmcount: Fix spurious mcount entries on powerpc mfd: core: Set fwnode for created devices mfd: arizona: Fix undefined behavior mfd: hi655x-pmic: Fix missing return value check for devm_regmap_init_mmio_clk um: Silence lockdep complaint about mmap_sem powerpc/4xx/uic: clear pending interrupt after irq type/pol change RDMA/i40iw: Set queue pair state when being queried serial: sh-sci: Terminate TX DMA during buffer flushing serial: sh-sci: Fix TX DMA buffer flushing and workqueue races kallsyms: exclude kasan local symbols on s390 perf test mmap-thread-lookup: Initialize variable to suppress memory sanitizer warning perf session: Fix potential NULL pointer dereference found by the smatch tool perf annotate: Fix dereferencing freed memory found by the smatch tool RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM PCI: dwc: pci-dra7xx: Fix compilation when !CONFIG_GPIOLIB powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h f2fs: avoid out-of-range memory access mailbox: handle failed named mailbox channel request powerpc/eeh: Handle hugepages in ioremap space block/bio-integrity: fix a memory leak bug sh: prevent warnings when using iounmap mm/kmemleak.c: fix check for softirq context 9p: pass the correct prototype to read_cache_page mm/gup.c: mark undo_dev_pagemap as __maybe_unused mm/gup.c: remove some BUG_ONs from get_gate_page() mm/mmu_notifier: use hlist_add_head_rcu() locking/lockdep: Fix lock used or unused stats error locking/lockdep: Hide unused 'class' variable drm/crc: Only report a single overflow when a CRC fd is opened drm/crc-debugfs: Also sprinkle irqrestore over early exits usb: wusbcore: fix unbalanced get/put cluster_id usb: pci-quirks: Correct AMD PLL quirk detection KVM: nVMX: do not use dangling shadow VMCS after guest reset btrfs: inode: Don't compress if NODATASUM or NODATACOW set x86/sysfb_efi: Add quirks for some devices with swapped width and height x86/speculation/mds: Apply more accurate check on hypervisor platform binder: prevent transactions to context manager from its own process. fpga-manager: altera-ps-spi: Fix build error hpet: Fix division by zero in hpet_time_div() ALSA: line6: Fix wrong altsetting for LINE6_PODHD500_1 ALSA: hda - Add a conexant codec entry to let mute led work powerpc/xive: Fix loop exit-condition in xive_find_target_in_mask() powerpc/tm: Fix oops on sigreturn on systems without TM access: avoid the RCU grace period for the temporary subjective credentials Linux 4.14.135 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
755 lines
20 KiB
C
755 lines
20 KiB
C
/*
|
|
* ChaCha20-Poly1305 AEAD, RFC7539
|
|
*
|
|
* Copyright (C) 2015 Martin Willi
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
|
|
#include <crypto/internal/aead.h>
|
|
#include <crypto/internal/hash.h>
|
|
#include <crypto/internal/skcipher.h>
|
|
#include <crypto/scatterwalk.h>
|
|
#include <crypto/chacha.h>
|
|
#include <crypto/poly1305.h>
|
|
#include <linux/err.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
|
|
#include "internal.h"
|
|
|
|
#define CHACHAPOLY_IV_SIZE 12
|
|
|
|
struct chachapoly_instance_ctx {
|
|
struct crypto_skcipher_spawn chacha;
|
|
struct crypto_ahash_spawn poly;
|
|
unsigned int saltlen;
|
|
};
|
|
|
|
struct chachapoly_ctx {
|
|
struct crypto_skcipher *chacha;
|
|
struct crypto_ahash *poly;
|
|
/* key bytes we use for the ChaCha20 IV */
|
|
unsigned int saltlen;
|
|
u8 salt[];
|
|
};
|
|
|
|
struct poly_req {
|
|
/* zero byte padding for AD/ciphertext, as needed */
|
|
u8 pad[POLY1305_BLOCK_SIZE];
|
|
/* tail data with AD/ciphertext lengths */
|
|
struct {
|
|
__le64 assoclen;
|
|
__le64 cryptlen;
|
|
} tail;
|
|
struct scatterlist src[1];
|
|
struct ahash_request req; /* must be last member */
|
|
};
|
|
|
|
struct chacha_req {
|
|
u8 iv[CHACHA_IV_SIZE];
|
|
struct scatterlist src[1];
|
|
struct skcipher_request req; /* must be last member */
|
|
};
|
|
|
|
struct chachapoly_req_ctx {
|
|
struct scatterlist src[2];
|
|
struct scatterlist dst[2];
|
|
/* the key we generate for Poly1305 using Chacha20 */
|
|
u8 key[POLY1305_KEY_SIZE];
|
|
/* calculated Poly1305 tag */
|
|
u8 tag[POLY1305_DIGEST_SIZE];
|
|
/* length of data to en/decrypt, without ICV */
|
|
unsigned int cryptlen;
|
|
/* Actual AD, excluding IV */
|
|
unsigned int assoclen;
|
|
/* request flags, with MAY_SLEEP cleared if needed */
|
|
u32 flags;
|
|
union {
|
|
struct poly_req poly;
|
|
struct chacha_req chacha;
|
|
} u;
|
|
};
|
|
|
|
static inline void async_done_continue(struct aead_request *req, int err,
|
|
int (*cont)(struct aead_request *))
|
|
{
|
|
if (!err) {
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
|
|
rctx->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
|
err = cont(req);
|
|
}
|
|
|
|
if (err != -EINPROGRESS && err != -EBUSY)
|
|
aead_request_complete(req, err);
|
|
}
|
|
|
|
static void chacha_iv(u8 *iv, struct aead_request *req, u32 icb)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
__le32 leicb = cpu_to_le32(icb);
|
|
|
|
memcpy(iv, &leicb, sizeof(leicb));
|
|
memcpy(iv + sizeof(leicb), ctx->salt, ctx->saltlen);
|
|
memcpy(iv + sizeof(leicb) + ctx->saltlen, req->iv,
|
|
CHACHA_IV_SIZE - sizeof(leicb) - ctx->saltlen);
|
|
}
|
|
|
|
static int poly_verify_tag(struct aead_request *req)
|
|
{
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
u8 tag[sizeof(rctx->tag)];
|
|
|
|
scatterwalk_map_and_copy(tag, req->src,
|
|
req->assoclen + rctx->cryptlen,
|
|
sizeof(tag), 0);
|
|
if (crypto_memneq(tag, rctx->tag, sizeof(tag)))
|
|
return -EBADMSG;
|
|
return 0;
|
|
}
|
|
|
|
static int poly_copy_tag(struct aead_request *req)
|
|
{
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
|
|
scatterwalk_map_and_copy(rctx->tag, req->dst,
|
|
req->assoclen + rctx->cryptlen,
|
|
sizeof(rctx->tag), 1);
|
|
return 0;
|
|
}
|
|
|
|
static void chacha_decrypt_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_verify_tag);
|
|
}
|
|
|
|
static int chacha_decrypt(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct chacha_req *creq = &rctx->u.chacha;
|
|
struct scatterlist *src, *dst;
|
|
int err;
|
|
|
|
if (rctx->cryptlen == 0)
|
|
goto skip;
|
|
|
|
chacha_iv(creq->iv, req, 1);
|
|
|
|
sg_init_table(rctx->src, 2);
|
|
src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
|
|
dst = src;
|
|
|
|
if (req->src != req->dst) {
|
|
sg_init_table(rctx->dst, 2);
|
|
dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen);
|
|
}
|
|
|
|
skcipher_request_set_callback(&creq->req, rctx->flags,
|
|
chacha_decrypt_done, req);
|
|
skcipher_request_set_tfm(&creq->req, ctx->chacha);
|
|
skcipher_request_set_crypt(&creq->req, src, dst,
|
|
rctx->cryptlen, creq->iv);
|
|
err = crypto_skcipher_decrypt(&creq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
skip:
|
|
return poly_verify_tag(req);
|
|
}
|
|
|
|
static int poly_tail_continue(struct aead_request *req)
|
|
{
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
|
|
if (rctx->cryptlen == req->cryptlen) /* encrypting */
|
|
return poly_copy_tag(req);
|
|
|
|
return chacha_decrypt(req);
|
|
}
|
|
|
|
static void poly_tail_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_tail_continue);
|
|
}
|
|
|
|
static int poly_tail(struct aead_request *req)
|
|
{
|
|
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct poly_req *preq = &rctx->u.poly;
|
|
__le64 len;
|
|
int err;
|
|
|
|
sg_init_table(preq->src, 1);
|
|
len = cpu_to_le64(rctx->assoclen);
|
|
memcpy(&preq->tail.assoclen, &len, sizeof(len));
|
|
len = cpu_to_le64(rctx->cryptlen);
|
|
memcpy(&preq->tail.cryptlen, &len, sizeof(len));
|
|
sg_set_buf(preq->src, &preq->tail, sizeof(preq->tail));
|
|
|
|
ahash_request_set_callback(&preq->req, rctx->flags,
|
|
poly_tail_done, req);
|
|
ahash_request_set_tfm(&preq->req, ctx->poly);
|
|
ahash_request_set_crypt(&preq->req, preq->src,
|
|
rctx->tag, sizeof(preq->tail));
|
|
|
|
err = crypto_ahash_finup(&preq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_tail_continue(req);
|
|
}
|
|
|
|
static void poly_cipherpad_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_tail);
|
|
}
|
|
|
|
static int poly_cipherpad(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct poly_req *preq = &rctx->u.poly;
|
|
unsigned int padlen, bs = POLY1305_BLOCK_SIZE;
|
|
int err;
|
|
|
|
padlen = (bs - (rctx->cryptlen % bs)) % bs;
|
|
memset(preq->pad, 0, sizeof(preq->pad));
|
|
sg_init_table(preq->src, 1);
|
|
sg_set_buf(preq->src, &preq->pad, padlen);
|
|
|
|
ahash_request_set_callback(&preq->req, rctx->flags,
|
|
poly_cipherpad_done, req);
|
|
ahash_request_set_tfm(&preq->req, ctx->poly);
|
|
ahash_request_set_crypt(&preq->req, preq->src, NULL, padlen);
|
|
|
|
err = crypto_ahash_update(&preq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_tail(req);
|
|
}
|
|
|
|
static void poly_cipher_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_cipherpad);
|
|
}
|
|
|
|
static int poly_cipher(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct poly_req *preq = &rctx->u.poly;
|
|
struct scatterlist *crypt = req->src;
|
|
int err;
|
|
|
|
if (rctx->cryptlen == req->cryptlen) /* encrypting */
|
|
crypt = req->dst;
|
|
|
|
sg_init_table(rctx->src, 2);
|
|
crypt = scatterwalk_ffwd(rctx->src, crypt, req->assoclen);
|
|
|
|
ahash_request_set_callback(&preq->req, rctx->flags,
|
|
poly_cipher_done, req);
|
|
ahash_request_set_tfm(&preq->req, ctx->poly);
|
|
ahash_request_set_crypt(&preq->req, crypt, NULL, rctx->cryptlen);
|
|
|
|
err = crypto_ahash_update(&preq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_cipherpad(req);
|
|
}
|
|
|
|
static void poly_adpad_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_cipher);
|
|
}
|
|
|
|
static int poly_adpad(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct poly_req *preq = &rctx->u.poly;
|
|
unsigned int padlen, bs = POLY1305_BLOCK_SIZE;
|
|
int err;
|
|
|
|
padlen = (bs - (rctx->assoclen % bs)) % bs;
|
|
memset(preq->pad, 0, sizeof(preq->pad));
|
|
sg_init_table(preq->src, 1);
|
|
sg_set_buf(preq->src, preq->pad, padlen);
|
|
|
|
ahash_request_set_callback(&preq->req, rctx->flags,
|
|
poly_adpad_done, req);
|
|
ahash_request_set_tfm(&preq->req, ctx->poly);
|
|
ahash_request_set_crypt(&preq->req, preq->src, NULL, padlen);
|
|
|
|
err = crypto_ahash_update(&preq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_cipher(req);
|
|
}
|
|
|
|
static void poly_ad_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_adpad);
|
|
}
|
|
|
|
static int poly_ad(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct poly_req *preq = &rctx->u.poly;
|
|
int err;
|
|
|
|
ahash_request_set_callback(&preq->req, rctx->flags,
|
|
poly_ad_done, req);
|
|
ahash_request_set_tfm(&preq->req, ctx->poly);
|
|
ahash_request_set_crypt(&preq->req, req->src, NULL, rctx->assoclen);
|
|
|
|
err = crypto_ahash_update(&preq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_adpad(req);
|
|
}
|
|
|
|
static void poly_setkey_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_ad);
|
|
}
|
|
|
|
static int poly_setkey(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct poly_req *preq = &rctx->u.poly;
|
|
int err;
|
|
|
|
sg_init_table(preq->src, 1);
|
|
sg_set_buf(preq->src, rctx->key, sizeof(rctx->key));
|
|
|
|
ahash_request_set_callback(&preq->req, rctx->flags,
|
|
poly_setkey_done, req);
|
|
ahash_request_set_tfm(&preq->req, ctx->poly);
|
|
ahash_request_set_crypt(&preq->req, preq->src, NULL, sizeof(rctx->key));
|
|
|
|
err = crypto_ahash_update(&preq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_ad(req);
|
|
}
|
|
|
|
static void poly_init_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_setkey);
|
|
}
|
|
|
|
static int poly_init(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct poly_req *preq = &rctx->u.poly;
|
|
int err;
|
|
|
|
ahash_request_set_callback(&preq->req, rctx->flags,
|
|
poly_init_done, req);
|
|
ahash_request_set_tfm(&preq->req, ctx->poly);
|
|
|
|
err = crypto_ahash_init(&preq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_setkey(req);
|
|
}
|
|
|
|
static void poly_genkey_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_init);
|
|
}
|
|
|
|
static int poly_genkey(struct aead_request *req)
|
|
{
|
|
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct chacha_req *creq = &rctx->u.chacha;
|
|
int err;
|
|
|
|
rctx->assoclen = req->assoclen;
|
|
|
|
if (crypto_aead_ivsize(tfm) == 8) {
|
|
if (rctx->assoclen < 8)
|
|
return -EINVAL;
|
|
rctx->assoclen -= 8;
|
|
}
|
|
|
|
sg_init_table(creq->src, 1);
|
|
memset(rctx->key, 0, sizeof(rctx->key));
|
|
sg_set_buf(creq->src, rctx->key, sizeof(rctx->key));
|
|
|
|
chacha_iv(creq->iv, req, 0);
|
|
|
|
skcipher_request_set_callback(&creq->req, rctx->flags,
|
|
poly_genkey_done, req);
|
|
skcipher_request_set_tfm(&creq->req, ctx->chacha);
|
|
skcipher_request_set_crypt(&creq->req, creq->src, creq->src,
|
|
POLY1305_KEY_SIZE, creq->iv);
|
|
|
|
err = crypto_skcipher_decrypt(&creq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
return poly_init(req);
|
|
}
|
|
|
|
static void chacha_encrypt_done(struct crypto_async_request *areq, int err)
|
|
{
|
|
async_done_continue(areq->data, err, poly_genkey);
|
|
}
|
|
|
|
static int chacha_encrypt(struct aead_request *req)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
struct chacha_req *creq = &rctx->u.chacha;
|
|
struct scatterlist *src, *dst;
|
|
int err;
|
|
|
|
if (req->cryptlen == 0)
|
|
goto skip;
|
|
|
|
chacha_iv(creq->iv, req, 1);
|
|
|
|
sg_init_table(rctx->src, 2);
|
|
src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
|
|
dst = src;
|
|
|
|
if (req->src != req->dst) {
|
|
sg_init_table(rctx->dst, 2);
|
|
dst = scatterwalk_ffwd(rctx->dst, req->dst, req->assoclen);
|
|
}
|
|
|
|
skcipher_request_set_callback(&creq->req, rctx->flags,
|
|
chacha_encrypt_done, req);
|
|
skcipher_request_set_tfm(&creq->req, ctx->chacha);
|
|
skcipher_request_set_crypt(&creq->req, src, dst,
|
|
req->cryptlen, creq->iv);
|
|
err = crypto_skcipher_encrypt(&creq->req);
|
|
if (err)
|
|
return err;
|
|
|
|
skip:
|
|
return poly_genkey(req);
|
|
}
|
|
|
|
static int chachapoly_encrypt(struct aead_request *req)
|
|
{
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
|
|
rctx->cryptlen = req->cryptlen;
|
|
rctx->flags = aead_request_flags(req);
|
|
|
|
/* encrypt call chain:
|
|
* - chacha_encrypt/done()
|
|
* - poly_genkey/done()
|
|
* - poly_init/done()
|
|
* - poly_setkey/done()
|
|
* - poly_ad/done()
|
|
* - poly_adpad/done()
|
|
* - poly_cipher/done()
|
|
* - poly_cipherpad/done()
|
|
* - poly_tail/done/continue()
|
|
* - poly_copy_tag()
|
|
*/
|
|
return chacha_encrypt(req);
|
|
}
|
|
|
|
static int chachapoly_decrypt(struct aead_request *req)
|
|
{
|
|
struct chachapoly_req_ctx *rctx = aead_request_ctx(req);
|
|
|
|
rctx->cryptlen = req->cryptlen - POLY1305_DIGEST_SIZE;
|
|
rctx->flags = aead_request_flags(req);
|
|
|
|
/* decrypt call chain:
|
|
* - poly_genkey/done()
|
|
* - poly_init/done()
|
|
* - poly_setkey/done()
|
|
* - poly_ad/done()
|
|
* - poly_adpad/done()
|
|
* - poly_cipher/done()
|
|
* - poly_cipherpad/done()
|
|
* - poly_tail/done/continue()
|
|
* - chacha_decrypt/done()
|
|
* - poly_verify_tag()
|
|
*/
|
|
return poly_genkey(req);
|
|
}
|
|
|
|
static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
|
|
unsigned int keylen)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(aead);
|
|
int err;
|
|
|
|
if (keylen != ctx->saltlen + CHACHA_KEY_SIZE)
|
|
return -EINVAL;
|
|
|
|
keylen -= ctx->saltlen;
|
|
memcpy(ctx->salt, key + keylen, ctx->saltlen);
|
|
|
|
crypto_skcipher_clear_flags(ctx->chacha, CRYPTO_TFM_REQ_MASK);
|
|
crypto_skcipher_set_flags(ctx->chacha, crypto_aead_get_flags(aead) &
|
|
CRYPTO_TFM_REQ_MASK);
|
|
|
|
err = crypto_skcipher_setkey(ctx->chacha, key, keylen);
|
|
crypto_aead_set_flags(aead, crypto_skcipher_get_flags(ctx->chacha) &
|
|
CRYPTO_TFM_RES_MASK);
|
|
return err;
|
|
}
|
|
|
|
static int chachapoly_setauthsize(struct crypto_aead *tfm,
|
|
unsigned int authsize)
|
|
{
|
|
if (authsize != POLY1305_DIGEST_SIZE)
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int chachapoly_init(struct crypto_aead *tfm)
|
|
{
|
|
struct aead_instance *inst = aead_alg_instance(tfm);
|
|
struct chachapoly_instance_ctx *ictx = aead_instance_ctx(inst);
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
|
|
struct crypto_skcipher *chacha;
|
|
struct crypto_ahash *poly;
|
|
unsigned long align;
|
|
|
|
poly = crypto_spawn_ahash(&ictx->poly);
|
|
if (IS_ERR(poly))
|
|
return PTR_ERR(poly);
|
|
|
|
chacha = crypto_spawn_skcipher(&ictx->chacha);
|
|
if (IS_ERR(chacha)) {
|
|
crypto_free_ahash(poly);
|
|
return PTR_ERR(chacha);
|
|
}
|
|
|
|
ctx->chacha = chacha;
|
|
ctx->poly = poly;
|
|
ctx->saltlen = ictx->saltlen;
|
|
|
|
align = crypto_aead_alignmask(tfm);
|
|
align &= ~(crypto_tfm_ctx_alignment() - 1);
|
|
crypto_aead_set_reqsize(
|
|
tfm,
|
|
align + offsetof(struct chachapoly_req_ctx, u) +
|
|
max(offsetof(struct chacha_req, req) +
|
|
sizeof(struct skcipher_request) +
|
|
crypto_skcipher_reqsize(chacha),
|
|
offsetof(struct poly_req, req) +
|
|
sizeof(struct ahash_request) +
|
|
crypto_ahash_reqsize(poly)));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void chachapoly_exit(struct crypto_aead *tfm)
|
|
{
|
|
struct chachapoly_ctx *ctx = crypto_aead_ctx(tfm);
|
|
|
|
crypto_free_ahash(ctx->poly);
|
|
crypto_free_skcipher(ctx->chacha);
|
|
}
|
|
|
|
static void chachapoly_free(struct aead_instance *inst)
|
|
{
|
|
struct chachapoly_instance_ctx *ctx = aead_instance_ctx(inst);
|
|
|
|
crypto_drop_skcipher(&ctx->chacha);
|
|
crypto_drop_ahash(&ctx->poly);
|
|
kfree(inst);
|
|
}
|
|
|
|
static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
|
|
const char *name, unsigned int ivsize)
|
|
{
|
|
struct crypto_attr_type *algt;
|
|
struct aead_instance *inst;
|
|
struct skcipher_alg *chacha;
|
|
struct crypto_alg *poly;
|
|
struct hash_alg_common *poly_hash;
|
|
struct chachapoly_instance_ctx *ctx;
|
|
const char *chacha_name, *poly_name;
|
|
int err;
|
|
|
|
if (ivsize > CHACHAPOLY_IV_SIZE)
|
|
return -EINVAL;
|
|
|
|
algt = crypto_get_attr_type(tb);
|
|
if (IS_ERR(algt))
|
|
return PTR_ERR(algt);
|
|
|
|
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
|
|
return -EINVAL;
|
|
|
|
chacha_name = crypto_attr_alg_name(tb[1]);
|
|
if (IS_ERR(chacha_name))
|
|
return PTR_ERR(chacha_name);
|
|
poly_name = crypto_attr_alg_name(tb[2]);
|
|
if (IS_ERR(poly_name))
|
|
return PTR_ERR(poly_name);
|
|
|
|
poly = crypto_find_alg(poly_name, &crypto_ahash_type,
|
|
CRYPTO_ALG_TYPE_HASH,
|
|
CRYPTO_ALG_TYPE_AHASH_MASK |
|
|
crypto_requires_sync(algt->type,
|
|
algt->mask));
|
|
if (IS_ERR(poly))
|
|
return PTR_ERR(poly);
|
|
poly_hash = __crypto_hash_alg_common(poly);
|
|
|
|
err = -EINVAL;
|
|
if (poly_hash->digestsize != POLY1305_DIGEST_SIZE)
|
|
goto out_put_poly;
|
|
|
|
err = -ENOMEM;
|
|
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
|
|
if (!inst)
|
|
goto out_put_poly;
|
|
|
|
ctx = aead_instance_ctx(inst);
|
|
ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize;
|
|
err = crypto_init_ahash_spawn(&ctx->poly, poly_hash,
|
|
aead_crypto_instance(inst));
|
|
if (err)
|
|
goto err_free_inst;
|
|
|
|
crypto_set_skcipher_spawn(&ctx->chacha, aead_crypto_instance(inst));
|
|
err = crypto_grab_skcipher(&ctx->chacha, chacha_name, 0,
|
|
crypto_requires_sync(algt->type,
|
|
algt->mask));
|
|
if (err)
|
|
goto err_drop_poly;
|
|
|
|
chacha = crypto_spawn_skcipher_alg(&ctx->chacha);
|
|
|
|
err = -EINVAL;
|
|
/* Need 16-byte IV size, including Initial Block Counter value */
|
|
if (crypto_skcipher_alg_ivsize(chacha) != CHACHA_IV_SIZE)
|
|
goto out_drop_chacha;
|
|
/* Not a stream cipher? */
|
|
if (chacha->base.cra_blocksize != 1)
|
|
goto out_drop_chacha;
|
|
|
|
err = -ENAMETOOLONG;
|
|
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
|
|
"%s(%s,%s)", name, chacha->base.cra_name,
|
|
poly->cra_name) >= CRYPTO_MAX_ALG_NAME)
|
|
goto out_drop_chacha;
|
|
if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
|
|
"%s(%s,%s)", name, chacha->base.cra_driver_name,
|
|
poly->cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
|
|
goto out_drop_chacha;
|
|
|
|
inst->alg.base.cra_flags = (chacha->base.cra_flags | poly->cra_flags) &
|
|
CRYPTO_ALG_ASYNC;
|
|
inst->alg.base.cra_priority = (chacha->base.cra_priority +
|
|
poly->cra_priority) / 2;
|
|
inst->alg.base.cra_blocksize = 1;
|
|
inst->alg.base.cra_alignmask = chacha->base.cra_alignmask |
|
|
poly->cra_alignmask;
|
|
inst->alg.base.cra_ctxsize = sizeof(struct chachapoly_ctx) +
|
|
ctx->saltlen;
|
|
inst->alg.ivsize = ivsize;
|
|
inst->alg.chunksize = crypto_skcipher_alg_chunksize(chacha);
|
|
inst->alg.maxauthsize = POLY1305_DIGEST_SIZE;
|
|
inst->alg.init = chachapoly_init;
|
|
inst->alg.exit = chachapoly_exit;
|
|
inst->alg.encrypt = chachapoly_encrypt;
|
|
inst->alg.decrypt = chachapoly_decrypt;
|
|
inst->alg.setkey = chachapoly_setkey;
|
|
inst->alg.setauthsize = chachapoly_setauthsize;
|
|
|
|
inst->free = chachapoly_free;
|
|
|
|
err = aead_register_instance(tmpl, inst);
|
|
if (err)
|
|
goto out_drop_chacha;
|
|
|
|
out_put_poly:
|
|
crypto_mod_put(poly);
|
|
return err;
|
|
|
|
out_drop_chacha:
|
|
crypto_drop_skcipher(&ctx->chacha);
|
|
err_drop_poly:
|
|
crypto_drop_ahash(&ctx->poly);
|
|
err_free_inst:
|
|
kfree(inst);
|
|
goto out_put_poly;
|
|
}
|
|
|
|
static int rfc7539_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
{
|
|
return chachapoly_create(tmpl, tb, "rfc7539", 12);
|
|
}
|
|
|
|
static int rfc7539esp_create(struct crypto_template *tmpl, struct rtattr **tb)
|
|
{
|
|
return chachapoly_create(tmpl, tb, "rfc7539esp", 8);
|
|
}
|
|
|
|
static struct crypto_template rfc7539_tmpl = {
|
|
.name = "rfc7539",
|
|
.create = rfc7539_create,
|
|
.module = THIS_MODULE,
|
|
};
|
|
|
|
static struct crypto_template rfc7539esp_tmpl = {
|
|
.name = "rfc7539esp",
|
|
.create = rfc7539esp_create,
|
|
.module = THIS_MODULE,
|
|
};
|
|
|
|
static int __init chacha20poly1305_module_init(void)
|
|
{
|
|
int err;
|
|
|
|
err = crypto_register_template(&rfc7539_tmpl);
|
|
if (err)
|
|
return err;
|
|
|
|
err = crypto_register_template(&rfc7539esp_tmpl);
|
|
if (err)
|
|
crypto_unregister_template(&rfc7539_tmpl);
|
|
|
|
return err;
|
|
}
|
|
|
|
static void __exit chacha20poly1305_module_exit(void)
|
|
{
|
|
crypto_unregister_template(&rfc7539esp_tmpl);
|
|
crypto_unregister_template(&rfc7539_tmpl);
|
|
}
|
|
|
|
module_init(chacha20poly1305_module_init);
|
|
module_exit(chacha20poly1305_module_exit);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");
|
|
MODULE_DESCRIPTION("ChaCha20-Poly1305 AEAD");
|
|
MODULE_ALIAS_CRYPTO("rfc7539");
|
|
MODULE_ALIAS_CRYPTO("rfc7539esp");
|