172c33676SMaxim Ag /* $OpenBSD: crypto_lock.c,v 1.2 2018/11/28 15:51:32 jsing Exp $ */
272c33676SMaxim Ag /*
372c33676SMaxim Ag  * Copyright (c) 2018 Brent Cook <bcook@openbsd.org>
472c33676SMaxim Ag  *
572c33676SMaxim Ag  * Permission to use, copy, modify, and distribute this software for any
672c33676SMaxim Ag  * purpose with or without fee is hereby granted, provided that the above
772c33676SMaxim Ag  * copyright notice and this permission notice appear in all copies.
872c33676SMaxim Ag  *
972c33676SMaxim Ag  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1072c33676SMaxim Ag  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1172c33676SMaxim Ag  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1272c33676SMaxim Ag  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1372c33676SMaxim Ag  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1472c33676SMaxim Ag  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1572c33676SMaxim Ag  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1672c33676SMaxim Ag  */
1772c33676SMaxim Ag 
1872c33676SMaxim Ag #include <pthread.h>
1972c33676SMaxim Ag 
2072c33676SMaxim Ag #include <openssl/crypto.h>
2172c33676SMaxim Ag 
2272c33676SMaxim Ag static pthread_mutex_t locks[] = {
2372c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
2472c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
2572c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
2672c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
2772c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
2872c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
2972c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3072c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3172c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3272c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3372c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3472c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3572c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3672c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3772c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3872c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
3972c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4072c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4172c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4272c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4372c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4472c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4572c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4672c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4772c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4872c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
4972c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5072c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5172c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5272c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5372c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5472c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5572c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5672c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5772c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5872c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
5972c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
6072c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
6172c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
6272c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
6372c33676SMaxim Ag 	PTHREAD_MUTEX_INITIALIZER,
6472c33676SMaxim Ag };
6572c33676SMaxim Ag 
6672c33676SMaxim Ag #define CTASSERT(x)	extern char  _ctassert[(x) ? 1 : -1 ] \
6772c33676SMaxim Ag 			    __attribute__((__unused__))
6872c33676SMaxim Ag 
6972c33676SMaxim Ag CTASSERT((sizeof(locks) / sizeof(*locks)) == CRYPTO_NUM_LOCKS);
7072c33676SMaxim Ag 
7172c33676SMaxim Ag void
CRYPTO_lock(int mode,int type,const char * file,int line)7272c33676SMaxim Ag CRYPTO_lock(int mode, int type, const char *file, int line)
7372c33676SMaxim Ag {
7472c33676SMaxim Ag 	if (type < 0 || type >= CRYPTO_NUM_LOCKS)
7572c33676SMaxim Ag 		return;
7672c33676SMaxim Ag 
7772c33676SMaxim Ag 	if (mode & CRYPTO_LOCK)
7872c33676SMaxim Ag 		(void) pthread_mutex_lock(&locks[type]);
7972c33676SMaxim Ag 	else if (mode & CRYPTO_UNLOCK)
8072c33676SMaxim Ag 		(void) pthread_mutex_unlock(&locks[type]);
8172c33676SMaxim Ag }
8272c33676SMaxim Ag 
8372c33676SMaxim Ag int
CRYPTO_add_lock(int * pointer,int amount,int type,const char * file,int line)8472c33676SMaxim Ag CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
8572c33676SMaxim Ag     int line)
8672c33676SMaxim Ag {
8772c33676SMaxim Ag 	int ret;
8872c33676SMaxim Ag 
8972c33676SMaxim Ag 	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE, type, file, line);
9072c33676SMaxim Ag 	ret = *pointer + amount;
9172c33676SMaxim Ag 	*pointer = ret;
9272c33676SMaxim Ag 	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE, type, file, line);
9372c33676SMaxim Ag 
9472c33676SMaxim Ag 	return (ret);
9572c33676SMaxim Ag }
96