Commit c434e25b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'v6.11-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto update from Herbert Xu:
 "API:
   - Test setkey in no-SIMD context
   - Add skcipher speed test for user-specified algorithm

  Algorithms:
   - Add x25519 support on ppc64le
   - Add VAES and AVX512 / AVX10 optimized AES-GCM on x86
   - Remove sm2 algorithm

  Drivers:
   - Add Allwinner H616 support to sun8i-ce
   - Use DMA in stm32
   - Add Exynos850 hwrng support to exynos"

* tag 'v6.11-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (81 commits)
  hwrng: core - remove (un)register_miscdev()
  crypto: lib/mpi - delete unnecessary condition
  crypto: testmgr - generate power-of-2 lengths more often
  crypto: mxs-dcp - Ensure payload is zero when using key slot
  hwrng: Kconfig - Do not enable by default CN10K driver
  crypto: starfive - Fix nent assignment in rsa dec
  crypto: starfive - Align rsa input data to 32-bit
  crypto: qat - fix unintentional re-enabling of error interrupts
  crypto: qat - extend scope of lock in adf_cfg_add_key_value_param()
  Documentation: qat: fix auto_reset attribute details
  crypto: sun8i-ce - add Allwinner H616 support
  crypto: sun8i-ce - wrap accesses to descriptor address fields
  dt-bindings: crypto: sun8i-ce: Add compatible for H616
  hwrng: core - Fix wrong quality calculation at hw rng registration
  hwrng: exynos - Enable Exynos850 support
  hwrng: exynos - Add SMC based TRNG operation
  hwrng: exynos - Implement bus clock control
  hwrng: exynos - Use devm_clk_get_enabled() to get the clock
  hwrng: exynos - Improve coding style
  dt-bindings: rng: Add Exynos850 support to exynos-trng
  ...
parents 720261cf df1e9791
......@@ -143,8 +143,8 @@ Description:
This attribute is only available for qat_4xxx devices.
What: /sys/bus/pci/devices/<BDF>/qat/auto_reset
Date: March 2024
KernelVersion: 6.8
Date: May 2024
KernelVersion: 6.9
Contact: qat-linux@intel.com
Description: (RW) Reports the current state of the autoreset feature
for a QAT device
......
......@@ -18,6 +18,7 @@ properties:
- allwinner,sun50i-a64-crypto
- allwinner,sun50i-h5-crypto
- allwinner,sun50i-h6-crypto
- allwinner,sun50i-h616-crypto
reg:
maxItems: 1
......@@ -49,6 +50,7 @@ if:
compatible:
enum:
- allwinner,sun20i-d1-crypto
- allwinner,sun50i-h616-crypto
then:
properties:
clocks:
......
......@@ -26,6 +26,9 @@ properties:
items:
- const: core
power-domains:
maxItems: 1
required:
- compatible
- reg
......
......@@ -12,14 +12,17 @@ maintainers:
properties:
compatible:
const: samsung,exynos5250-trng
enum:
- samsung,exynos5250-trng
- samsung,exynos850-trng
clocks:
maxItems: 1
minItems: 1
maxItems: 2
clock-names:
items:
- const: secss
minItems: 1
maxItems: 2
reg:
maxItems: 1
......@@ -30,6 +33,35 @@ required:
- clock-names
- reg
allOf:
- if:
properties:
compatible:
contains:
const: samsung,exynos850-trng
then:
properties:
clocks:
items:
- description: SSS (Security Sub System) operating clock
- description: SSS (Security Sub System) bus clock
clock-names:
items:
- const: secss
- const: pclk
else:
properties:
clocks:
items:
- description: SSS (Security Sub System) operating clock
clock-names:
items:
- const: secss
additionalProperties: false
examples:
......
......@@ -980,6 +980,12 @@ F: include/uapi/linux/psp-dbc.h
F: tools/crypto/ccp/*.c
F: tools/crypto/ccp/*.py
AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER - HSTI SUPPORT
M: Mario Limonciello <mario.limonciello@amd.com>
L: linux-crypto@vger.kernel.org
S: Supported
F: drivers/crypto/ccp/hsti.*
AMD DISPLAY CORE
M: Harry Wentland <harry.wentland@amd.com>
M: Leo Li <sunpeng.li@amd.com>
......
......@@ -17,6 +17,7 @@
#include <linux/module.h>
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
MODULE_DESCRIPTION("Bit sliced AES using NEON instructions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("ecb(aes)");
......
......@@ -48,6 +48,7 @@
*/
#include <linux/linkage.h>
#include <linux/cfi_types.h>
#include <asm/assembler.h>
.text
......@@ -123,11 +124,12 @@
* uint crc32_pmull_le(unsigned char const *buffer,
* size_t len, uint crc32)
*/
ENTRY(crc32_pmull_le)
SYM_FUNC_START(crc32_pmull_le)
adr r3, .Lcrc32_constants
b 0f
SYM_FUNC_END(crc32_pmull_le)
ENTRY(crc32c_pmull_le)
SYM_FUNC_START(crc32c_pmull_le)
adr r3, .Lcrc32c_constants
0: bic LEN, LEN, #15
......@@ -236,8 +238,7 @@ fold_64:
vmov r0, s5
bx lr
ENDPROC(crc32_pmull_le)
ENDPROC(crc32c_pmull_le)
SYM_FUNC_END(crc32c_pmull_le)
.macro __crc32, c
subs ip, r2, #8
......@@ -296,11 +297,11 @@ ARM_BE8(rev16 r3, r3 )
.endm
.align 5
ENTRY(crc32_armv8_le)
SYM_TYPED_FUNC_START(crc32_armv8_le)
__crc32
ENDPROC(crc32_armv8_le)
SYM_FUNC_END(crc32_armv8_le)
.align 5
ENTRY(crc32c_armv8_le)
SYM_TYPED_FUNC_START(crc32c_armv8_le)
__crc32 c
ENDPROC(crc32c_armv8_le)
SYM_FUNC_END(crc32c_armv8_le)
......@@ -241,6 +241,7 @@ module_init(crc32_pmull_mod_init);
module_exit(crc32_pmull_mod_exit);
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
MODULE_DESCRIPTION("Accelerated CRC32(C) using ARM CRC, NEON and Crypto Extensions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("crc32");
MODULE_ALIAS_CRYPTO("crc32c");
......@@ -84,5 +84,6 @@ module_init(crc_t10dif_mod_init);
module_exit(crc_t10dif_mod_exit);
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
MODULE_DESCRIPTION("Accelerated CRC-T10DIF using ARM NEON and Crypto Extensions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("crct10dif");
......@@ -133,4 +133,5 @@ module_exit(arm_curve25519_exit);
MODULE_ALIAS_CRYPTO("curve25519");
MODULE_ALIAS_CRYPTO("curve25519-neon");
MODULE_DESCRIPTION("Public key crypto: Curve25519 (NEON-accelerated)");
MODULE_LICENSE("GPL v2");
......@@ -267,6 +267,7 @@ static void __exit arm_poly1305_mod_exit(void)
module_init(arm_poly1305_mod_init);
module_exit(arm_poly1305_mod_exit);
MODULE_DESCRIPTION("Accelerated Poly1305 transform for ARM");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("poly1305");
MODULE_ALIAS_CRYPTO("poly1305-arm");
......
......@@ -16,6 +16,7 @@
#include <linux/module.h>
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
MODULE_DESCRIPTION("Bit sliced AES using NEON instructions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("ecb(aes)");
......
......@@ -98,7 +98,7 @@ static struct shash_alg crc_t10dif_alg[] = {{
.base.cra_name = "crct10dif",
.base.cra_driver_name = "crct10dif-arm64-neon",
.base.cra_priority = 100,
.base.cra_priority = 150,
.base.cra_blocksize = CRC_T10DIF_BLOCK_SIZE,
.base.cra_module = THIS_MODULE,
}, {
......@@ -138,6 +138,7 @@ module_cpu_feature_match(ASIMD, crc_t10dif_mod_init);
module_exit(crc_t10dif_mod_exit);
MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
MODULE_DESCRIPTION("CRC-T10DIF using arm64 NEON and Crypto Extensions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("crct10dif");
MODULE_ALIAS_CRYPTO("crct10dif-arm64-ce");
......@@ -226,6 +226,7 @@ static void __exit neon_poly1305_mod_exit(void)
module_init(neon_poly1305_mod_init);
module_exit(neon_poly1305_mod_exit);
MODULE_DESCRIPTION("Poly1305 transform using NEON instructions");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("poly1305");
MODULE_ALIAS_CRYPTO("poly1305-neon");
......@@ -2,6 +2,17 @@
menu "Accelerated Cryptographic Algorithms for CPU (powerpc)"
config CRYPTO_CURVE25519_PPC64
tristate "Public key crypto: Curve25519 (PowerPC64)"
depends on PPC64 && CPU_LITTLE_ENDIAN
select CRYPTO_LIB_CURVE25519_GENERIC
select CRYPTO_ARCH_HAVE_LIB_CURVE25519
help
Curve25519 algorithm
Architecture: PowerPC64
- Little-endian
config CRYPTO_CRC32C_VPMSUM
tristate "CRC32c"
depends on PPC64 && ALTIVEC
......
......@@ -17,6 +17,7 @@ obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o
obj-$(CONFIG_CRYPTO_CHACHA20_P10) += chacha-p10-crypto.o
obj-$(CONFIG_CRYPTO_POLY1305_P10) += poly1305-p10-crypto.o
obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o
obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o
aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o
md5-ppc-y := md5-asm.o md5-glue.o
......@@ -29,6 +30,7 @@ aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-p
chacha-p10-crypto-y := chacha-p10-glue.o chacha-p10le-8x.o
poly1305-p10-crypto-y := poly1305-p10-glue.o poly1305-p10le_64.o
vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o
curve25519-ppc64le-y := curve25519-ppc64le-core.o curve25519-ppc64le_asm.o
ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
override flavour := linux-ppc64le
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2024- IBM Corp.
*
* X25519 scalar multiplication with 51 bits limbs for PPC64le.
* Based on RFC7748 and AArch64 optimized implementation for X25519
* - Algorithm 1 Scalar multiplication of a variable point
*/
#include <crypto/curve25519.h>
#include <crypto/internal/kpp.h>
#include <linux/types.h>
#include <linux/jump_label.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/cpufeature.h>
#include <linux/processor.h>
typedef uint64_t fe51[5];
asmlinkage void x25519_fe51_mul(fe51 h, const fe51 f, const fe51 g);
asmlinkage void x25519_fe51_sqr(fe51 h, const fe51 f);
asmlinkage void x25519_fe51_mul121666(fe51 h, fe51 f);
asmlinkage void x25519_fe51_sqr_times(fe51 h, const fe51 f, int n);
asmlinkage void x25519_fe51_frombytes(fe51 h, const uint8_t *s);
asmlinkage void x25519_fe51_tobytes(uint8_t *s, const fe51 h);
asmlinkage void x25519_cswap(fe51 p, fe51 q, unsigned int bit);
#define fmul x25519_fe51_mul
#define fsqr x25519_fe51_sqr
#define fmul121666 x25519_fe51_mul121666
#define fe51_tobytes x25519_fe51_tobytes
static void fadd(fe51 h, const fe51 f, const fe51 g)
{
h[0] = f[0] + g[0];
h[1] = f[1] + g[1];
h[2] = f[2] + g[2];
h[3] = f[3] + g[3];
h[4] = f[4] + g[4];
}
/*
* Prime = 2 ** 255 - 19, 255 bits
* (0x7fffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffed)
*
* Prime in 5 51-bit limbs
*/
static fe51 prime51 = { 0x7ffffffffffed, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff};
static void fsub(fe51 h, const fe51 f, const fe51 g)
{
h[0] = (f[0] + ((prime51[0] * 2))) - g[0];
h[1] = (f[1] + ((prime51[1] * 2))) - g[1];
h[2] = (f[2] + ((prime51[2] * 2))) - g[2];
h[3] = (f[3] + ((prime51[3] * 2))) - g[3];
h[4] = (f[4] + ((prime51[4] * 2))) - g[4];
}
static void fe51_frombytes(fe51 h, const uint8_t *s)
{
/*
* Make sure 64-bit aligned.
*/
unsigned char sbuf[32+8];
unsigned char *sb = PTR_ALIGN((void *)sbuf, 8);
memcpy(sb, s, 32);
x25519_fe51_frombytes(h, sb);
}
static void finv(fe51 o, const fe51 i)
{
fe51 a0, b, c, t00;
fsqr(a0, i);
x25519_fe51_sqr_times(t00, a0, 2);
fmul(b, t00, i);
fmul(a0, b, a0);
fsqr(t00, a0);
fmul(b, t00, b);
x25519_fe51_sqr_times(t00, b, 5);
fmul(b, t00, b);
x25519_fe51_sqr_times(t00, b, 10);
fmul(c, t00, b);
x25519_fe51_sqr_times(t00, c, 20);
fmul(t00, t00, c);
x25519_fe51_sqr_times(t00, t00, 10);
fmul(b, t00, b);
x25519_fe51_sqr_times(t00, b, 50);
fmul(c, t00, b);
x25519_fe51_sqr_times(t00, c, 100);
fmul(t00, t00, c);
x25519_fe51_sqr_times(t00, t00, 50);
fmul(t00, t00, b);
x25519_fe51_sqr_times(t00, t00, 5);
fmul(o, t00, a0);
}
static void curve25519_fe51(uint8_t out[32], const uint8_t scalar[32],
const uint8_t point[32])
{
fe51 x1, x2, z2, x3, z3;
uint8_t s[32];
unsigned int swap = 0;
int i;
memcpy(s, scalar, 32);
s[0] &= 0xf8;
s[31] &= 0x7f;
s[31] |= 0x40;
fe51_frombytes(x1, point);
z2[0] = z2[1] = z2[2] = z2[3] = z2[4] = 0;
x3[0] = x1[0];
x3[1] = x1[1];
x3[2] = x1[2];
x3[3] = x1[3];
x3[4] = x1[4];
x2[0] = z3[0] = 1;
x2[1] = z3[1] = 0;
x2[2] = z3[2] = 0;
x2[3] = z3[3] = 0;
x2[4] = z3[4] = 0;
for (i = 254; i >= 0; --i) {
unsigned int k_t = 1 & (s[i / 8] >> (i & 7));
fe51 a, b, c, d, e;
fe51 da, cb, aa, bb;
fe51 dacb_p, dacb_m;
swap ^= k_t;
x25519_cswap(x2, x3, swap);
x25519_cswap(z2, z3, swap);
swap = k_t;
fsub(b, x2, z2); // B = x_2 - z_2
fadd(a, x2, z2); // A = x_2 + z_2
fsub(d, x3, z3); // D = x_3 - z_3
fadd(c, x3, z3); // C = x_3 + z_3
fsqr(bb, b); // BB = B^2
fsqr(aa, a); // AA = A^2
fmul(da, d, a); // DA = D * A
fmul(cb, c, b); // CB = C * B
fsub(e, aa, bb); // E = AA - BB
fmul(x2, aa, bb); // x2 = AA * BB
fadd(dacb_p, da, cb); // DA + CB
fsub(dacb_m, da, cb); // DA - CB
fmul121666(z3, e); // 121666 * E
fsqr(z2, dacb_m); // (DA - CB)^2
fsqr(x3, dacb_p); // x3 = (DA + CB)^2
fadd(b, bb, z3); // BB + 121666 * E
fmul(z3, x1, z2); // z3 = x1 * (DA - CB)^2
fmul(z2, e, b); // z2 = e * (BB + (DA + CB)^2)
}
finv(z2, z2);
fmul(x2, x2, z2);
fe51_tobytes(out, x2);
}
void curve25519_arch(u8 mypublic[CURVE25519_KEY_SIZE],
const u8 secret[CURVE25519_KEY_SIZE],
const u8 basepoint[CURVE25519_KEY_SIZE])
{
curve25519_fe51(mypublic, secret, basepoint);
}
EXPORT_SYMBOL(curve25519_arch);
void curve25519_base_arch(u8 pub[CURVE25519_KEY_SIZE],
const u8 secret[CURVE25519_KEY_SIZE])
{
curve25519_fe51(pub, secret, curve25519_base_point);
}
EXPORT_SYMBOL(curve25519_base_arch);
static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
unsigned int len)
{
u8 *secret = kpp_tfm_ctx(tfm);
if (!len)
curve25519_generate_secret(secret);
else if (len == CURVE25519_KEY_SIZE &&
crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
memcpy(secret, buf, CURVE25519_KEY_SIZE);
else
return -EINVAL;
return 0;
}
static int curve25519_generate_public_key(struct kpp_request *req)
{
struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
const u8 *secret = kpp_tfm_ctx(tfm);
u8 buf[CURVE25519_KEY_SIZE];
int copied, nbytes;
if (req->src)
return -EINVAL;
curve25519_base_arch(buf, secret);
/* might want less than we've got */
nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
nbytes),
buf, nbytes);
if (copied != nbytes)
return -EINVAL;
return 0;
}
static int curve25519_compute_shared_secret(struct kpp_request *req)
{
struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
const u8 *secret = kpp_tfm_ctx(tfm);
u8 public_key[CURVE25519_KEY_SIZE];
u8 buf[CURVE25519_KEY_SIZE];
int copied, nbytes;
if (!req->src)
return -EINVAL;
copied = sg_copy_to_buffer(req->src,
sg_nents_for_len(req->src,
CURVE25519_KEY_SIZE),
public_key, CURVE25519_KEY_SIZE);
if (copied != CURVE25519_KEY_SIZE)
return -EINVAL;
curve25519_arch(buf, secret, public_key);
/* might want less than we've got */
nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
nbytes),
buf, nbytes);
if (copied != nbytes)
return -EINVAL;
return 0;
}
static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
{
return CURVE25519_KEY_SIZE;
}
static struct kpp_alg curve25519_alg = {
.base.cra_name = "curve25519",
.base.cra_driver_name = "curve25519-ppc64le",
.base.cra_priority = 200,
.base.cra_module = THIS_MODULE,
.base.cra_ctxsize = CURVE25519_KEY_SIZE,
.set_secret = curve25519_set_secret,
.generate_public_key = curve25519_generate_public_key,
.compute_shared_secret = curve25519_compute_shared_secret,
.max_size = curve25519_max_size,
};
static int __init curve25519_mod_init(void)
{
return IS_REACHABLE(CONFIG_CRYPTO_KPP) ?
crypto_register_kpp(&curve25519_alg) : 0;
}
static void __exit curve25519_mod_exit(void)
{
if (IS_REACHABLE(CONFIG_CRYPTO_KPP))
crypto_unregister_kpp(&curve25519_alg);
}
module_init(curve25519_mod_init);
module_exit(curve25519_mod_exit);
MODULE_ALIAS_CRYPTO("curve25519");
MODULE_ALIAS_CRYPTO("curve25519-ppc64le");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Danny Tsen <dtsen@us.ibm.com>");
This diff is collapsed.
......@@ -18,6 +18,7 @@ config CRYPTO_AES_NI_INTEL
depends on X86
select CRYPTO_AEAD
select CRYPTO_LIB_AES
select CRYPTO_LIB_GF128MUL
select CRYPTO_ALGAPI
select CRYPTO_SKCIPHER
select CRYPTO_SIMD
......
......@@ -48,8 +48,12 @@ chacha-x86_64-$(CONFIG_AS_AVX512) += chacha-avx512vl-x86_64.o
obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
aesni-intel-$(CONFIG_64BIT) += aesni-intel_avx-x86_64.o \
aes_ctrby8_avx-x86_64.o aes-xts-avx-x86_64.o
aesni-intel-$(CONFIG_64BIT) += aes_ctrby8_avx-x86_64.o \
aes-gcm-aesni-x86_64.o \
aes-xts-avx-x86_64.o
ifeq ($(CONFIG_AS_VAES)$(CONFIG_AS_VPCLMULQDQ),yy)
aesni-intel-$(CONFIG_64BIT) += aes-gcm-avx10-x86_64.o
endif
obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o
sha1-ssse3-y := sha1_avx2_x86_64_asm.o sha1_ssse3_asm.o sha1_ssse3_glue.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1720,5 +1720,6 @@ module_exit(curve25519_mod_exit);
MODULE_ALIAS_CRYPTO("curve25519");
MODULE_ALIAS_CRYPTO("curve25519-x86");
MODULE_DESCRIPTION("Curve25519 algorithm, ADX optimized");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment